前言
提示:工具准备:
python3.*+Fiddler+sqlmap+mysql(可选)
实现效果: 浏览器操作系统Fiddler将自动抓包接口数据存入.txt文件>运行python sqlmap 程序 >自动化sql注入扫描>将扫描结果写入mysql>导出测试报告
一、配置Fiddler自定义规则脚本
打开fiddler
找到方法 【static function OnBeforeRequest(oSession: Session)】
在此方法最后添加
try {
//过滤无关请求,只关注特定请求
if (oSession.fullUrl.Contains("www.baidu.com")) {
var fso;
var file;
var method = oSession.oRequest.headers.HTTPMethod;
if (method=='GET' || method=='POST'){
fso = new ActiveXObject("Scripting.FileSystemObject");
//文件保存路径,可自定义
//var fieName= String(oSession.url).Replace("/","-");
file = fso.OpenTextFile("D://api//" +"www.baidu.com" + ".txt",8 ,true, true);
file.writeLine("--start--" + "\n");
file.writeLine("url: " + oSession.url);
file.writeLine("method: " + method);
file.writeLine("header:" + "\n" + oSession.oRequest.headers);
//if (method=='POST'){
file.writeLine("RequestBody: " + oSession.GetRequestBodyAsString());
file.writeLine("\n");
file.writeLine("--end--" + "\n")
file.close();
}
}
}
catch(err){
var err;
}
}
二、 安装sqlmap,并且打开sqlmapapi后台服务
注:sqlmap 运行要求python2.7版本,安装教程略。
运行步骤
1进入sqlmap安装目录
2运行 python2 sqlmapapi.py -s
3运行成功后会开启端口:127.0.0.1:8775
4开启nginx 外网端口转发至8775(如果是本地运行不需要此操作)
三、进行浏览器抓包
启动Fiddle
在Fiddle脚本里配置过滤的域名 , 操作浏览器Fiddle会将接口数据包存储txt文件中。
四、运行python 程序
需要配置:
mysql连接
抓包数据txt路径
sqlmapapi服务地址
import datetime
import time
import re
import pymysql
import requests
import json
from tenacity import *
class SqlMapExtension:
def __init__(self, server_host):
self.server_host = server_host
self.task_id = None
self.engine_id = None
@retry(stop=stop_after_delay(1) | stop_after_delay(5))
def create_task(self):
url = self.server_host + "/task/new"
result = requests.get(url).json()
self.task_id = result["taskid"]
return self.task_id
@retry(stop=stop_after_delay(1) | stop_after_delay(5))
def get_task_status(self):
url = self.server_host + f"/scan/{self.task_id}/status"
result = requests.get(url).json()
return result["status"]
@retry(stop=stop_after_delay(1) | stop_after_delay(5))
def task_start(self, parameter, ):
server_url = self.server_host + f"/scan/{self.task_id}/start"
print("正在扫描" + server_url)
headers = {'Content-Type': 'application/json;charset=utf-8'}
body = json.dumps(parameter)
print(body)
result = requests.post(server_url, data=body, headers=headers).json()
if result["success"]:
print(result)
return True
def get_task_log(self):
pass
@retry(stop=stop_after_delay(1) | stop_after_delay(5))
def get_scan_result(self):
url = self.server_host + f"/scan/{self.task_id}/data"
result = requests.get(url).json()
return result
def delete_task(self):
pass
def get_option_list(self):
url = self.server_host + f"/option/{self.task_id}/list"
pass
@retry(stop=stop_after_delay(5) | stop_after_delay(5)) #失败重连
class MsqlLink(object):
def __init__(self, ):
# print(data,level)
# 打开数据库连接
self.db = pymysql.connect(host='127.0.0.1', user='abc', port=3306,
password='abc123.', database="test_01",
charset='utf8mb4')
def insert_data(self, sql):
try:
insert = self.db.cursor()
msg = insert.execute(sql)
print("执行insert结果:", msg, sql)
self.db.commit()
return True
except BaseException as er:
print("执行错误 0:", sql, er)
def close_sql(self):
self.db.close()
print("mysql连接已经关闭")
def handle_sql(self, sql_list):
# try:
sql = f"INSERT INTO sqlmap_test (url,method,result,parameters,status,date_time) VALUES (%s,%s, %s,%s,%s, %s)"
insert = self.db.cursor()
aa = tuple(sql_list)
print("正在写入mysql" + str(aa))
insert.execute(sql, aa)
self.db.commit()
return True
# except Exception as e:
# return e
def read_api_file(file_dir):
with open(file_dir, mode="r", encoding="utf-16") as f:
data = {}
url = ''
method = ''
api_list = []
# for line in f:
# if line.replace("\n", '') == "--start--":
for i in f.readlines():
# print(i[0:7])
if i[0:4] == 'url:':
data["url"] = i[5:-1]
if i[0:7] == 'method:':
method = (i[7:-1]).replace(" ", "")
if method == "GET":
data["method"] = "GET"
# api_list.append([url, "GET"])
if method == "POST":
data["method"] = "POST"
# api_list.append([url, "POST"])
# print(i[0:11])
if i[0:12] == 'RequestBody:':
data["data"] = i[12:-1].replace(" ", "")
api_list.append(data)
data = {}
get_tmp = []
for i in api_list:
if i not in get_tmp:
get_tmp.append(i)
return get_tmp
if __name__ == '__main__':
#这里配置sqlmapapi的地址+端口
SqlMap = SqlMapExtension(server_host="http://127.0.0.1:8110")
#这里配置抓包的数据包文件
api_list = read_api_file(file_dir=r'D://api//www.baidu.com.txt')
test_result = "通过"
status = 1
for g in api_list:
if len(g["data"]) >= 1500:
g["data"] = ''
#data 这里可以阅读sqlmap文档进行参数指定
data = {"url": "http://" + g["url"],
"data": g["data"],
"level": 1, #扫描测试等级 默认1
"dbms ": "mysql", #指定数据库 选填
"headers": "Token:XXX"} #自定义请求头 选填
task_id = SqlMap.create_task()
SqlMap.task_start(parameter=data)
print("正在获取扫描结果。。。。")
while True:
time.sleep(1)
if SqlMap.get_task_status() == 'terminated':
data = SqlMap.get_scan_result()
if len(data["data"]) == 0:
print("测试结果-正常:" + str(data))
test_result = "通过"
status = 1
break
else:
print("测试结果-异常!!:" + str(data))
test_result = json.dumps(json.dumps(data))
print(test_result)
status = 0
break
system_time = datetime.datetime.now()
url = g["url"]
method = g["method"]
parameters = g["data"]
sql_list = [url, method, test_result, parameters, status, str(system_time)]
sql_ink = MsqlLink()
sql_ink.handle_sql(sql_list)
sql_ink.close_sql()
运行
附 mysql表脚本
CREATE TABLE `sqlmap_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '接口地址',
`method` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '请求方式',
`parameters` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '请求参数',
`result` varchar(15000) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '测试结果',
`date_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`status` int(1) NOT NULL DEFAULT 0 COMMENT '1 正常 0异常',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1563 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
五 生成测试报告
打开数据库导出表格
六 总结
以上都能在本地运行。
程序写的比较草率还有很多优化的地方。
sqlmapapi说明可以参考: https://www.cnblogs.com/shengulong/p/6855098.html