最近在学习Java内存shell相关知识,总结沉淀几篇文章,权当学习笔记了。
Java内存webshell史
直接引用c0ny1师傅的总结,写的太好了
1 | 其实内存马由来已久,早在17年n1nty师傅的《Tomcat源码调试笔记-看不见的shell》中已初见端倪,但一直不温不火。后经过rebeyong师傅使用agent技术加持后,拓展了内存马的使用场景,然终停留在奇技淫巧上。在各类hw洗礼之后,文件shell明显气数已尽。内存马以救命稻草的身份重回大众视野。特别是今年在shiro的回显研究之后,引发了无数安全研究员对内存webshell的研究,其中涌现出了LandGrey师傅构造的Spring controller内存马。至此内存马开枝散叶发展出了三大类型: |
D盾、安全狗,以及各云厂商对于webshell识别技术愈发成熟,webshell生存空间一直被压缩,内存shell或许可以提供新的攻防方向。
n1nty师傅的jsp内存shell
n1nty师傅2017年的文章,见参考【1】,摘取其中重点逻辑代码
1 | <% |
其中n1nty师傅是以jsp文件方式给出,jsp运行过程中会被编译成class,然后最终交由servlet处理
这个payload为servlet内存马的filter型的实现,下面解释其原理
Servlet 必备知识
Demo Code
1 | import javax.servlet.*; |
Filter
Filter是过滤器,正常是在web.xml,详情可以参考【4】中的过滤器一节,总结几个要点
Servlet Filter过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。
配置中指定 /* ,可适用所有servlet
web.xml 中的 filter-mapping 元素的顺序决定了 Web 容器应用过滤器到 Servlet 的顺序。若要反转过滤器的顺序,您只需要在 web.xml 文件中反转 filter-mapping 元素即可。
问题:除了静态配置web.xml,如何动态创建Filter?
调用链
正常的一个Servlet调用链
1 | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) |
Servlet内存shell
Filter型
恶意Filter
以下Filter针对每个请求,如果参数带cmd,则bash -c执行其参数
1 | Filter filter = new Filter() { |
加载Filter
n1nty师傅代码已经给出了加载Filter的方法:
1 | // 组装 fiter 为FilterMap |
但是又是如何定位到的呢?
** step1: 官方ServletContext自带的addFilter 接口 **
类org.apache.catalina.core.ApplicationContextFacade#addFilter接口
调用org.apache.catalina.core.ApplicationContext#addFilter接口
但是不行,存在限制,容器启动之后无法调用
** step2 手动实现addFilter接口 **
调试最终定位到
org.apache.catalina.core.ApplicationFilterFactory#createFilterChain
排序Filter
threedr3am师傅有在参考【6】中提及,tomcat回显时涉及到Filter排序的问题
internalDoFilter默认会执行所有的Filter,然后再进入doGet/doPost流程
Shiro是自定义的Filter,所以不能通过通过这种方式取到response回显。
(shiro的大概逻辑明白了,有空调试下)
前文有提到web.xml中Filter的排序执行问题,对于只是tomcat内存shell的话,几乎无影响
threedr3am师傅的TomcatShell有默认把evil Filter放在首位
Servlet型
待补充
小结
思考问题
n1nty师傅还提到 “动态插入 Valve” 的方式,如何实现?
php作为最火的语言,可以实现无文件webshell吗?
如上,python框架,flask/django,uwsgi呢?