1. 程式人生 > >【強網杯2018】逆向hide

【強網杯2018】逆向hide

style wro enter inline import HR add bcd stat

這是事後才做出來的,網上沒有找到現成的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