來源:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=45
python ByteCode
請看這裏: http://pan.baidu.com/s/1jGpB8DS
下載後是一個名爲 crackme.pyc文件
python逆向基礎資源:
- 用 Python 反編譯 Python 軟件:http://bbs.pediy.com/archive/index.php?t-111428.html
- 工具uncompyle2:https://github.com/wibiti/uncompyle2
本題分析:
1.話說用python中的dis模塊可以自己編個反編譯程序,但是我目前不會,就不羅嗦了。下載uncompyle2後,可以在終端進入uncompyle2目錄下,找到setup.py,就可運行下列命令執行安裝:
python setup.py install
如果要反編譯*.pyc程序,可以運行下列命令:
python C:\Python27\Scripts\uncompyle2 crackme.pyc > crackme.py
其他用法
Examples:
uncompyle2 foo.pyc bar.pyc # decompile foo.pyc, bar.pyc to stdout
uncompyle2 -o . foo.pyc bar.pyc # decompile to ./foo.pyc_dis and ./bar.pyc_dis
uncompyle2 -o /tmp /usr/lib/python1.5 # decompile whole library
然後在同目錄下打開生成的crackme.py
我反編譯出來的內容如下:
# 2016.06.30 18:21:49 中國標準時間
#Embedded file name: d:/idf.py
def encrypt(key, seed, string):
rst = []
for v in string:
rst.append((ord(v) + seed ^ ord(key[seed])) % 255)
seed = (seed + 1) % len(key)
return rst
if __name__ == '__main__':
print "Welcome to idf's python crackme"
flag = input('Enter the Flag: ')
KEY1 = 'Maybe you are good at decryptint Byte Code, have a try!'
KEY2 = [124,
48,
52,
59,
164,
50,
37,
62,
67,
52,
48,
6,
1,
122,
3,
22,
72,
1,
1,
14,
46,
27,
232]
en_out = encrypt(KEY1, 5, flag)
if KEY2 == en_out:
print 'You Win'
else:
print 'Try Again !'
+++ okay decompyling crackme.pyc
# decompiled 1 files: 1 okay, 0 failed, 0 verify failed
# 2016.06.30 18:21:50 中國標準時間
2.從程序看,KEY2內的整數似乎像ascii數值,但數字和英文字符少,直接轉換意義不大。關鍵在於分析encrypt(KEY1, 5, flag)。
3.對encrypt函數的分析:用戶輸入一個字符串(ascii值必小於128),然後取出每個字符求其ascii值,加上seed,然後用其和與KEY1中一字符的ascii進行異或(算符^,注意+比^的優先級高),然後對255求餘。
4.編寫解密程序。顯然正確的密碼字符串加密後結果爲KEY2,那麼逆向分析編碼即可。程序如下:
#python script
KEY2 = [124,
48,
52,
59,
164,
50,
37,
62,
67,
52,
48,
6,
1,
122,
3,
22,
72,
1,
1,
14,
46,
27,
232]
KEY1 = 'Maybe you are good at decryptint Byte Code, have a try!'
def encrypt(key, seed, string):
rst = []
for v in string:
rst.append((ord(v) + seed ^ ord(key[seed])) % 255)
seed = (seed + 1) % len(key)
return rst
def decrypt(key,seed,en_out ):
string = ''
for i in en_out :
v = (i ^ ord(key[seed]))-seed
seed = (seed + 1) % len(key)
if v > 0:
string += chr(v)
return string
if __name__ == '__main__':
print decrypt(KEY1,5,KEY2)
答案:WCTF{ILOVEPYTHONSOMUCH}