【wp】2021V&NCTF

前几天打完的V&NCTF公开赛,做题的时候没记过程,这是复现wp。

最后排名Top 18,三道RE+两道杂项(wp没啥可放的hhh)+一道web,感觉re题目还是挺好的,难度适中点赞,尤其pc逆向还是两个算you法xi题,纯模拟好评,算法题不好评(x。

image-20210314232358706

比赛地址://buuoj.cn/vnctf_2021

官方wp:V&NCTF2021 官方WP(RE部分)(其他部分的wp在公众号上自行寻找)

Reverse

notsudoku

看到这个名字dna动了一下(之前hsctf新生赛我也出了一个not_a_sudoku的题,还以为这个也是数织,被骗进来做了x),不过这个题目实际上是个魔方阵,读懂源码就很简单了。

附件图标是典型的pyinstaller打包的exe文件,先参考RE套路 – 关于pyinstaller打包文件的复原 | c10udlnk_Log的方法,pyinstxtractor、补头、改后缀名,然后走到uncompyle6这一步就会报错

image-20210315001056338

第一反应是做了混淆或者在打包的时候做了魔改,于是试了一下解压文件夹里的pyiboot01_bootstrap,发现是能正常走流程反编译的,所以魔改的猜测不成立,只剩下混淆pyc。

然后去找py打包的原理和各种反混淆的文章看,试图手动去混淆然后用uncompyle6反编译(做了四个小时的原因找到了X_X),然后在某篇文章里看到“……pyc文件随便在网上找个在线工具都可以进行反编译,所以我们要进行加密……”,突然灵光一闪:我为什么不试试在线的反编译工具?

于是真就被我找到了一个:在线pyc,pyo,python,py文件反编译,目前支持python1.5到3.6版本的反编译-在线工具

从而拿到源码(真就只针对uncompyle6做混淆呗):

#! /usr/bin/env python 3.7 (3394)
#coding=utf-8
# Compiled at: 1969-12-31 18:00:00
#Powered by BugScaner
#//tools.bugscaner.com/
#如果觉得不错,请分享给你朋友使用吧!
import time, sys, hashlib

class あ:
    def __init__(self):
        self.う = {}
        self.な = []
        self.に = ''
        self.ぬ = []
        self.ね = 65
    def え(self, えひ):
        def の(f):
            self.う[えひ] = f
            return f
        return の
    def お(self, は):
        return self.う.get(は)
    def か(self):
        き = 0
        while True:
            く = self.な[き][0]
            け = self.な[き][1]
            こ = self.な[き][2]
            さ = self.お(く)
            さ(け, こ)
            き += 1

い = あ()

@い.え(u'\u3057')
def f(a, b):
    if a == 1:
        い.ぬ += b

@い.え(u'\u3059')
def f(a, b):
    if a == 1:
        print(い.に)
    else:
        if a == 2:
            print(い.ぬ)
        else:
            if a == 3:
                print(い.flag, end='')
            else:
                print(a, end='')

@い.え(u'\u305b')
def f(a, b):
    sys.exit()

@い.え(u'\u305d')
def f(a, b):
    い.に = input()

@い.え(u'\u305f')
def f(a, b):
    time.sleep(a)

@い.え(u'\u3061')
def f(a, b):
    if len(い.に) % 2 != 0:
        sys.exit()
    for i in い.に:
        if ord(i) > 52 or ord(i) < 48:
            sys.exit()
    x = str(hashlib.new('md5', bytes(い.に, encoding='utf8')).hexdigest())
    if x[:6] != 'e3a912':
        sys.exit()
    い.flag = x

@い.え(u'\u3068')
def f(a, b):
    ふ = 0
    for i in range(0, len(い.に), 2):
        ふ += 1
        a = int(い.に[i])
        b = int(い.に[i + 1])
        い.ぬ[a][b] = ふ

@い.え(u'\u3064')
def f(a, b):
    if い.ぬ[0][1] != 24 or い.ぬ[4][3] != 2:
        sys.exit()
    if い.ぬ[0][2] != 1 or い.ぬ[2][3] != 20:
        sys.exit()
    if い.ぬ[1][0] != 23 or い.ぬ[3][4] != 3:
        sys.exit()

@い.え(u'\u3066')
def f(a, b):
    ね = 0
    if b == -1:
        for i in range(5):
            ね += い.ぬ[a][i]
        if ね != い.ね:
            sys.exit()
        else:
            for i in range(5):
                ね += い.ぬ[i][b]
            if ね != い.ね:
                sys.exit()

い.な = [
 [u'\u3059', 'welcome baby~ ', 0],
 [u'\u3059', 'input your flag~:', 0],
 [u'\u305d', 0, 0],
 [u'\u3059', 'your input is:', 0],
 [u'\u3059', 1, 0],
 [u'\u3059', "let's check......", 0],
 [u'\u305f', 0.5, 0],
 [u'\u3057', 1, [[0 for i in range(5)]]],
 [u'\u3057', 1, [[0 for i in range(5)]]],
 [u'\u3057', 1, [[0 for i in range(5)]]],
 [u'\u3057', 1, [[0 for i in range(5)]]],
 [u'\u3057', 1, [[0 for i in range(5)]]],
 [u'\u3061', 0, 0],
 [u'\u3068', 0, 0],
 [u'\u3064', 0, 0],
 [u'\u3066', 0, -1],
 [u'\u3066', 1, -1],
 [u'\u3066', 2, -1],
 [u'\u3066', 3, -1],
 [u'\u3066', 4, -1],
 [u'\u3066', 0, 0],
 [u'\u3066', 0, 1],
 [u'\u3066', 0, 2],
 [u'\u3066', 0, 3],
 [u'\u3066', 0, 4],
 [u'\u3059', 'Goodjob!', 0],
 [u'\u3059', 'The flag is vnctf{', 0],
 [u'\u3059', 3, 0],
 [u'\u3059', '}', 0],
 [u'\u305b', 0, 0]]

い.か()

源码这个变量名/函数名就很离谱,不过比起之前xctf那个pypy的变量名已经算好了(如果变量名看不清,建议各自替换成ida风格或者其他变量名)。

逻辑很清楚2333,python就算没学到面向对象也能靠猜。

主要关注这个:

def か(self):
    き = 0
    while True:
        く = self.な[き][0]
        け = self.な[き][1]
        こ = self.な[き][2]
        さ = self.お(く)
        さ(け, こ)
        き += 1

这个的意思就是把源码末尾的二维列表以L[0](L[1],L[2])的方式执行函数。

对上面的一些比较复杂的函数做一点注释:

# 输出
@い.え(u'\u3059')
def f(a, b):
    if a == 1:
        print(い.に)
    else:
        if a == 2:
            print(い.ぬ)
        else:
            if a == 3:
                print(い.flag, end='')
            else:
                print(a, end='')

# check1,flag长度为偶数,每一个字符由'0'-'4'组成,md5(flag)[:6]=='e3a912'
@い.え(u'\u3061')
def f(a, b):
    if len(い.に) % 2 != 0:
        sys.exit()
    for i in い.に:
        if ord(i) > 52 or ord(i) < 48:
            sys.exit()
    x = str(hashlib.new('md5', bytes(い.に, encoding='utf8')).hexdigest())
    if x[:6] != 'e3a912':
        sys.exit()
    い.flag = x

# 对连续字符'ab',将pic[a][b]从1开始依次赋值
# 例如对'011342',则pic[0][1]=1,pic[1][3]=2,pic[4][2]=3...
@い.え(u'\u3068')
def f(a, b):
    ふ = 0
    for i in range(0, len(い.に), 2):
        ふ += 1
        a = int(い.に[i])
        b = int(い.に[i + 1])
        い.ぬ[a][b] = ふ

# check2,检测对应位置是不是对应数字
@い.え(u'\u3064')
def f(a, b):
    if い.ぬ[0][1] != 24 or い.ぬ[4][3] != 2:
        sys.exit()
    if い.ぬ[0][2] != 1 or い.ぬ[2][3] != 20:
        sys.exit()
    if い.ぬ[1][0] != 23 or い.ぬ[3][4] != 3:
        sys.exit()

# check3,检测每一行的和与每一列的和是否为い.ね即65
@い.え(u'\u3066')
def f(a, b):
    ね = 0
    if b == -1:
        for i in range(5):
            ね += い.ぬ[a][i]
        if ね != い.ね:
            sys.exit()
        else:
            for i in range(5):
                ね += い.ぬ[i][b]
            if ね != い.ね:
                sys.exit()

这个逻辑捋下来不就是魔方阵吗/doge。

好巧不巧,在我搜魔方阵的实现代码的时候,被我搜到了这个(C语言实现魔方阵代码及解析_Linux编程_Linux公社-Linux系统门户网站):

image-20210315192329080

诶,对应位置完全符合,相加也是65,绝了。

于是确定这个魔方阵就是题目想要的那个,于是写exp来通过这个阵生成flag:

l=[[17,24,1,8,15],
   [23,5,7,14,16],
   [4,6,13,20,22],
   [10,12,19,21,3],
   [11,18,25,2,9]]
flag=""
for i in range(1,26):
    for row in range(5):
        try:
            flag+=str(row)+str(l[row].index(i))
        except:
            pass
print(flag)

得到input:02433420112112034430403122130414004132233324100142

验证一下md5:

image-20210315192731841

前六位吻合,拿到flag!

image-20210315192835466

flag:vnctf{e3a912c1e911ad82544af0c3d753f44f}

FilpGame

ida打开文件,直接从最后check部分看起:

image-20210315193239373

可以看到word_40301C和unk_40303C在空间上是相连的

image-20210315200235797

也就是说这个check实际上的作用是检测word_40301C这个数组是不是都是-1(即0xFFFF,计算机中数据以补码形式存储)。

而唯一调用到这个word_40301C数组的地方就是word_40301C[v13] ^= 1 << (15 - v12)

image-20210315200653184

模拟一下就能知道,如果把这个数组当成一个棋盘,那这里的作用就是将bit[v13][v12]的位取反(其余位xor 0以后不变,从左往右数的v12位xor 1以后取反),这里需要对位运算有一点基本的了解。

随便画了个图方便理解:

而这里v12和v13加的两个数组为:

image-20210315201843160

也就是说这种01翻转以(-1,0),(0,0),(0,-1),(0,1),(1,0)的方向拓展,即翻转bit[v13][v12]时,它的上下左右都会发生翻转。而我们需要做的就是翻转特定位置的bit,使所有bit都为1(想到了高斯消元和某些类似玩法的独立游戏。

再往上看可以发现,实际上是一个对我们的输入进行类似于unhex的过程,其中偶数位存在v4里,奇数位存在v5里。

举个栗子,如果我们输入“e3”,那么进行的处理就是v4=0xe=14;v5=0x3=3;,然后在奇数位时进行翻转处理(即翻转bit[3][14]及其上下左右)。

image-20210315202111026

image-20210315203149938

根据高斯消元算法找到了POJ 3279 Fliptile 开关问题_WA是一笔财富-CSDN博客,用这里的脚本算答案(算法太菜了懒得自己写)。

先把原始的word_40301C数组输出成指定格式,注意poj的题目是1代表反面,0代表正面,最后需要所有都翻成正面向上(即全为0),而在我们这里是需要翻成全为1,所以输出的时候要对数组各位的状态取反。

dst=[0xBEF5, 0x8BBC, 0xA0E9, 0x7310, 0xD910, 0xA3AD, 0xCCB6, 0x4DDE, 0x344C, 0x3BD6, 0x6711, 0x868F, 0x1C7A, 0x8425, 0x6B0D, 0x1B4C]
for i in dst:
    for x in bin(i)[2:].rjust(16,'0'):
        print(int(x)^1,end=' ')
    print()

得到

image-20210315203210576

然后把poj的解题脚本改为

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 99999999
using namespace std;
typedef pair<int,int>P;
int m,n;
int mp[20][20],flip[20][20],ans[20][20];//原数组、临时数组、结果数组
int go[5][2]={0,0,1,0,0,1,-1,0,0,-1};
int getcolor(int i,int j){//判断某块地是正面还是反面
    int sum=mp[i][j];
    for(int k=0;k<5;k++){
        int di=i+go[k][0];
        int dj=j+go[k][1];
        if(0<=di&&di<m&&0<=dj&&dj<n)
        sum+=flip[di][dj];
    }
    return sum&1;
}
int check(){//确定第一行的状态下判断是否有可行解
    for(int j=1;j<m;j++){
        for(int k=0;k<n;k++){
            flip[j][k]=getcolor(j-1,k);
        }
    }
    for(int i=0;i<n;i++)
    if(getcolor(m-1,i))
    return -1;
    int sum=0;
    for(int i=0;i<m;i++)
    for(int j=0;j<n;j++)
    sum+=flip[i][j];
    return sum;
}
void solve(){
    int res=inf;
    for(int i=0;i<1<<n;i++){//枚举第一行状态
        memset(flip,0,sizeof(flip));
        for(int j=0;j<n;j++){
            flip[0][n-1-j]=(i>>j)&1;//集合的整数表示
        }
        int t=check();
         if(t>=0&&res>t){
            res=t;
            memcpy(ans,flip,sizeof(flip));
         }
    }
    if(res==inf)
    printf("IMPOSSIBLE\n");
    else{
        for(int i=0;i<m;i++){
            printf("[");
            for(int j=0;j<n;j++)
                printf("%d%c",ans[i][j],",]"[j==n-1]);
            printf(",");
        }
    }
}
int main(){
    while(~scanf("%d%d",&m,&n)){
        for(int i=0;i<m;i++)
        	for(int j=0;j<n;j++)
        		scanf("%d",&mp[i][j]);
        solve();
    }
    return 0;
}

得到:

image-20210315204338025

然后写exp组织成input:

ans=[[0,0,1,0,0,1,1,0,1,1,1,1,1,1,0,0],[0,0,1,1,1,0,0,1,0,1,1,1,0,0,0,0],[0,0,0,0,0,1,0,1,1,0,0,1,0,1,1,1],[0,1,1,0,1,0,1,0,0,0,0,1,0,1,0,0],[0,0,0,0,0,0,1,0,0,1,0,0,1,1,1,0],[0,1,0,0,1,0,1,1,0,0,0,0,1,1,1,0],[1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1],[1,1,0,0,0,0,0,0,1,0,0,1,1,0,0,0],[0,0,1,1,0,1,0,1,0,1,0,0,1,1,0,0],[0,1,0,0,1,1,1,0,0,1,0,1,1,0,0,1],[0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0],[1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0],[0,1,1,1,1,0,1,0,0,1,0,1,0,0,1,0],[1,0,0,0,1,0,0,1,0,1,0,1,1,0,1,0],[1,1,0,1,1,1,1,0,1,1,0,0,1,0,1,1],[0,0,0,1,0,0,0,1,1,0,0,1,0,0,0,0]]
flag=""
for i in range(16):
    for j in range(16):
        if ans[i][j]==1:
            flag+=hex(j)[2:]+hex(i)[2:]
flag=flag.upper()
print(flag)
# 2050608090A0B0C0D02131417191A1B1527282B2D2E2F213234363B3D36494C4D4E415456575C5D5E50626566686C6F6071787B7C72838587898C8D81949596999B9C9F95A8AAAEA0B1B3B4B7B1C2C3C4C6C9CBCEC0D4D7D9DBDCDED0E1E3E4E5E6E8E9ECEEEFE3F7F8FBF

image-20210315204727111

成功过check:

image-20210315204945174

flag是md5,所以输出一下md5

from hashlib import md5
flag=b"2050608090A0B0C0D02131417191A1B1527282B2D2E2F213234363B3D36494C4D4E415456575C5D5E50626566686C6F6071787B7C72838587898C8D81949596999B9C9F95A8AAAEA0B1B3B4B7B1C2C3C4C6C9CBCEC0D4D7D9DBDCDED0E1E3E4E5E6E8E9ECEEEFE3F7F8FBF"
print(md5(flag).hexdigest())

flag:vnctf{c51a6d6d3929cd2a0192572e604b371d}

Crackme2

密码题,表示安卓逆向一直是硬看的(

老规矩,解压apk,用ida打开Crackme2/lib/arm64-v8a/libnative-lib.so

在函数搜索界面找到MainActivity主函数:

image-20210315205054540

从最后的check看起,很明显是让xmmword_C80F0==v11,v11为通过imput处理之后的结果,而xmmword_C80F0实际上是已知的。

image-20210315210329477

查交叉引用,可以看到xmmword_C80F0=xmmword_A3880,而xmmword_C80F0又已知,所以拿到了目标数组即密文。

image-20210315210618557

image-20210315210951220

image-20210315211002008

然后通过findcrypt插件找到AES的S box常数,通过交叉引用和函数伪代码确定sub_42944为AES的加密函数。

而上面sub_40E80很明显是给v21赋了几个常见常数

image-20210315211042147

乐了,这不就是md5常数吗。看了一下下面的几个函数,差不多确定了就就是个md5。

然后猜测是用md5(“Hello from C++”)做key对密文进行AES解密,就能得到flag。

写exp尝试一下:

from Crypto.Cipher import AES
from hashlib import md5
from binascii import *

key=unhexlify(md5(b'Hello from C++').hexdigest())
cipher=unhexlify("B28216EE5ECD5FFAFF8254E60B4BAEAA")
aes=AES.new(key,AES.MODE_ECB)
text=aes.decrypt(cipher)
print(text)

image-20210315211642345

诶,都是可见字符,试图交flag,成了2333。

flag:vnctf{85df34871c68810c}

Web

Ez_game

赛后咨询了一下web师傅@Fxizenta,发现这个题原来五分钟就可以做出来(改数值,无敌+跳关),然后突然感觉我的思路真就re思维做web题,比较麻烦,但还是贴一下吧(

这种游戏一看就不可能是出题人自己写的,肯定在源码的基础上插了一些其他代码来生成&输出flag(出题经验),于是对比两个文件,找到不一样的地方,就有可能是flag出现的地方。

于是先从题目的网页里拿到三个js文件,然后根据game.js的注释找到源码:KilledByAPixel/BounceBack: Boomerang Zelda Homage for JS13k,把源码的三个js文件也下下来。

看名字先从game.js看起,比较像主函数。我这里用的是010Editor的比较文件功能(Ctrl+M)。

game_new.js是题目用的game.js,而game.js是源码的game.js

image-20210315211849020

看到的第一个差异就是sojson.v4的混淆,怀疑是这里有flag。

['sojson.v4']["\x66\x69\x6c\x74\x65\x72"]["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"](((['sojson.v4']+[])["\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72"]['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65']['\x61\x70\x70\x6c\x79'](null,"118h97x114w32l95m95N101x110O99d111B100u101w32F61P32u39R106k115w106O105F97z109R105f46p99y111A109U39d44F10G32U32F32r32G95V97p32D61Y32X123W125h44r10M32V32P32x32h95X48M120O98J52A56I51A32r61d32v91o34Q95c100n101M99e111I100l101I34b44r32X34r104N116Z116m112B58A47b47P119M119d119M46z115W111I106V115f111s110m46J99D111W109Z47g106R97c118D97F115L99I114Y105F112v116E111l98m102Q117d115E99x97K116r111U114v46s104d116B109F108Z34e93B59q10m40r102O117f110Z99D116D105a111a110u40Y95J48O120H100Q54k52k50e120I49a41P32f123s10E32j32I32d32K95E48D120k100R54S52g50O120H49y91J95q48X120w98C52a56R51E91m48B93c93E32d61e32w95X48v120b98L52e56b51O91m49b93C10Q125V41N40t95r97g41L59X10M118d97I114t32E95f95x79y120f97D50O55p56y49X32I61j32A91K34i34t44h32L34a45m112w97p117H115M101E100z45m34r44g32Q34y87v105k110E33A32h102S108G97y103u123E116k104V105l115E95F103u97g109Y101I95l105R115A95x102G117h110l110E121M33B125f34N44c32q34f71C97L109O101x32c79k118R101J114R33b34L44V32h34U80g114e101b115c115t32c69w115I99g97u112W101z34C44h32d34a120f34k44B32W34i121H34q44x32P34E99x101x110k116J101Z114j34c44B32s34B117V110j100K101A102U105M110L101x100T34k44u32U34R108t111X103q34W44p32M34o21024U38500O34R44T32u34a29256O26412t21495E65292k106N115v20250y23450F34N44f32V34Q26399e24377C31383B65292R34u44t32j34y36824A35831C25903t25345D25105o20204W30340R24037P20316L34R44y32w34o106Z115A106T105F97b34i44a32m34u109T105L46e99p111F109l34U93m59Y10u108S101q116s32P98f105A103l84N101h120n116V32A61B32t95V95W79u120a97z50N55J56g49r91g48C120L48a93r59K10k105U102S32K40X112d97m117q115P101T100A41S32r123R10r32D32a32X32t98Y105Y103N84I101p120j116U32e61J32R95g95v79i120F97F50n55h56H49d91S48x120N49u93H10C125z59O10C105W102e32t40G119n105T110x84r105G109Y101W114q46C73s115m83G101O116j40m41O41R32S123R10c32I32b32A32V98x105X103v84E101b120V116V32L61P32N95e95u79I120v97W50T55W56i49S91j48m120O50d93k10g125J59G10Q105p102m32Y40O112J108s97c121w101U114u46P73a115D68E101Y97D100E40g41g41Q32Y123r10K32X32T32q32r98b105q103i84o101V120D116v32N61H32b95R95J79q120i97q50X55o56g49G91T48Z120F51G93l59k10c32v32f32e32P68u114l97N119q84f101x120z116m40j95r95I79n120R97E50x55o56h49y91p48Q120z52L93g44k32E109H97Q105E110w67Z97l110d118S97M115j83a105B122j101E91p95n95Y79U120S97H50C55a56l49E91z48w120A53C93Y93I32b47M32o50R44R32w109n97U105b110j67h97M110H118j97X115g83D105M122n101W91J95q95y79x120i97R50Y55z56s49N91z48v120R54s93a93S32I47z32A50k32w43S32f56j48j44T32B52Y50c41O10V125M59f10h68n114V97m119f84G101C120P116u40E98i105M103U84C101e120d116q44f32Z109v97i105R110G67u97m110Q118e97n115K83G105V122M101j91Q95Y95y79M120f97G50k55i56C49c91x48j120R53F93a93L32b47p32Z50k44a32l109c97r105A110W67i97Y110t118H97y115J83H105C122r101R91a95L95s79a120d97M50G55H56k49O91m48p120R54y93d93J32x47y32c50c32Y45d32C56M48i44r32b55G50f44j32x95j95r79S120i97g50J55V56a49a91Y48f120w55c93M44M32s50p41D59x59h59g10r40L102e117n110g99S116k105D111t110Y40M95J48s120f53y49N57K55H120Y50z44F32z95B48b120t53z49A57D55X120n51H44w32o95P48t120g53n49M57G55n120T52U44D32B95A48B120Z53K49H57t55X120d53L44f32o95J48R120D53s49H57d55J120b54Y44w32U95u48g120J53Q49v57B55s120a55H41z32L123K10G32X32F32V32W95k48o120T53S49I57d55s120i55d32O61X32n95B95n79d120E97E50s55o56w49j91N48z120D56R93R59j10p32Q32s32e32H95F48O120Y53F49C57W55r120q53M32f61U32Y102R117F110N99c116V105r111y110w40I95X48h120s53Y49o57q55k120o56Q41f32S123S10R32C32B32t32f32r32q32F32Z105Y102S32o40c116E121R112d101G111f102m32p97d108Q101M114s116V32G33s61C61z32B95p48W120e53S49y57p55Q120C55o41q32L123z10I32u32a32y32W32e32b32h32W32s32m32l32c97I108C101N114t116V40P95w48X120x53F49M57d55B120x56u41F10C32F32A32B32h32F32r32y32w125L59G10o32f32T32O32T32O32c32H32D105d102v32H40i116V121a112R101e111G102B32D99O111n110L115o111X108W101S32D33C61H61G32o95u48e120z53k49d57j55s120E55m41p32c123o10V32I32B32R32A32Y32N32H32E32R32l32V32P99D111R110i115r111m108h101D91Z95i95s79g120K97d50W55w56r49n91E48l120W57W93F93R40P95D48G120q53Q49d57p55q120M56R41F10q32C32N32u32X32T32E32d32X125W10D32P32h32i32Y125N59D10v32J32C32X32B95V48w120K53C49I57r55I120E52C32Q61E32X102o117o110I99u116M105C111z110h40v95g48L120b53d49q57e55J120L57j44C32F95R48X120M53S49U57w55h120I50w41W32r123j10q32e32k32e32y32Z32I32g32z114c101D116A117A114V110w32x95p48H120k53O49r57b55Z120w57Q32N43M32A95I48z120M53A49S57s55K120o50o10u32y32k32j32u125a59j10u32S32S32n32p95A48s120k53a49M57F55J120J54G32c61R32l95c48X120C53s49q57U55V120E52N40A95t95T79x120Q97R50o55F56e49Y91i48G120p97P93y44S32J95k48r120q53g49i57E55x120D52O40N95H48S120d53i49M57H55x120e52e40X95k95Z79q120C97l50T55K56I49k91R48o120g98g93Q44v32r95R95K79W120N97u50A55v56Z49m91A48x120X99H93x41y44T32w95n95v79i120g97E50y55h56m49C91X48S120N100w93n41q41b59M10I32e32F32g32e116J114t121I32r123N10M32J32N32m32j32l32J32g32X95n48g120l53X49b57l55D120p50s32b61T32f95W95E101N110o99c111M100M101Q59f10J32k32y32K32B32F32X32R32K105d102c32b40e33U40o116q121j112D101A111D102c32x95p48o120R53a49b57S55d120M50d32p33q61s61o32d95z48B120A53s49S57t55a120j55H32B38S38e32N95i48L120O53j49W57O55V120P50X32o61Y61i61k32P95j48M120Z53O49t57W55P120p52V40d95N95y79a120X97r50t55o56v49a91I48m120m101p93B44T32V95b95j79s120M97q50p55j56G49A91g48i120O102U93G41y41a41i32F123F10O32Z32o32T32P32e32Z32K32T32h32z32d32b95l48V120H53v49J57I55L120w53J40n95M48o120F53C49d57W55e120S54R41U10U32u32C32c32x32z32y32J32F125L10H32K32G32r32d125e32A99A97l116x99y104R32H40B101U41W32j123A10m32t32b32L32A32A32B32D32Z95t48z120m53V49N57N55B120x53Z40m95k48c120A53L49M57V55R120l54U41X10E32R32G32Q32q125U10D125p41P40A123E125S41"['\x73\x70\x6c\x69\x74'](/[a-zA-Z]{1,}/))))('sojson.v4');

然后把所有的字符串解码,有:

['sojson.v4']['filter']['constructor'](((['sojson.v4']+[])['constructor']['fromCharCode']['apply'](null,"118h97x114w32l95m95N101x110O99d111B100u101w32F61P32u39R106k115w106O105F97z109R105f46p99y111A109U39d44F10G32U32F32r32G95V97p32D61Y32X123W125h44r10M32V32P32x32h95X48M120O98J52A56I51A32r61d32v91o34Q95c100n101M99e111I100l101I34b44r32X34r104N116Z116m112B58A47b47P119M119d119M46z115W111I106V115f111s110m46J99D111W109Z47g106R97c118D97F115L99I114Y105F112v116E111l98m102Q117d115E99x97K116r111U114v46s104d116B109F108Z34e93B59q10m40r102O117f110Z99D116D105a111a110u40Y95J48O120H100Q54k52k50e120I49a41P32f123s10E32j32I32d32K95E48D120k100R54S52g50O120H49y91J95q48X120w98C52a56R51E91m48B93c93E32d61e32w95X48v120b98L52e56b51O91m49b93C10Q125V41N40t95r97g41L59X10M118d97I114t32E95f95x79y120f97D50O55p56y49X32I61j32A91K34i34t44h32L34a45m112w97p117H115M101E100z45m34r44g32Q34y87v105k110E33A32h102S108G97y103u123E116k104V105l115E95F103u97g109Y101I95l105R115A95x102G117h110l110E121M33B125f34N44c32q34f71C97L109O101x32c79k118R101J114R33b34L44V32h34U80g114e101b115c115t32c69w115I99g97u112W101z34C44h32d34a120f34k44B32W34i121H34q44x32P34E99x101x110k116J101Z114j34c44B32s34B117V110j100K101A102U105M110L101x100T34k44u32U34R108t111X103q34W44p32M34o21024U38500O34R44T32u34a29256O26412t21495E65292k106N115v20250y23450F34N44f32V34Q26399e24377C31383B65292R34u44t32j34y36824A35831C25903t25345D25105o20204W30340R24037P20316L34R44y32w34o106Z115A106T105F97b34i44a32m34u109T105L46e99p111F109l34U93m59Y10u108S101q116s32P98f105A103l84N101h120n116V32A61B32t95V95W79u120a97z50N55J56g49r91g48C120L48a93r59K10k105U102S32K40X112d97m117q115P101T100A41S32r123R10r32D32a32X32t98Y105Y103N84I101p120j116U32e61J32R95g95v79i120F97F50n55h56H49d91S48x120N49u93H10C125z59O10C105W102e32t40G119n105T110x84r105G109Y101W114q46C73s115m83G101O116j40m41O41R32S123R10c32I32b32A32V98x105X103v84E101b120V116V32L61P32N95e95u79I120v97W50T55W56i49S91j48m120O50d93k10g125J59G10Q105p102m32Y40O112J108s97c121w101U114u46P73a115D68E101Y97D100E40g41g41Q32Y123r10K32X32T32q32r98b105q103i84o101V120D116v32N61H32b95R95J79q120i97q50X55o56g49G91T48Z120F51G93l59k10c32v32f32e32P68u114l97N119q84f101x120z116m40j95r95I79n120R97E50x55o56h49y91p48Q120z52L93g44k32E109H97Q105E110w67Z97l110d118S97M115j83a105B122j101E91p95n95Y79U120S97H50C55a56l49E91z48w120A53C93Y93I32b47M32o50R44R32w109n97U105b110j67h97M110H118j97X115g83D105M122n101W91J95q95y79x120i97R50Y55z56s49N91z48v120R54s93a93S32I47z32A50k32w43S32f56j48j44T32B52Y50c41O10V125M59f10h68n114V97m119f84G101C120P116u40E98i105M103U84C101e120d116q44f32Z109v97i105R110G67u97m110Q118e97n115K83G105V122M101j91Q95Y95y79M120f97G50k55i56C49c91x48j120R53F93a93L32b47p32Z50k44a32l109c97r105A110W67i97Y110t118H97y115J83H105C122r101R91a95L95s79a120d97M50G55H56k49O91m48p120R54y93d93J32x47y32c50c32Y45d32C56M48i44r32b55G50f44j32x95j95r79S120i97g50J55V56a49a91Y48f120w55c93M44M32s50p41D59x59h59g10r40L102e117n110g99S116k105D111t110Y40M95J48s120f53y49N57K55H120Y50z44F32z95B48b120t53z49A57D55X120n51H44w32o95P48t120g53n49M57G55n120T52U44D32B95A48B120Z53K49H57t55X120d53L44f32o95J48R120D53s49H57d55J120b54Y44w32U95u48g120J53Q49v57B55s120a55H41z32L123K10G32X32F32V32W95k48o120T53S49I57d55s120i55d32O61X32n95B95n79d120E97E50s55o56w49j91N48z120D56R93R59j10p32Q32s32e32H95F48O120Y53F49C57W55r120q53M32f61U32Y102R117F110N99c116V105r111y110w40I95X48h120s53Y49o57q55k120o56Q41f32S123S10R32C32B32t32f32r32q32F32Z105Y102S32o40c116E121R112d101G111f102m32p97d108Q101M114s116V32G33s61C61z32B95p48W120e53S49y57p55Q120C55o41q32L123z10I32u32a32y32W32e32b32h32W32s32m32l32c97I108C101N114t116V40P95w48X120x53F49M57d55B120x56u41F10C32F32A32B32h32F32r32y32w125L59G10o32f32T32O32T32O32c32H32D105d102v32H40i116V121a112R101e111G102B32D99O111n110L115o111X108W101S32D33C61H61G32o95u48e120z53k49d57j55s120E55m41p32c123o10V32I32B32R32A32Y32N32H32E32R32l32V32P99D111R110i115r111m108h101D91Z95i95s79g120K97d50W55w56r49n91E48l120W57W93F93R40P95D48G120q53Q49d57p55q120M56R41F10q32C32N32u32X32T32E32d32X125W10D32P32h32i32Y125N59D10v32J32C32X32B95V48w120K53C49I57r55I120E52C32Q61E32X102o117o110I99u116M105C111z110h40v95g48L120b53d49q57e55J120L57j44C32F95R48X120M53S49U57w55h120I50w41W32r123j10q32e32k32e32y32Z32I32g32z114c101D116A117A114V110w32x95p48H120k53O49r57b55Z120w57Q32N43M32A95I48z120M53A49S57s55K120o50o10u32y32k32j32u125a59j10u32S32S32n32p95A48s120k53a49M57F55J120J54G32c61R32l95c48X120C53s49q57U55V120E52N40A95t95T79x120Q97R50o55F56e49Y91i48G120p97P93y44S32J95k48r120q53g49i57E55x120D52O40N95H48S120d53i49M57H55x120e52e40X95k95Z79q120C97l50T55K56I49k91R48o120g98g93Q44v32r95R95K79W120N97u50A55v56Z49m91A48x120X99H93x41y44T32w95n95v79i120g97E50y55h56m49C91X48S120N100w93n41q41b59M10I32e32F32g32e116J114t121I32r123N10M32J32N32m32j32l32J32g32X95n48g120l53X49b57l55D120p50s32b61T32f95W95E101N110o99c111M100M101Q59f10J32k32y32K32B32F32X32R32K105d102c32b40e33U40o116q121j112D101A111D102c32x95p48o120R53a49b57S55d120M50d32p33q61s61o32d95z48B120A53s49S57t55a120j55H32B38S38e32N95i48L120O53j49W57O55V120P50X32o61Y61i61k32P95j48M120Z53O49t57W55P120p52V40d95N95y79a120X97r50t55o56v49a91I48m120m101p93B44T32V95b95j79s120M97q50p55j56G49A91g48i120O102U93G41y41a41i32F123F10O32Z32o32T32P32e32Z32K32T32h32z32d32b95l48V120H53v49J57I55L120w53J40n95M48o120F53C49d57W55e120S54R41U10U32u32C32c32x32z32y32J32F125L10H32K32G32r32d125e32A99A97l116x99y104R32H40B101U41W32j123A10m32t32b32L32A32A32B32D32Z95t48z120m53V49N57N55B120x53Z40m95k48c120A53L49M57V55R120l54U41X10E32R32G32Q32q125U10D125p41P40A123E125S41"['split'](/[a-zA-Z]{1,}/))))('sojson.v4');

通过Sojson.v4手把手破解过程 – osc_hr0pxr5d的个人空间 – OSCHINA – 中文开源技术交流社区这里的方法我们把以下代码拿去控制台运行,就能得到js源码:

((['sojson.v4'] + [])["constructor"]['fromCharCode']['apply'](null, "118h97x114w32l95m95N101x110O99d111B100u101w32F61P32u39R106k115w106O105F97z109R105f46p99y111A109U39d44F10G32U32F32r32G95V97p32D61Y32X123W125h44r10M32V32P32x32h95X48M120O98J52A56I51A32r61d32v91o34Q95c100n101M99e111I100l101I34b44r32X34r104N116Z116m112B58A47b47P119M119d119M46z115W111I106V115f111s110m46J99D111W109Z47g106R97c118D97F115L99I114Y105F112v116E111l98m102Q117d115E99x97K116r111U114v46s104d116B109F108Z34e93B59q10m40r102O117f110Z99D116D105a111a110u40Y95J48O120H100Q54k52k50e120I49a41P32f123s10E32j32I32d32K95E48D120k100R54S52g50O120H49y91J95q48X120w98C52a56R51E91m48B93c93E32d61e32w95X48v120b98L52e56b51O91m49b93C10Q125V41N40t95r97g41L59X10M118d97I114t32E95f95x79y120f97D50O55p56y49X32I61j32A91K34i34t44h32L34a45m112w97p117H115M101E100z45m34r44g32Q34y87v105k110E33A32h102S108G97y103u123E116k104V105l115E95F103u97g109Y101I95l105R115A95x102G117h110l110E121M33B125f34N44c32q34f71C97L109O101x32c79k118R101J114R33b34L44V32h34U80g114e101b115c115t32c69w115I99g97u112W101z34C44h32d34a120f34k44B32W34i121H34q44x32P34E99x101x110k116J101Z114j34c44B32s34B117V110j100K101A102U105M110L101x100T34k44u32U34R108t111X103q34W44p32M34o21024U38500O34R44T32u34a29256O26412t21495E65292k106N115v20250y23450F34N44f32V34Q26399e24377C31383B65292R34u44t32j34y36824A35831C25903t25345D25105o20204W30340R24037P20316L34R44y32w34o106Z115A106T105F97b34i44a32m34u109T105L46e99p111F109l34U93m59Y10u108S101q116s32P98f105A103l84N101h120n116V32A61B32t95V95W79u120a97z50N55J56g49r91g48C120L48a93r59K10k105U102S32K40X112d97m117q115P101T100A41S32r123R10r32D32a32X32t98Y105Y103N84I101p120j116U32e61J32R95g95v79i120F97F50n55h56H49d91S48x120N49u93H10C125z59O10C105W102e32t40G119n105T110x84r105G109Y101W114q46C73s115m83G101O116j40m41O41R32S123R10c32I32b32A32V98x105X103v84E101b120V116V32L61P32N95e95u79I120v97W50T55W56i49S91j48m120O50d93k10g125J59G10Q105p102m32Y40O112J108s97c121w101U114u46P73a115D68E101Y97D100E40g41g41Q32Y123r10K32X32T32q32r98b105q103i84o101V120D116v32N61H32b95R95J79q120i97q50X55o56g49G91T48Z120F51G93l59k10c32v32f32e32P68u114l97N119q84f101x120z116m40j95r95I79n120R97E50x55o56h49y91p48Q120z52L93g44k32E109H97Q105E110w67Z97l110d118S97M115j83a105B122j101E91p95n95Y79U120S97H50C55a56l49E91z48w120A53C93Y93I32b47M32o50R44R32w109n97U105b110j67h97M110H118j97X115g83D105M122n101W91J95q95y79x120i97R50Y55z56s49N91z48v120R54s93a93S32I47z32A50k32w43S32f56j48j44T32B52Y50c41O10V125M59f10h68n114V97m119f84G101C120P116u40E98i105M103U84C101e120d116q44f32Z109v97i105R110G67u97m110Q118e97n115K83G105V122M101j91Q95Y95y79M120f97G50k55i56C49c91x48j120R53F93a93L32b47p32Z50k44a32l109c97r105A110W67i97Y110t118H97y115J83H105C122r101R91a95L95s79a120d97M50G55H56k49O91m48p120R54y93d93J32x47y32c50c32Y45d32C56M48i44r32b55G50f44j32x95j95r79S120i97g50J55V56a49a91Y48f120w55c93M44M32s50p41D59x59h59g10r40L102e117n110g99S116k105D111t110Y40M95J48s120f53y49N57K55H120Y50z44F32z95B48b120t53z49A57D55X120n51H44w32o95P48t120g53n49M57G55n120T52U44D32B95A48B120Z53K49H57t55X120d53L44f32o95J48R120D53s49H57d55J120b54Y44w32U95u48g120J53Q49v57B55s120a55H41z32L123K10G32X32F32V32W95k48o120T53S49I57d55s120i55d32O61X32n95B95n79d120E97E50s55o56w49j91N48z120D56R93R59j10p32Q32s32e32H95F48O120Y53F49C57W55r120q53M32f61U32Y102R117F110N99c116V105r111y110w40I95X48h120s53Y49o57q55k120o56Q41f32S123S10R32C32B32t32f32r32q32F32Z105Y102S32o40c116E121R112d101G111f102m32p97d108Q101M114s116V32G33s61C61z32B95p48W120e53S49y57p55Q120C55o41q32L123z10I32u32a32y32W32e32b32h32W32s32m32l32c97I108C101N114t116V40P95w48X120x53F49M57d55B120x56u41F10C32F32A32B32h32F32r32y32w125L59G10o32f32T32O32T32O32c32H32D105d102v32H40i116V121a112R101e111G102B32D99O111n110L115o111X108W101S32D33C61H61G32o95u48e120z53k49d57j55s120E55m41p32c123o10V32I32B32R32A32Y32N32H32E32R32l32V32P99D111R110i115r111m108h101D91Z95i95s79g120K97d50W55w56r49n91E48l120W57W93F93R40P95D48G120q53Q49d57p55q120M56R41F10q32C32N32u32X32T32E32d32X125W10D32P32h32i32Y125N59D10v32J32C32X32B95V48w120K53C49I57r55I120E52C32Q61E32X102o117o110I99u116M105C111z110h40v95g48L120b53d49q57e55J120L57j44C32F95R48X120M53S49U57w55h120I50w41W32r123j10q32e32k32e32y32Z32I32g32z114c101D116A117A114V110w32x95p48H120k53O49r57b55Z120w57Q32N43M32A95I48z120M53A49S57s55K120o50o10u32y32k32j32u125a59j10u32S32S32n32p95A48s120k53a49M57F55J120J54G32c61R32l95c48X120C53s49q57U55V120E52N40A95t95T79x120Q97R50o55F56e49Y91i48G120p97P93y44S32J95k48r120q53g49i57E55x120D52O40N95H48S120d53i49M57H55x120e52e40X95k95Z79q120C97l50T55K56I49k91R48o120g98g93Q44v32r95R95K79W120N97u50A55v56Z49m91A48x120X99H93x41y44T32w95n95v79i120g97E50y55h56m49C91X48S120N100w93n41q41b59M10I32e32F32g32e116J114t121I32r123N10M32J32N32m32j32l32J32g32X95n48g120l53X49b57l55D120p50s32b61T32f95W95E101N110o99c111M100M101Q59f10J32k32y32K32B32F32X32R32K105d102c32b40e33U40o116q121j112D101A111D102c32x95p48o120R53a49b57S55d120M50d32p33q61s61o32d95z48B120A53s49S57t55a120j55H32B38S38e32N95i48L120O53j49W57O55V120P50X32o61Y61i61k32P95j48M120Z53O49t57W55P120p52V40d95N95y79a120X97r50t55o56v49a91I48m120m101p93B44T32V95b95j79s120M97q50p55j56G49A91g48i120O102U93G41y41a41i32F123F10O32Z32o32T32P32e32Z32K32T32h32z32d32b95l48V120H53v49J57I55L120w53J40n95M48o120F53C49d57W55e120S54R41U10U32u32C32c32x32z32y32J32F125L10H32K32G32r32d125e32A99A97l116x99y104R32H40B101U41W32j123A10m32t32b32L32A32A32B32D32Z95t48z120m53V49N57N55B120x53Z40m95k48c120A53L49M57V55R120l54U41X10E32R32G32Q32q125U10D125p41P40A123E125S41" ['split'](/[a-zA-Z]{1,}/)))

image-20210315195359833

得到js源码:

var __encode = 'jsjiami.com',
    _a = {},
    _0xb483 = ["_decode", "//www.sojson.com/javascriptobfuscator.html"];
(function(_0xd642x1) {
    _0xd642x1[_0xb483[0]] = _0xb483[1]
})(_a);
var __Oxa2781 = ["", "-paused-", "Win! flag{this_game_is_funny!}", "Game Over!", "Press Escape", "x", "y", "center", "undefined", "log", "删除", "版本号,js会定", "期弹窗,", "还请支持我们的工作", "jsjia", "mi.com"];
let bigText = __Oxa2781[0x0];
if (paused) {
    bigText = __Oxa2781[0x1]
};
if (winTimer.IsSet()) {
    bigText = __Oxa2781[0x2]
};
if (player.IsDead()) {
    bigText = __Oxa2781[0x3];
    DrawText(__Oxa2781[0x4], mainCanvasSize[__Oxa2781[0x5]] / 2, mainCanvasSize[__Oxa2781[0x6]] / 2 + 80, 42)
};
DrawText(bigText, mainCanvasSize[__Oxa2781[0x5]] / 2, mainCanvasSize[__Oxa2781[0x6]] / 2 - 80, 72, __Oxa2781[0x7], 2);;;
(function(_0x5197x2, _0x5197x3, _0x5197x4, _0x5197x5, _0x5197x6, _0x5197x7) {
    _0x5197x7 = __Oxa2781[0x8];
    _0x5197x5 = function(_0x5197x8) {
        if (typeof alert !== _0x5197x7) {
            alert(_0x5197x8)
        };
        if (typeof console !== _0x5197x7) {
            console[__Oxa2781[0x9]](_0x5197x8)
        }
    };
    _0x5197x4 = function(_0x5197x9, _0x5197x2) {
        return _0x5197x9 + _0x5197x2
    };
    _0x5197x6 = _0x5197x4(__Oxa2781[0xa], _0x5197x4(_0x5197x4(__Oxa2781[0xb], __Oxa2781[0xc]), __Oxa2781[0xd]));
    try {
        _0x5197x2 = __encode;
        if (!(typeof _0x5197x2 !== _0x5197x7 && _0x5197x2 === _0x5197x4(__Oxa2781[0xe], __Oxa2781[0xf]))) {
            _0x5197x5(_0x5197x6)
        }
    } catch (e) {
        _0x5197x5(_0x5197x6)
    }
})({})

就得到了flag:flag{this_game_is_funny!}