1. 程式人生 > >2018/11/26-湖湘杯-Replace

2018/11/26-湖湘杯-Replace

題目連結:https://pan.baidu.com/s/1PNNAo2Ive4K7eYEifVIwsQ
提取碼:8b2v

用Exeinfo PE查殼發現是UPX殼

使用UPX-3.95(可以在吾愛破解Tools->Packers可以下到)的upx -d 命令脫殼

然後我們在IDA裡找到關鍵演算法部分

可以看出迴圈是根據每個字元生成v6和v7,然後16*v6+v7當下標,在數字byte_4021A0中就行尋值。然後和(v11+v12)^0x19進行比較,若不相等則失敗,而v11和v12是根據陣列byte_402150生成的。

其實對輸入字元處理到最後的16*v6+v7仍然是輸入字元的ascii值,而v11+v12其實就是byte_401250處儲存的字串“2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6”的每兩位的寫入記憶體的十六進位制,相當於python3的bytes.fromhex()函式。

也就是說最後的比較就是data[input[i]] == arr[i]^0x19

我們把byte_4021A0處的資料dump下來,然後寫指令碼執行即可得到flag。

data = open('E:\\data','rb').read()
arr = bytes.fromhex("2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6")
for i in range(len(arr)):
    print(chr(data.index(arr[i]^0x19)),end="")

如果看不出來對字元的處理是怎麼回事的話,也可以進行爆破。

def fun(i):
    if(data1[i] < 48 | data1[i] > 57):
        a = data1[i] - 87
    else:
        a = data1[i] - 48
    a = a * 16
    if(data1[i+1] < 48 | data1[i+1] > 57):
        b = data1[i+1] - 87
    else:
        b = data1[i+1] - 48
    return ((a + b) ^ 0x19)

for i in range(35):
    z 
= i for m in range(128): a = (m >> 4) % 16 b = (16 * m >> 4) % 16 j = 16 * a + b k = fun(i*2) if(data[j] == k): print(chr(m),end="")