3nohtyp.pyc

这题作为VM还是很简单的,主要时间都在去混淆上了。

拿到pyc,在线反汇编一下:

佤 = 0
侰 = ~佤 * ~佤
俴 = 侰 + 侰

def 䯂(䵦):
    굴 = 佤
    굿 = 佤
    괠 = [佤] * 俴 ** (俴 * 俴)
    궓 = [佤] * 100
    괣 = []
    while 䵦[굴][佤] != "듃":
        굸 = 䵦[굴][佤].lower()
        亀 = 䵦[굴][侰:]
        if 굸 == "뉃":
            괠[亀[佤]] = 괠[亀[侰]] + 괠[亀[俴]]
        elif 굸 == "렀":
            괠[亀[佤]] = 괠[亀[侰]] ^ 괠[亀[俴]]
        elif 굸 == "렳":
            괠[亀[佤]] = 괠[亀[侰]] - 괠[亀[俴]]
        elif 굸 == "냃":
            괠[亀[佤]] = 괠[亀[侰]] * 괠[亀[俴]]
        elif 굸 == "뢯":
            괠[亀[佤]] = 괠[亀[侰]] / 괠[亀[俴]]
        elif 굸 == "륇":
            괠[亀[佤]] = 괠[亀[侰]] & 괠[亀[俴]]
        elif 굸 == "맳":
            괠[亀[佤]] = 괠[亀[侰]] | 괠[亀[俴]]
        elif 굸 == "괡":
            괠[亀[佤]] = 괠[亀[佤]]
        elif 굸 == "뫇":
            괠[亀[佤]] = 괠[亀[侰]]
        elif 굸 == "꼖":
            괠[亀[佤]] = 亀[侰]
        elif 굸 == "뫻":
            궓[亀[佤]] = 괠[亀[侰]]
        elif 굸 == "딓":
            괠[亀[佤]] = 궓[亀[侰]]
        elif 굸 == "댒":
            괠[亀[佤]] = 佤
        elif 굸 == "묇":
            궓[亀[佤]] = 佤
        elif 굸 == "묟":
            괠[亀[佤]] = input(괠[亀[侰]])
        elif 굸 == "꽺":
            궓[亀[佤]] = input(괠[亀[侰]])
        elif 굸 == "돯":
            print(괠[亀[佤]])
        elif 굸 == "뭗":
            print(궓[亀[佤]])
        elif 굸 == "뭿":
            굴 = 괠[亀[佤]]
        elif 굸 == "뮓":
            굴 = 궓[亀[佤]]
        elif 굸 == "뮳":
            굴 = 괣.pop()
        elif 굸 == "믃" or 괠[亀[侰]] > 괠[亀[俴]]:
            굴 = 亀[佤]
            괣.append(굴)
            continue
        elif 굸 == "꽲":
            괠[7] = 佤
            for i in range(len(괠[亀[佤]])):
                if 괠[亀[佤]] != 괠[亀[侰]]:
                    괠[7] = 侰
                    굴 = 괠[亀[俴]]
                    괣.append(굴)
        elif 굸 == "꾮":
            괢 = ""
            for i in range(len(괠[亀[佤]])):
                괢 += chr(ord(괠[亀[佤]][i]) ^ 괠[亀[侰]])
            괠[亀[佤]] = 괢
        elif 굸 == "꿚":
            괢 = ""
            for i in range(len(괠[亀[佤]])):
                괢 += chr(ord(괠[亀[佤]][i]) - 괠[亀[侰]])
            괠[亀[佤]] = 괢
        elif 굸 == "떇" or 괠[亀[侰]] > 괠[亀[俴]]:
            굴 = 괠[亀[佤]]
            괣.append(굴)
            continue
        elif 굸 == "뗋" or 괠[亀[侰]] > 괠[亀[俴]]:
            굴 = 궓[亀[佤]]
            괣.append(굴)
            continue
        elif 굸 == "똷" or 괠[亀[侰]] == 괠[亀[俴]]:
            굴 = 亀[佤]
            괣.append(굴)
            continue
        elif 굸 == "뚫" or 괠[亀[侰]] == 괠[亀[俴]]:
            굴 = 괠[亀[佤]]
            괣.append(굴)
            continue
        elif 굸 == "띇" and 괠[亀[侰]] == 괠[亀[俴]]:
            굴 = 궓[亀[佤]]
            괣.append(굴)
            continue
        굴 += 侰

䯂(
    [
        ["꼖", 佤, "Authentication token: "],
        ["꽺", 佤, 佤],
        [
            "꼖",
            6,
            "á×äÓâæíäàßåÉÛãåäÉÖÓÉäàÓÉÖÓåäÉÓÚÕæïèäßÙÚÉÛÓäàÙÔÉÓâæÉàÓÚÕÓÒÙæäàÉäàßåÉßåÉäàÓÉÚÓáÉ·Ôâ×ÚÕÓÔɳÚÕæïèäßÙÚÉÅä×ÚÔ׿ÔÉ×Úïá×ïåÉßÉÔÙÚäÉæÓ×ÜÜïÉà×âÓÉ×ÉÑÙÙÔÉâßÔÉÖãäÉßÉæÓ×ÜÜïÉÓÚÞÙïÉäàßåÉåÙÚÑÉßÉàÙèÓÉïÙãÉáßÜÜÉÓÚÞÙïÉßäÉ×åáÓÜܗÉïÙãäãÖӚÕÙۙá×äÕà©â«³£ï²ÕÔÈ·±â¨ë",
        ],
        ["꼖", 俴, 俴 ** (3 * 俴 + 侰) - 俴 ** (俴 + 侰)],
        ["꼖", 4, 15],
        ["꼖", 3, 侰],
        ["냃", 俴, 俴, 3],
        ["뉃", 俴, 俴, 4],
        ["괡", 佤, 俴],
        ["댒", 3],
        ["꾮", 6, 3],
        ["꼖", 佤, "Thanks."],
        ["꼖", 侰, "Authorizing access..."],
        ["돯", 佤],
        ["딓", 佤, 佤],
        ["꾮", 佤, 俴],
        ["꿚", 佤, 4],
        ["꼖", 5, 19],
        ["꽲", 佤, 6, 5],
        ["돯", 侰],
        ["듃"],
        ["꼖", 侰, "Access denied!"],
        ["돯", 侰],
        ["듃"],
    ]
)

很明显这是加了替换反混淆,而且看形式非常像vm虚拟机(非常多的if、elif),我们根据这几个韩语(可能是)分别代表的功能,尝试着替换一下,

下面是初步替换的结果:

def vm(program):
    i = 0
    j = 0
    reg1 = [0] * 16
    reg2 = [0] * 100
    stack = []
    while program[i][0] != "end":
        opcode = program[i][0].lower()
        arr = program[i][1:]
        if opcode == "add":
            reg1[arr[0]] = reg1[arr[1]] + reg1[arr[2]]
        elif opcode == "xor":
            reg1[arr[0]] = reg1[arr[1]] ^ reg1[arr[2]]
        elif opcode == "sub":
            reg1[arr[0]] = reg1[arr[1]] - reg1[arr[2]]
        elif opcode == "mul":
            reg1[arr[0]] = reg1[arr[1]] * reg1[arr[2]]
        elif opcode == "div":
            reg1[arr[0]] = reg1[arr[1]] / reg1[arr[2]]
        elif opcode == "and_":
            reg1[arr[0]] = reg1[arr[1]] & reg1[arr[2]]
        elif opcode == "or_":
            reg1[arr[0]] = reg1[arr[1]] | reg1[arr[2]]
        elif opcode == "mov1":
            reg1[arr[0]] = reg1[arr[0]]
        elif opcode == "mov2":
            reg1[arr[0]] = reg1[arr[1]]
        elif opcode == "move":
            reg1[arr[0]] = arr[1]
        elif opcode == "mov4":
            reg2[arr[0]] = reg1[arr[1]]
        elif opcode == "mov5":
            reg1[arr[0]] = reg2[arr[1]]
        elif opcode == "setz1":
            reg1[arr[0]] = 0
        elif opcode == "setz2":
            reg2[arr[0]] = 0
        elif opcode == "input1":
            reg1[arr[0]] = input(reg1[arr[1]])
        elif opcode == "input2":
            reg2[arr[0]] = input(reg1[arr[1]])
        elif opcode == "print1":
            print(reg1[arr[0]])
        elif opcode == "print2":
            print(reg2[arr[0]])
        elif opcode == "reg1_to_i":
            i = reg1[arr[0]]
        elif opcode == "reg2_to_i":
            i = reg2[arr[0]]
        elif opcode == "stack_to_i":
            i = stack.pop()
        elif opcode == "믃" or reg1[arr[1]] > reg1[arr[2]]:
            i = arr[0]
            stack.append(i)
            continue
        elif opcode == "꽲":
            reg1[7] = 0
            for i in range(len(reg1[arr[0]])):
                if reg1[arr[0]] != reg1[arr[1]]:
                    reg1[7] = 1
                    i = reg1[arr[2]]
                    stack.append(i)
        elif opcode == "Sum_xor":
            str1 = ""
            for i in range(len(reg1[arr[0]])):
                str1 += chr(ord(reg1[arr[0]][i]) ^ reg1[arr[1]])
            reg1[arr[0]] = str1
        elif opcode == "Sum_gap":
            str1 = ""
            for i in range(len(reg1[arr[0]])):
                str1 += chr(ord(reg1[arr[0]][i]) - reg1[arr[1]])
            reg1[arr[0]] = str1
        elif opcode == "떇" or reg1[arr[1]] > reg1[arr[2]]:
            i = reg1[arr[0]]
            stack.append(i)
            continue
        elif opcode == "뗋" or reg1[arr[1]] > reg1[arr[2]]:
            i = reg2[arr[0]]
            stack.append(i)
            continue
        elif opcode == "똷" or reg1[arr[1]] == reg1[arr[2]]:
            i = arr[0]
            stack.append(i)
            continue
        elif opcode == "뚫" or reg1[arr[1]] == reg1[arr[2]]:
            i = reg1[arr[0]]
            stack.append(i)
            continue
        elif opcode == "띇" and reg1[arr[1]] == reg1[arr[2]]:
            i = reg2[arr[0]]
            stack.append(i)
            continue
        i += 1

vm(
    [
        ["move", 0, "Authentication token: "],
        ["input2", 0, 0]
        ["move", 6, "á×äÓâæíäàßåÉÛãåäÉÖÓÉäàÓÉÖÓåäÉÓÚÕæïèäßÙÚÉÛÓäàÙÔÉÓâæÉàÓÚÕÓÒÙæäàÉäàßåÉßåÉäàÓÉÚÓáÉ·Ôâ×ÚÕÓÔɳÚÕæïèäßÙÚÉÅä×ÚÔ׿ÔÉ×Úïá×ïåÉßÉÔÙÚäÉæÓ×ÜÜïÉà×âÓÉ×ÉÑÙÙÔÉâßÔÉÖãäÉßÉæÓ×ÜÜïÉÓÚÞÙïÉäàßåÉåÙÚÑÉßÉàÙèÓÉïÙãÉáßÜÜÉÓÚÞÙïÉßäÉ×åáÓÜܗÉïÙãäãÖӚÕÙۙá×äÕà©â«³£ï²ÕÔÈ·±â¨ë",],
        ["move", 2, 120],
        ["move", 4, 15],
        ["move", 3, 1],
        ["mul", 2, 2, 3],
        ["add", 2, 2, 4],
        ["mov1", 0, 2],
        ["setz1", 3],
        ["Sum_xor", 6, 3],
        ["move", 0, "Thanks."],
        ["move", 1, "Authorizing access..."],
        ["print1", 0],
        ["mov5", 0, 0],
        ["Sum_xor", 0, 2],
        ["Sum_gap", 0, 4],
        ["move", 5, 19],
        ["꽲", 0, 6, 5],
        ["print1", 1],
        ["end"],
        ["move", 1, "Access denied!"],
        ["print1", 1],
        ["end"],
    ]
)

有部分字符还没有替换,用到时候再看一下,

那么下面的数组内容就是伪汇编了,

下一步是尝试从这里简单反汇编一下:

vm(
    [
        ["move", 0, "Authentication token: "],
        ["input2", 0, 0]    # reg2[0] = input("Authentication token: ")

        ["move", 6, "á×äÓâæíäàßåÉÛãåäÉÖÓÉäàÓÉÖÓåäÉÓÚÕæïèäßÙÚÉÛÓäàÙÔÉÓâæÉàÓÚÕÓÒÙæäàÉäàßåÉßåÉäàÓÉÚÓáÉ·Ôâ×ÚÕÓÔɳÚÕæïèäßÙÚÉÅä×ÚÔ׿ÔÉ×Úïá×ïåÉßÉÔÙÚäÉæÓ×ÜÜïÉà×âÓÉ×ÉÑÙÙÔÉâßÔÉÖãäÉßÉæÓ×ÜÜïÉÓÚÞÙïÉäàßåÉåÙÚÑÉßÉàÙèÓÉïÙãÉáßÜÜÉÓÚÞÙïÉßäÉ×åáÓÜܗÉïÙãäãÖӚÕÙۙá×äÕà©â«³£ï²ÕÔÈ·±â¨ë",],
										        # reg1[6] = "á×äÓâ..."
        
        ["move", 2, 120],   # reg1[2] = 120
        ["move", 4, 15],    # reg1[4] = 15
        ["move", 3, 1],     # reg1[3] = 1
        ["mul", 2, 2, 3],   # reg1[2] = reg1[2] * reg1[3] = 120
        ["add", 2, 2, 4],   # reg1[2] = reg1[2] + reg1[4] = 135
        ["mov1", 0, 2],     # reg1[0] = reg1[0]
        ["setz1", 3],       # reg1[3] = 0
        ["Sum_xor", 6, 3],  # reg1[6] = reg1[6][i] ^ reg1[3] -> reg1[6] ^= 0

        ["move", 0, "Thanks."],
										        #reg1[0] = "Thanks."
        ["move", 1, "Authorizing access..."],
										        #reg1[1] = "Authorizing access..."
										        
        ["print1", 0],      # print("Thanks.")

        ["mov5", 0, 0],     # reg1[0] = reg2[0] = INPUT
        ["Sum_xor", 0, 2],  # reg1[0] = reg1[0][i] ^ reg1[2] -> INPUT ^= 135
        ["Sum_gap", 0, 4],  # reg1[0] = reg1[0][i] - reg1[4] -> reg1[0] -= 15
        ["move", 5, 19],    # reg1[5] = 19

        ["check", 0, 6, 5], # INPUT == reg1[6] ? reg1[7] = 0 : reg1[7] = 1

        ["print1", 1],      # print("Authorizing access...")
        ["end"],            # end
        
        ["move", 1, "Access denied!"],
        ["print1", 1],      # print("Access denied!")
        ["end"],            # end
    ]
)

反汇编大概就是这样的,可以看到对input的操作就是减去了异或了135再减去15,,最后跟密文对照,直接写代码解密:

enc = "á×äÓâæíäàßåÉÛãåäÉÖÓÉäàÓÉÖÓåäÉÓÚÕæïèäßÙÚÉÛÓäàÙÔÉÓâæÉàÓÚÕÓÒÙæäàÉäàßåÉßåÉäàÓÉÚÓáÉ·Ôâ×ÚÕÓÔɳÚÕæïèäßÙÚÉÅä×ÚÔ׿ÔÉ×Úïá×ïåÉßÉÔÙÚäÉæÓ×ÜÜïÉà×âÓÉ×ÉÑÙÙÔÉâßÔÉÖãäÉßÉæÓ×ÜÜïÉÓÚÞÙïÉäàßåÉåÙÚÑÉßÉàÙèÓÉïÙãÉáßÜÜÉÓÚÞÙïÉßäÉ×åáÓÜܗÉïÙãäãÖӚÕÙۙá×äÕà©â«³£ï²ÕÔÈ·±â¨ë"

for i in enc:
    print(chr((ord(i) + 15) ^ 135), end = '')

flag很长:

watevr{this_must_be_the_best_encryption_method_evr_henceforth_this_is_the_new_Advanced_Encryption_Standard_anyways_i_dont_really_have_a_good_vid_but_i_really_enjoy_this_song_i_hope_you_will_enjoy_it_aswell!_youtube.com/watch?v=E5yFcdPAGv0}