【hxpCTF 2022】required - WP
本帖最后由 sixxx1 于 2023-3-15 16:55 编辑比赛时间是2023年3月11-13日,不过这次hxpCTF写的是2022。
0x01 题目说明
Description:
I have written a super safe flag encryptor. I’m sure nobody can figure out what my original flag was:
0xd19ee193b461fd8d1452e7659acb1f47dc3ed445c8eb4ff191b1abfa7969
Dockerfile for your convenience / to ensure correct environment.
题目附件
Download:
(https://2022.ctf.link/assets/files/required-27edfc0c02c5f748.tar.xz)
0x02 解题思路
题目是利用大量的 require 函数对大量 js 文件进行包含引入模块,从而将 flag 数组做加密,类似于一种代码混淆。
每一个js文件最终生效的是后面对 f 数组的操作,前面只是一些模块导出语法。
(PS:nodejs可以用chrome调试,在命令行中用 node inspect app.js,在chrome中访问 chrome://inspect,然后打开DevTools就可以调试了。)
flag长度有30位,所以i、j、t一直在做取余30的计算。
因为是动态解析js文件再做包含,其中还包括了一些复杂的模块导出和引入、清除 require 缓存的操作,如果直接解析 js 语法提取所有对 flag 数组的操作,有点绕了弯路。。一开始在这里卡了很久。
后来想到,何不直接改了所有js文件,再其中插入console.log,让模块被加载的同时也把操作语句给输出。
import os
path = './files'
outpath = './out'
files = os.listdir(path)
s = []
for file in files:
str = ""
if not os.path.isdir(file) and file.endswith(".js") and file != "required.js":
f = open(path + "/" + file, "r")
str = f.read()
f.close()
# 原文件内容:
# module.exports=(i,j,t)=>(i%=30,j%=30,t%=30,i+=[],j+"",t=(t+{}).split("["),f+=f,f&=0xff)
# 修改成:
# module.exports=(i,j,t)=>(i%=30,j%=30,t%=30,i+=[],j+"",t=(t+{}).split("["),console.log("f[" + j + "]+=f[" + i + "],f[" + j + "]&=0xff"),f+=f,f&=0xff)
if 'i%=30' in str:
oper = re.findall(r'f\[.*?$', str)[:-1]
oper = oper.replace('i', '\" + i + \"').replace('j', '\" + j + \"').replace('t', '\" + t + \"')
patch = "split(\"[\"),console.log(\"" + oper + "\"),"
str = str.replace("split(\"[\"),", patch)
f = open(path + "/" + file, "w")
f.write(str)
f.close()
print ("[+] Open And Write: " + file)
print ("[+] " + str)
再次运行 required.js,获得 flag 数组的所有操作
全部整理如下(一共300行,这里只放了前面几行):
f+=f,f&=0xff
f=~f&0xff
f^=f
f=f<<7&0xff|f>>1
f=~f&0xff
f=f<<7&0xff|f>>1
f=f^(f>>1)
f=f^(f>>1)
f^=f
f^=f
f=f^(f>>1)
f=f<<1&0xff|f>>7
f=~f&0xff
f=~f&0xff
f+=f,f&=0xff
f+=f,f&=0xff
f=~f&0xff
f-=f,f&=0xff
f-=f,f&=0xff
f-=f,f&=0xff
f=f<<1&0xff|f>>7
f=f^(f>>1)
f-=f,f&=0xff
f^=f
f^=f
f=f<<7&0xff|f>>1
f^=f
f-=f,f&=0xff
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f^=f
f=f<<7&0xff|f>>1
f-=f,f&=0xff
f=~f&0xff
f-=f,f&=0xff
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f-=f,f&=0xff
f-=f,f&=0xff
f=~f&0xff
// ......
接下来就是所有语句倒序,并做逆运算。
替换+去重,只有以下这些算法,需要获得所有逆运算方式。
A=~A&0xff
A-=B,A&=0xff
A+=B,A&=0xff
A=A^(A>>1)
A^=B
A=(((A*0x0802&0x22110)|(A*0x8020&0x88440))*0x10101>>>16)&0xff
A=A<<1&0xff|A>>7
A=A<<7&0xff|A>>1
逆运算整理:
// 1、原句不动可逆向
f=~f&0xff
f=~f&0xff
// 2/3、+ 和 - 互换即可
f+=f,f&=0xff
f-=f,f&=0xff
// 4、不知道怎么逆向ing,卡在这里
f=f^(f>>1)
// 5、直接可逆
f^=f
f^=f
// 6、直接可逆
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
// 7、按下面改,1和7互换
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
// 8、按下面改,7和1互换
f=f<<7&0xff|f>>1
f=f<<1&0xff|f>>7
后来其实在第4个加密这里卡了很久,查了很多资料没找到逆向方法。既然逆不出来,那就直接爆破大招吧,用for来替换:
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
0x03 EXP
getflag.js:
f =
f=~f&0xff
f+=f,f&=0xff
f-=f,f&=0xff
f+=f,f&=0xff
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f-=f,f&=0xff
f-=f,f&=0xff
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f+=f,f&=0xff
f^=f
f-=f,f&=0xff
f+=f,f&=0xff
f^=f
f^=f
f=~f&0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=~f&0xff
f+=f,f&=0xff
f-=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f+=f,f&=0xff
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f-=f,f&=0xff
f^=f
f=~f&0xff
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f=f<<7&0xff|f>>1
f^=f
f=f<<1&0xff|f>>7
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f+=f,f&=0xff
f=~f&0xff
f-=f,f&=0xff
f^=f
f=~f&0xff
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f+=f,f&=0xff
f+=f,f&=0xff
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<1&0xff|f>>7
f-=f,f&=0xff
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f=f<<1&0xff|f>>7
f-=f,f&=0xff
f-=f,f&=0xff
f-=f,f&=0xff
f=f<<7&0xff|f>>1
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f^=f
f+=f,f&=0xff
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f-=f,f&=0xff
f+=f,f&=0xff
f+=f,f&=0xff
f=~f&0xff
f=f<<7&0xff|f>>1
f^=f
f=~f&0xff
f+=f,f&=0xff
f=f<<1&0xff|f>>7
f-=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<7&0xff|f>>1
f^=f
f^=f
f+=f,f&=0xff
f^=f
f^=f
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f^=f
f+=f,f&=0xff
f^=f
f^=f
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f^=f
f-=f,f&=0xff
f+=f,f&=0xff
f-=f,f&=0xff
f+=f,f&=0xff
f^=f
f=f<<7&0xff|f>>1
f=f<<7&0xff|f>>1
f=f<<7&0xff|f>>1
f=f<<7&0xff|f>>1
f-=f,f&=0xff
f+=f,f&=0xff
f^=f
f^=f
f=f<<1&0xff|f>>7
f+=f,f&=0xff
f-=f,f&=0xff
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=~f&0xff
f^=f
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f+=f,f&=0xff
f=f<<1&0xff|f>>7
f=f<<1&0xff|f>>7
f-=f,f&=0xff
f^=f
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f^=f
f^=f
f^=f
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f-=f,f&=0xff
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f=~f&0xff
f^=f
f=f<<7&0xff|f>>1
f-=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<1&0xff|f>>7
f=~f&0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f=~f&0xff
f^=f
f-=f,f&=0xff
f=f<<1&0xff|f>>7
f=~f&0xff
f-=f,f&=0xff
f^=f
f+=f,f&=0xff
f^=f
f+=f,f&=0xff
f=f<<1&0xff|f>>7
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f+=f,f&=0xff
f^=f
f^=f
f-=f,f&=0xff
f=f<<1&0xff|f>>7
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f+=f,f&=0xff
f=f<<7&0xff|f>>1
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f=f<<7&0xff|f>>1
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f^=f
f=f<<7&0xff|f>>1
f=f<<1&0xff|f>>7
f=~f&0xff
f^=f
f^=f
f^=f
f^=f
f=f<<1&0xff|f>>7
f^=f
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f=~f&0xff
f^=f
f^=f
f-=f,f&=0xff
f-=f,f&=0xff
f^=f
f+=f,f&=0xff
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f=(((f*0x0802&0x22110)|(f*0x8020&0x88440))*0x10101>>>16)&0xff
f+=f,f&=0xff
f^=f
f+=f,f&=0xff
f+=f,f&=0xff
f^=f
f-=f,f&=0xff
f+=f,f&=0xff
f+=f,f&=0xff
f-=f,f&=0xff
f=~f&0xff
f=f<<1&0xff|f>>7
f-=f,f&=0xff
f=f<<1&0xff|f>>7
f=f<<1&0xff|f>>7
f+=f,f&=0xff
f=f<<1&0xff|f>>7
f^=f
f=f<<1&0xff|f>>7
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f+=f,f&=0xff
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f-=f,f&=0xff
f^=f
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f=~f&0xff
f+=f,f&=0xff
f+=f,f&=0xff
f^=f
f-=f,f&=0xff
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=~f&0xff
f=f<<1&0xff|f>>7
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f^=f
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f-=f,f&=0xff
f=~f&0xff
f+=f,f&=0xff
f-=f,f&=0xff
f+=f,f&=0xff
f+=f,f&=0xff
f-=f,f&=0xff
f-=f,f&=0xff
f=f<<7&0xff|f>>1
f=f<<1&0xff|f>>7
f^=f
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f-=f,f&=0xff
f-=f,f&=0xff
f+=f,f&=0xff
f^=f
f=~f&0xff
f=f<<1&0xff|f>>7
f=f<<1&0xff|f>>7
f=f<<1&0xff|f>>7
f+=f,f&=0xff
f+=f,f&=0xff
f-=f,f&=0xff
f^=f
f-=f,f&=0xff
f=f<<7&0xff|f>>1
f-=f,f&=0xff
f-=f,f&=0xff
f=~f&0xff
f+=f,f&=0xff
f+=f,f&=0xff
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f=~f&0xff
f+=f,f&=0xff
f=f<<1&0xff|f>>7
f^=f
f=f<<1&0xff|f>>7
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f^=f
f=f<<1&0xff|f>>7
f^=f
f^=f
f+=f,f&=0xff
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<7&0xff|f>>1
f+=f,f&=0xff
f+=f,f&=0xff
f+=f,f&=0xff
f=~f&0xff
f-=f,f&=0xff
f-=f,f&=0xff
f=~f&0xff
f=~f&0xff
f=f<<7&0xff|f>>1
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f^=f
f^=f
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
// f=f^(f>>1)
for (var i = 0; i <= 255; i++) {
if ((i^(i>>1)) == f) {
f = i
break
}
}
f=f<<1&0xff|f>>7
f=~f&0xff
f=f<<1&0xff|f>>7
f^=f
f=~f&0xff
f-=f,f&=0xff
console.log("f = " + f)
out = ''
for (let i of f) {
out += String.fromCharCode(i)
}
console.log(out)
hxp{Cann0t_f1nd_m0dule_'fl4g'}
0x04 题目下载
chayan插言插言 liwei518 发表于 2023-3-15 18:51
chayan插言插言
duoxie 谢谢你的分享哈 感谢分享 66666666666666666666666666666666 感想分享,奇怪的知识增加了 感谢楼主分享,顶一个! good,我是做不出来这题 感谢分享,支持一下!
页:
[1]