渗透测试-19:业务逻辑漏洞


业务逻辑漏洞

  • 逻辑漏洞就是指攻击者利用业务/功能上的设计缺陷,获取敏感信息或破坏业务的完整性,一般出现在密码修改、越权访问、密码找回、交易支付金额等功能处
  • 逻辑漏洞的破坏方式并非是向程序添加破坏内容,而是利用逻辑处理不严密、代码问题或固有不足,操作上并不影响程序运行,在逻辑上是顺利执行的
  • 这种漏洞一般的防护手段或设备无法阻止,因为走的都是合法流量,也没有防护标准

支付漏洞

  • 在支付订单时,可以篡改价格为任意金额;或者可以篡改运费或数量为负数,导致总金额降低
  • 这个漏洞的关键在于服务器没有验证这些数字是否小于0、价格没有从服务器端获取、数量是否大于0等
  • 曾经有不少体量不小的电子商务网站都出现过支付漏洞,最终导致的结果是不花钱或者花很少的钱买更多的东西,还真的有不少人测试漏洞之后真的收到了东西,这种天上掉馅饼的漏洞太有诱惑力了

利用方式

支付漏洞,是一种简单的逻辑漏洞,支付漏洞的主要利用方式:

  • 修改支付价格
  • 修改商品编号为负值或为高价商品的编号
  • 修改支付状态
  • 修改订单数量
  • 修改附属值(比如优惠券),选择优惠券后修改金额大于等于商品的价格
  • 越权支付,用别人的钱包购买自己的东西

修复方式

  1. 后端检查每一项值,包括支付状态
  2. 校验价格、数量参数,比如产品数量只能为正整数,并限制购买数量
  3. 与第三方支付平台检查,实际支付的金额是否与订单金额一致
  4. 支付参数进行 MD5 加密、解密、数字签名及验证,这个可以有效的避免数据修改、重放攻击中的各种问题
  5. 金额超过阈值,进行人工审核

越权访问

  • 可以通过越权漏洞访问他人信息或者操纵他人账号

  • 其中越权访问又分为水平越权和垂直越权两种

    • 水平越权:相同级别(权限)的用户或者同一角色中不同的用户之间,可以越权访问、修改或者删除其他用户信息的非法操作。如果出现此漏洞,可能会造成大批量数据的泄露,严重的甚至会造成用户信息被恶意篡改
    • 垂直越权:就是不同级别之间的用户或不同角色之间用户的越权,比如普通用户可以执行管理员才能执行的功
  • 水平越权和垂直越权的定义不一样,但漏洞原理是一样的,都是账户体系上在判断权限时不严格导致存在绕过漏洞,这一类的绕过通常发生在cookie验证不严、简单判断用户提交的参数,归根结底,都是因为这些参数是在客户端提交,服务端未严格校验

  • 举例:当前A用户查看自己详细订单的URL为/1.php?ordered=111,当用户手动提交/1.php?ordered=112时,则可以看到订单为112的别人的订单情况

利用方式

  • 修改url中出现的用户名或用户ID

  • 拥有管理员级别的操作数据包的情况下,可以使用用户级别的cookie在数据包中进行替换,实现与管理员同级别的操作

  • 修改普通用户的cookie信息,将身份直接转换为管理员

密码找回

密码找回是出现逻辑漏洞问题较多的一个功能,因为它的交互流程最多,目前找回密码的方式比较常见的有邮箱验证码、手机验证码以及密保问题,流程如下:

  1. 输入用户名/邮箱/手机阶段
  • 交互过程:即输入要重置的账号信息,点击确定时,大部分应用会直接从数据库中读取用户邮箱和手机信息,并且发送验证码,还有部分程序在输入用户名后,会提示使用手机还是邮箱找回密码
  • 在提交的时候可以直接抓包修改手机或者邮箱参数,这时如果后端没有做验证,原本发送给账号A的验证码就会发送到被我们篡改的手机或者邮箱上,利用接收到的验证码即可重置密码
  1. 填写验证码和新密码阶段
    填写验证码和新密码就意味着我们已经拿到了验证码或者重置密码的URL,这里存在的主要问题有:

    1. 验证凭证较简单,可以暴力破解

      目前大多数手机短信重置密码的验证码都是4位或者6位数字,如果提交验证码的地方没有对这个验证码进行错误次数限制,则会存在可以爆破的问题,这是目前最常见的一种找回密码漏洞利用方式

    2. 验证凭证算法简单,凭证可预测

      部分网站找回密码的Token是根据当前用户的“用户名+邮箱”或者时间戳进行一次MD5后生成,这就存在一定的预测性,利用自己写的算法去碰撞即可拿到争取到的重置密码凭证

    3. 验证凭证直接保存在源码里

      目前这种比较少,不过也存在一定比例,一种是在点击发送验证码的时候就可以直接在源码里看到给当前用手机或者邮箱发送过去的验证码,还有一种是在输入验证码的时候,源码里面就直接保存了正确的验证码

  2. 发送新密码阶段
    凭证未绑定用户:我们在找回密码的时候,发送到邮箱的链接通常是如下这个样子:http://www.xxx.com/user.php?m=repwd&uid=用户ID&key=凭证密钥&email=邮箱 当请求这个链接的时候,后端程序根据uid和key对应上了从而判断这个找回密码的链接是否有效,但是在将新密码提交到服务器的时候,服务器端并没有判断当前这个key是否跟uid或者email匹配,而是直接修改掉了uid或者email指定的用户密码,这样我们只要拦截修改密码的请求包,将里面的用户参数修改成我们要篡改密码的用户账号即可

修复建议

  • 接收验证码的邮箱和手机号不可由用户控制,应该直接从数据库中读取出来
  • 加强验证凭证复杂度,防止被暴力破解
  • 限制验证凭证错误次数,单个用户在半个小时内验证码错误三次,半小时内禁止找回密码
  • 验证凭证设置失效时间
  • 验证凭证不要保存在页面
  • 输入用户邮箱或ID、手机号取验证凭证的地方需要设置验证码防止短信炸弹和批量找回等
  • 验证凭证跟用户名、用户ID、用户邮箱绑定,找回密码时验证当前凭证是否是当前用户的

投票/积分/抽奖

  • 投票和抽奖以及积分在很多促销活动或者推广手段上都经常用到,背后的奖品成本可能上数十万,如果这些奖品被恶意用户刷走了,不仅推广的效果没有,而且浪费了成本投入
  • 不管是投票、积分还是抽奖,都存在一个公共点:即单个用户次数存在限制,比如一场活动中一个用户只能抽奖一次,这样的限制也会存在很多绕过方式

补天上一个真实漏洞案例:

  • 做完任务后有两次抽奖机会,抽完后删除cookie shared_t42014和logind_t42014,刷新页面后即可再次做任务并抽奖
  • 案例中程序是基于cookie验证,所以删除相应cookie即可绕过限制

利用方式

  1. Cookie和POST请求正文绕过
    有的应用将验证是否抽奖或者领取积分的判断值放置在cookie或者POST的请求正文里,服务器端获取到这个结果后判断是否还有机会抽奖,而这个数据我们是可以直接在数据包中修改的,所以就会产生绕过,比如cookie中isok=1代表已经抽奖,isok=0代表还没有抽奖,而我们只要再点击抽奖,然后把isok的值改为0即可一直抽奖。

  2. 基于IP验证
    做的比较弱的统计是直接基于IP验证,像访问量、推广获取积分等,这类要看程序获取IP的方式,如果是client_ip或者x_forword_for获取IP,则可以直接伪造IP绕过

  3. 基于用户认证
    也有一部分应用需要登陆以后才能抽奖或者投票,这类可以结合看看能不能批量注册,如果可以,则可以用程序实现批量登陆刷票,或者投票的时候POST包或者cookie里面的当前uid\用户名等是否可以随意修改绕过用户单次限制

防御方式

从上面利用手段可以看到主要的三个点是IP、登录用户和cookie、分析出可用性较高的防御手段如下:

  • 机器识别码验证,每台机器都可以根据硬件信息生成唯一的识别码
  • 操作需要登陆,当前用户信息从session中读取

敏感信息泄露

由于后台人员的疏忽或者不当的设计,导致不应该被前端用户看到的数据被轻易的访问到,如:

  • 通过访问url下的目录,可以直接列出目录下的文件列表
  • 输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版本或其他信息
  • 前端的源码(html,css,js)里面包含了敏感信息,比如后台登录地址、内网接口信息、甚至账号密码等