刷到nssctf學到的新東西,記錄一下經驗。

ciscn 2020 reverse z3_字符串

題目前面的附件分析和代碼定位都挺簡單。

ciscn 2020 reverse z3_偽代碼_02


這裏這個程序使用了程序代碼優化,所以進來之後沒有main函數,但是進來就是start函數,也很容易找到主函數(這裏的main是我自己把ida的偽代碼改名字的結果)

ciscn 2020 reverse z3_偽代碼_03


主函數裏面的東西也很容易分析出邏輯,為了防止偽代碼沒有完整翻譯彙編代碼,我們進入到彙編代碼裏面再去看一眼。

ciscn 2020 reverse z3_異常處理機制_04


大致看一眼就可以看到(也算是為了降低難度的提示,沒有藏很深),可以看到有個“yes”字符串,通過判斷r12與r13寄存器的值來判斷是否進入到這一段代碼,但是可以看到沒有對r12有任何的操作,猜測這裏還是藏代碼了(前車經驗)。

ciscn 2020 reverse z3_異常處理機制_05


進入到這一段代碼處,可以看到把flag的大概格式給出了,我們通過提示構造一個測試字符串到相關的位置,這裏我構造的是flag{aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3861},通過動調運行到

sub_404BF5(),我們會發現,每次動調步過這個函數之後,這個程序就馬上退出了,這裏應該是利用了程序的一些機制問題,這時候我還不知道,也實在沒有思路去處理這個問題了。於是去搜索之後我知道了相關的知識點。

https://military-axe.github.io/blog/2023-06-11-2023-ciscn-ezbytes-write-up/
我是通過這個人的文章學習的

這個程序藏代碼的方法是利用c++的異常處理機制,將相關代碼藏在dwarf字節碼裏面,然後利用異常處理機制去執行這段隱藏的代碼,因為本質上利用的是程序的異常處理機制,所以運行過這一部分的時候是會直接程序報錯退出的。

程序的dwarf字節碼的格式叫做.ez_frame,可以利用指令readelf -Wwf filename來讀取異常處理相關的代碼。

ciscn 2020 reverse z3_字符串_06


然後pc對應的值就是ida中相關函數的入口地址,通過在ida中查找相關的函數入口地址我們可以快速定位到某一些可能的用異常處理代碼隱藏的正確代碼。

ciscn 2020 reverse z3_偽代碼_07


ciscn 2020 reverse z3_偽代碼_08

然後丟給ai或者查找dwarf相關的代碼語法,然後分析出主要的邏輯寫一個代碼然後組合在一起就是我們爭取的flag了。

r12=(2616514329260088143^1237891274917891239)-1892739
r13=(8502251781212277489^1209847170981118947)-8971237
r14=(2451795628338718684^1098791727398412397)-1512312
r15=(8722213363631027234^1890878197237214971)-9123704

print(b'flag{'+r12.to_bytes(8,'little')+r13.to_bytes(8,'little')+r14.to_bytes(8,'little')+r15.to_bytes(8,'little')+b'3861}')
#flag{e609efb5-e70e-4e94-ac69-ac31d96c3861}