【強網杯2018】逆向hide
這是事後才做出來的,網上沒有找到現成的writeup,所以在這裏記錄一下
UPX加殼,而且linux下upx -d無法解,也無法gdb/ida attach
因為是64位,所以沒有pushad,只能挨個函數進入,退出,看看程序是否恢復。
當運行到一0x400dd0,發現此時已經可以看見字符串了
用dumphex的腳本來dump出內存,見hide_dump
static main(void)
{
auto fp, begin, end, dexbyte;
fp = fopen("C:\\dump.dex", "wb");
begin = 0x400000;
end = 0xADC000;
for ( dexbyte = begin; dexbyte < end; dexbyte ++ )
fputc(Byte(dexbyte), fp);
}
此時dump出的內容已經有程序運行的字符串了,通過字符串反查,這裏
0x400890才是真正的啟動地址
以後運行程序,在ida裏面輸入一下內容,即可直接運行到0x4009ef
from idaapi import *
from idc import *
run_to(0x4009ef)
qwb{this_is_wrong_flag}
check到一個假flag,如果此時繞過ptrace且用ctrl+d作為結束,可以輸出right。
但是輸入到正常程序是報wrong的,說明還有地方反調試以及修改了邏輯
根據ptrace.h,ptrace這裏是PTRACE_TRACEME,自我調試
突然發現“Enter the flag:”字符串有2處引用
在4C8EA0也有類似的輸出,懷疑正式運行時是這裏。恢復函數失敗,只能動態調試
上面這裏判斷是不是qwb{}格式,構造payload
然後調用3次以下2個函數,輸入內容為qwb{0123456789abcdef}中間部分的0123456789abcdef
sub_4C8CC0(__int64 a1)
這部分算法恢復見test2.py中的loop_j
sub_4C8E50——按位異或
目標:rdi(qwb{}中間內容經過上面的多次變換後) == rsi(如下),
經過test2.py的逆向,得到一個有意義的輸入串f1Nd_TH3HldeC0dE
所以認為flag是qwb{f1Nd_TH3HldeC0dE}
實際運行,輸入完qwb{f1Nd_TH3HldeC0dE}後,用ctrl+d可以看到成功(回車不行,因為用sys_read會連回車也認為是字符?)
但是實際為何會運行到hide腳本,就沒有分析了,因為ptrace自己後發生什麽事情,很難搞。
以下是通過IDA運行並跳過反調試的腳本
from idaapi import *
from idc import *
run_to(0x4009ef)
GetDebuggerEvent(WFNE_SUSP, -1)
SetRegValue(0x4C8EA0,"RIP")
GetDebuggerEvent(WFNE_SUSP, -1)
run_to(0x4C8EB3)
GetDebuggerEvent(WFNE_SUSP, -1)
SetRegValue(0,"RAX")
run_to(0x4C8CC0)
腳本含義
【強網杯2018】逆向hide