【wp】2021V&NCTF

今天打完的V&NCTF公开赛,做题的时候没记过程,现在来复现一下。

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

比赛地址:https://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这一步就会报错

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#! /usr/bin/env python 3.7 (3394)
#coding=utf-8
# Compiled at: 1969-12-31 18:00:00
#Powered by BugScaner
#http://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就算没学到面向对象也能靠猜。

主要关注这个:

1
2
3
4
5
6
7
8
9
def か(self):
き = 0
while True:
く = self.な[き][0]
け = self.な[き][1]
こ = self.な[き][2]
さ = self.お(く)
さ(け, こ)
き += 1

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 输出
@い.え(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系统门户网站):

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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:

前六位吻合,拿到flag!

flag:vnctf{e3a912c1e911ad82544af0c3d753f44f}

FilpGame

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

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

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

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

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

随便画了个图方便理解:

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

也就是说这种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]及其上下左右)。

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

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

1
2
3
4
5
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()

得到

然后把poj的解题脚本改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#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;
}

得到:

然后写exp组织成input:

1
2
3
4
5
6
7
8
9
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

成功过check:

flag是md5,所以输出一下md5

1
2
3
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主函数:

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

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

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

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

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

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

写exp尝试一下:

1
2
3
4
5
6
7
8
9
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)

诶,都是可见字符,试图交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

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

1
['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');

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

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

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

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

得到js源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var __encode = 'jsjiami.com',
_a = {},
_0xb483 = ["_decode", "http://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!}

本文作者: c10udlnk
本文链接: https://c10udlnk.top/p/wpFor-2021VNCTF/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 c10udlnk' Blog (https://c10udlnk.top)!