HITCON 2016 Quals: Handcrafted pyc (rev50)

Reading time ~2 minutes

Saved payload as pyc with this script:

import marshal, zlib, base64

open('code.pyc','wb').write('03f30d0a5a8cbc52'.decode('hex') + zlib.decompress(base64.b64decode('eJyNVktv...kLHmeCBQ==')))

Disassembled the pyc file with uncompyle:

kt@ubuntu:~/ctf/hitcon2016$ uncompyle6 code.pyc
# Python 2.7 (decompiled from Python 2.7)
# Embedded file name: <string>
# Compiled at: 2013-12-26 21:06:50


def main--- This code section failed: ---

   1       0    LOAD_GLOBAL       'chr'
           3    LOAD_CONST        108
           6    CALL_FUNCTION_1   ''
           9    LOAD_GLOBAL       'chr'
          12    LOAD_CONST        108
          15    CALL_FUNCTION_1   ''
          18    LOAD_GLOBAL       'chr'
          21    LOAD_CONST        97
...

Simulated the string creation with this C# code:

static void HandcraftedPyc()
{
    // Call me a Python virtual machine! I can interpret Python bytecodes!!!

    var cmds = File.ReadAllLines(@"disas.txt").Select(x => Regex.Match(x, @"(.*?)\s+(.*)").Groups.OfType<Group>().Skip(1).Select(g => g.Value).ToArray()).ToArray();
    var stack = new Stack<string>();
    foreach (var cmd in cmds)
    {
        if (cmd[0] == "LOAD_GLOBAL" || cmd[0] == "LOAD_CONST")
            stack.Push(cmd[1]);
        else if (cmd[0] == "CALL_FUNCTION_1")
        {
            var arg = stack.Pop();
            var func = stack.Pop();
            if (func == "'chr'")
                stack.Push("" + (char)int.Parse(arg));
            else
                Debugger.Break();
        }
        else if (cmd[0] == "ROT_TWO")
        {
            var arg1 = stack.Pop();
            var arg2 = stack.Pop();
            stack.Push(arg1);
            stack.Push(arg2);
        }
        else if (cmd[0] == "BINARY_ADD")
        {
            var arg1 = stack.Pop();
            var arg2 = stack.Pop();
            stack.Push(arg2 + arg1);
        }
        else
            Debugger.Break();
    }
}

At the end the stack contains one variable, the ‘decrypted’ string. The first code block created the string “Call me a Python virtual machine! I can interpret Python bytecodes!!!”, while the second code block created the flag:

hitcon{Now you can compile and run Python bytecode in your brain!}

HITCON CTF 2019 Quals: Reverse - EmojiVM

This challenge was a VM implemented where every instruction was an emoji. For the first part of the challenge we had to reverse a flag ch...… Continue reading

HITCON CTF 2019 Quals: Reverse - CoreDumb

Published on October 19, 2019

HITCON CTF 2019 Quals: Pwn - Crypto in the shell

Published on October 19, 2019