170818 逆向 南郵CTF(WxyVM2)

2021-08-07 02:35:27 字數 2896 閱讀 7306

1625-5 王子昂 總結《2023年8月18日》 【連續第320天總結】

a. 南郵ctf-wxyvm2

b. 上次沒做完的正巧在52破解論壇上看到有人發問了,就摸過來再做做看

跟wxyvm1比較像,不過感覺這題相比vm來說更像花指令~

首先看原始碼分析,先驗證長度為25,然後進行了一大片的加減異或操作,最後與記憶體中的乙個字串進行比較

上次乍一看大片的加減異或操作不好處理,也沒想到怎麼將指令dump下來逆操作

這次仔細的分析一下發現大部分的操作都是無意義的:

仔細觀察,輸入在0x694100處,單位為byte,長度為25

也就是說,輸入的字串固定在0x694100-0x694118內,大片的dword操作都是超出這個範圍的,它們沒有意義

最後的比較字串位於0x694060處,單位為dword,長度為25,是不變的字串,直接idc指令碼dump出來即可

那麼關鍵在於如何提取有意義的操作:

我是直接全選idc反編譯出來的命令,掐頭去尾,以「;」作為分隔符得到命令集合的列表,然後分析特徵:無意義的操作開頭為dowrd,所需要的操作開頭為byte(另外還有一些自加自減操作需要另外處理)

遍歷列表,將有意義的儲存下來,然後再分析提取被運算元(即下標)、操作命令和運算元

確認正向測驗的指令碼結果與動態除錯中所檢視到的記憶體無誤,說明思路和指令碼都正確,將命令加減顛倒,處理字串改為直接dump出來的結果即可

附上python指令碼:

def

arr(list, s):

# 分析字串,將被運算元、命令、運算元分別放入陣列

tmp = [0, 『』, 0]

tmp[0] = int(s[9], 10) * 16 + int(s[10], 16)#被運算元下標

tmp[1] = s[12]#操作符

tmp[2] = s[15:]#運算元

if (len(tmp[2]) == 0):#提取失敗,為自增/減型別(++byte_***型)

tmp[0] = int(s[11], 10) * 16 + int(s[12], 16)

# print(i,tmp[0])

tmp[1] = s[0]

tmp[2] = '1'

if (tmp[2][0] is

'0'):#運算元為十六進製制

tmp[2] = int(tmp[2][2:-1], 16)

else:

if (tmp[2][-1] is

'u'): tmp[2] = tmp[2][:-1]#運算元末尾去除'u'

tmp[2] = int(tmp[2], 10)

defpositive

(list):

#正向操作函式

ori = input("please input the flag(25):")

flag =

# 提取ascii並進行操作

for i in ori:

for i in list:

n = flag[i[0]]

if (i[1] is

'+'):

n = n + i[2]

if (i[1] is

'-'):

n = n - i[2]

if (i[1] is

'^'):

n = n ^ i[2]

flag[i[0]] = n % 256

#操作單位為位元組,解決溢位

return flag

defnegative

(list, ori):

#逆向還原函式

flag = ""

for i in list[::-1]:

n = ori[i[0]]

if (i[1] is

'+'):

n = n - i[2]

if (i[1] is

'-'):

n = n + i[2]

if (i[1] is

'^'):

n = n ^ i[2]

ori[i[0]] = n % 256

for i in ori:

flag = flag + chr(i)

return flag

#operator為ida反編譯出的全部命令

o = operator.split(";")#分割命令形成列表

operators_str = #初步有效命令列表

operators_com = #最終分析命令列表

#記憶體中dump出來的,0x401060的結果

ori = [0xffffffc0, 0xffffff85, 0xfffffff9, 0x6c, 0xffffffe2, 0x14, 0xffffffbb, 0xffffffe4, 0xd, 0x59, 0x1c, 0x23,

0xffffff88, 0x6e, 0xffffff9b, 0xffffffca, 0xffffffba, 0x5c, 0x37, 0xffffffff, 0x48, 0xffffffd8, 0x1f, 0xffffffab,

0xffffffa5]

# 去除混淆命令和開頭的換行、空格符號

for i in o[:-1]:

if (i[3] is

not'd'):

# 分析

for i in operators_str:

arr(operators_com, i)

# positive(operators_com)

print(negative(operators_com, ori))

c. 明日計畫

natas

170707 逆向 南郵CTF逆向(WxyVM1)

1625 5 王子昂 總結 2017年7月7日 連續第278天總結 a.南郵ctf逆向 4 b.4 記事本開啟發現檔案頭是elf,拖入ida進行反編譯,發現只有幾個函式 檢視main函式,發現輸入以後呼叫sub 4005b6 函式,然後判斷長度是否為24和字串0x601060比較 再進一步看4005...

170706 逆向 南郵CTF平台 1 3

1625 5 王子昂 總結 2017年7月6日 連續第277天總結 a.南郵ctf逆向 1 3 b.1.拖入ida,入門級的re,直接f5看到main的 很簡單,寫入記憶體的flag 剛開始看的時候沒理解galf是什麼意思,照著輸卻報錯 後來下斷到記憶體裡看,發現是大端序的原因。每個變數的四位元組需...

南郵ctf逆向最後一題

你大概需要乙個優秀的mac 雖然是osx下的程式,但並不一定真的要有mac 正好我也沒mac,只能拖到ida裡面了,發現還真可以 ida有點厲害 找到right wrong字串,觀察下主框架然後果斷f5看下偽 可以看出來就是簡單的輸入長度為56的字串然後經過func1,xfun1,xfun2,xfu...