[NISACTF 2022]babyupload 详解

试图传文件,但是失败了,有过滤于是查看了下源代码,发现了一个/source
然后输入对应地址,下载下来了源代码
from flask import Flask, request, redirect, g, send_from_directory import sqlite3 import os import uuid app = Flask(__name__) SCHEMA = """CREATE TABLE files ( id text primary key, path text ); """ def db(): g_db = getattr(g, '_database', None) if g_db is None: g_db = g._database = sqlite3.connect("database.db") return g_db @app.before_first_request def setup(): os.remove("database.db") cur = db().cursor() cur.executescript(SCHEMA) @app.route('/') def hello_world(): return """<!DOCTYPE html> <html> <body> <form action="/upload" method="post" enctype="multipart/form-data"> Select image to upload: <input type="file" name="file"> <input type="submit" value="Upload File" name="submit"> </form> <!-- /source --> </body> </html>""" @app.route('/source') def source(): return send_from_directory(directory="/var/www/html/", path="www.zip", as_attachment=True) @app.route('/upload', methods=['POST']) def upload(): if 'file' not in request.files: return redirect('/') file = request.files['file'] if "." in file.filename: return "Bad filename!", 403 conn = db() cur = conn.cursor() uid = uuid.uuid4().hex try: cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,)) except sqlite3.IntegrityError: return "Duplicate file" conn.commit() file.save('uploads/' + file.filename) return redirect('/file/' + uid) @app.route('/file/<id>') def file(id): conn = db() cur = conn.cursor() cur.execute("select path from files where id=?", (id,)) res = cur.fetchone() if res is None: return "File not found", 404 # print(res[0]) with open(os.path.join("uploads/", res[0]), "r") as f: return f.read() if __name__ == '__main__': app.run(host='0.0.0.0', port=80)
进行代码审计
@app.route('/upload', methods=['POST']) def upload(): if 'file' not in request.files: return redirect('/') file = request.files['file'] if "." in file.filename: return "Bad filename!", 403 conn = db() cur = conn.cursor() uid = uuid.uuid4().hex try: cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,)) except sqlite3.IntegrityError: return "Duplicate file" conn.commit() file.save('uploads/' + file.filename) return redirect('/file/' + uid)
上述代码首先一个个分析,
首先是POST方式传递文件,然后是过滤的地方
if "." in file.filename: return "Bad filename!", 403
这段代码过滤了带文件名中带 . 的文件。
然后接下来是后面
try: cur.execute("insert into files (id, path) values (?, ?)", (uid, file.filename,)) except sqlite3.IntegrityError: return "Duplicate file"
上面这个代码是进行一个sql语句,表示增加一个数据,数据为uid和文件名。
因此我们只需要传输一个文件名为/flag的文件就可以得到flag的uid。然后再访问对应路径就可以得到flag
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!