逆向ctf-2020湖湘杯Re_03
樣本連結:https://pan.baidu.com/s/14o1QOjYVtOspZd9koT4JCg
提取碼:jwrp
一、獲取題目壓縮包,解壓後發現是一個為ReMe.exe的可執行檔案,但是奇怪的是在exeinfope中查詢結果為:
很明顯了,不是PE檔案,看圖示猜測為python打包的exe檔案。既然如此就對exe檔案進行反編譯操作,因為是使用pyinstaller生成的exe檔案,所以對於python打包的exe檔案反編譯操作流程為,首先下載pyinstxtractor.py檔案並放到ReMe.exe資料夾中,之後在命令列中執行 python pyinstxtractor.py Reme.exe進行反編譯得到一個ReMe.exe_extracted資料夾,如圖:
當執行到這裡時,進入資料夾找到:
對於ReMe和struct這兩個沒有字尾的檔案,就是我們要得到的檔案。但是目前ReMe檔案缺失pyc檔案相對應的頭部資訊,所以使用十六進位制檢視器WinHex開啟兩個檔案:
對於開啟後的結果進行對比後發現,struct檔案比ReMe檔案在頭部多出:
42 0D 0D 0A 00 00 00 00 70 79 69 30 10 01 00 00
這樣一段,將這一部分以十六進位制數值複製出來,copy到ReMe檔案地址00000000處(就是開始),對複製好的ReMe檔案進行字尾的修改變為ReMe.pyc檔案。到這一步就可以選擇網上pyc檔案反編譯或者使用uncompyle6進行反編譯(說一下,我在做這道題時用網上反編譯一直報錯,不能完整反編譯出來),如果沒有安裝uncompyle6,就執行cmd命令:pip install uncompyle,反編譯命令為:
uncompyle6 ReMe.pyc > ReMe.py
執行後,在ReMe.exe_extracted資料夾中會發現ReMe.py這個檔案,開啟發現:
# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 16:30:00) [MSC v.1900 64 bit (AMD64)]
# Embedded file name: ReMe.py
# Compiled at: 1995-09-28 00:18:56
# Size of source mod 2**32: 272 bytes
import sys, hashlib
check = [
'e5438e78ec1de10a2693f9cffb930d23',
'08e8e8855af8ea652df54845d21b9d67',
'a905095f0d801abd5865d649a646b397',
'bac8510b0902185146c838cdf8ead8e0',
'f26f009a6dc171e0ca7a4a770fecd326',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'4cb467175ab6763a9867b9ed694a2780',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'fd311e9877c3db59027597352999e91f',
'49733de19d912d4ad559736b1ae418a7',
'7fb523b42413495cc4e610456d1f1c84',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'acb465dc618e6754de2193bf0410aafe',
'bc52c927138231e29e0b05419e741902',
'515b7eceeb8f22b53575afec4123e878',
'451660d67c64da6de6fadc66079e1d8a',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'fe86104ce1853cb140b7ec0412d93837',
'acb465dc618e6754de2193bf0410aafe',
'c2bab7ea31577b955e2c2cac680fb2f4',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'f077b3a47c09b44d7077877a5aff3699',
'620741f57e7fafe43216d6aa51666f1d',
'9e3b206e50925792c3234036de6a25ab',
'49733de19d912d4ad559736b1ae418a7',
'874992ac91866ce1430687aa9f7121fc']
def func(num):
result = []
while num != 1:
num = num * 3 + 1 if num % 2 else num // 2 #滿足求餘==0時執行num//2反之執行num*3+1
result.append(num)
return result
if __name__ == '__main__':
print('Your input is not the FLAG!')
inp = input()
if len(inp) != 27:
print('length error!')
sys.exit(-1)
for i, ch in enumerate(inp):
ret_list = func(ord(ch))
s = ''
for idx in range(len(ret_list)):
s += str(ret_list[idx]) # 將陣列第idx個放入
s += str(ret_list[(len(ret_list) - idx - 1)])#將陣列倒序len(陣列)-idx-1放入
md5 = hashlib.md5()
md5.update(s.encode('utf-8'))
if md5.hexdigest() != check[i]: #判斷對第i輪字元生成陣列的md5值與check[i]的值
sys.exit(i)
md5 = hashlib.md5()
md5.update(inp.encode('utf-8')) #想輸出到這,前面每一輪加密後的字串必須都要對應相等check中的值
print('You win!')
print('flag{' + md5.hexdigest() + '}')
# okay decompiling ReMe.pyc
對於這個加密方式採用爆破就能直接解出,思路為每一輪都遍歷0x20-0x7f之間的數(設為j),採用func函式生成陣列並md5加密,並與check【輪數】對比,相等就將遍歷的數j進行字元轉換並存起來。程式碼如下;
import sys, hashlib
check = [
'e5438e78ec1de10a2693f9cffb930d23',
'08e8e8855af8ea652df54845d21b9d67',
'a905095f0d801abd5865d649a646b397',
'bac8510b0902185146c838cdf8ead8e0',
'f26f009a6dc171e0ca7a4a770fecd326',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'4cb467175ab6763a9867b9ed694a2780',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'fd311e9877c3db59027597352999e91f',
'49733de19d912d4ad559736b1ae418a7',
'7fb523b42413495cc4e610456d1f1c84',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'acb465dc618e6754de2193bf0410aafe',
'bc52c927138231e29e0b05419e741902',
'515b7eceeb8f22b53575afec4123e878',
'451660d67c64da6de6fadc66079e1d8a',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'fe86104ce1853cb140b7ec0412d93837',
'acb465dc618e6754de2193bf0410aafe',
'c2bab7ea31577b955e2c2cac680fb2f4',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'f077b3a47c09b44d7077877a5aff3699',
'620741f57e7fafe43216d6aa51666f1d',
'9e3b206e50925792c3234036de6a25ab',
'49733de19d912d4ad559736b1ae418a7',
'874992ac91866ce1430687aa9f7121fc']
def func(num):
result = []
print(num)
while num != 1:
num = num * 3 + 1 if num % 2 else num // 2
result.append(num)
print(result)
return result
flag = ''
for i in range(27):
for j in range(0x20, 0x7f):
ret_list = func(j)
s = ''
print(ret_list)
for idx in range(len(ret_list)):
s += str(ret_list[idx])
s += str(ret_list[(len(ret_list) - idx - 1)])
print(s)
md5 = hashlib.md5()
md5.update(s.encode('utf-8'))
if md5.hexdigest() == check[i]:
flag += chr(j)
break
print(flag)
執行後的結果為:
flag{My_M@th_3X+1_R3v_Te5t}
但是題目要求提交還需要放到ReMe.exe中執行得到:
也就是題目要求了。
flag{0584cfa2ce502951ef5606f6b99fc921}
相關文章
- 2020湖湘杯部分writeup
- 綠盟科技榮獲2020“湖湘杯”網路安全應急演練大賽一等獎
- 再創佳績 | 綠盟科技安全戰隊斬獲湖湘杯網路安全技能大賽一等獎
- 2024 強網杯逆向 Writeups
- 百度品牌之夜——華瑞IT教育綻放湖湘品牌魅力
- 湘宜購商城系統開發/湘宜購商城小程式開發技術方案
- 淺談創業教父李澤湘創業
- 逆向通達信 x 逆向微信 x 逆向QtQT
- 羽夏逆向——逆向基礎
- 資料湖--架構師如何助力“湖加速”?架構
- 資料湖
- Android 逆向(四) - adb常用逆向命令Android
- 資料湖架構,為什麼需要“湖加速”?架構
- 【JS逆向百例】cebupacificair 航空逆向分析JSAI
- 逆向工程核心原理(1)逆向基礎
- 逆向3
- 逆向logmein
- SMC逆向
- JS 逆向JS
- Flutter逆向Flutter
- 逆向-1
- 湘龍科技微應用解決方案產品線
- 資料湖+資料倉儲 = 資料湖庫架構架構
- 湘宜購商城(系統開發)小程式技術搭建
- 藍湖 Axure 墨刀
- 逆向WeChat(八)
- 逆向WeChat(七)
- Mybatis逆向工程MyBatis
- 阿里bxet逆向阿里
- 逆向WeChat(四)
- 逆向WeChat(三)
- 逆向WeChat (二)
- Skype逆向之旅
- buuctf 逆向 xor
- 病毒逆向分析
- 基於 Paimon 的袋鼠雲實時湖倉入湖實戰剖析AI
- 藍橋杯
- 太湖杯writeup