Mas0n
to be reverse engineer🐧
翻车鱼

第四届强网杯拟态挑战赛

第四届强网杯拟态挑战赛

正好和浙江省省赛撞上,跑去打了半天省赛,然后整场比赛就肝了一题……简单写下吧,容易忘。

fastjs

这题上个月比赛做到过类似的……

其实还是quickjs

版本是2021-03-27也就是3.0.4

https://cdn.shi1011.cn/2021/10/801d81cf9698b491d338aa37775e18ef.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

clone下https://code.dopame.me/unofficial-mirrors/quickjs

老办法

https://cdn.shi1011.cn/2021/10/c0c66fd77862b19c01f5d2afb37af3e9.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

然后插入代码

#if DUMP_BYTECODE
    js_dump_function_bytecode(ctx, b);
#endif

注意:插入的位置跟之前老版本有点不一样

插入点在JS_ReadFunctionTag下的(插错位置会导致各种奇怪的问题)

https://cdn.shi1011.cn/2021/10/6f6cfc89c1bb72b99d3d8dcf5db69e9c.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

后面就是翻译字节码了

得到字节码太长,不贴了。

上个py脚本

# -*- coding:utf-8 -*-
"""
@Author: Mas0n
@File: test9.py
@Time: 2021-10-23 17:17
@Desc: It's all about getting better.
"""
import math
import struct


def long2str(v, w):
    n = (len(v) - 1) << 2
    if w:
        m = v[-1]
        if (m < n - 3) or (m > n): return ''
        n = m
    s = struct.pack('<%iL' % len(v), *v)
    return s[0:n] if w else s


def str2long(s, w):
    n = len(s)
    m = (4 - (n & 3) & 3) + n
    s = s.ljust(m, b"\0")
    v = list(struct.unpack('<%iL' % (m >> 2), s))
    if w: v.append(n)
    return v

def xxtea(strs:str, key):
    if strs == "":
        return ""
    v = str2long(strs, True)
    k = str2long(key, False)
    sums = 0
    n = len(v) - 1
    z = v[n]
    y = v[0]
    delta = 2654435769
    q = 6 + 52 // (n + 1)
    while q > 0:
        sums = (sums + delta) & 0xffffffff
        e = sums >> 2 & 3
        for p in range(n):
            y = v[p + 1]
            v[p] = (v[p] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sums ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff
            z = v[p]
        y = v[0]
        v[n] = (v[n] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sums ^ y) + (k[n & 3 ^ e] ^ z))) & 0xffffffff
        z = v[n]
        q -= 1
    return long2str(v, False)

def decrypt(strs, key):
    if strs == '':
        return strs
    v = str2long(strs, False)
    k = str2long(key.ljust(16, b"\0"), False)
    n = len(v) - 1
    z = v[n]
    y = v[0]
    q = 6 + 52 // (n + 1)
    delta = 2654435769
    sum = (q * delta) & 0xffffffff
    while (sum != 0):
        e = sum >> 2 & 3
        for p in range(n, 0, -1):
            z = v[p - 1]
            v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff
            y = v[p]
        z = v[n]
        v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff
        y = v[0]
        sum = (sum - delta) & 0xffffffff
    return ''.join([struct.pack("<L", vd).replace(b"\x00", b'').decode() for vd in v])


def dfsfs(input):
    output = ""
    i = 0
    _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    while 1:
        try:
            chr1 = ord(input[i])
            i += 1
            chr2 = ord(input[i])
            i += 1
            chr3 = ord(input[i])
            i += 1
            enc1 = chr1 >> 2
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4)
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6)
            enc4 = chr3 & 63
            output += _keyStr[enc1] + _keyStr[enc2] + _keyStr[enc3] + _keyStr[enc4]
        except:
            pass

        if i >= len(input):
            break
    return output

def dec(input):
    output = ""
    i = 0
    _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    while 1:
        try:
            enc1 = _keyStr.index(input[i])
            i += 1
            enc2 = _keyStr.index(input[i])
            i += 1
            enc3 = _keyStr.index(input[i])
            i += 1
            enc4 = _keyStr.index(input[i])
            i += 1

            chr1 = (enc1 << 2) | (enc2 >> 4)
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2)
            chr3 = ((enc3 & 3) << 6) | enc4
            output = output + chr(chr1)
            if enc3 != 64:
                output = output + chr(chr2)

            if enc4 != 64:
                output = output + chr(chr3)
        except:
            pass


        if i >= len(input):
            break
    return output


def main(flag):
    print("your input: ", flag)
    input = flag
    encflag = dfsfs(input)
    key = "no_thing_is_true"
    enc2flag = xxtea(encflag, key)

    if len(enc2flag) == 112:
        target = "05aed0ce441f80b5bc36af4c698509fc6cc3c97146353de5a95c6abea07fd4a7070932d86ac32d628672a59123e5972331db5dffe7057362"
        if enc2flag == target:
            print("yes")
            return
    print("false")
    return

value = b"".fromhex("05aed0ce441f80b5bc36af4c698509fc6cc3c97146353de5a95c6abea07fd4a7070932d86ac32d628672a59123e5972331db5dffe7057362")
print(struct.unpack("14L", value))
print([hex(i) for i in struct.unpack("4L", b"no_thing_is_true")])
mapsEncStr = decrypt(value, b"no_thing_is_true")
print(mapsEncStr)
arrs = []

keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
print(dec(mapsEncStr))

print(arrs)

# https://admhelp.microfocus.com/alm/api_refs/REST/Content/REST_API/base_64_example.htm

其实就是xxtea + base64……

本文链接:https://blog.shi1011.cn/ctf/1734
本文采用 CC BY-NC-SA 4.0 Unported 协议进行许可

Mas0n

文章作者

发表回复

textsms
account_circle
email

翻车鱼

第四届强网杯拟态挑战赛
正好和浙江省省赛撞上,跑去打了半天省赛,然后整场比赛就肝了一题……简单写下吧,容易忘。 fastjs 这题上个月比赛做到过类似的…… 其实还是quickjs 版本是2021-03-27也就…
扫描二维码继续阅读
2021-10-26