CTF 【每日一題20160630】PYTHON 字節碼

來源: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逆向基礎資源:


本題分析:
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}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章