[NISACTF 2022]babyupload

php 复制代码
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    #生成uid
    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)

def upload() 要求上传的文件不能有后缀,且文件名前会拼接一个前缀upload/,使得输出的文件只能是在目录upload/下的,这里就涉及到os.path.join()的绝对路径拼接漏洞:

绝对路径拼接漏洞

os.path.join(path,*paths)函数用于将多个文件路径连接成一个组合的路径。第一个函数通常包含了基础路径,而之后的每个参数被当作组件拼接到基础路径之后。

然而,这个函数有一个少有人知的特性,如果拼接的某个路径以 / 开头,那么包括基础路径在内的所有前缀路径都将被删除,该路径将视为绝对路径。

php 复制代码
with open(os.path.join("uploads/", res[0]), "r") as f:
    return f.read() 

就是说传/flag,那么之前的upload/就会删除,就直接读取了根目录下的flag文件。抓包将文件名改为/flag。

直接访问得到的路径,获得flag:

相关推荐
Seven9713 分钟前
一文带你了解缓存和数据库一致性问题
redis·mysql
heath ceTide23 分钟前
第二章从事件驱动到信号
数据库·系统架构
StarRocks_labs34 分钟前
欧洲数字化养殖平台 Herdwatch 借力 Iceberg + StarRocks 提升分析能力
数据库·starrocks·iceberg·湖仓一体架构·herdwatch
TDengine (老段)1 小时前
TDengine IDMP 5 个实测场景让监控变简单
大数据·数据库·物联网·ai·时序数据库·tdengine·涛思数据
Xasxxs1 小时前
【网络安全】XSS漏洞——PortSwigger靶场-DOM破坏
javascript·安全·web安全·xss
秋难降1 小时前
零基础学习SQL(九)——存储引擎
前端·sql·mysql
叫我阿柒啊2 小时前
Java全栈开发面试实战:从基础到复杂场景的深度解析
java·数据库·spring boot·面试·vue·测试·全栈开发
岛屿旅人2 小时前
欧盟《人工智能法案》生效一年主要实施进展概览(二)
网络·人工智能·安全·web安全·架构
万邦科技Lafite2 小时前
京东API分类接口实战指南:获取各类商品信息
数据库·人工智能·api接口·开放api·电商开放平台
望获linux5 小时前
【Linux基础知识系列】第一百一十篇 - 使用Nmap进行网络安全扫描
java·linux·开发语言·前端·数据库·信息可视化·php