Handcrafted pyc

195 Teams solved.

Description

Can your brain be a Python VM? (Please use Python 2.7)



crackme.py

Hint

None

提示されたPythonのコードは、base64でエンコードされた文字列をbase64でデコードし、それをzlibで解凍した結果をmarshalで読み込んでexecで実行しています。marshalで読み込んだコードはPythonのバイトコードになっているので、disで逆アセンブルします。
>>> import dis
>>> import marshal,zlib,base64
>>> code = 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==')))
>>> dis.dis(code)
逆アセンブルした結果は次のとおりです。
  1           0 LOAD_CONST               1 (<code object main at 00000000022FA1B0, file "<string>", line 1>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (main)

  4           9 LOAD_NAME                1 (__name__)
             12 LOAD_CONST               2 ('__main__')
             15 COMPARE_OP               2 (==)
             18 POP_JUMP_IF_FALSE       31

  5          21 LOAD_NAME                0 (main)
             24 CALL_FUNCTION            0
             27 POP_TOP
             28 JUMP_FORWARD             0 (to 31)
        >>   31 LOAD_CONST               0 (None)
             34 RETURN_VALUE
さらに、main関数をdisで逆アセンブルします。
>>> dis.dis(main)
逆アセンブルした結果は次のとおりです。chr関数で文字コードから文字列を生成しています。
  1           0 LOAD_GLOBAL              0 (chr)
              3 LOAD_CONST               1 (108)
              6 CALL_FUNCTION            1 l
              9 LOAD_GLOBAL              0 (chr)
             12 LOAD_CONST               1 (108)
             15 CALL_FUNCTION            1 l
             18 LOAD_GLOBAL              0 (chr)
             21 LOAD_CONST               2 (97)
             24 CALL_FUNCTION            1 a
             27 LOAD_GLOBAL              0 (chr)
             30 LOAD_CONST               3 (67)
             33 CALL_FUNCTION            1 C
(略) 
上記で、2列目の数字がバイト数です。0~725バイトまでこのような処理が続いており、そこで生成される文字列は、次のとおりとなります。
Call me a Python virtual machine! I can interpret Python bytecodes!!!
さらに、その先のバイトコードを見てみると、上記文字列をpassword変数に格納し、入力値と比較しています。比較した結果一致していない場合、1591バイトにジャンプしています。
(略)
            741 JUMP_ABSOLUTE          759
        >>  744 LOAD_GLOBAL              1 (raw_input)
            747 JUMP_ABSOLUTE         1480
        >>  750 LOAD_FAST                0 (password)
            753 COMPARE_OP               2 (==)
            756 JUMP_ABSOLUTE          767
        >>  759 ROT_TWO
            760 STORE_FAST               0 (password)
            763 POP_TOP
            764 JUMP_ABSOLUTE          744
        >>  767 POP_JUMP_IF_FALSE     1591 
入力値とpasswordが一致していた場合は、以下のコードが実行されます。文字コードから文字列を生成しています。ここで生成される文字列がフラグになります。
            770 LOAD_GLOBAL              0 (chr)
            773 LOAD_CONST              17 (99)
            776 CALL_FUNCTION            1 c
            779 LOAD_GLOBAL              0 (chr)
            782 LOAD_CONST              10 (116)
            785 CALL_FUNCTION            1 t
            788 LOAD_GLOBAL              0 (chr)
            791 LOAD_CONST              14 (105)
            794 CALL_FUNCTION            1 i
            797 LOAD_GLOBAL              0 (chr)
            800 LOAD_CONST               9 (104)
            803 CALL_FUNCTION            1 h
(略) 
それでは、codeを実行してパスワードを入力してみます。次のとおりフラグが表示されました。
>>> exec(code)
password: Call me a Python virtual machine! I can interpret Python bytecodes!!!
hitcon{Now you can compile and run Python bytecode in your brain!}
フラグは、
hitcon{Now you can compile and run Python bytecode in your brain!}