🥷 OffSec CTF Writeup体验
因为上课要求要打一道 CTF 以及写一个 writeup, 所以在 ctftime 首页上看了几个正在进行的 CTF, 看到这个里的这道题.
📝 题目
Perhaps You Can
550d0d0a00000000b7e8566370030000e300000000000000000000000000000000080000004000000073300200006500640083015a0165026501830164016b02731c650364028301010065046501a005a100830164036b02733465036402830101006501640464058502190064066b02734c650364028301010065016407190064086b027360650364028301010065066501640919008301640a1800650665016405190083016b02738465036402830101006501640b190065076508650965066501640c19008301830164046404640785031900830183016b0273b6650364028301010065066501640b19008301640d180065066501640d190083016b0273da650364028301010065066501640e190083015a0a65066501640f190083015a0b650a650b170064106b02900173086503640283010100650c650a650b830264116b0090017320650364028301010065016412641385021900a005a100a00da10064146b029001734265036402830101006501641319006501641519006b029001735c65036402830101006501641519006501641619006b029001737665036402830101006506650164171900830165066501641819008301140064196b029001739c650364028301010065066501641a1900830165066501641b19008301140065066501641c190083011400641d6b02900173ce6503640283010100650e641ea00f6510641f64208400650164216422850219008302a10183015a116511a012a1000100641ea00f6511a10164236b029002730e650364028301010065016424190064256b0290027324650364028301010065136426830101006404530029277a07696e7075743e20e926000000e90100000069d20d00004ee9060000007a0655444354467be9fffffffffa017de905000000e902000000e907000000e903000000e909000000e908000000e90a000000e9eb000000e977000000e90b000000e9180000005a1a3333356636323333363536653566363237393734373433333665e91b000000e91f000000e919000000e91a00000069522e0000e91c000000e91d000000e91e0000006960630900da0063010000000000000000000000010000000300000043000000730c000000740074017c0083018301530029014e2902da03737472da036f72642901da0178a900721c000000fa087472796d652e7079da083c6c616d6264613e20000000f300000000721e000000e920000000e9250000005a0e3030303131313131313132353537e922000000da01347a07596f752077696e2914da05696e707574da03746d70da036c656eda0465786974da0373756dda06656e636f6465721a000000da03636872da03696e747219000000721b000000da0179da036d6178da03686578da046c697374da046a6f696eda036d6170da027979da04736f7274da057072696e74721c000000721c000000721c000000721d000000da083c6d6f64756c653e01000000734a00000008010c01080110010801100108010c0108011c0108012a0108011c0108010c010c010e010801100108011a01080112010801120108011e0108012a01080120010801100108010e010801
🧐 答案
拿到数字后, 观察即可知道, 这是一个十六进制的字符串, 于是放到 CyberChef 上, 选择 From Hex
, 尝试获取更多信息.
于是我们可以从 output
中看到很多代码关键字, 但是没有办法确定是什么语言, 可能大概率是 python
.
之后我们再回到 input
中, 来敲定代码的语言. 我们通过搜索前六位的前缀 550d0d0a
, 可以从这个 magic number 中知道文件是 .pyc
.
然后我们再通过脚本将 hex string
转换为 binary compiler pyc 文件.
import binascii
hexString = "550d0d0a......"
binary = binascii.a2b_hex(c)
file = open('binary.pyc','wb')
file.write(binary)
得到 binary.pyc
的文件后, 我们可以使用 uncompyle6
或者 PyC decompiler
来反编译这个二进制文件, 得到 .py
的源码.
# uncompyle6 version 3.5.0
# Python bytecode 3.8 (3413)
# Decompiled from: Python 2.7.5 (default, Nov 16 2020, 22:23:17)
# [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
# Embedded file name: tryme.py
# Size of source mod 2**32: 880 bytes
tmp = input('input> ')
if not len(tmp) == 38:
exit(1)
if not sum(tmp.encode()) == 3538:
exit(1)
if not tmp[:6] == 'UDCTF{':
exit(1)
if not tmp[(-1)] == '}':
exit(1)
if not ord(tmp[5]) - 2 == ord(tmp[6]):
exit(1)
if not tmp[7] == chr(int(str(ord(tmp[3]))[::-1])):
exit(1)
if not ord(tmp[7]) - 9 == ord(tmp[9]):
exit(1)
x = ord(tmp[8])
y = ord(tmp[10])
if not x + y == 235:
exit(1)
if not max(x, y) < 119:
exit(1)
if not tmp[11:24].encode().hex() == '335f6233656e5f62797474336e':
exit(1)
if not tmp[24] == tmp[27]:
exit(1)
if not tmp[27] == tmp[31]:
exit(1)
if not ord(tmp[25]) * ord(tmp[26]) == 11858:
exit(1)
if not ord(tmp[28]) * ord(tmp[29]) * ord(tmp[30]) == 615264:
exit(1)
yy = list(''.join(map(lambda x: str(ord(x)), tmp[32:37])))
yy.sort()
if not ''.join(yy) == '00011111112557':
exit(1)
if not tmp[34] == '4':
exit(1)
print('You win')
于是我们可以对这个代码进行分析, 得到 flag:
- 对每个判断进行逐步分析, "翻译" 为
py
代码, 直接得到大部份的 flag. - 对 flag 的语义进行猜测, 如最后的
sn4ke
, 在最后一个判断揭示中间字符为4
后就可以结合前面的内容猜出这个词.
import binascii
flag = 'U D C T F {'.split() + ['*'] * (38 - 6)
flag[6] = chr(ord(flag[5]) - 2)
flag[7] = chr(int(str(ord(flag[3]))[::-1]))
flag[9] = chr(ord(flag[7]) - 9)
flag[-1] = '}'
flag[34] = '4'
flag[8] = 'u'
flag[10] = 'v'
flag_0 = str(binascii.a2b_hex('335f6233656e5f62797474336e'))[2:-1]
flag_1 = ''.join(flag)[:11] + flag_0
flag[25] = 'y'
flag[26] = 'b'
flag[28] = 't'
flag[29] = 'f'
flag[30] = 'h'
flag_2 = '_'+'b'+'y'+'_'+'t'+'h'+'3' + '_'
print(flag_1 + flag_2 + 'sn4ke}')
🚩 Flag
UDCTF{y0u'v3_b3en_bytt3n_by_th3_sn4ke}