requests

requests 是 Python 生态中最为广泛使用的 HTTP 客户端库。在网络安全自动化场景(如资产探测、目录爆破、漏洞 PoC 编写)中,它以高度封装的 API 提供了极其便捷的网络交互能力。

一、 基础通信机制 (HTTP Methods)

在编写自动化脚本时,最常用的通信方式为 GET 与 POST 请求。

  • GET 请求 (信息获取/探测): 常用于 URL 参数传递与页面抓取。
1
2
3
4
5
import requests

url = "http://target.com/api"
params = {"id": "1' OR '1'='1"} # 常用于测试 SQL 注入等
response = requests.get(url, params=params)
  • POST 请求 (数据提交/交互): 常用于表单提交、JSON 载荷发送或文件上传漏洞测试。

    1
    2
    3
    4
    5
    6
    data = {"username": "admin", "password": "password123"}
    # 表单类型 (application/x-www-form-urlencoded)
    response = requests.post(url, data=data)

    # JSON 类型 (application/json)
    response = requests.post(url, json=data)

二、 核心响应对象解析 (Response Object)

处理目标服务器返回的数据是爬虫与扫描器的关键步骤。以下是必须掌握的响应属性:

属性/方法 返回类型 实战应用场景
r.status_code int 状态码校验:判断页面是否存在 (200, 404) 或是否存在权限控制 (401, 403)。
r.text str 文本解析:提取 HTML 源码,用于正则匹配或 BeautifulSoup 解析提取敏感信息。
r.content bytes 二进制流获取:下载验证码图片、可执行文件或处理非 UTF-8 编码的特殊页面。
r.headers dict 指纹识别:读取 ServerX-Powered-By 字段,识别目标 Web 容器及版本。
r.json() dict API 交互:快速反序列化 RESTful API 返回的 JSON 格式数据。

三、 进阶配置 (针对反爬与安全规避机制)

在实际的网络攻防中,目标系统通常部署了 WAF (Web 应用防火墙) 或反爬策略。熟练运用以下参数是绕过基础防护的前提:

  • 1. 伪造请求头 (Headers Spoofing):

    默认情况下,requests 的 User-Agent 是 python-requests/x.x.x,这会被大多数安全设备直接拦截。必须进行伪装。

1
2
3
4
5
6
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": "https://google.com",
"X-Forwarded-For": "127.0.0.1" # 尝试伪造来源 IP
}
r = requests.get(url, headers=headers)
  • 2. 代理池接入 (Proxy Routing):

    为防止单 IP 探测频率过高被封禁,需结合代理池使用。

1
2
3
4
5
proxies = {
"http": "http://user:pass@10.10.1.10:3128",
"https": "http://10.10.1.10:1080",
}
r = requests.get(url, proxies=proxies)
  • 3. 忽略 SSL 证书校验 (SSL Verification):

    在测试自签名证书的内网系统或被中间人代理抓包时,常会遇到 SSL 错误。

1
2
3
4
import urllib3
urllib3.disable_warnings() # 禁用烦人的 InsecureRequestWarning 警告

r = requests.get("https://internal-target.local", verify=False)
  • 4. 超时控制 (Timeout Control):

    扫描海量资产时,避免因目标主机不响应而导致脚本无限期挂起(线程阻塞)。

1
2
# 设置连接超时为 3 秒,读取超时为 5 秒
r = requests.get(url, timeout=(3, 5))

四、 会话维持 (requests.Session)

在需要身份认证的测试场景(如后台漏洞利用)中,使用 Session 对象可以自动处理和跨请求保持 Cookies,无需每次手动提取和附加。

1
2
3
4
5
6
7
8
session = requests.Session()

# 1. 登录获取凭证
login_data = {"user": "admin", "pass": "admin"}
session.post("http://target.com/login", data=login_data)

# 2. 访问需要登录的敏感接口 (此时会自动携带登录成功后的 Cookie)
secret_page = session.get("http://target.com/admin_dashboard")

BeautifulSoup

BeautifulSoup(简称 BS4)是一个能够从 HTML 或 XML 文件中提取数据的 Python 库。它通过转换文档树,为复杂的 DOM 结构提供了简单、Pythonic 的导航、搜索和修改接口。

一、 核心解析器选择与初始化

在网络攻防和自动化扫描中,目标网页的结构往往并不规范(存在标签缺失、闭合错误等)。选择合适的解析器至关重要:

解析器 语法 优势 劣势 推荐场景
html.parser BeautifulSoup(html, "html.parser") Python 内置,无需额外安装。 容错能力一般,速度适中。 轻量级脚本,环境受限时使用。
lxml BeautifulSoup(html, "lxml") 速度极快,容错能力极强。 需要安装 C 语言依赖库 (pip install lxml)。 安全扫描、大规模爬虫的首选。

标准初始化代码:

1
2
3
4
5
6
from bs4 import BeautifulSoup
import requests

html_doc = requests.get("http://target.com").text
# 推荐使用 lxml 解析器以应对不规范的网页代码
soup = BeautifulSoup(html_doc, 'lxml')

二、 核心搜索与定位方法 (DOM 遍历)

在自动化脚本中,最常用的操作是从海量源码中精准提取特定标签。

  • 1. find()find_all() (基于标签与属性的提取):

    • find(): 返回匹配到的第一个元素,常用于定位唯一的登录表单或特定的标题。

    • find_all(): 返回包含所有匹配元素的列表,常用于遍历所有链接或图片。

1
2
3
4
5
6
7
8
# 查找页面中所有的 <a> 标签 (超链接)
links = soup.find_all('a')

# 查找特定 class 或 id 的特定元素 (例如查找登录表单)
login_form = soup.find('form', id='login-form')

# 组合查找:查找含有特定类名的所有 div
target_divs = soup.find_all('div', class_='vulnerable-class')
  • 2. CSS 选择器 select() (更灵活的定位方式):

    支持类似 jQuery 的 CSS 选择器语法,在处理层级极深的复杂页面时比 find_all 更简洁。

    Python

    1
    2
    3
    4
    5
    # 提取 id 为 "content" 的 div 下面的所有 a 标签
    urls = soup.select('#content a')

    # 提取带有特定 name 属性的 input 标签
    inputs = soup.select('input[name="username"]')

三、 网络攻防实战场景应用

在编写安全工具时,BS4 的应用场景通常非常明确。以下是三个高频实战代码模板:

场景 1:提取页面所有链接 (用于爬虫目录遍历与攻击面扩展)

我们需要提取 <a> 标签的 href 属性,以收集目标站点的路由信息。

1
2
3
4
5
6
7
8
9
def extract_all_links(html_content):
soup = BeautifulSoup(html_content, 'lxml')
links = []
for a_tag in soup.find_all('a', href=True):
href = a_tag['href']
# 过滤掉 javascript:void(0) 或邮件链接
if href.startswith('http') or href.startswith('/'):
links.append(href)
return set(links) # 使用 set 去重

场景 2:获取表单隐藏字段 (自动化利用、绕过 Anti-CSRF Token)

在编写漏洞利用 PoC 时,经常需要先 GET 请求页面,提取隐藏的 token,再带入 POST 请求中。

1
2
3
4
5
6
7
8
def extract_csrf_token(html_content):
soup = BeautifulSoup(html_content, 'lxml')
# 定位 type="hidden" 且 name="csrf_token" 的 input 标签
token_input = soup.find('input', attrs={'type': 'hidden', 'name': 'csrf_token'})

if token_input:
return token_input.get('value') # 提取 value 属性的值
return None

场景 3:提取 HTML 注释 (敏感信息泄露探测)

开发人员常在前端代码中留下包含内部 IP、测试账号或接口逻辑的注释。

1
2
3
4
5
6
7
8
9
10
11
from bs4 import Comment

def find_sensitive_comments(html_content):
soup = BeautifulSoup(html_content, 'lxml')
# 提取所有注释节点
comments = soup.find_all(string=lambda text: isinstance(text, Comment))

for comment in comments:
# 简单过滤,查找可能包含敏感词的注释
if any(keyword in comment.lower() for keyword in ['admin', 'password', 'test', 'TODO']):
print(f"[!] 发现潜在敏感注释: {comment.strip()}")