HGAME 2020 Week2 wp

武汉加油!

Reverse

1. Classic_CrackMe

file查看文件类型



.net的逆向可以用dnSpy
核心代码为

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.status == 1)
            {
                MessageBox.Show("你已经激活成功啦,快去提交flag吧~~~");
                return;
            }
            string text = this.textBox1.Text;
            if (text.Length != 46 || text.IndexOf("hgame{") != 0 || text.IndexOf("}") != 45)
            {
                MessageBox.Show("Illegal format");
                return;
            }
            string base64iv = text.Substring(6, 24);
            string str = text.Substring(30, 15);
            try
            {
                Aes aes = new Aes("SGc0bTNfMm8yMF9XZWVLMg==", base64iv);
                Aes aes2 = new Aes("SGc0bTNfMm8yMF9XZWVLMg==", "MFB1T2g5SWxYMDU0SWN0cw==");
                string text2 = aes.DecryptFromBase64String("mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I=");
                if (text2.Equals("Same_ciphertext_"))
                {
                    byte[] array = new byte[16];
                    Array.Copy(aes2.EncryptToByte(text2 + str), 16, array, 0, 16);
                    if (Convert.ToBase64String(array).Equals("dJntSWSPWbWocAq4yjBP5Q=="))
                    {
                        MessageBox.Show("注册成功!");
                        this.Text = "已激活,欢迎使用!";
                        this.status = 1;
                    }
                    else
                    {
                        MessageBox.Show("注册失败!\nhint: " + aes2.DecryptFromBase64String("mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I="));
                    }
                }
                else
                {
                    MessageBox.Show("注册失败!\nhint: " + aes2.DecryptFromBase64String("mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I="));
                }
            }
            catch
            {
                MessageBox.Show("注册失败!");
            }
        }

flag由字符串base64iv和str拼接而成。
AES加密类型可看出为CBC加密,填补方式为PKCS7.



例子中的第一次AES加密明文长度为块大小,填充一个与块大小相同,内容为块大小的数据,因而第二次加密数据的明文和密文均不需要进行分析。根据AES-CBC加密的流程,先将明文P与初始化向量IV进行异或,再进行AES加密置换,解密流程为先将密文C进行AES解密置换,再与初始化向量IV进行异或。密文已知,只取前16字节(块大小)。

from Crypto.Cipher import AES
import base64

def xor(s1, s2):
    return bytes(map( (lambda x: x[0]^x[1]), zip(s1, s2) ))

key = base64.b64decode(b"SGc0bTNfMm8yMF9XZWVLMg==")
cipher = base64.b64decode(b"mjdRqH4d1O8nbUYJk+wVu3AeE7ZtE9rtT/8BA8J897I=")
aes = AES.new(key, AES.MODE_ECB)
msg = aes.decrypt(cipher)[:16]
target = b"Same_ciphertext_"
iv = xor(msg, target)

即可获得IV。
第二次加密总共两块,已知第二块的密文,第一块的明文,求第二块的明文。要注意解密后的为填补后的(15填补为16),应去除最后一字节。

aes2 = AES.new(key, AES.MODE_CBC, base64.b64decode(b"MFB1T2g5SWxYMDU0SWN0cw=="))
cipher1 = aes2.encrypt(target)
msg = aes.decrypt(base64.b64decode(b"dJntSWSPWbWocAq4yjBP5Q=="))

综合一下,即可得到对应的flag

print(b"hgame{" + base64.b64encode(iv) + xor(msg, cipher1)[:-1] + b"}")

2. babyPy

https://docs.python.org/zh-cn/3/library/dis.html
根据官方文档,可还原Python字节码。

def encrypt(OOo):
    O0O = OOo[::-1]
    O0o = list(O0O)
    for O0 in range(1, len(O0o)):
        Oo = O0o[O0 - 1] ^ O0o[O0]
        O0o[O0] = Oo
    O = bytes(O0o)
    return O.hex()

因此,脚本如下

from binascii import unhexlify
def encrypt(OOo):
    O0O = OOo[::-1]
    O0o = list(O0O)
    for O0 in range(1, len(O0o)):
        Oo = O0o[O0 - 1] ^ O0o[O0]
        O0o[O0] = Oo
    O = bytes(O0o)
    return O.hex()
def decrypt(bhstr):
    bhstr = unhexlify(bhstr)
    bhstr = list(bhstr)
    for i in range(len(bhstr)-1, 0, -1):
        bhstr[i] = bhstr[i-1] ^ bhstr[i]
    return bytes(bhstr[::-1])
print(decrypt('7d037d045717722d62114e6a5b044f2c184c3f44214c2d4a22'))

3. babyPyc

使用uncompyle6反编译代码失败。

# uncompyle6 version 3.6.2
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: task.py
# Size of source mod 2**32: 1056 bytes


# file babyPyc_task_a1f4a8cf21.cpython-37.pyc
# --- This code section failed: ---

   3       0  JUMP_ABSOLUTE         2  'to 2'
           2  LOAD_CONST               0
           4  LOAD_CONST               None
           6  IMPORT_NAME              os
           8  STORE_NAME               os
          10  LOAD_CONST               0
          12  LOAD_CONST               None
          14  IMPORT_NAME              sys

   4      16  STORE_NAME               sys
          18  LOAD_CONST               0
          20  LOAD_CONST               ('b64encode',)
          22  IMPORT_NAME              base64
          24  IMPORT_FROM              b64encode
          26  STORE_NAME               b64encode

   6      28  POP_TOP
          30  LOAD_CONST               b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J'

   8      32  STORE_GLOBAL             O0o
          34  LOAD_CODE                
          36  LOAD_STR                 'getFlag'
          38  MAKE_FUNCTION_0          ''

  16      40  STORE_NAME               getFlag
          42  LOAD_NAME                getFlag
          44  CALL_FUNCTION_0       0  ''

  18      46  STORE_NAME               flag
          48  LOAD_NAME                flag
          50  LOAD_CONST               None
          52  LOAD_CONST               6
          54  BUILD_SLICE_2         2
          56  BINARY_SUBSCR
          58  LOAD_CONST               b'hgame{'
          60  COMPARE_OP               !=
          62  POP_JUMP_IF_TRUE     76  'to 76'
          64  LOAD_NAME                flag
          66  LOAD_CONST               -1
          68  BINARY_SUBSCR
          70  LOAD_CONST               125
          72  COMPARE_OP               !=

  19      74  POP_JUMP_IF_FALSE    94  'to 94'
        76_0  COME_FROM            62  '62'
          76  LOAD_NAME                print
          78  LOAD_STR                 'Incorrect format!'
          80  CALL_FUNCTION_1       1  ''

  20      82  POP_TOP
          84  LOAD_NAME                sys
          86  LOAD_METHOD              exit
          88  LOAD_CONST               1
          90  CALL_METHOD_1         1  ''

  22      92  POP_TOP
        94_0  COME_FROM            74  '74'
          94  LOAD_NAME                flag
          96  LOAD_CONST               6
          98  LOAD_CONST               -1
         100  BUILD_SLICE_2         2
         102  BINARY_SUBSCR

  23     104  STORE_NAME               raw_flag
         106  LOAD_NAME                len
         108  LOAD_NAME                flag
         110  CALL_FUNCTION_1       1  ''
         112  LOAD_CONST               7
         114  BINARY_SUBTRACT
         116  LOAD_CONST               36
         118  COMPARE_OP               !=

  24     120  POP_JUMP_IF_FALSE   140  'to 140'
         122  LOAD_NAME                print
         124  LOAD_STR                 'Wrong length!'
         126  CALL_FUNCTION_1       1  ''

  25     128  POP_TOP
         130  LOAD_NAME                sys
         132  LOAD_METHOD              exit
         134  LOAD_CONST               2
         136  CALL_METHOD_1         1  ''

  27     138  POP_TOP
       140_0  COME_FROM           120  '120'
         140  LOAD_NAME                raw_flag
         142  LOAD_CONST               None
         144  LOAD_CONST               None
         146  LOAD_CONST               -1
         148  BUILD_SLICE_3         3
         150  BINARY_SUBSCR

  28     152  STORE_NAME               raw_flag
         154  LOAD_LISTCOMP            '>'
         156  LOAD_STR                 ''
         158  MAKE_FUNCTION_0          ''
         160  LOAD_NAME                range
         162  LOAD_CONST               6
         164  CALL_FUNCTION_1       1  ''
         166  GET_ITER
         168  CALL_FUNCTION_1       1  ''

  30     170  STORE_NAME               ciphers
         172  SETUP_LOOP          260  'to 260'
         174  LOAD_NAME                range
         176  LOAD_CONST               5
         178  CALL_FUNCTION_1       1  ''
         180  GET_ITER
         182  FOR_ITER            258  'to 258'

  31     184  STORE_NAME               row
         186  SETUP_LOOP          256  'to 256'
         188  LOAD_NAME                range
         190  LOAD_CONST               6
         192  CALL_FUNCTION_1       1  ''
         194  GET_ITER
         196  FOR_ITER            254  'to 254'

  32     198  STORE_NAME               col
         200  LOAD_NAME                ciphers
         202  LOAD_NAME                row
         204  BINARY_SUBSCR
         206  LOAD_NAME                col
         208  DUP_TOP_TWO
         210  BINARY_SUBSCR
         212  LOAD_NAME                ciphers
         214  LOAD_NAME                row
         216  LOAD_CONST               1
         218  BINARY_ADD
         220  BINARY_SUBSCR
         222  LOAD_NAME                col
         224  BINARY_SUBSCR
         226  INPLACE_ADD
         228  ROT_THREE

  33     230  STORE_SUBSCR
         232  LOAD_NAME                ciphers
         234  LOAD_NAME                row
         236  BINARY_SUBSCR
         238  LOAD_NAME                col
         240  DUP_TOP_TWO
         242  BINARY_SUBSCR
         244  LOAD_CONST               256
         246  INPLACE_MODULO
         248  ROT_THREE
         250  STORE_SUBSCR
         252  JUMP_BACK           196  'to 196'
         254  POP_BLOCK
       256_0  COME_FROM_LOOP      186  '186'
         256  JUMP_BACK           182  'to 182'

  35     258  POP_BLOCK
       260_0  COME_FROM_LOOP      172  '172'
         260  LOAD_CONST               b''

  36     262  STORE_NAME               cipher
         264  SETUP_LOOP          336  'to 336'
         266  LOAD_NAME                range
         268  LOAD_CONST               6
         270  CALL_FUNCTION_1       1  ''
         272  GET_ITER
         274  FOR_ITER            334  'to 334'

  37     276  STORE_NAME               row
         278  LOAD_CONST               0

  38     280  STORE_NAME               col
         282  SETUP_LOOP          330  'to 330'
         284  LOAD_NAME                col
         286  LOAD_CONST               6
         288  COMPARE_OP               <
         290  POP_JUMP_IF_FALSE   328  'to 328'
         294  LOAD_NAME                cipher
         296  LOAD_NAME                bytes
         298  LOAD_NAME                ciphers
         300  LOAD_NAME                row
         302  BINARY_SUBSCR
         304  LOAD_NAME                col
         306  BINARY_SUBSCR
         308  BUILD_LIST_1          1
         310  CALL_FUNCTION_1       1  ''
         312  INPLACE_ADD

  40     314  STORE_NAME               cipher
         316  LOAD_NAME                col
         318  LOAD_CONST               1
         320  INPLACE_ADD
         322  STORE_NAME               col
         324  JUMP_BACK           284  'to 284'
       328_0  COME_FROM           290  '290'
         328  POP_BLOCK
       330_0  COME_FROM_LOOP      282  '282'
         330  JUMP_BACK           274  'to 274'

  42     334  POP_BLOCK
       336_0  COME_FROM_LOOP      264  '264'
         336  LOAD_NAME                b64encode
         338  LOAD_NAME                cipher
         340  CALL_FUNCTION_1       1  ''

  44     342  STORE_NAME               cipher
         344  LOAD_NAME                cipher
         346  LOAD_GLOBAL              O0o
         348  COMPARE_OP               ==
         350  POP_JUMP_IF_FALSE   364  'to 364'
         354  LOAD_NAME                print
         356  LOAD_STR                 'Great, this is my flag.'
         358  CALL_FUNCTION_1       1  ''
         360  POP_TOP

  47     362  JUMP_FORWARD        372  'to 372'
       364_0  COME_FROM           350  '350'
         364  LOAD_NAME                print
         366  LOAD_STR                 'Wrong flag.'
         368  CALL_FUNCTION_1       1  ''
         370  POP_TOP
       372_0  COME_FROM           362  '362'

Parse error at or near `None' instruction at offset -1

根据以上,可还原出部分代码。

import os
import sys
from base64 import b64encode
O0o = b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J'
flag = getFlag()
if b'hgame{' != flag[:6] or flag[-1] != b'}':
    print('Incorrect format!')
    sys.exit(1)
raw_flag = flag[6:-1]
if len(flag) - 7 != 36:
    print('Wrong length!')
    sys.exit(2)
raw_flag = raw_flag[::-1]
# ciphers = 一个列表推导式
for row in range(5):
    for col in range(6):
        ciphers[row][col] += ciphers[row + 1][col]
        ciphers[row][col] %= 256
cipher = b''
for row in range(6):
    col = 0
    while col < 6:
        cipher += bytes([ciphers[row][col]])
        col += 1
# assert O0o == b64encode(cipher)

中间的列表推导式部分无法使用uncompyle6查看,但可使用dis和marshal来反编译代码。
结合资料可知,3.7的pyc文件,头部大小为16字节,因此略过16字节,获得的字节码对象如下。

>>> import dis, marshal
>>> f = open("babyPyc_task_a1f4a8cf21.cpython-37.pyc", "rb")
>>> f.read(16)
b'B\r\r\n\x00\x00\x00\x00\xdaR%^ \x04\x00\x00'
>>> code = marshal.load(f)
>>> code
 at 0x000001E7C7F45C90, file "task.py", line 3>
>>> dis.dis(code)
  3           0 JUMP_ABSOLUTE            2
        >>    2 LOAD_CONST               0 (0)
              4 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (os)
              8 STORE_NAME               0 (os)
             10 LOAD_CONST               0 (0)
             12 LOAD_CONST               1 (None)
             14 IMPORT_NAME              1 (sys)

  4          16 STORE_NAME               1 (sys)
             18 LOAD_CONST               0 (0)
             20 LOAD_CONST               2 (('b64encode',))
             22 IMPORT_NAME              2 (base64)
             24 IMPORT_FROM              3 (b64encode)
             26 STORE_NAME               3 (b64encode)

  6          28 POP_TOP
             30 LOAD_CONST               3 (b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J')

  8          32 STORE_GLOBAL             4 (O0o)
             34 LOAD_CONST               4 ()
             36 LOAD_CONST               5 ('getFlag')
             38 MAKE_FUNCTION            0

 16          40 STORE_NAME               5 (getFlag)
             42 LOAD_NAME                5 (getFlag)
             44 CALL_FUNCTION            0

 18          46 STORE_NAME               6 (flag)
             48 LOAD_NAME                6 (flag)
             50 LOAD_CONST               1 (None)
             52 LOAD_CONST               6 (6)
             54 BUILD_SLICE              2
             56 BINARY_SUBSCR
             58 LOAD_CONST               7 (b'hgame{')
             60 COMPARE_OP               3 (!=)
             62 POP_JUMP_IF_TRUE        76
             64 LOAD_NAME                6 (flag)
             66 LOAD_CONST               8 (-1)
             68 BINARY_SUBSCR
             70 LOAD_CONST               9 (125)
             72 COMPARE_OP               3 (!=)

 19          74 POP_JUMP_IF_FALSE       94
        >>   76 LOAD_NAME                7 (print)
             78 LOAD_CONST              10 ('Incorrect format!')
             80 CALL_FUNCTION            1

 20          82 POP_TOP
             84 LOAD_NAME                1 (sys)
             86 LOAD_METHOD              8 (exit)
             88 LOAD_CONST              11 (1)
             90 CALL_METHOD              1

 22          92 POP_TOP
        >>   94 LOAD_NAME                6 (flag)
             96 LOAD_CONST               6 (6)
             98 LOAD_CONST               8 (-1)
            100 BUILD_SLICE              2
            102 BINARY_SUBSCR

 23         104 STORE_NAME               9 (raw_flag)
            106 LOAD_NAME               10 (len)
            108 LOAD_NAME                6 (flag)
            110 CALL_FUNCTION            1
            112 LOAD_CONST              12 (7)
            114 BINARY_SUBTRACT
            116 LOAD_CONST              13 (36)
            118 COMPARE_OP               3 (!=)

 24         120 POP_JUMP_IF_FALSE      140
            122 LOAD_NAME                7 (print)
            124 LOAD_CONST              14 ('Wrong length!')
            126 CALL_FUNCTION            1

 25         128 POP_TOP
            130 LOAD_NAME                1 (sys)
            132 LOAD_METHOD              8 (exit)
            134 LOAD_CONST              15 (2)
            136 CALL_METHOD              1

 27         138 POP_TOP
        >>  140 LOAD_NAME                9 (raw_flag)
            142 LOAD_CONST               1 (None)
            144 LOAD_CONST               1 (None)
            146 LOAD_CONST               8 (-1)
            148 BUILD_SLICE              3
            150 BINARY_SUBSCR

 28         152 STORE_NAME               9 (raw_flag)
            154 LOAD_CONST              16 ( at 0x000001E7C7F280C0, file "task.py", line 28>)
            156 LOAD_CONST              17 ('')
            158 MAKE_FUNCTION            0
            160 LOAD_NAME               11 (range)
            162 LOAD_CONST               6 (6)
            164 CALL_FUNCTION            1
            166 GET_ITER
            168 CALL_FUNCTION            1

 30         170 STORE_NAME              12 (ciphers)
            172 SETUP_LOOP              86 (to 260)
            174 LOAD_NAME               11 (range)
            176 LOAD_CONST              18 (5)
            178 CALL_FUNCTION            1
            180 GET_ITER
        >>  182 FOR_ITER                74 (to 258)

 31         184 STORE_NAME              13 (row)
            186 SETUP_LOOP              68 (to 256)
            188 LOAD_NAME               11 (range)
            190 LOAD_CONST               6 (6)
            192 CALL_FUNCTION            1
            194 GET_ITER
        >>  196 FOR_ITER                56 (to 254)

 32         198 STORE_NAME              14 (col)
            200 LOAD_NAME               12 (ciphers)
            202 LOAD_NAME               13 (row)
            204 BINARY_SUBSCR
            206 LOAD_NAME               14 (col)
            208 DUP_TOP_TWO
            210 BINARY_SUBSCR
            212 LOAD_NAME               12 (ciphers)
            214 LOAD_NAME               13 (row)
            216 LOAD_CONST              11 (1)
            218 BINARY_ADD
            220 BINARY_SUBSCR
            222 LOAD_NAME               14 (col)
            224 BINARY_SUBSCR
            226 INPLACE_ADD
            228 ROT_THREE

 33         230 STORE_SUBSCR
            232 LOAD_NAME               12 (ciphers)
            234 LOAD_NAME               13 (row)
            236 BINARY_SUBSCR
            238 LOAD_NAME               14 (col)
            240 DUP_TOP_TWO
            242 BINARY_SUBSCR
            244 LOAD_CONST              19 (256)
            246 INPLACE_MODULO
            248 ROT_THREE
            250 STORE_SUBSCR
            252 JUMP_ABSOLUTE          196
        >>  254 POP_BLOCK
        >>  256 JUMP_ABSOLUTE          182

 35     >>  258 POP_BLOCK
        >>  260 LOAD_CONST              20 (b'')

 36         262 STORE_NAME              15 (cipher)
            264 SETUP_LOOP              70 (to 336)
            266 LOAD_NAME               11 (range)
            268 LOAD_CONST               6 (6)
            270 CALL_FUNCTION            1
            272 GET_ITER
        >>  274 FOR_ITER                58 (to 334)

 37         276 STORE_NAME              13 (row)
            278 LOAD_CONST               0 (0)

 38         280 STORE_NAME              14 (col)
            282 SETUP_LOOP              46 (to 330)
        >>  284 LOAD_NAME               14 (col)
            286 LOAD_CONST               6 (6)
            288 COMPARE_OP               0 (<)
            290 EXTENDED_ARG             1

 39         292 POP_JUMP_IF_FALSE      328
            294 LOAD_NAME               15 (cipher)
            296 LOAD_NAME               16 (bytes)
            298 LOAD_NAME               12 (ciphers)
            300 LOAD_NAME               13 (row)
            302 BINARY_SUBSCR
            304 LOAD_NAME               14 (col)
            306 BINARY_SUBSCR
            308 BUILD_LIST               1
            310 CALL_FUNCTION            1
            312 INPLACE_ADD

 40         314 STORE_NAME              15 (cipher)
            316 LOAD_NAME               14 (col)
            318 LOAD_CONST              11 (1)
            320 INPLACE_ADD
            322 STORE_NAME              14 (col)
            324 EXTENDED_ARG             1
            326 JUMP_ABSOLUTE          284
        >>  328 POP_BLOCK
        >>  330 EXTENDED_ARG             1
            332 JUMP_ABSOLUTE          274

 42     >>  334 POP_BLOCK
        >>  336 LOAD_NAME                3 (b64encode)
            338 LOAD_NAME               15 (cipher)
            340 CALL_FUNCTION            1

 44         342 STORE_NAME              15 (cipher)
            344 LOAD_NAME               15 (cipher)
            346 LOAD_GLOBAL              4 (O0o)
            348 COMPARE_OP               2 (==)
            350 EXTENDED_ARG             1

 45         352 POP_JUMP_IF_FALSE      364
            354 LOAD_NAME                7 (print)
            356 LOAD_CONST              21 ('Great, this is my flag.')
            358 CALL_FUNCTION            1
            360 POP_TOP

 47         362 JUMP_FORWARD             8 (to 372)
        >>  364 LOAD_NAME                7 (print)
            366 LOAD_CONST              22 ('Wrong flag.')
            368 CALL_FUNCTION            1
            370 POP_TOP
        >>  372 LOAD_CONST               1 (None)
            374 RETURN_VALUE

Disassembly of :
 10           0 LOAD_GLOBAL              0 (print)
              2 LOAD_CONST               1 ('Give me the flag')
              4 CALL_FUNCTION            1
              6 POP_TOP

 11           8 LOAD_GLOBAL              1 (input)
             10 LOAD_CONST               2 ('> ')
             12 CALL_FUNCTION            1
             14 STORE_FAST               0 (flag)

 12          16 LOAD_FAST                0 (flag)
             18 LOAD_METHOD              2 (encode)
             20 CALL_METHOD              0
             22 STORE_FAST               0 (flag)

 13          24 LOAD_CONST               3 (b'Qn/ZgNOeWqXCoNKYceeX3NO8n7h0lL+tzrdbkM2pZ3IwZX5Q')
             26 STORE_GLOBAL             3 (O0o)

 14          28 LOAD_FAST                0 (flag)
             30 RETURN_VALUE

Disassembly of  at 0x000001E7C7F280C0, file "task.py", line 28>:
 28           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                26 (to 32)
              6 STORE_DEREF              0 (col)
              8 LOAD_CLOSURE             0 (col)
             10 BUILD_TUPLE              1
             12 LOAD_CONST               0 ( at 0x000001E7C7F28B70, file "task.py", line 28>)
             14 LOAD_CONST               1 ('.')
             16 MAKE_FUNCTION            8
             18 LOAD_GLOBAL              0 (range)
             20 LOAD_CONST               2 (6)
             22 CALL_FUNCTION            1
             24 GET_ITER
             26 CALL_FUNCTION            1
             28 LIST_APPEND              2
             30 JUMP_ABSOLUTE            4
        >>   32 RETURN_VALUE

Disassembly of  at 0x000001E7C7F28B70, file "task.py", line 28>:
 28           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                20 (to 26)
              6 STORE_FAST               1 (row)
              8 LOAD_GLOBAL              0 (raw_flag)
             10 LOAD_CONST               0 (6)
             12 LOAD_FAST                1 (row)
             14 BINARY_MULTIPLY
             16 LOAD_DEREF               0 (col)
             18 BINARY_ADD
             20 BINARY_SUBSCR
             22 LIST_APPEND              2
             24 JUMP_ABSOLUTE            4
        >>   26 RETURN_VALUE

根据以上字节码,可还原源码为

import os
import sys
from base64 import b64encode
O0o = b'/KDq6pvN/LLq6tzM/KXq59Oh/MTqxtOTxdrqs8OoR3V1X09J'
flag = input()
O0o = b'Qn/ZgNOeWqXCoNKYceeX3NO8n7h0lL+tzrdbkM2pZ3IwZX5Q'
if b'hgame{' != flag[:6] or flag[-1] != b'}':
    print('Incorrect format!')
    sys.exit(1)
raw_flag = flag[6:-1]
if len(flag) - 7 != 36:
    print('Wrong length!')
    sys.exit(2)
raw_flag = raw_flag[::-1]
ciphers = [ [ raw_flag[6*j+i] for j in range(6) ] for i in range(6) ]
for row in range(5):
    for col in range(6):
        ciphers[row][col] += ciphers[row + 1][col]
        ciphers[row][col] %= 256
cipher = b''
for row in range(6):
    col = 0
    while col < 6:
        cipher += bytes([ciphers[row][col]])
        col += 1
assert O0o == b64encode(cipher)

因此,脚本如下:

from base64 import b64decode
cipher = b'Qn/ZgNOeWqXCoNKYceeX3NO8n7h0lL+tzrdbkM2pZ3IwZX5Q'
cipher = b64decode(cipher)
ciphers = [ [ cipher[j + 6*i] for j in range(6)] for i in range(6) ]
for row in range(5):
    for col in range(6):
        ciphers[4 - row][col] -= ciphers[5 - row][col]
        ciphers[4 - row][col] %= 256
cipher = b""
for row in range(6):
    col = 0
    while col < 6:
        cipher += bytes([ciphers[col][row]])
        col += 1
cipher = cipher[::-1]
print(b"hgame{" + cipher + b"}")

Crypto

1. Verification_code

爆破就好啦

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import string
import time
from hashlib import sha256
from socket import socket

L = string.ascii_letters+string.digits
sock = socket()
sock.connect(("47.98.192.231", 25678))
s = sock.recv(1024).split(b"\n")[0]
_hexdigest = s[-64:].decode()
sub = s[12:28]
print(sock.recv(1024))
for a in L:
    for b in L:
        for c in L:
            for d in L:
                pre = (a+b+c+d).encode()
                hexstr = sha256(pre + sub).hexdigest()
                if hexstr == _hexdigest:
                    print(pre)
                    sock.send(pre)
                    print(sock.recv(1024))
                    sock.recv(1024)
                    sock.send(b"I like playing Hgame")
                    print(sock.recv(1024))
                    print(sock.recv(1024))
                    exit()
  1. Remainder
    中国剩余定理就Vans啦
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from Crypto.Util.number import inverse

p = 94598296305713376652540411631949434301396235111673372738276754654188267010805522542068004453137678598891335408170277601381944584279339362056579262308427544671688614923839794522671378559276784734758727213070403838632286280473450086762286706863922968723202830398266220533885129175502142533600559292388005914561
q = 150088216417404963893679242888992998793257903343994792697939121738029477790454833496600101388493792476973514786401036309378542808470513073408894727406158296404360452232777491992630316999043165374635001806841520490997788796152678742544032835808854339130676283497122770901196468323977265095016407164510827505883
r = 145897736096689096151704740327665176308625097484116713780050311198775607465862066406830851710261868913835866335107146242979359964945125214420821146670919741118254402096944139483988745450480989706524191669371208210272907563936516990473246615375022630708213486725809819360033470468293100926616729742277729705727
e = 65537

cp = 78430786011650521224561924814843614294806974988599591058915520397518526296422791089692107488534157589856611229978068659970976374971658909987299759719533519358232180721480719635602515525942678988896727128884803638257227848176298172896155463813264206982505797613067215182849559356336015634543181806296355552543 
cq = 49576356423474222188205187306884167620746479677590121213791093908977295803476203510001060180959190917276817541142411523867555147201992480220531431019627681572335103200586388519695931348304970651875582413052411224818844160945410884130575771617919149619341762325633301313732947264125576866033934018462843559419 
cr = 48131077962649497833189292637861442767562147447040134411078884485513840553188185954383330236190253388937785530658279768620213062244053151614962893628946343595642513870766877810534480536737200302699539396810545420021054225204683428522820350356470883574463849146422150244304147618195613796399010492125383322922
m = p*q*r
Mp = q*r
Mq = p*r
Mr = p*q
dp = inverse(Mp, p)
dq = inverse(Mq, q)
dr = inverse(Mr, r)
msg = (dp*Mp*cp+dq*Mq*cq+dr*Mr*cr) % m
phim = (p-1)*(q-1)*(r-1)
de = inverse(e, phim)
msg = pow(msg, de, m)
msg = hex(msg)[2:-1]
if len(msg) % 2 == 1:
    msg = "0" + msg
msg = msg.decode("hex")
print(msg)
s = ""
for st in msg.split("\n")[3:-3]:
    s += st[:2]
print(s)

3. Inv

求置换群的逆元,之后仿照欧几里得除法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def Subs(S, X):
    return bytes([ S[x] for x in X ])

def Mul(A, B):
    assert len(A)==len(B)
    return Subs(A, B)

def Pow(X, E):
    Y = X
    E = bin(E)[3:]
    for e in E:
        Y = Mul(Y, Y)
        if e=='1':
            Y = Mul(X, Y)
    return Y

def Inv(G : bytes):
    ans = [0] * 256
    for i in range(256):
        ans[G[i]] = i.to_bytes(1, "little")
    return b"".join(ans)

A = b'\xc8&\xc1E\xbe*\xc5\x84\xdb1\x05\x9b\xc0\xf2\xac/\x0b0\x8d\'\xc2b\x89\x93\xa6\xcd\xe1\x1b\xf4H\xffa\x90A\xf7,(\xea?\xa8\xa0\x8b\xf1\xf9"X\n\x86fj\x074\x7fBO\xd4F\xbd\xe6\xd9\xa7\xaf\x8a\x8c\xde\xab;!PT\x15)+w\xbc\x00>\xc6g\xc3\x85=9K\xb6<\xb7x\xaeUG\x83vk\xa9\xf6{\x03Y\x87\x14e\xfd\xed@i\xcc.\xd1\xebo\x106\xe2\xe7\xd7\xeeu\x9e\xfe\x95^R\xfb8\x04\xb4S\x16\xe0\xad\xd8\x98n\xca\xe4\xdd\xd2\xc7\x99l\xb3\\2L\xa3\x1d:_\x12\xb87\x17\x01\xb1#~q\x1c\t\xe8\xdar\xef\xcb\x0c\xe5\x80\xdf\xc9y\x0e`\xe9\x94\xd0\xcfW\x1f5\xf5h\xbf\xba\x91\xb9d\xfcM\x81\xec\x88\xb2c\x9f\xa4J|\xd3m\xd6s\xd5\x92\x9d\x9a3\xa2\xb5\xfa\x19N\xa1\x82][\xf8\x06\x13\xdcC\x1e\x1a\xaa\xc4tz\x08\x8f%$D\xbb\x97 \xce\x96V\xe3\x02I\x18\x11\x0f\r\xf3p\x8e\xa5Z-\xf0}\xb0Q\x9c'
B = b'U\x17\x8aE\xa6\x19\xab\x7fd0\xd2)\xc0\xae\xcc/G_\xe3\'\r\xfb\xaf\x00\xb1hgi-\xc1\xffa\x8d\t&\x99k\x95\x93\xa8.\x07\xcd\x87\x01\xe8\x89\x86\xf6f48F\xdc\x96\xd4`P\xd6!\xfe\xc4B:\xd31C\x9f\x1dT{2c9\x0bY5#\xf7\xb8H\xe0Db\xb6wv\xe1\xbbI\x8f\x83l\x80\xa9\x04q\x03\xf0m\xf4\x1bp\x8e\xc6u\xfd\x16$\x06\xf9Z\xec\xa2\xcb\xd7V\xb9\xd1\xbdt^\xe7\xe2\xac\x18\xb4\x15=n\xad\xd8S+\xca\xeb\xdd\xd0;\x84\xe6\x08\x8c3\xb3\x90\x02\xc8}\xee\xea7K\x98\xde\x8b~\xcf\xfa\x11\n\xda\xa4L\xa3\x0cWQ\xdf\xc9yj\x9d\xe9\xfcJO\x1a\x1f\xdb\xf5M\xbf\x9e e\x1c*\x9b\x85\xe5\x88\xb2\xc7\xf2\x91\x10\x0e,\xd9R\x9a\x94\x0fX\xf3\xbe?\xa5\xe4\xa0z\xf16\x81\x9c'
E = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
a = 595
b = 739
enc = b"\\-\xa5{\xb9\x85J @\xfa\x91\x0b\x88\r4I\x7f\xb9\xe5\r\xc0\x84\x8f\xa6\xc0i\xb0\xa4\x1b\x8fIw\x84'\xa2\xa4\x00\x91\x87\x10\r\\\x8c\x12"
a, b = b, a
A, B = B, A
q = a // b
r = a - b*q
R = B
while True:
    B_ = Inv(B)
    R = Mul(A, Pow(B_, q))
    a, b = b, r
    A, B = B, R
    if b <= 1:
        break
    q = a // b
    r = a - b*q
S = B
print(S)
flag = b""
for c in enc:
    index = S.find(c)
    flag += index.to_bytes(1, "little")
print(flag)

MISC

2.所见即为假

ZIP伪加密,之后F5-JPG隐写,最后出来base16,之后RAR,之后出FLAG。

你可能感兴趣的:(HGAME 2020 Week2 wp)