一.這道題應該就是正常情況下的一個難題了,沒有強大的偽代碼分析和寫腳本的功底,這道題確實不太好寫,我看網上有好多angr指令解出來的,雖然這也是種方法,但是我覺得還是用正常的方法寫,自己才能進步的更快,
1.正常IDA打開:

主函式是比較正常的,flag一共有22位,第18-22行有個判斷,我們可以知道a1的值,注意第12行sub_41644A函式,這個函式沒有引數,點進去里面是個套娃,通過動態除錯還有一次次的實驗嘗試,最終知道了是將輸入的字串每一個加“i”,然后再異或“i”,
2.第13-17行的運算程序也比較正常,直接正向寫腳本爆破就可以,因為第16行的
a1[i] = ((int)(unsigned __int8)a1[i] >> 3) | (32 * a1[i]);
這個逆向程序確實不太好寫(反正我是不會逆著寫,,),所以我們通過正向的程序,爆破一下輸入的值,加上最后的判斷,就能得到flag經過sub_41644A函式變換后的值,具體的python腳本:
a1 = [0x6E, 0x10, 0xEC, 0x13, 0xC1, 0xCB, 0xF0, 0x2D, 0xC6, 0x32,
0xFD, 0x86, 0xEE, 0xCB, 0x89, 0x92, 0x3C, 0x46, 0x49, 0x71,
0x62, 0x57]
dword_424080 = [0x21,0x3f,0xa3,0xe9,0x8f,0x00]
for j in range(1,len(a1)):
for i in range(256):
c = i
c += (dword_424080[j % 6] >> 6) ^ (16 * dword_424080[(j - 1) % 6])
c = ((c&0xff) >> 3) | (32 * (c&0xff))
if (c&0xff) == a1[j]:
print(chr(i),end='')
#pue|nYD^]DwNZaOBJ{!
我們得到了經過變化的flag從第二位到最后一位的值,再根據動態除錯,第一位輸入什么就輸出什么,所以根據最后一個判斷,它的值是0x6E,也就是“n”,這時候,我們可以再寫一個腳本,逆向還原出flag:
a = 'npue|nYD^]DwNZaOBJ{!' #剛才得到的字串前面加“n”
for i in range(len(a)):
flag = ''
flag += chr((ord(a[i])^i)-i) #通過動調得到
print(flag,end='')
#npuctf{WDNMDo6F_OBFU!}
本來以為這肯定就是flag了,沒想到還是我年輕了,,,
3.中間三位o6F感覺和flag關系不大,其中三位中的第一位應該是“_”,剩下兩位直接爆破:
from itertools import *
import subprocess #subprocess 模塊允許你生成新的行程,連接它們的輸入、輸出、錯誤管道,并且獲取它們的回傳碼
for i in range(1):
for j in range(32,127):
for k in range(32,127):
flag ="npuctf{WDNMD_"+chr(j)+chr(k)+"_OBFU!}"
p = subprocess.Popen([r"C:\\Users\\admin\\Desktop\\attachment.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(flag.encode())
p.stdin.close()
out=p.stdout.read()
p.stdout.close()
if "E".encode() not in out:
print(flag)
exit()
這個爆破腳本淺顯易懂,稍微復雜點的可能是subprocess這個模塊,具體可以參考:https://docs.python.org/zh-cn/3/library/subprocess.html#using-the-subprocess-module
運行得到flag

npuctf{WDNMD_LJ_OBFU!}
像這個爆破腳本的話, 有的windows下的exe程式可以爆破出來,有的爆破不出來,這個我還正在研究,不過上述爆破腳本完全可以當成一個模板來使用,具體了解原理的大佬可以一起交流一下,
二.此外還有第二種,也就是angr指令的方式得到flag,
from angr import *
p = Project('C:\\Users\\admin\\Desktop\\attachment.exe',auto_load_libs = False)
state = p.factory.blank_state(addr=0x004164F8)
simfd = state.posix.get_fd(0)
data,real_size = simfd.read_data(22)
state.memory.store(0x0042612C,data)
state.memory.store(0x00426020,data)
sm = p.factory.simulation_manager(state)
sm.one_active.options.add(options.LAZY_SOLVES)
sm.explore(find = 0x00416609,avoid = 0x004165EA)
text = sm.one_found.solver.eval(sm.one_found.memory.load(0x0042612C,22),cast_to = bytes)
print (text)
這個腳本是參照別的大佬的wp,具體的angr原理可以參考:
https://xz.aliyun.com/t/3990
之后我會做angr指令專題詳解,運行之后得到:

最終得到flag:
flag{WDNMD_LJ_OBFU!}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/379528.html
標籤:其他
上一篇:selenium自動化測驗03
