服务器端漏洞篇介绍
服务器端漏洞篇 – 商业逻辑漏洞专题
什么是商业逻辑漏洞?
商业逻辑漏洞,其实很好理解,梨子觉得burp的描述有点过于正经了,感觉有点咬文嚼字的意思,所以梨子就用自己的理解来讲一下什么是商业逻辑漏洞,应用程序的架构和代码都是由不同的工程师来负责的,由于出现了技术或者架构思维上的缺陷,应用程序在执行某个逻辑的时候会很容易被攻击者发现漏洞而进入了奇怪的逻辑,比如我们在讲身份验证专题的时候,我们可以利用代码逻辑上的漏洞绕过验证码阶段直接进入已经处于登录状态的用户,这就是一个简单的逻辑漏洞,还有影响更严重的,比如一些购物平台仅仅通过做加法来计算购物车金额,如果这时候把商品的价格修改成负数的就会导致不仅没有付钱反而还成功购买了商品,当然了,这种漏洞肯定早就修复了,不然现在这些购物平台遇上职业薅羊毛党,那还得了?接下来我们详细地讲解商业逻辑漏洞
商业逻辑漏洞是怎么产生的?
一般逻辑漏洞是由于开发团队对用户输入的预判不够完全,导致出现了各种意外,这时候就给了攻击者可乘之机,攻击者可以通过修改请求包触发某种意外导致一些意想不到的效果,尤其是越复杂的应用程序逻辑漏洞就越隐蔽,并且危害越大,这就需要架构和开发工程师对整个应用程序了如指掌,以免在架构逻辑或代码逻辑上有任何疏漏
商业逻辑漏洞的例子
对客户端控件的过度信任
有的应用程序仅通过前端代码对用户输入进行检测,这就导致攻击者完全可以先利用合规的数据通过前端的检测以后利用burp再修改输入的内容,这样的话风险就非常大了,这种检测根本形同虚设,所以最好是在后端检测,这样不管你怎么改,到了我后台就是你提交的最后版本了,下面我们来看一个例子
配套靶场:对客户端控件的过度信任
题目要求我们购买那个什么夹克,但是我们没有那么多钱,我们用burp抓一下包,发现了参数price,我们将其改成一块钱
然后放包,发现我们成功用一块钱就买了一件我们掏空钱包里的钱都买不起的夹克!
无法处理非常规输入
企业逻辑的作用是限制用户的输入在允许的范围内,但是毕竟所有的逻辑规则都需要开发团队提前预见用户的输入才能对症下药,肯定会存在开发团队没有预见的情况,这就又给了攻击者可乘之机,让不允许的输入也通过了提前设置的逻辑规则进入后端造成一些意想不到的意外,下面我们来看一段代码
$transferAmount = $_POST['amount'];
$currentBalance = $user->getBalance();
if ($transferAmount <= $currentBalance) {
// Complete the transfer
} else {
// Block the transfer: insufficient funds
}
上面代码是一段用来判断是否有足够余额来转账的逻辑规则,但是逻辑仅判断转账金额是否小于余额,但是并没有判断转正金额是否为正值,那么我们如果修改成负值会发生什么呢,对,会将功能从转账变成充值,余额没有因为转账而减少反而增加了,哇,这就说明逻辑漏洞是非常危险的,会为企业带来巨额的经济和名誉的损失,下面我们通过几个例子来深入讲解
配套靶场:高级别逻辑漏洞
像往常一样,我们拦截结算的包,发现只有一个参数可能存在逻辑漏洞,quantity
我们还是要买那件夹克,既然我们能修改数量的话,我们就想想改成负数会怎样呢
我们看到结算的时候真的就因为数量是负的而正负相抵,最后我们成功以极低的价格买到了夹克!
配套靶场:低级别逻辑缺陷
我们像上一题一样修改数量为负数发现已经不生效了,然后我们就尝试将数量调到最大,再利用Intruder的null payload模式无限发包,发现金额到了最大值以后会从负数最小值继续往大增加,就这样继续无限发包,直到我们看到购物车的结算金额到了我们能支付得起的时候停止发包,然后我们就再一次,而且买到了三万多件夹克!
配套靶场:异常处理不一致的输入
本来想注册一个administrator,但是提示用户已存在,但是没有忘记密码功能,所以这个思路不太行,既然是要访问管理员面板,那我们试一下/admin这个页面存不存在
这样我们就成功注册到了可以进入/admin页面的DontWannaCry用户
既然进入了/admin页面,我们就可以删除指定用户了
对用户行为做出错误的预判
导致这一类逻辑漏洞的原因就是开发团队过于相信用户,对用户的行为做出了错误的预判,比如违反常理的数值的情况就没有做出相应的处理方案,下面我们深入讲解一些典型的情况
受信任的用户不会永远可信
有的应用程序虽然设置了很多逻辑规则来规范用户的输入,但是毕竟人无完人,就总会有遗漏的点,但是应用系统往往会对通过逻辑规则的输入保持完全的信任,这就导致一些虽然通过了逻辑规则但是仍然会对应用程序造成不同程度破坏的输入进入应用程序
配套靶场:前后不一的安全控制
首先我们进入注册页面
发现我们可以不需要任何验证就进行修改,然后我们就可以访问/admin页面了
放包,发现可以不需要旧密码就能修改administrator的密码,我们就可以用新密码登录并且删除指定用户了
用户不可能总是循规蹈矩
这个就很好理解了,因为我们在身份验证专题讲过一种情况,用户在输入用户名密码以后账户其实已经处于登录状态了,这时候直接将URL改成用户主页就可以跳过验证码阶段,这就是不循规蹈矩的结果,不仅可以跳过某些步骤,还可以通过重放包的方式打乱请求的执行序列,也是可以导致一些意想不到的效果的,总之就是用非常人的思路就可能挖掘到逻辑漏洞
配套靶场:工作流程验证不足
我们先随便购买一个便宜的商品,发现比买不起的情况多出一个请求
然后我们再选中第5个请求包,点击”configure items”,然后将获取Gift-Card参数的方式修改成如下方式
等待一段时间后,余额终于满足要求了,终于可以买到梦寐以求的夹克了!
我们发现如果邮箱地址格式不合规的话会在页面中回显这么一句话,我们看一下请求包是什么样的
删除以后再按照原格式编码回去,在解密点看看能不能解密出来
发现会有报错,说密码密文分块必须是16的倍数,于是我们需要填充一些字节让其达到16的倍数,所以我们填充9个无用字符,然后因为是无用的,填充完以后再删除32字节就可以正常解密了
我们就成功地构造出不仅没有无用前缀而且还能成功解密的密文,于是我们将其替换到stay-logged-in参数值,并替换成新的session值,发现我们就可以进入administrator用户页面了
然后我们就能删除指定用户了
如何防止商业逻辑漏洞?
burp总结了两点防止此类漏洞的方法
- 确保开发和测试人员了解应用程序所属的领域
- 避免对用户行为或应用程序其他部分的行为做出默认信任
言外之意就是不要太相信用户输入,尽量做到严格的过滤,把能想到的情况都考虑到,所以需要开发和测试人员对业务非常地熟悉才能预想出大部分可能发生的情况,这里burp给出了一个实践指南
- 维护所有事务和工作流的清晰的设计文档和数据流,并注意在每个阶段所做的任何假设
- 尽可能清晰地编写代码
- 注意对使用每个组件的其他代码的任何引用
总结
主要介绍了逻辑漏洞的常见情况,主要就是因为开发和测试人员对业务不够熟悉,未能对所有可能发生的情况做出相应的处置方案并且默认完全信任通过逻辑规则的用户输入,所以说逻辑漏洞还是很危险的,尤其是越复杂的业务系统,逻辑漏洞的发现难度越大,其危害就越大,还是不容忽视的