逻辑漏洞实战

一、什么是逻辑漏洞?大白话解释

逻辑漏洞 = 程序员写代码时逻辑考虑不严谨,导致攻击者能钻空子

和SQL注入、XSS这些技术型漏洞不同,逻辑漏洞不是代码写错了,而是业务逻辑设计有缺陷

逻辑漏洞的危害:0元购事件

想象一下:

• 你在电商平台买东西,本来要付100元

• 但你抓包修改了价格参数,改成0.01元

• 系统没校验,直接让你用1分钱买到了商品

这就是真实的"0元购"事件,商家损失惨重!


二、越权漏洞:水平越权 vs 垂直越权

概念区分

类型 解释 举例
水平越权 同级别用户之间互相访问 张三登录后,能看到李四的个人信息
垂直越权 低权限用户获得高权限 普通用户登录后,能执行管理员操作

三、水平越权实战(Pikachu靶场)

靶场搭建

1. 下载 Pikachu 靶场

2. 放到 phpStudy 的 WWW 目录下

3. 修改 inc/config.inc.php 配置数据库

4. 访问 http://localhost/pikachu/install.php 初始化

5. 访问 http://localhost/pikachu/ 进入靶场

漏洞复现

靶场地址

复制代码
http://localhost/pikachu/vul/overpermission/op1/op1_login.php

第一步:正常登录

点击"提示"获取账号密码,用 test 账号登录。

登录后看到个人信息页面,URL 类似:

复制代码
http://127.0.0.1/pikachu/vul/overpermission/op1/op1_mem.php?username=test&submit=点击查看个人信息

第二步:水平越权

直接修改 URL 中的 username 参数:

复制代码
http://127.0.0.1/pikachu/vul/overpermission/op1/op1_mem.php?username=kobe&submit=点击查看个人信息

刷新后,页面显示的是 kobe 的个人信息!

漏洞原因 :服务器只检查了用户是否登录,没检查当前用户是否有权查看 username 对应的信息。


四、垂直越权实战(Pikachu靶场)

漏洞复现

靶场地址

复制代码
http://localhost/pikachu/vul/overpermission/op2/op2_login.php

目标:用普通用户账号,执行管理员操作(添加用户)

第一步:普通用户登录

test 账号登录,只能查看用户列表,没有添加用户的权限。

第二步:尝试直接访问管理员页面

访问:

复制代码
http://127.0.0.1/pikachu/vul/overpermission/op2/op2_admin.php

系统提示需要管理员登录。

第三步:找到管理员操作接口

通过目录扫描或源码分析,发现管理员添加用户的接口:

复制代码
http://127.0.0.1/pikachu/vul/overpermission/op2/op2_admin_edit.php

第四步:垂直越权成功

用普通用户登录状态,直接访问这个接口:

复制代码
http://127.0.0.1/pikachu/vul/overpermission/op2/op2_admin_edit.php

竟然可以添加用户!

漏洞原因分析

查看源码 op2_admin_edit.php

复制代码
<?php
// 只检查了是否登录,没检查是否是管理员!
if(isset($_SESSION['user'])) {
    // 执行添加用户操作
    // ...
}
?>

问题 :代码只判断了用户是否登录(isset($_SESSION['user'])),没判断用户是否是管理员角色!


五、业务逻辑漏洞:0元购/1元购

案例1:商品编号篡改

场景:购买商品A,但实际扣费的是商品B(更便宜的那个)

攻击方式

1. 选择一个便宜商品(比如1元的优惠券)

2. 抓包记录商品ID

3. 选择一个贵商品(比如5000元的手机)

4. 抓包修改商品ID为便宜商品的ID

5. 用1元的价格买到了5000元的手机

案例2:金额数据篡改

场景:直接修改支付金额

攻击方式

复制代码
POST /pay HTTP/1.1
...
product_id=123&price=5000&quantity=1

用 Burp Suite 抓包,修改 price 参数:

复制代码
POST /pay HTTP/1.1
...
product_id=123&price=1&quantity=1

如果后端没校验价格是否匹配商品,就能用1元买5000元的商品!

案例3:数量篡改

场景:购买负数数量的商品

复制代码
POST /pay HTTP/1.1
...
product_id=123&price=100&quantity=-1

如果计算总价时没考虑负数:

复制代码
$total = $price * $quantity;  // 100 * (-1) = -100

可能导致账户余额反而增加了!


六、支付漏洞实战案例(大米CMS)

漏洞1:直接修改商品价格

参考案例:wooyun-2016-0226613

步骤

1. 选择一个5400元的手机,抓包:

复制代码
index.php?m=Member&a=gobuy&iscart=0&id=69&name=大米CMS手机开发专版&qty=1&price=5400&gtype=灰色

1. 再选择一个6000元的手机,抓包

1. 把5400元手机的请求数据包替换到6000元的请求

1. 6000元的手机变成5400元了!

漏洞2:修改支付状态

有些系统在支付成功后会设置一个状态字段:

复制代码
POST /pay HTTP/1.1
...
order_id=123&status=0

直接改成:

复制代码
POST /pay HTTP/1.1
...
order_id=123&status=1

系统可能直接把订单标记为"已支付"!


七、逻辑漏洞防御方法

1. 越权漏洞防御

防御措施 具体做法
权限校验 每个操作都要检查当前用户是否有权限
用户身份绑定 从Session获取当前用户ID,不从参数获取
角色验证 关键操作前验证用户角色是否匹配

安全代码示例

复制代码
<?php
// 不安全:从参数获取用户ID
$user_id = $_GET['user_id'];
$data = getUserData($user_id);

// 安全:从Session获取当前用户ID
$user_id = $_SESSION['user_id'];
$data = getUserData($user_id);

// 安全:操作前验证权限
if($_SESSION['role'] != 'admin') {
    die('权限不足!');
}
// 执行管理员操作
?>

2. 支付漏洞防御

防御措施 具体做法
服务端计算价格 不信任前端传的价格,根据商品ID从数据库查价格
价格签名验证 前端传价格时带签名,后端验证签名
数量校验 数量必须大于0且小于库存上限
支付状态校验 支付状态由支付回调接口设置,不信任用户输入

安全代码示例

复制代码
<?php
// 不安全:直接用前端传的价格
$price = $_POST['price'];
$total = $price * $_POST['quantity'];

// 安全:从数据库查价格
$product_id = $_POST['product_id'];
$price = getPriceFromDB($product_id);  // 从数据库获取真实价格
$quantity = intval($_POST['quantity']);

// 校验数量
if($quantity <= 0 || $quantity > $product['stock']) {
    die('数量不合法!');
}

$total = $price * $quantity;
?>

八、逻辑漏洞速查表

漏洞类型 漏洞原理 攻击方式 防御方法
水平越权 未校验数据归属 修改用户ID参数 从Session获取当前用户ID
垂直越权 未校验用户角色 直接访问高权限接口 操作前验证角色
0元购 未校验价格 修改价格参数 服务端查库计算价格
数量篡改 未校验数量范围 修改数量为负数 校验数量 > 0
支付状态篡改 未校验支付来源 修改支付状态 由回调接口设置状态

总结

逻辑漏洞的核心特点

1. 不是代码错误,是业务设计缺陷

2. 往往需要理解业务流程才能发现

3. 危害可能比技术漏洞更大(直接造成经济损失)

记住一句话:永远不要信任用户输入的任何数据,关键操作必须在服务端重新校验!