【2020XCTF/華為杯】PYPY WriteUp
阿新 • • 發佈:2020-12-25
技術標籤:CTF
題目是一個PYPY打包的elf程式,使用pygame寫了一個貪吃蛇遊戲,現有的pyinstaller的解包指令碼好像不太好使,那麼自己動手
根據輸出報錯資訊定位程式碼,這個qword_6077E0應該是反序列化pyc程式碼的函式,gdb斷在這裡,即可拿到對應的pyc檔案
這個函式會被執行4次,第4次是我們期望的程式碼,第四次斷下後使用 dump memory ./dmp $rdi $rdi+$rsi 拿到檔案,補上前8個位元組的檔案頭以後,加上.pyc字尾然後使用uncompyle6反編譯,得到原始碼
DEFAULT_KEY = 'Yó\x02Ã%\x9a\x820\x0b»%\x7f~;ÒÜ'
def rc4(msg, key=DEFAULT_KEY, skip=1024):
barray = bytearray([i for i in range(256)])
curr = 0
for i in range(256):
curr = (curr + barray[i] + ord(key[(i % len(key))])) % 256
t = barray[i]
barray[i] = barray[curr]
barray[curr] = t
else:
curr = 0
another = 0
blist = []
if skip > 0:
for i in range(skip):
curr = (curr + 1) % 256
another = (another + barray[curr]) % 256
barray[curr], barray[another] = barray[another], barray[curr]
for j in msg:
curr = (curr + 1) % 256
another = (another + barray[curr]) % 256
barray[curr], barray[another] = barray[another], barray[curr]
t = barray[((barray[curr] + barray[another]) % 256)]
blist.append(chr(ord(j) ^ t))
else:
return ''.join(blist)
def func():
t = rc4('flag{this is a fake flag}')
if t.encode(
'utf-8').hex() == '275b39c381c28b701ac3972338456022c2ba06c3b04f5501471c47c38ac380c29b72c3b5c38a7ec2a5c2a0':
return 'YOU WIN'
return 'YOU LOSE'
程式碼被混淆了,我重新命名了一下變數,提取了關鍵部分貼出來
發現是rc4加密,給了key和加密後的值,當你得到5192296858534827628530496329220096分以後,就會輸出YOU LOSE,如果想得到YOU WIN,則需要讓flag滿足上面的條件
和異或類似,rc4再加密一次就還原了
解密指令碼:
import binascii
msg = binascii.a2b_hex('275b39c381c28b701ac3972338456022c2ba06c3b04f5501471c47c38ac380c29b72c3b5c38a7ec2a5c2a0')
key = 'Yó\x02Ã%\x9a\x820\x0b»%\x7f~;ÒÜ'
def rc4(msg, skip=1024):
barray = bytearray([i for i in range(256)])
curr = 0
for i in range(256):
curr = (curr + barray[i] + ord(key[(i % len(key))])) % 256
t = barray[i]
barray[i] = barray[curr]
barray[curr] = t
else:
curr = 0
another = 0
blist = []
if skip > 0:
for i in range(skip):
curr = (curr + 1) % 256
another = (another + barray[curr]) % 256
barray[curr], barray[another] = barray[another], barray[curr]
for j in msg:
curr = (curr + 1) % 256
another = (another + barray[curr]) % 256
barray[curr], barray[another] = barray[another], barray[curr]
t = barray[((barray[curr] + barray[another]) % 256)]
blist.append(chr(ord(j) ^ t))
else:
return ''.join(blist)
print(rc4(str(msg, 'utf8')))
flag{snake_bao_is_really_lucky}