Skip to content

Instantly share code, notes, and snippets.

@Redict
Created October 13, 2019 13:24
Show Gist options
  • Select an option

  • Save Redict/a0d58c9e98117095540ab7cd2141a8f0 to your computer and use it in GitHub Desktop.

Select an option

Save Redict/a0d58c9e98117095540ab7cd2141a8f0 to your computer and use it in GitHub Desktop.
Messaging Tool Writeup

Messaging Tool


  • Открываем msg.py и видим что-то наподобии меча, а так же импорт serpent модуля.
  • Гуглим serpent python github: link
  • Открываем код проекта и смотрим, как создаётся меч и что он значит.
  • Копируем часть кода:
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:])
        for item in code.co_consts:
            print('\t\t%s: %r' % (type(item), item))
            if str(type(item)) == "<type 'code'>":
                uncompyle6.main.decompile(2.7, item, sys.stdout)

и вытаскиваем оттуда переменные mod_fix, KEY, функции get_next_key и decrypt, а так же длинный массив байт: flag = [62, 125, 128, 30, 59, 77, 9, 125, 32, 40, 187, 190, 227, 207, 120, 195, 88, 210, 27, 20, 147, 218, 153, 83, 197]

  • Скрипт по дешифровке флага будет выглядеть так:
import struct

mod_fix = 0xFFFFFFFF
KEY = "SAFE"
flag = [62, 125, 128, 30, 59, 77, 9, 125, 32, 40, 187, 190, 227, 207, 120, 195, 88, 210, 27, 20, 147, 218, 153, 83, 197]

def get_next_key(current_key, current_byte):
    a = current_byte + current_key
    a = ((a << 12) + a + 0x7ED55D16) & mod_fix
    a = ((a >> 19) ^ a ^ 0xC761C23C)
    a = ((a << 5) + a + 0x165667B1) & mod_fix
    a = ((a << 9) ^ (a - 0x2C5D9B94))
    a = ((a << 3) + a - 0x28FB93B) & mod_fix
    a = ((a >> 16) ^ a ^ 0xB55A4F09)
    return a



def decrypt(data, bytes_key):
    key = struct.unpack('=L', bytes_key)[0]
    data = bytearray(data)
    for i in range(len(data)):
        old_byte = data[i]
        data[i] ^= key & 255
        key = get_next_key(key, old_byte)
    return bytes(data)


if __name__ == "__main__":
    print(decrypt(flag, KEY.encode("utf-8")))
  • Запускаем и получаем флаг: mctf{pyc_d3c0mp1l4710n!!}
@Defend2505

Defend2505 commented Oct 14, 2019

Copy link
Copy Markdown

не знаю, как ты это сделал, но это не работает

@Defend2505

Copy link
Copy Markdown

можешь объяснить подробнее, как ты вытаскивал код из бинарника?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment