Приветствую тебя хабраюзер! Недавно, закончилась ежегодная олимпиада по информационной безопасности UFO CTF 2017. В этой статье будет райтап одного задания из раздела PPC, под названием «King Arthur», за который можно было получить максимальное количество очков — 600.
Начнём
В описании к заданию было следующее:
Мы получили какое-то странное вложение в e-mail от фаната рыцарей. Помогите разобраться, что имел в виду автор.
И был доступен для скачивания файл:
#!/usr/bin/python import serpent """ ___ { _ } |/| {___} |_| |/| . |/| . (\________|w|________/) ( ___________________ ) v | | | v | | | | | | | | |PO0.HN7 | | | * TP0~~~< z| | |ON4.YH1 OP6| | | ON2| | |PO3| | |PY0 | | PY0 | | |PY0 z| | |PY0 PY0 | |z PY0| | | PY0| | |PY0| | |PH0 | | PY0 | | |PY0 z| | |PY0 PY0 | |z PY0| | | PY0| | |PY0| | |HN3 | | PY1 | | |PY0 z| | |PY0 PY0 | |z PN3| | | PT0| | |PY0| | |PN3 | | PY0 | | |PY0 z| | |TH3 PY0 | |z PY0| | | NY2| | |PY0| | |PY0 | | PN3 | | |PH0 z| | |PY0 PN4 | |z PY0| | | PY0| | |NY2| | |PT0 | | PY0 | | |YP3 z| | |PT0 PY0 | |z PO4| | | PY0| | |PY0| | |PT0 | | PN3 | | |PY0 z| | |PY0 HN2 | |z YO1| | | PO0| | |PY0| | |PY0 | | PY0 | | |TN2 z| | |YN3 YY7 | |z YY7| | | YY7| | |YY7| | |PO3 | | PY0 | | |PY0 z| | |PY0 PY0 | |z PH0| | | PY0| | |PY0| | |PY0 | | HO0 | | |PY0 z| | |PY0 PY0 | |z PO0| | | PY0| | |PY0| | |PY0 | | HN3 | | |YY4 z| | |PY0 PY0 | |z PY0| | | OP3| | |PY0| | |PY0 | | PN3 | | |PT0 z| | |PY0 PO4 | |z PT0| | | PY0| | |NO3| | |PT0 | | PY0 | | |NH3 z| | |PT0 PY0 | |z PN3| | | PY0| | |PY0| | |PN3 | | PH0 | | |PY0 z| | |PN3 PO0 | |z PY0| | | YP4| | |PO0| | |PY0 | | NP0 | | |PN3 z| | |PN0 PY0 | |z TY3| | | PO0| | |PY0| | |HO3 | | TO1 | | |PY0 z| | |PN3 YP0 | |z PY0| | | YH2| | |YO2| | |TN3 | | TN3 | | |PY0 z| | |NH3 PT0 | |z PY0| | | PN3| | |PH0| | |PY0 | | PN3 | | |PY0 z| | |PY0 PN3 | |z PO0| | | PY0| | |YP4| | |PO0 | | PY0 | | |NP0 z| | |PN3 YT0 | |z PY0| | | TY3| | |PO0| | |PY0 | | HO3 | | |HO3 z| | |PY0 PN3 | |z YP0| | | PY0| | |YH2| | |YO2 | | TN3 | | |TO2 z| | |PY0 NH3 | |z PT0| | | PY0| | |PN3| | |YH0 | | PY0 | | |TY0 z| | |PN3 YO0 | |z PY0| | | TY0| | |PN3| | |PO0 | | PY0 | | |TY0 z| | |YP4 PO0 | |z PY0| | | NP0| | |PN3| | |YN0 | | PY0 | | |TY3 z| | |PO0 PY0 | |z HO3| | | OT4| | |PY0| | |PN3 | | YP0 | | |PY0 z| | |YH2 YO2 | |z TN3| | | YN1| | |PY0| | |NH3 | | PT0 | | |PY0 z| | |PN3 TP0 | |z PY0| | | TY0| | |PN3| | |PH0 | | PY0 | | |TY0 z| | |PN3 PO0 | |z PY0| | | TY0| | |YP4| | |PO0 | | PY0 | | |NP0 z| | |PN3 TY0 | |z PY0| | | TY3| | |PO0| | |PY0 | | HO3 | | |TN2 z| | |PY0 PN3 | |z YP0| | | PY0| | |YH2| | |YO2 | | TN3 | | |YP0 z| | |PY0 PN3 | |z TH0| | | PY0| | |YH2| | |YO2 | | PN3 | | |PY0 z| | |PY0 HN2 | |z YO1| | | TO0| | |PY0| | |PY0 | | PY0 | | |TN2 z| | |HN3 TO0 | |z PY0| | | PY0| | |PY0| | |YP2 | | TN3 | | |OP3 z| | |YP3 HO3 | |z PY1| | | TH3| | |YN3| | |TN3 | | YP3 | | |NY1 z| | |PY1 TP0 | |z YN3| | | TN0| | |PY0| | |PY0 | | PY0 | | |YN3 z| | |PH0 PY0 | |z PY0| | | PY0| | |OP3| | |YH0 | | PY0 | | |PY0 z| | |PY0 ON2 | |z TO2| | | YH3| | |NP1| | |OT3 | | OT1 | | |OT1 z| | |HN3 YP0 | |z PY0| | | PY0| | |PY0| | |YT2 | | PT3 | | |YN3 z| | |TH3 PT1 | |z OP3| | | YO0| | |PY0| | |PY0 | | PY0 | | |NP3 z| | |PH2 YT3 | |z PH2| | | YH3| | |NP1| | |OT3 | | PT3 | | |YN3 z| | |HP0 PY0 | |z PY0| | | PY0| | |YN3| | |PP0 | | PY0 | | |PY0 z| | |PY0 OP3 | |z YO0| | | PY0| | |PY0| | |PY0 | | NP2 | | |HT1 z| | |HY2 ON2 | |z HT3| | | YH3| | |YH3| | |PH2 | | YN3 | | |PT0 z| | |PY0 PY0 | |z PY0| | | OP3| | |YH0| | |PY0 | | PY0 | | |PY0 z| | |HN1 OH2 | |z OH1| | | OP1| | |TY3| | |YO3 | | OH3 | | |HN3 z| | |YO0 PY0 | |z PY0| | | PY0| | |HN2| | |OY3 | | PO3 | | |PO3 z| | |YP3 HN3 | |z HN3| | | PT1| | |YO1| | |PH0 | | PY0 | | |PY0 z| | |PY0 OP3 | |z YN0| | | PY0| | |PY0| | |PY0 | | HO3 | | |PT3 z| | |OH3 YY2 | |z YN3| | | TN3| | |HY3| | |OY3 | | OP3 | | |OP3 z| | |PN0 PY0 | |z PY0| | | PY0| | |TH3| | |YN3 | | TN3 | | |YP3 z| | |YO1 PH0 | |z PY0| | | PY0| | |PY0| | |HO2 | | PN0 | | |PY0 z| | |PY0 PY0 | |z HO2| | | YP0| | |PY0| | |PY0 | | PY0 | | |YO1 z| | |PY0 PY0 | |z PY0| | | PY0| | |YO1| | |PY0 | | PY0 | | |PY0 z| | |PY0 HN3 | |z HP2| | | PY0| | |PY0| | |PY0 | | PN2 | | |NY1 z| | |NH2 PN2 | |z HP3| | | OH3| | |TN3| | |TH3 | | HP3 | | |PT3 z| | |PN3 HN3 | |z NH2| | | OY2| | |YT2| | |HP2 | | PO2 | | |OP2 z| | |YT2 NH2 | |z OP2| | | PT2| | |HN2| | |TY2 | | HN2 | | |NH2 z| | |HN3 YP3 | |z HO3| | | HY3| | |YP3| | |TN3 | | OP3 | | |NH2 z| | |HN3 HP3 | |z OY3| | | HO3| | |PO3| | |YP3 | | HN3 | | |NH2 z| | |HN2 YP3 | |z HO3| | | HY3| | |YP3| | |TN3 | | OP3 | | |TO1 z| | |TO3 PT3 | |z HN3| | | OP3| | |YP3| | |HO3 | | NH2 | | |HN2 z| | |YP3 HO3 | |z HY3| | | YP3| | |TN3| | |OP3 | | TO1 | | |TO3 z| | |PT3 HN3 | |z OP3| | | YP3| | |HO3| | |NH2 | | OP3 | | |YP3 z| | |HN3 OP3 | |z TN1| | | HY3| | |NP3| | |HN3 | | PN0 | | |PY0 z| | |PY0 PY0 | |z OP3| | | PT3| | |HN3| | |TY3 | | PN0 | | |PY0 z| | |PY0 PY0 | |z HN3| | | HY0| | |PY0| | |PY0 | | PY0 | | |PY0 z| | |PT0 TH0 | |z PT0| | | NP0| | |PT0| | |YO0 | | PT0 | | |NP0 z| | |PT0 YO0 | |z PO0| | | NH0| | |PT0| | |TH1 | | PH0 | | |YO1 z| | |PH0 PY0 | |z PY0| | | PY0| | |OP3| | |YH0 | | PY0 | | |PY0 z| | |PY0 HN3 | |z YP3| | | HO3| | |HY3| | |YP3 | | TN3 | | |OP3 z| | |OP3 PN0 | |z PY0| | | PY0| | |PY0| | |OP3 | | PT3 | | |HN3 z| | |TY3 YO1 | |z PH0| | | PY0| | |PY0| | |PY0 | | HO2 | | |YT0 z| | |PY0 PY0 | |z PY0| | | HO2| | |YH0| | |PY0 | | PY0 | | |PY0 z| | |YO1 PY0 | |z PY0| | | PY0| | |PY0| | |YO1 | | PY0 | | |PY0 z| | |PY0 PY0 | |z HN3| | | HP2| | |PY0| | |PY0 | | PY0 | | |PN2 z| | |NY1 NH2 | |z PN2| | | HP3| | |OH3| | |TN3 | | TH3 | | |HP3 z| | |PT3 PN3 | |z HN3| | | NH2| | |OY2| | |YT2 | | HP2 | | |PO2 z| | |OP2 YT2 | |z NH2| | | OP2| | |PT2| | |HN2 | | TY2 | | |HN2 z| | |NH2 HN3 | |z YP3| | | HO3| | |HY3| | |YP3 | | TN3 | | |OP3 z| | |NH2 HN3 | |z HP3| | | OY3| | |HO3| | |PO3 | | YP3 | | |HN3 z| | |NH2 HN2 | |z YP3| | | HO3| | |HY3| | |YP3 | | TN3 | | |OP3 z| | |TO1 TO3 | |z PT3| | | HN3| | |OP3| | |YP3 | | HO3 | | |NH2 z| | |HN2 YP3 | |z HO3| | | HY3| | |YP3| | |TN3 | | OP3 | | |TO1 z| | |TO3 PT3 | |z HN3| | | OP3| | |YP3| | |HO3 | | NH2 | | |OP3 z| | |YP3 HN3 | |z OP3| | | TN1| | |HY3| | |NP3 | | HN3 | | |YO0 z| | |PY0 PY0 | |z PY0| | | NH1| | |TO3| | |HP3 | | PN3 | | |OY3 z| | |TH3 YP3 | |z PP1| | | PT0| | |PY0| | |PY0 | | PY0 | | |HN3 z| | |PN0 PY0 | |z PY0| | | PY0| | |TH0| | |PO0 | | YN0 | | |TO0 z| | |zz z | | z | | | | | | | | \|/ v """
Сразу привлекает внимание строка import serpent. По запросу «python serpent sword» в гугл можно наткнуться на git-репозиторий, который судя по описанию — как раз то что нам нужно.
Изучив код serpent.py находим там описание принципа «превращения» кода в меч:
Given the hex digit 65:
65 % 32 = 1
floor( 65 / 32 ) = 2
so the alphabet symbol for 65 is the symbol at index 1: ‘PT’.
65 is also the 3rd occurrence of a 32-modulus of 1 (with 1
being the first occurrence and 33 being the second of course.)
so the code for this hex symbol is PT2
Но самое интересное расположено ниже:
elif scriptType is _SERPENT: pyc = _serpent_sword_alphabet_to_hex(_lex_hex(sys.argv[0])) pycout = ".".join(sys.argv[0].split(".")[0:-1])+".pyc" with open(pycout, "wb") as f: for val in pyc: f.write(chr(val))
Этот код, считывает преобразованный файл, и переводит его обратно в .pyc. Переименуем файл sword.py в sword.ss.py и попробуем его обратить:
gh0st3rs@gh0st3rs-pc:KingArthur$ python sword.ss.py RuntimeError: Bad magic number in .pyc file
Немного изменив код, таким образом чтобы файл sword.ss.pyc не удалялся обнаруживаем, что у полученного файла поврежден заголовок.
После долгих поисков, находим примерное описание заголовка .pyc файла. Но все попытки изменить его на верный не увенчались успехом.
Там же в статье, есть пример компиляции не всего файла, а отдельного участка кода. Вероятно таким же образом получится минуя заголовок, восстановить оставшуюся часть кода. Накидаем для этих целей небольшой скрипт:
#!/usr/bin/python import re import sys import marshal alphabet = [ "PY", "PT", "PH", "PO", "PN", "YP", "YT", "YH", "YO", "YN", "TP", "TY", "TH", "TO", "TN", "HP", "HY", "HT", "HO", "HN", "OP", "OY", "OT", "OH", "ON", "NP", "NY", "NT", "NH", "NO", "PP", "YY" ] def _serpent_sword_alphabet_to_hex(sentence): "Convert the serpent alphabet string back to python bytecode" return [alphabet.index(symbol[0:-1]) + int(symbol[-1]) * 32 for symbol in sentence] def _lex_hex(infile): "Extract the serpent string from the ss file" with open(infile, 'r') as source: regex = re.compile(r'[PYTHON][PYTHON][0-9]') tokens = [] for line in source: pos = 0 while(pos < len(line)): match = regex.match(line, pos) if match: tokens.append(match.group(0)) pos += 1 return tokens def convert_to_pyc(fname): pyc = _serpent_sword_alphabet_to_hex(_lex_hex(fname)) pycout = ".".join(fname.split(".")[0:-1]) + ".pyc" with open(pycout, "wb") as f: for val in pyc: f.write(chr(val)) f.close() return pycout fname = sys.argv[1] pycout = convert_to_pyc(fname) f = open(pycout, "rb").read() for x in range(len(f)): try: code = marshal.loads(f[x:]) print('Offset found: %d' % x) print('\targcount: %s' % code.co_argcount) print('\tcode: %s' % code.co_code.encode('hex')) print('\tconsts count: %d' % len(code.co_consts)) for item in code.co_consts: print('\t\t%s: %r' % (type(item), item)) print('\tfilename: %s' % code.co_filename) print('\tfirstlineno: %s' % code.co_firstlineno) print('\tflags: %s' % code.co_flags) print('\tname: %s' % code.co_name) print('\tnlocals: %s' % code.co_nlocals) print('\tstacksize: %s' % code.co_stacksize) print('\tvarnames count: %d' % len(code.co_varnames)) for item in code.co_varnames: print('\t\t%r' % item) break except ValueError: continue
После запуска получаем вывод:
gh0st3rs@gh0st3rs-pc:KingArthur$ ./unserpent.py sword.ss.py Offset found: 7 argcount: 0 code: 6401006400006c00005a00006402008400005a01006501008300000164000053 consts count: 3 <type 'NoneType'>: None <type 'int'>: -1 <type 'code'>: <code object task at 0x7f7e85aa9eb0, file "D:\Downloads\UFOCTF\TASKS\serpent\sources\Serpent-master\Serpent-master\test.py", line 4> filename: D:\Downloads\UFOCTF\TASKS\serpent\sources\Serpent-master\Serpent-master\test.py firstlineno: 1 flags: 0 name: <module> nlocals: 0 stacksize: 2 varnames count: 2 'serpent' 'task'
Как можно заметить, тут есть ещё 1 объект code, он то нам и нужен. Добавим ещё пару строк, для его декомпиляции:
import uncompyle6 ... uncompyle6.main.uncompyle(2.7, code.co_consts[2], sys.stdout)
Снова запускаем и получаем готовый скрипт:
# uncompyle6 version 2.9.10 # Python bytecode 2.7 # Decompiled from: Python 2.7.6 (default, Oct 26 2016, 20:30:19) # [GCC 4.8.4] # Embedded file name: D:\Downloads\UFOCTF\TASKS\serpent\sources\Serpent-master\Serpent-master\test.py line = raw_input('Enter line: \n') if line[:14:2] != 'XMg9v66': print 'Fail!' elif line[14::2] != 'yBfBg9va': print 'Fail!' elif line[-15:-30:-2] != 'Y1PXqggB': print 'Fail!' elif line[-1:-14:-2] != '3W74khw': print 'Fail!' else: print 'Success!'
Осталось дело за малым, по полученному коду восстанавливаем флаг:
ufoctf{XBMggg9qvX6P61yYBwfhBkg497vWa3}
Задание пройдено! +600 к рейтингу!
ссылка на оригинал статьи https://habrahabr.ru/post/325580/
Добавить комментарий