逻辑错误漏洞是指由于程序逻辑不严谨、逻辑太复杂,导致一些逻辑分支不能够正常处理或处理错误。通俗地讲:一个系统的功能大多后,程序开发人员就难以思考全面,对某些地方可能有遗漏,或者未能正确处理,从而导致逻辑漏洞。逻辑漏洞也可以说是程序开发人员的思路错误、程序开发人员的逻辑存在漏洞。
逻辑漏洞是非常隐蔽的,它不像SQL注入、XSS跨站脚本、命令执行漏洞有鲜明的标识,自动化扫描器可以定义一系列的规则识别出这些漏洞,而逻辑漏洞一般出现在功能(业务流程)上,这是漏洞扫描工具无法识别的。逻辑漏洞的危害也是巨大的,根据不同的场景所产生的效果也不同,比如,任意密码修改、越权访问、密码找回、交易支付金额修改等。
在十大漏洞中,逻辑漏洞被称为“不安全的对象引用,和功能级访问控制缺失”。
http://www.secbug.org提供了用户修改资料的功能,当回URL: http://www.secbug.org/userinfo.action?id=2时,将会显示自己的信息,并且可以编辑,UserInfo.java源代码如下:
public String execute (){ int id - this.user.getUserId(); this.user = new UserProxy.findUserById(id); return sUCCESS; }
这段代码并没有对ID做任何验证,直接接收用户的ID,然后根据ID来查询用户信息。
当提交URL为:http:/www.secbug.org/userinfo.action?id=3时,程序就会按部就班地执行,返回ID为3的User 信息到页面中,这就是水平越权。
总的来说,水平越权就是相同级别(权限)的用户或者同一角色的不同用户之间,可以越权访问、修改或者删除的非法操作。如果出现此类漏洞,那么将可能会造成大批量数据泄露,严重的甚至会造成用户信息被恶意篡改。
低权限用户访问到了高权限用户,比如普通用户可以执行管理员才可以执行的操作。
由于后台应用没有做权限控制,或仅仅在菜单,按钮上做了权限控制,导致了恶意用户只要猜测其他管理页面的URL或者敏感的参数信息,就可以访问或者控制其他角色拥有的数据或页面,达到提权的目的
水平越权和垂直越权的定义不一样,但漏洞的原理都是一样的,都是账户体系上在判断权限时不严格导致存在绕过漏洞,这一类的绕过通常发生在cookie验证不严,简单判断用户提交的参数,归根截底,都是因为这些参数实在客户端提交,服务端未严格校验
1.通过隐藏URL实现控制访问有些程序的管理员的管理页面只有管理员才显示,普通用户看不到,利用URL实现访问控制,但URL泄露或被恶意攻击者猜到后,这会导致越权攻击
2.直接对象引用这种通过修改参数就可以产生水平越权,例如查看用户信息页面URL后加上自己的id便可查看,当修改为他人的id号时会返回他人的信息,便产生了水平越权
3.多阶段功能多阶段功能是一个功能有多个阶段的实现,例如:修改密码,可能第一步是验证用户身份信息,号码验证码类的,当验证成功后,跳到第二部,输入新的密码,很多程序会在这一步不在验证用户身份,导致恶意用户抓包直接修改密码
4.静态文件很多网站的下载功能,一些被下载的静态文件,例如pdf、word、xls等,可能只有付费用户或者会员才可以下载,但当这些文件的URL地址泄露后,导致任何人可下载,如果知道URL命名规则,则可利用服务器的收费文档进行批量下载
5.平台配置错误一些程序通过控件来限制用户访问,例如后台地址,普通用户不属于管理员组,则不能访问。但当配置平台或配置控件错误时,就会出现越权访问。
1.前后端同时对用户输入信息进行校验,双重验证机制
2.执行关键操作前必须验证用户身份,验证用户是否具备操作数据的权限
3.特别敏感操作可以让用户再次输入密码或其他的验证信息
4.可以从用户的加密认证cookie中获取当前用户的id防止攻击者对其修改,或在session、cookie中加入不可预测、不可猜解的user信息
5.直接对象引用的加密资源ID,防止攻击者枚举ID敏感数据特殊化处理
6.永远不要相信来自用户的输入,对于可控参数进行严格的检查与过滤
如果后台没有对旧密码进行验证,就直接让输入新密码
1.第一种,如果存在csrf漏洞我们就可以直接修改一波
2.如果存在越权漏洞就可以直接修改其他人的密码
3.点击修改后抓包测试,观察数据包有没有验证类似cookie随机数,如果没有的话可以尝试修改用户名,手机号或者uid来尝试重置其他密码
4.如果后台是通过向注册手机或者注册邮箱来重置密码的,关于验证码的漏洞我们都可以尝试,这种方式的前提是你已经通过某种方式进入到了对方的个人中心所以意义不大。
一般情况下当我们点击找回密码的时候都是通过验证手机号或者邮箱,这就又变成了验证码的问题:
1.验证码发送后前端返回
2.验证码时效导致验证码爆破
3.验证码有规律可控
4.验证码被放回在返回包中
5.输入验证码后通过修改响应包的状态来重置密码
6.验证码为空(原理就是后台未考虑验证码为空的情况,直接就是如果存在,然后下面仅判断了存在的情况)绕过过或使用万能密码
7.拦截数据包,发送验证码时可以向多个手机号发送验证码,这个时候就可以添加个云短信,直接接受验证码完成修改
输入用户名/邮箱/手机阶段
交互过程;即输入要重置账户信息点击确定时,大部分应用都用会直接从数据库中读取用户邮箱和手机信息,并且发送验证码,还有部分程序在输入用户名后,会提示使用手机还是邮箱找回密码。在提交的时候可以直接抓包修改手机或者邮箱参数,这是如果后端没有做验证,原本发送给账户A的验证码就会发送到被我们篡改的手机或者邮箱上,利用接收到的验证码即可重置密码。
填写验证码和新密码阶段填写验证码和新密码就意味着我们已经拿到了验证码或者重置密码的URL这里存在的问题有:
1.验证凭证较简单,可以暴力破解
2.验证凭证算法简单,凭证可预测
3.验证凭证直接保存在源码里
验证凭证较简单,可以暴力破解目前大多数手机短信重置密码的验证码比较简单4位或6位数字如果提交验证码的地方没有对这个验证码进行错误次数限制,则会存在可以爆破的问题,这是 目前比较常见的一种密码找回方式
验证凭证算法简单,凭证可预测部分网站找回密码的Token是根据当前用户的 “用户名”+“邮箱”或者时间戳进行一次MD5后生成,这就存在一定的预测性,利用自己写的算法去碰撞即可拿到重置密码凭证
验证凭证直接保存在源码里目前这种比较少,不过也存在一定比例,一种是在点击发送验证码的时候就可以直接在源码里看到给当前手机或者邮箱发送过去的验证码,还有一种就是在输入验证码的时候源码里面就直接保存了正确的验证码
发送新密码阶段凭证未绑定用户:我们在找回密码的时候发送到邮箱的链接通常是如下这个样子
http:///www.xxx.com//user.php?m=repwd&uid=用户ID&key=凭证密钥&email=邮箱
当请求这个链接的时候,后端程序根据uid和key对应上了从而判断这个找回密码的链接是否有效,但是在将新密码提交到服务器的时候,服务端并没有判断当前这个key是否跟uid或者email匹配,而是直接修改掉了uid或者email指定的用户密码这样我们只要拦截修改密码的请求包,将里面用户参数修改成我们要篡改密码的用户账户即可。
1.接受验证码的邮箱和手机号不可由用户控制,应该直接从数据库中读取出来
2.加强验证凭证复杂度,防止暴力破解
3.限制验证凭证错误次数,单个用户在半个小时内验证码错误三次,禁止一段时间
4.验证码凭证设置失效时间
5.验证凭证不要保存在页面
6.输入用户邮箱或ID,手机号取验证凭证的地方需要设置验证码防止短信炸弹和批量找回等
7.验证凭证跟用户名、用户ID、用户邮箱绑定、找回密码是验证当前凭证是否是当前用户的
在支付订单时,可以篡改价格为任意金额;或者可以篡改运费或其它费用为负数,导致总金额降低。