1. 程式人生 > >2018/12/07-SCUCTF-re5

2018/12/07-SCUCTF-re5

 

 

連結:https://pan.baidu.com/s/14evvLd4jTLHp2Zg7_ugr0g
提取碼:auki

根據題目意思,程式是一個加密器,檔案中的txt中是截獲的密文,txt中的內容是“T2aNoifxUjIgKYMxKCsHKxAUZsDDGStqwV8Gh3W=”,可以猜到和base64加密有關。

可以發現每執行一次程式就會生成一個txt,可以猜到輸入和生成的txt有關。

程式使用C++寫的,靜態分析起來很頭痛,大部分資訊都是用OD除錯獲得和確定的。

首先是有兩個輸入,一個是輸入name,name的長度不小於8,一個是information,長度不小於0。

sub_401640函式來處理兩個輸入,但是函式裡面反編譯地很亂不知道在幹什麼。

但經過除錯我們發現函式的作用將輸入的input複製到記憶體的另一個地方,然後函式的第一個引數應該是一個結構體,然後函式處理完成後,檢視第一個引數的地址+4的word值,就是字串複製到記憶體另一個地方的起始地址,+8的word值是結束地址。

 

以v26(對應input2,即information)為例,v26在記憶體中的地址是0x19FEEC,然後地址+4的word值就是0x02B00E30,+8的word值是0x02B00E36,然後我們檢視0x2B00E30可以發現就是輸入的input2。

 繼續往下看。

sub_401242函式是一個被改的rc4加密,根據裡面中的函式多次出現256可以猜到。

關於rc4加密可以看一下這篇文章https://www.52pojie.cn/thread-800115-1-1.html。

並且動態除錯時候發現,只加密了input2即information,進去分析一下。

主要是這三個函式,其中函式sub_401432是將字串“'rm36ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678'”中的前四位即“rm36”與0xce進行異或運算,然後異或後的四個值作為fake_rc4的金鑰。

fake_rc4分為sub_401314和sub_13A0,一個是根據金鑰進行初始化,一個是對data進行加密。

fake_rc4的初始化函式和加密函式都和rc4不一樣。

fake_rc4初始化函式中,這三處異或明顯和rc4不同,從而導致生成的生成的SBox不一樣了。

 

fake_rc4加密函式中,同樣也是三處異或明顯不同。

那麼我們如何寫指令碼時如何處理這個fake_rc4加密呢,我們發現金鑰是固定的,也就是說fake_rc4初始化函式得到的SBox是固定的,而加密的資料只有在最後一處異或時參與運算,並且因為SBox是固定的,所以加密資料異或的值和順序也都是固定。

也就是說我們完全可以動態除錯,把異或的值都記錄下來。

在此處設斷點,然後根據後面base64解密得到的值的長度可知記錄需要29個,我們輸入的information的長度大於29然後除錯即可記錄異或的值,可以得到異或的29個值為[0xc8,0x23,0x0f,0x36,0x46,0xa9,0xda,0x76,0x4d,0x20,0x35,0x61,0x0f,0x20,0x3d,0x0d,0xb9,0x46,0xbe,0x62,0xf4,0x57,0x3a,0x95,0xdf,0xc1,0x6b,0x60,0x06]。

繼續向下分析。

sub_4017CE作用即是對fake_rc4加密輸入information得到的資料進行base64加密,但是需要主要的base64的編碼表是經過變化的。

進去分析一下。

函式sub_4018D1的功能即是變化編碼表,用OD動態除錯可以得到變化後的編碼表為”AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789/+“,下面的就是base64加密的部分了。

再回到main函式裡繼續往下分析。

函式sub_40147C的作用是生成txt檔名,和flag沒有什麼關係,就不仔細分析了。

然後下面的操作就是生成txt檔案了,內容就是密文即是先fake_rc4再base64得到的,檔名即base32得到的。

現在程式邏輯已經清楚了,flag經過這個加密器程式得到txt檔案即是題目給的,其中的密文就是flag加密的密文。

然後我們寫出指令碼即可得到flag,指令碼思路就是首先對題目txt檔案中的密文進行base64解密,注意編碼表是變化了的,然後在異或我們動態除錯得到的值即可。

from string import maketrans

base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
diy_base = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789/+'
t = maketrans(base, diy_base)
t2 = maketrans(diy_base, base)

def cus_base64_enc(x):
    return x.encode('base64').translate(t)
def cus_base64_dec(x):
    return x.translate(t2).decode('base64')

str = "T2aNoifxUjIgKYMxKCsHKxAUZsDDGStqwV8Gh3W="
str1 = cus_base64_dec(str)

flag = []
xor_data = [0xc8,0x23,0x0f,0x36,0x46,0xa9,0xda,0x76,0x4d,0x20,0x35,0x61,0x0f,0x20,0x3d,0x0d,0xb9,0x46,0xbe,0x62,0xf4,0x57,0x3a,0x95,0xdf,0xc1,0x6b,0x60,0x06]
for i in range(len(str1)):
    a = ord(str1[i]) ^ xor_data[i]
    flag.append(a)
print ''.join(map(chr,flag))

執行即可得到flag。