Tomcat-Upgrade

0x01 Previous Review

上篇的Executor内存马是在EndPoint下的,实际上Processor中也能找到内存马的植入点

image-20230204104009226

Processor负责处理字节流生成Tomcat Request 对象,将Tomcat Request对象传递给 Adapter。其实就是处理HTTP请求的,对应的类为AbstractProcessorLight

0x02 Analysis

NioEndpoint#doRun处理网络Socket连接,调用AbstractProtocol$ConnectionHandler#process

image-20230204194027659

跟进看到,创建了一个Http11ProcessorAbstractProcessorLight子类),并调用其process方法,跟进去看看

image-20230204194544213
image-20230204195124117

status为OPEN_READ,调用service方法

image-20230204195506315

若请求的Connection头字段有Upgrade标志,且存在Upgrade头,首先通过AbstractProtocol#getUpgradeProtocol获取UpgradeProtocol对象,再调用其accept方法(利用点便在此)

image-20230204195807803

拿到Upgrade头字段后,通过httpUpgradeProtocols.get(upgradeName)获取UpgradeProtocol

image-20230204200625102

所以接下来的关注点就在httpUpgradeProtocols

全局搜索httpUpgradeProtocols,发现AbstractHttp11Protocol#configureUpgradeProtocol往其添加UpgradeProtocol

image-20230204201141244

搜索发现AbstractHttp11Protocol#init中调用了configureUpgradeProtocol

image-20230204201511121

说明httpUpgradeProtocols是在Tomcat启动时被实例化的。

在当前上下文找到AbstractHttp11Protocol(上下文环境中会是Http11NioProtocol),通过反射往httpUpgradeProtocols加入我们自定义的UpgradeProtocol就行,UpgradeProtocolaccept方法加入恶意代码。

0x03 POC

构造恶意UpgradeProtocol

Http11Processorprocess方法中会检测ConnectionUpgrade的头部字段,根据Upgrade头部字段获取UpgradeProtocol,调用其accept方法,参数是org.apache.coyote.Request,刚好能通过反射获取到response对象。

反射修改httpUpgradeProtocols

访问时需带上下面头字段:

Upgrade: p4d0rn

Connection: Upgrade

cmd: calc

完整POC:

image-20230204213657337

参考:

一种新的Tomcat内存马 - Upgrade内存马 - 跳跳糖 (tttang.com)

初探Upgrade内存马(内存马系列篇六) - FreeBuf网络安全行业门户

Last updated

Was this helpful?