[re]符號執行一把梭:2020網鼎杯青龍組re_signal_wp
這道題是2020網鼎杯青龍組的一道逆向提signal,一道虛擬機逆向題目,題目本身不難,可以直接分析也可以符號執行秒掉。
題目分析
正常windows逆向,開局直接輸flag,也不多bibi:
逆向分析程序:
程序開始將全局變量區的opcode作爲參數給vm_operad函數,看名字也能看出是一個虛擬機分析的題目,先把opcode提取出來:
\x0A \x04 \x10 \x08 \x03 \x05 \x01 \x04 \x20 \x08 \x05 \x03 \x01 \x03 \x02 \x08
\x0B \x01 \x0C \x08 \x04 \x04 \x01 \x05 \x03 \x08 \x03 \x21 \x01 \x0B \x08 \x0B
\x01 \x04 \x09 \x08 \x03 \x20 \x01 \x02 \x51 \x08 \x04 \x24 \x01 \x0C \x08 \x0B
\x01 \x05 \x02 \x08 \x02 \x25 \x01 \x02 \x36 \x08 \x04 \x41 \x01 \x02 \x20 \x08
\x05 \x01 \x01 \x05 \x03 \x08 \x02 \x25 \x01 \x04 \x09 \x08 \x03 \x20 \x01 \x02
\x41 \x08 \x0C \x01 \x07 \x22 \x07 \x3F \x07 \x34 \x07 \x32 \x07 \x72 \x07 \x33
\x07 \x18 \x07 \xA7 \x07 \x31 \x07 \xF1 \x07 \x28 \x07 \x84 \x07 \xC1 \x07 \x1E
\x07 \x7A
然後查看行爲,順便給變量改個名:
一般vm的題目就是一個大的switch,根據分析把操作整理出來,有的操作,如加法,需要一個立即數參與,然後數組下標有好幾個變量,我這裏通用i表示了(實際做題不用這麼細緻。。):
01 :result[i]=temp
02 imm:temp=input[i]+imm
03 imm:temp=input[i]-imm
04 imm:temp=input[i]^imm
05 imm:temp=input[i]*imm
06 :i++
07 imm:result[i]==imm
08 :imput[i]=temp
0A :input 輸入字符串
0B :temp=input[i]--
0C :temp=input[i]++
可以看到opcode最後也是一堆0x7,說明是最後校驗flag.
手動解題
flag不長可以直接手動恢復:
input[0]^0x10-0x05=0x22 input[0]='7'
input[1]^0x20*0x03=0x3f input[1]='5'
input[2]-0x02-0x01=0x34 input[2]='7'
input[3]+1^0x04=0x32 input[3]='5'
input[4]*3-0x21=0x72 input[4]='1'
input[5]-2=0x33 input[5]='5'
input[6]^0x09-0x20=0x18 input[6]='1'
input[7]+0x51^0x24=0xA7 input[7]='2'
input[8]=0x31 input[8]='1'
input[9]*2+0x25=0xf1 input[9]='f'
input[10]+0x36^0x41=0x28 input[10]='3'
input[11]+0x20=0x84 input[11]='d'
input[12]*3+0x25=0xC1 input[12]='4'
input[13]^0x09-0x20=0x1E input[13]='7'
input[14]+0x42=0x7A input[14]='8'
所以最後flag是:flag{757515121f3d478}
符號執行自動秒題
隊裏師傅是用angr直接跑的,這種題目確實可以用符號執行約束求解來解答。這裏使用angr來進行符號執行。
我比較懶,需要用到啥新環境第一個想到的肯定是docker(自己配環境是萬萬不可能的),於是找了一下,有angr的docker:
附上dockerhub鏈接:https://hub.docker.com/r/angr/angr
docker pull angr/angr
docker run -it -v /mnt/hgfs/share:/mnt/ angr/angr
#/mnt/hgfs/share 目錄是我題目所在的目錄,直接掛載在docker裏的/tmp目錄
然後進入docker 後,在/mnt/目錄下就是你的代碼和程序。
這道題根本不用什麼angr的高端操作,直接一把梭即可:
import angr
p = angr.Project('./signal.exe') #指定angr跑的程序
state = p.factory.entry_state() #新建一個SimState的對象,得到一個初始化到二進制入口函數的SimState對象。
simgr = p.factory.simgr(state) #創建simulation manager,angr的主要入口
simgr.explore(find=0x004017A5 ,avoid=0x004016E6) #爭取跑到輸出成功的地址,避免跑到輸出wrong的地址
flag = simgr.found[0].posix.dumps(0)[:15] #得到flag
print(flag)
一把梭跑出flag:
這道題比較簡單甚至不用約束直接求解即可,更多關於angr的進階知識可以看先知社區的“深入淺出angr”系列
https://xz.aliyun.com/t/3990