English [Hitcon 2016] [REVERSE 50 – Handcrafted pyc] Write Up

Description

Handcrafted pyc
238 Teams solved.
Description
Can your brain be a Python VM? (Please use Python 2.7)

crackme
Hint
None

Resolution

We were given a python crackme (sources are in the description).
Executing the given script yield us:

laxa:handcrafted_pyc:12:46:02$ ./crackme.py
password: qwd
Wrong password... Please try again. Do not brute force. =)

We will use the python console to see what’s our code all about, to find some informations:

laxa:handcrafted_pyc:12:52:22$ python
Python 2.7.9 (default, Jun 29 2016, 13:08:31) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import marshal, zlib, base64
>>> 
>>> a = marshal.loads(zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGORtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ==')))
>>> type(a)
<type 'code'>
>>> dir(a)
['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
>>> a.co_consts
(None, <code object main at 0x7fca8f844e30, file "<string>", line 1>, '__main__')
>>> a.co_code
'd\x01\x00\x84\x00\x00Z\x00\x00e\x01\x00d\x02\x00k\x02\x00r\x1f\x00e\x00\x00\x83\x00\x00\x01n\x00\x00d\x00\x00S'
>>> a.co_consts[1]
<code object main at 0x7fca8f844e30, file "<string>", line 1>
>>> a.co_consts[1].co_code
't\x00\x00d\x01\x00\x83\x01\x00t\x00\x00d\x01\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00t\x00\x00d\x03\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\x06\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x07\x00\x83\x01\x00t\x00\x00d\x08\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\t\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17\x17t\x00\x00d\n\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x0e\x00\x83\x01\x00t\x00\x00d\x0f\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x01\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00t\x00\x00d\x10\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\t\x00\x83\x01\x00t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00t\x00\x00d\x06\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x0e\x00\x83\x01\x00\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x12\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17\x17\x17t\x00\x00d\x02\x00\x83\x01\x00t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x13\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x0e\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x14\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00\x02\x17t\x00\x00d\x08\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17\x17t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\t\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00t\x00\x00d\x07\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00\x02\x17t\x00\x00d\n\x00\x83\x01\x00t\x00\x00d\x07\x00\x83\x01\x00t\x00\x00d\x15\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17t\x00\x00d\x16\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x17\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00\x02\x17t\x00\x00d\x12\x00\x83\x01\x00t\x00\x00d\x12\x00\x83\x01\x00t\x00\x00d\x12\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17\x17\x17\x17d\x00\x00\tq\xf7\x02t\x01\x00q\xc8\x05|\x00\x00k\x02\x00q\xff\x02\x02}\x00\x00\x01q\xe8\x02r7\x06t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00t\x00\x00d\x0e\x00\x83\x01\x00t\x00\x00d\t\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x18\x00\x83\x01\x00t\x00\x00d\x19\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x07\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x1a\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x10\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17\x17t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x0e\x00\x83\x01\x00t\x00\x00d\x14\x00\x83\x01\x00t\x00\x00d\x06\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x02\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\x01\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x16\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00\x02\x17t\x00\x00d\x10\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17\x17\x17t\x00\x00d\x07\x00\x83\x01\x00t\x00\x00d\x08\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\t\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\n\x00\x83\x01\x00t\x00\x00d\x07\x00\x83\x01\x00t\x00\x00d\x15\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x16\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17\x17t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x0e\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x10\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\x07\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x15\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x0e\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00\x02\x17t\x00\x00d\x1b\x00\x83\x01\x00t\x00\x00d\x12\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17\x17\x17\x17q\xa4\x08t\x00\x00d\x02\x00\x83\x01\x00t\x00\x00d\x14\x00\x83\x01\x00\x02\x17t\x00\x00d\x1a\x00\x83\x01\x00t\x00\x00d\x17\x00\x83\x01\x00t\x00\x00d\x17\x00\x83\x01\x00\x02\x17\x02\x17\x17t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x1c\x00\x83\x01\x00t\x00\x00d\x16\x00\x83\x01\x00\x02\x17\x02\x17\x17\x17\x83\x01\x00q\xee\x02t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x1d\x00\x83\x01\x00\x02\x17\x02\x17t\x00\x00d\x14\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x1e\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x17\x00\x83\x01\x00t\x00\x00d\x17\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00\x02\x17\x02\x17t\x00\x00d\x16\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\x1a\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17\x17t\x00\x00d\x1f\x00\x83\x01\x00t\x00\x00d\x1f\x00\x83\x01\x00t\x00\x00d\x1f\x00\x83\x01\x00\x02\x17\x02\x17t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\x01\x00\x83\x01\x00t\x00\x00d\x08\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\x17\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x07\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17\x17\x17t\x00\x00d\x02\x00\x83\x01\x00t\x00\x00d\x1e\x00\x83\x01\x00t\x00\x00d\x02\x00\x83\x01\x00\x02\x17\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x1f\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00t\x00\x00d\x0e\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d \x00\x83\x01\x00\x02\x17\x02\x17t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00t\x00\x00d\x0b\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17\x17t\x00\x00d\x10\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x15\x00\x83\x01\x00\x02\x17\x02\x17t\x00\x00d!\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\n\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17t\x00\x00d\x05\x00\x83\x01\x00t\x00\x00d\x11\x00\x83\x01\x00t\x00\x00d\r\x00\x83\x01\x00t\x00\x00d\x0c\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17t\x00\x00d"\x00\x83\x01\x00t\x00\x00d#\x00\x83\x01\x00t\x00\x00d\x04\x00\x83\x01\x00t\x00\x00d\x1f\x00\x83\x01\x00\x02\x17\x02\x17\x02\x17\x17\x17\x17\x17GHd\x00\x00S'
>>> a.co_consts[1].co_consts
(None, 108, 97, 67, 32, 101, 109, 121, 80, 104, 116, 110, 111, 114, 105, 118, 117, 99, 33, 73, 112, 98, 100, 115, 78, 123, 119, 125, 58, 87, 103, 46, 68, 102, 41, 61)
>>> a.co_consts[1].co_varnames
('password',)
>>> b.co_names
('chr', 'raw_input')

From that we can see a list of things:
– We have 2 parts of the code, first one is pretty short, it’s the global scope of the script calling the main function,
– on the main function, we have 2 functions used: raw_input() and chr(),
– we have some constants used, a list of integer that doesn’t give us the flag directly,
– we have a varname ‘password’.

Now we are running this little script:

#!/usr/bin/env python                                                                                                                                                                                                                                                             
# -*- coding: utf-8 -*-                                                                                                                                                                                                                                                           

import marshal, zlib, base64
import dis

a = marshal.loads(zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6\
xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7\
Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGO\
Rtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ==')))
dis.disassemble_string(a.co_consts[1].co_code)

And then trying to see how things are loaded directly in the python bytecode/asm:

laxa:handcrafted_pyc:13:02:11$ cat disas | grep LOAD | sort -u
          0 LOAD_GLOBAL         0 (0)
       1001 LOAD_GLOBAL         0 (0)
       1004 LOAD_CONST          6 (6)
       1010 LOAD_GLOBAL         0 (0)
       1013 LOAD_CONST         12 (12)
       1026 LOAD_GLOBAL         0 (0)
       1029 LOAD_CONST          2 (2)
       1035 LOAD_GLOBAL         0 (0)
       1038 LOAD_CONST          4 (4)
        103 LOAD_GLOBAL         0 (0)
       1044 LOAD_GLOBAL         0 (0)
       1047 LOAD_CONST          5 (5)
       1053 LOAD_GLOBAL         0 (0)
       1056 LOAD_CONST          1 (1)
       1068 LOAD_GLOBAL         0 (0)
        106 LOAD_CONST          4 (4)
       1071 LOAD_CONST         22 (22)
       1077 LOAD_GLOBAL         0 (0)
       1080 LOAD_CONST         11 (11)
       1088 LOAD_GLOBAL         0 (0)
       1091 LOAD_CONST         16 (16)
       1097 LOAD_GLOBAL         0 (0)
       1100 LOAD_CONST         13 (13)
       1106 LOAD_GLOBAL         0 (0)
       1109 LOAD_CONST          4 (4)
       1123 LOAD_GLOBAL         0 (0)
       1126 LOAD_CONST          7 (7)
        112 LOAD_GLOBAL         0 (0)
       1132 LOAD_GLOBAL         0 (0)
       1135 LOAD_CONST          8 (8)
       1141 LOAD_GLOBAL         0 (0)
       1144 LOAD_CONST          4 (4)
       1150 LOAD_GLOBAL         0 (0)
       1153 LOAD_CONST         11 (11)
        115 LOAD_CONST          2 (2)
       1165 LOAD_GLOBAL         0 (0)
       1168 LOAD_CONST         11 (11)
       1174 LOAD_GLOBAL         0 (0)
       1177 LOAD_CONST         12 (12)
       1183 LOAD_GLOBAL         0 (0)
       1186 LOAD_CONST          9 (9)
       1192 LOAD_GLOBAL         0 (0)
       1195 LOAD_CONST         10 (10)
       1208 LOAD_GLOBAL         0 (0)
       1211 LOAD_CONST         10 (10)
       1217 LOAD_GLOBAL         0 (0)
       1220 LOAD_CONST          7 (7)
       1226 LOAD_GLOBAL         0 (0)
       1229 LOAD_CONST         21 (21)
       1235 LOAD_GLOBAL         0 (0)
       1238 LOAD_CONST          4 (4)
       1250 LOAD_GLOBAL         0 (0)
       1253 LOAD_CONST         22 (22)
       1259 LOAD_GLOBAL         0 (0)
       1262 LOAD_CONST         12 (12)
       1268 LOAD_GLOBAL         0 (0)
       1271 LOAD_CONST         17 (17)
       1277 LOAD_GLOBAL         0 (0)
        127 LOAD_GLOBAL         0 (0)
       1280 LOAD_CONST          5 (5)
       1294 LOAD_GLOBAL         0 (0)
       1297 LOAD_CONST         11 (11)
         12 LOAD_CONST          1 (1)
       1303 LOAD_GLOBAL         0 (0)
       1306 LOAD_CONST         14 (14)
        130 LOAD_CONST          9 (9)
       1312 LOAD_GLOBAL         0 (0)
       1315 LOAD_CONST          4 (4)
       1321 LOAD_GLOBAL         0 (0)
       1324 LOAD_CONST          5 (5)
       1336 LOAD_GLOBAL         0 (0)
       1339 LOAD_CONST         16 (16)
       1345 LOAD_GLOBAL         0 (0)
       1348 LOAD_CONST         12 (12)
       1354 LOAD_GLOBAL         0 (0)
       1357 LOAD_CONST          7 (7)
       1363 LOAD_GLOBAL         0 (0)
       1366 LOAD_CONST          4 (4)
        136 LOAD_GLOBAL         0 (0)
       1379 LOAD_GLOBAL         0 (0)
       1382 LOAD_CONST         13 (13)
       1388 LOAD_GLOBAL         0 (0)
       1391 LOAD_CONST         21 (21)
       1397 LOAD_GLOBAL         0 (0)
        139 LOAD_CONST         10 (10)
       1400 LOAD_CONST          4 (4)
       1406 LOAD_GLOBAL         0 (0)
       1409 LOAD_CONST         13 (13)
       1421 LOAD_GLOBAL         0 (0)
       1424 LOAD_CONST         14 (14)
       1430 LOAD_GLOBAL         0 (0)
       1433 LOAD_CONST          2 (2)
       1441 LOAD_GLOBAL         0 (0)
       1444 LOAD_CONST         27 (27)
       1450 LOAD_GLOBAL         0 (0)
       1453 LOAD_CONST         18 (18)
       1459 LOAD_GLOBAL         0 (0)
       1462 LOAD_CONST         11 (11)
        147 LOAD_GLOBAL         0 (0)
    >> 1480 LOAD_GLOBAL         0 (0)
       1483 LOAD_CONST          2 (2)
       1489 LOAD_GLOBAL         0 (0)
       1492 LOAD_CONST         20 (20)
       1500 LOAD_GLOBAL         0 (0)
       1503 LOAD_CONST         26 (26)
       1509 LOAD_GLOBAL         0 (0)
        150 LOAD_CONST          4 (4)
       1512 LOAD_CONST         23 (23)
       1518 LOAD_GLOBAL         0 (0)
       1521 LOAD_CONST         23 (23)
       1532 LOAD_GLOBAL         0 (0)
       1535 LOAD_CONST         13 (13)
       1541 LOAD_GLOBAL         0 (0)
       1544 LOAD_CONST         12 (12)
       1552 LOAD_GLOBAL         0 (0)
       1555 LOAD_CONST          4 (4)
       1561 LOAD_GLOBAL         0 (0)
       1564 LOAD_CONST         28 (28)
        156 LOAD_GLOBAL         0 (0)
       1570 LOAD_GLOBAL         0 (0)
       1573 LOAD_CONST         22 (22)
    >> 1591 LOAD_GLOBAL         0 (0)
       1594 LOAD_CONST         12 (12)
        159 LOAD_CONST         11 (11)
       1600 LOAD_GLOBAL         0 (0)
       1603 LOAD_CONST         13 (13)
       1609 LOAD_GLOBAL         0 (0)
       1612 LOAD_CONST         29 (29)
       1622 LOAD_GLOBAL         0 (0)
       1625 LOAD_CONST         20 (20)
       1631 LOAD_GLOBAL         0 (0)
       1634 LOAD_CONST          4 (4)
       1640 LOAD_GLOBAL         0 (0)
       1643 LOAD_CONST         30 (30)
       1649 LOAD_GLOBAL         0 (0)
       1652 LOAD_CONST         11 (11)
        165 LOAD_GLOBAL         0 (0)
       1665 LOAD_GLOBAL         0 (0)
       1668 LOAD_CONST         23 (23)
       1674 LOAD_GLOBAL         0 (0)
       1677 LOAD_CONST         23 (23)
       1683 LOAD_GLOBAL         0 (0)
       1686 LOAD_CONST          2 (2)
        168 LOAD_CONST         12 (12)
       1696 LOAD_GLOBAL         0 (0)
       1699 LOAD_CONST         22 (22)
       1705 LOAD_GLOBAL         0 (0)
       1708 LOAD_CONST         13 (13)
       1714 LOAD_GLOBAL         0 (0)
       1717 LOAD_CONST         12 (12)
       1723 LOAD_GLOBAL         0 (0)
       1726 LOAD_CONST         26 (26)
       1740 LOAD_GLOBAL         0 (0)
       1743 LOAD_CONST         31 (31)
       1749 LOAD_GLOBAL         0 (0)
       1752 LOAD_CONST         31 (31)
       1758 LOAD_GLOBAL         0 (0)
       1761 LOAD_CONST         31 (31)
       1771 LOAD_GLOBAL         0 (0)
       1774 LOAD_CONST          5 (5)
       1780 LOAD_GLOBAL         0 (0)
       1783 LOAD_CONST          1 (1)
       1789 LOAD_GLOBAL         0 (0)
       1792 LOAD_CONST          8 (8)
       1798 LOAD_GLOBAL         0 (0)
       1801 LOAD_CONST          4 (4)
       1814 LOAD_GLOBAL         0 (0)
       1817 LOAD_CONST          4 (4)
        181 LOAD_GLOBAL         0 (0)
       1823 LOAD_GLOBAL         0 (0)
       1826 LOAD_CONST          5 (5)
       1832 LOAD_GLOBAL         0 (0)
       1835 LOAD_CONST         23 (23)
       1841 LOAD_GLOBAL         0 (0)
       1844 LOAD_CONST          2 (2)
        184 LOAD_CONST         10 (10)
       1856 LOAD_GLOBAL         0 (0)
       1859 LOAD_CONST          4 (4)
       1865 LOAD_GLOBAL         0 (0)
       1868 LOAD_CONST          7 (7)
       1874 LOAD_GLOBAL         0 (0)
       1877 LOAD_CONST         13 (13)
       1883 LOAD_GLOBAL         0 (0)
       1886 LOAD_CONST         10 (10)
         18 LOAD_GLOBAL         0 (0)
       1901 LOAD_GLOBAL         0 (0)
       1904 LOAD_CONST          2 (2)
        190 LOAD_GLOBAL         0 (0)
       1910 LOAD_GLOBAL         0 (0)
       1913 LOAD_CONST         30 (30)
       1919 LOAD_GLOBAL         0 (0)
       1922 LOAD_CONST          2 (2)
       1932 LOAD_GLOBAL         0 (0)
       1935 LOAD_CONST          4 (4)
        193 LOAD_CONST         13 (13)
       1941 LOAD_GLOBAL         0 (0)
       1944 LOAD_CONST         31 (31)
       1950 LOAD_GLOBAL         0 (0)
       1953 LOAD_CONST         11 (11)
       1959 LOAD_GLOBAL         0 (0)
       1962 LOAD_CONST         14 (14)
       1975 LOAD_GLOBAL         0 (0)
       1978 LOAD_CONST          4 (4)
       1984 LOAD_GLOBAL         0 (0)
       1987 LOAD_CONST         12 (12)
       1993 LOAD_GLOBAL         0 (0)
       1996 LOAD_CONST         32 (32)
        199 LOAD_GLOBAL         0 (0)
       2006 LOAD_GLOBAL         0 (0)
       2009 LOAD_CONST          4 (4)
       2015 LOAD_GLOBAL         0 (0)
       2018 LOAD_CONST         10 (10)
       2024 LOAD_GLOBAL         0 (0)
       2027 LOAD_CONST         12 (12)
        202 LOAD_CONST         14 (14)
       2033 LOAD_GLOBAL         0 (0)
       2036 LOAD_CONST         11 (11)
       2050 LOAD_GLOBAL         0 (0)
       2053 LOAD_CONST         16 (16)
       2059 LOAD_GLOBAL         0 (0)
       2062 LOAD_CONST         13 (13)
       2068 LOAD_GLOBAL         0 (0)
       2071 LOAD_CONST         21 (21)
       2081 LOAD_GLOBAL         0 (0)
       2084 LOAD_CONST         33 (33)
        208 LOAD_GLOBAL         0 (0)
       2090 LOAD_GLOBAL         0 (0)
       2093 LOAD_CONST          4 (4)
       2099 LOAD_GLOBAL         0 (0)
       2102 LOAD_CONST          5 (5)
       2108 LOAD_GLOBAL         0 (0)
       2111 LOAD_CONST         10 (10)
        211 LOAD_CONST         15 (15)
       2124 LOAD_GLOBAL         0 (0)
       2127 LOAD_CONST          5 (5)
       2133 LOAD_GLOBAL         0 (0)
       2136 LOAD_CONST         17 (17)
       2142 LOAD_GLOBAL         0 (0)
       2145 LOAD_CONST         13 (13)
       2151 LOAD_GLOBAL         0 (0)
       2154 LOAD_CONST         12 (12)
       2166 LOAD_GLOBAL         0 (0)
       2169 LOAD_CONST         34 (34)
       2175 LOAD_GLOBAL         0 (0)
       2178 LOAD_CONST         35 (35)
       2184 LOAD_GLOBAL         0 (0)
       2187 LOAD_CONST          4 (4)
       2193 LOAD_GLOBAL         0 (0)
       2196 LOAD_CONST         31 (31)
         21 LOAD_CONST          2 (2)
       2214 LOAD_CONST          0 (0)
        223 LOAD_GLOBAL         0 (0)
        226 LOAD_CONST          4 (4)
        232 LOAD_GLOBAL         0 (0)
        235 LOAD_CONST          1 (1)
        241 LOAD_GLOBAL         0 (0)
        244 LOAD_CONST          2 (2)
        250 LOAD_GLOBAL         0 (0)
        253 LOAD_CONST         16 (16)
        266 LOAD_GLOBAL         0 (0)
        269 LOAD_CONST          9 (9)
        275 LOAD_GLOBAL         0 (0)
        278 LOAD_CONST         17 (17)
         27 LOAD_GLOBAL         0 (0)
        284 LOAD_GLOBAL         0 (0)
        287 LOAD_CONST          2 (2)
        293 LOAD_GLOBAL         0 (0)
        296 LOAD_CONST          6 (6)
        308 LOAD_GLOBAL         0 (0)
         30 LOAD_CONST          3 (3)
        311 LOAD_CONST         11 (11)
        317 LOAD_GLOBAL         0 (0)
        320 LOAD_CONST         14 (14)
        328 LOAD_GLOBAL         0 (0)
        331 LOAD_CONST          4 (4)
        337 LOAD_GLOBAL         0 (0)
        340 LOAD_CONST         18 (18)
        346 LOAD_GLOBAL         0 (0)
        349 LOAD_CONST          5 (5)
        363 LOAD_GLOBAL         0 (0)
        366 LOAD_CONST          2 (2)
        372 LOAD_GLOBAL         0 (0)
        375 LOAD_CONST         17 (17)
        381 LOAD_GLOBAL         0 (0)
        384 LOAD_CONST          4 (4)
        390 LOAD_GLOBAL         0 (0)
        393 LOAD_CONST         19 (19)
          3 LOAD_CONST          1 (1)
        405 LOAD_GLOBAL         0 (0)
        408 LOAD_CONST         11 (11)
        414 LOAD_GLOBAL         0 (0)
        417 LOAD_CONST         14 (14)
        423 LOAD_GLOBAL         0 (0)
        426 LOAD_CONST          4 (4)
         42 LOAD_GLOBAL         0 (0)
        432 LOAD_GLOBAL         0 (0)
        435 LOAD_CONST         11 (11)
        448 LOAD_GLOBAL         0 (0)
        451 LOAD_CONST         20 (20)
        457 LOAD_GLOBAL         0 (0)
         45 LOAD_CONST          4 (4)
        460 LOAD_CONST         13 (13)
        466 LOAD_GLOBAL         0 (0)
        469 LOAD_CONST          5 (5)
        475 LOAD_GLOBAL         0 (0)
        478 LOAD_CONST         10 (10)
        490 LOAD_GLOBAL         0 (0)
        493 LOAD_CONST          5 (5)
        499 LOAD_GLOBAL         0 (0)
        502 LOAD_CONST         13 (13)
        510 LOAD_GLOBAL         0 (0)
        513 LOAD_CONST          8 (8)
        519 LOAD_GLOBAL         0 (0)
         51 LOAD_GLOBAL         0 (0)
        522 LOAD_CONST          4 (4)
        528 LOAD_GLOBAL         0 (0)
        531 LOAD_CONST         10 (10)
        544 LOAD_GLOBAL         0 (0)
        547 LOAD_CONST         12 (12)
         54 LOAD_CONST          5 (5)
        553 LOAD_GLOBAL         0 (0)
        556 LOAD_CONST          9 (9)
        562 LOAD_GLOBAL         0 (0)
        565 LOAD_CONST         10 (10)
        571 LOAD_GLOBAL         0 (0)
        574 LOAD_CONST          7 (7)
        586 LOAD_GLOBAL         0 (0)
        589 LOAD_CONST          4 (4)
        595 LOAD_GLOBAL         0 (0)
        598 LOAD_CONST         11 (11)
        606 LOAD_GLOBAL         0 (0)
        609 LOAD_CONST         10 (10)
         60 LOAD_GLOBAL         0 (0)
        615 LOAD_GLOBAL         0 (0)
        618 LOAD_CONST          7 (7)
        624 LOAD_GLOBAL         0 (0)
        627 LOAD_CONST         21 (21)
        639 LOAD_GLOBAL         0 (0)
         63 LOAD_CONST          6 (6)
        642 LOAD_CONST         22 (22)
        648 LOAD_GLOBAL         0 (0)
        651 LOAD_CONST         12 (12)
        657 LOAD_GLOBAL         0 (0)
        660 LOAD_CONST         17 (17)
        666 LOAD_GLOBAL         0 (0)
        669 LOAD_CONST          5 (5)
        681 LOAD_GLOBAL         0 (0)
        684 LOAD_CONST         23 (23)
        690 LOAD_GLOBAL         0 (0)
        693 LOAD_CONST          5 (5)
         69 LOAD_GLOBAL         0 (0)
        701 LOAD_GLOBAL         0 (0)
        704 LOAD_CONST         18 (18)
        710 LOAD_GLOBAL         0 (0)
        713 LOAD_CONST         18 (18)
        719 LOAD_GLOBAL         0 (0)
        722 LOAD_CONST         18 (18)
         72 LOAD_CONST          4 (4)
        737 LOAD_CONST          0 (0)
    >>  744 LOAD_GLOBAL         1 (1)
    >>  750 LOAD_FAST           0 (0)
        770 LOAD_GLOBAL         0 (0)
        773 LOAD_CONST         17 (17)
        779 LOAD_GLOBAL         0 (0)
        782 LOAD_CONST         10 (10)
        788 LOAD_GLOBAL         0 (0)
        791 LOAD_CONST         14 (14)
        797 LOAD_GLOBAL         0 (0)
        800 LOAD_CONST          9 (9)
        812 LOAD_GLOBAL         0 (0)
        815 LOAD_CONST         24 (24)
        821 LOAD_GLOBAL         0 (0)
        824 LOAD_CONST         25 (25)
        830 LOAD_GLOBAL         0 (0)
        833 LOAD_CONST         11 (11)
        839 LOAD_GLOBAL         0 (0)
        842 LOAD_CONST         12 (12)
        855 LOAD_GLOBAL         0 (0)
        858 LOAD_CONST          7 (7)
         85 LOAD_GLOBAL         0 (0)
        864 LOAD_GLOBAL         0 (0)
        867 LOAD_CONST          4 (4)
        873 LOAD_GLOBAL         0 (0)
        876 LOAD_CONST         26 (26)
        882 LOAD_GLOBAL         0 (0)
        885 LOAD_CONST         12 (12)
         88 LOAD_CONST          7 (7)
        897 LOAD_GLOBAL         0 (0)
        900 LOAD_CONST         17 (17)
        906 LOAD_GLOBAL         0 (0)
        909 LOAD_CONST          4 (4)
        915 LOAD_GLOBAL         0 (0)
        918 LOAD_CONST         16 (16)
        924 LOAD_GLOBAL         0 (0)
        927 LOAD_CONST         12 (12)
        941 LOAD_GLOBAL         0 (0)
        944 LOAD_CONST         17 (17)
         94 LOAD_GLOBAL         0 (0)
        950 LOAD_GLOBAL         0 (0)
        953 LOAD_CONST          4 (4)
        959 LOAD_GLOBAL         0 (0)
        962 LOAD_CONST         11 (11)
        968 LOAD_GLOBAL         0 (0)
        971 LOAD_CONST          2 (2)
         97 LOAD_CONST          8 (8)
        983 LOAD_GLOBAL         0 (0)
        986 LOAD_CONST         14 (14)
        992 LOAD_GLOBAL         0 (0)
        995 LOAD_CONST         20 (20)
          9 LOAD_GLOBAL         0 (0)
laxa:handcrafted_pyc:13:03:24$ cat disas | grep LOAD | sort -u | grep -v CONST | grep -v GLOBAL
    >>  750 LOAD_FAST           0 (0)

First we can see that a lots of LOAD_GLOBAL and LOAD_CONST are in the code, but only 1 LOAD_FAST. We know the consts already and the global refers to the functions. Maybe LOAD_FAST refers to the varnames we previously found which is password.

We also know that the script will print us a phrase just before ending. So, we made the assumptiong that the last instructions are the one being executed when we fail giving the good password and since python is stack based, we tried injecting LOAD_FAST just before the print statement to see if we could directly get the password.

For the reference, python opcodes and my system was located there: /usr/include/python2.7/opcode.h

Before injection we have the following end assembly:

laxa:handcrafted_pyc:13:08:02$ ./disas.py | tail
       2206 ROT_TWO        
       2207 BINARY_ADD     
       2208 BINARY_ADD     
       2209 BINARY_ADD     
       2210 BINARY_ADD     
       2211 BINARY_ADD     
    >> 2212 PRINT_ITEM     
       2213 PRINT_NEWLINE  
       2214 LOAD_CONST          0 (0)
       2217 RETURN_VALUE   

And after injecting the following sequence of byte “|\x00\x00” at offset 2211 we get this:

laxa:handcrafted_pyc:13:10:12$ ./solve.py | tail
       2208 BINARY_ADD     
       2209 BINARY_ADD     
       2210 BINARY_ADD     
       2211 BINARY_ADD     
    >> 2212 LOAD_FAST           0 (0)
       2215 PRINT_ITEM     
       2216 PRINT_NEWLINE  
       2217 LOAD_CONST          0 (0)
       2220 RETURN_VALUE   

So, running the code with our injected LOAD_FAST:

laxa:handcrafted_pyc:13:11:50$ ./solve.py 
password: wqd
Call me a Python virtual machine! I can interpret Python bytecodes!!!
laxa:handcrafted_pyc:13:11:52$ ./crackme.py 
password: Call me a Python virtual machine! I can interpret Python bytecodes!!!
hitcon{Now you can compile and run Python bytecode in your brain!}

The flag is: hitcon{Now you can compile and run Python bytecode in your brain!}

Here is the script used:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import marshal, zlib, base64
import dis

a = marshal.loads(zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGORtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ==')))

b = a.co_consts[1]
code = b.co_code[:-6] + "|\x00\x00" + b.co_code[2212:]
c = b.__class__(b.co_argcount, b.co_nlocals, b.co_stacksize, b.co_flags, code, b.co_consts, b.co_names, b.co_varnames, b.co_filename, b.co_name, b.co_firstlineno, b.co_lnotab, b.co_freevars, b.co_cellvars)

exec(c)

Leave a Reply

Your email address will not be published. Required fields are marked *