作者简介:
肖志华,rNma0y,信安自学,白帽子。(在安全圈子里,一直以来有“黑帽”、“白帽”的说法。黑帽子是指那些造成破坏的黑客,而白帽子均已建设更安全的互联网为己任。)
漏洞盒子排名 TOP 前 100,撞过很多坑,跌撞复前行。研究方向 Web,反黑产。目前某不知名安全团队成员,专职攻防领域,涉及面较广,爱好一切新鲜事物。
Web 漏洞里有 SQL 注入、XSS 等漏洞,但是逻辑漏洞等问题也是一个大的关键点。
逻辑漏洞比传统安全漏洞更难发现,也可以理解为在相关的业务流程程序出了一个 BUG,当然开发者设计逻辑正常来走是没问题的,一旦用户不走寻常路,就导致了一些看似莫名其妙的漏洞存在。
俗话来讲就是,服务器大哥懵逼了,无法理解你的意思,按照开发者给他划定的业务流程来讲,你这个行为是错误了,引起了服务器大哥的暂时懵逼。
挖掘逻辑漏洞从来不走正常的业务流程,走正常业务流程发现不了什么安全漏洞,毕竟是按照指定的程序来走。要挖,就别走寻常路。
逻辑漏洞的阐述
逻辑漏洞呢,也分很多种。总的来说是产品业务上的设计缺陷,导致了某接口或者业务存在漏洞。从密码找回开始引入话题吧。
密码找回漏洞
一般密码找回这种业务流程在设计的时候,粗讲有五步。
-
输入账号
-
验证你的身份
-
获取重置密码的途径(邮件、密保问题)
-
验证成功
-
重置密码完成
按照这五步来走的话,漏洞通常会在 2~3 步骤里,下面来看一下常见的几种密码找回漏洞。
密码找回漏洞测试流程
-
先尝试正确的密码找回流程,记录不同找回方式的所有数据包
-
分析数据包,找到有效数据部分
-
推测数据构造方法
-
构造数据包验证猜测
挖掘逻辑漏洞的需要渗透测试人员不断的去修改请求参数来尝试触发漏洞,这种行为业内称之为 “Fuzz test” 模糊测试,重放数次请求来观察服务器返回响应,从而发现漏洞所在。
我也拿乌云的案例来讲密码找回的逻辑漏洞例程。
身份验证码暴力破解
案例之一:搜狐某站任意用户帐号重置密码缺陷
如何绕过加密传输抓包不表……点击忘记密码,链接:
https://passport.souyidai.com/password/findpassword
然后输入我们测试用的手机号,用户名就是手机号,然后点申请密码找回。
点击获取,然后输入 1111, 抓包递归尝试 9999,线程开到 10,加足马力!一两分钟的事,没有限制。
这是失败返回如上图。
这是正确返回:
{"data":" 成功 ","errorCode":0}
但是当我们输入对验证码,会被提示验证码错误,请重新获取。于是,思绪一转,可以在返回值,改成:
{"data":" 成功 ","errorCode":0}
这样就大功告成了!
结束了回想一下,完全可以不用暴力啊。只要有手机号,有多少我就重置多少,改参数就可以啦!
不知道算不算两个漏洞,哈哈。 这可是关乎钱的网站啊。
我的点评
这个案例说明了该找回密码业务流程中,验证码这块可以爆破,甚至可以导致撞库的危害,修复建议是验证码尽量不要用 4 位,用数字 + 字母组合或者六位验证码。最好是设定了有效期限。
返回身份凭证信息
案例之二:天天网任意账号密码重置(非暴力温柔修改)
首先我们先来看一下找回密码的流程。
1. 填好邮箱和验证码 下一步
返回了邮箱。
2. 填写正确的验证码 抓包看一看
可以看到返回了一串加密字符串这个很重要,等会再说。经过测试证明 cookie 中的 值对找回密码没有影响。
3. 重置密码
可以看到 URL 中的 一串加密字符串正是 第二步中 返回的那串字符串。因为证明 cookie 中的 值对找回密码没有影响 所以只要拿到这个加密字符串就可以 任意重置密码。
那么怎么得到这个字符串呢?
这个是第二步中抓到的包 把 cookie 中的 LoginOrRegOftiantianUser 值 改成要重置的账号。这里我拿 service@tiantian.com 测试。
可以看到成功返回了加密字符串既然拿到了字符串,下一步就是重置密码了。首先输入邮箱和验证码,点击下一步,这一步是必须要做的,要不然不会成功。
然后直接用,拿到的字符串,访问重置密码的页面。假如,上一步没有做的话,到这一步会直接 302 跳转。
重置成功。
OK 密码被重置为 wooyun123
漏洞存在原因:页面返回了过多的信息,token 是可控的状态,导致拼接地址即可完成密码找回业务流程。
我的点评
该漏洞存在的原因是,返回了过多的信息,导致 token 可控完成修改密码的工作流程。针对此类安全漏洞修复建议是 token 使用随机生成,攻击者无法猜解。
邮箱弱 token 安全漏洞
案例之三:360 任意用户密码修改(危急 360 手机卫士、360 云盘、360 浏览器云同步,可泄露通讯录、短信、通话记录等)
本小学生记性不好,360 账号的密码很及时的忘记了。 于是有了如下情节。找回账号密码, 然后发了一篇邮件到我邮箱。
http://i.360.cn/findpwd/setpwdfromemail?vc=e%2FwljiqD9WGv%2FwDyS93BghveGh%2FDYG4oMjJwcxGlcnSDZP3qIW4deYwnCpkdbCSZ3ByODXHZYDCx32A46l%2FBXxk6qo5oABIr6ZrywAoPB8DZuX81j%2Bb%2F2w%3D%3D&qid=507290669
这是修改密码的连接地址 有没有发现亮点?qid=507290669 qid 如果被修改别人的是否会有用呢?然后修改为:
http://i.360.cn/findpwd/setpwdfromemail?vc=e%2FwljiqD9WGv%2FwDyS93BghveGh%2FDYG4oMjJwcxGlcnSDZP3qIW4deYwnCpkdbCSZ3ByODXHZYDCx32A46l%2FBXxk6qo5oABIr6ZrywAoPB8DZuX81j%2Bb%2F2w%3D%3D&qid=507290670
然后 360 网站提示可以修改,哦的天啊。那这样的话不是所有的账号都可以改了 为什么会鸡肋呢?问题是不知道别人的账号啊,进去个人中心也没有这个 id 提示。
别着急,我们继续挖,发现 360 旗下的一个网站:
http://www.woxihuan.com/
http://www.woxihuan.com/star/timeline?qid=268296138
是不是发现了什么 ? 没错 qid=268296138。这个 qid 我们找的是明星苗圃的。
然后构造如下链接:
http://i.360.cn/findpwd/setpwdfromemail?vc=e%2FwljiqD9WGv%2FwDyS93BghveGh%2FDYG4oMjJwcxGlcnSDZP3qIW4deYwnCpkdbCSZ3ByODXHZYDCx32A46l%2FBXxk6qo5oABIr6ZrywAoPB8DZuX81j%2Bb%2F2w%3D%3D&qid=268296138
我们祭出神器 Burpsuite。在利用找回密码链接修改密码时我们截取它 post 的包:
而且这里还发现,我们在知道邮箱,不知道 qid 的情况下,也可以修改密码:首先用自己的账号获取一个 360 找回密码的 URL,然后在修改密码时截包。
我们把这里的 uname 修改为要修改密码的目标的邮箱:
目标邮箱:410316816@qq.com
可以修改指定邮箱的密码,修改完成。
我的点评
修改密码的链接上未对用户进行二次效验,修复方法是在参数里添加多个安全的验证参数来二次效验。
来分析一下以上案例中所存在的安全漏洞。
1. 邮箱找回密码的情况
网站收到了你的密码找回请求,会给你发一份邮件,里面包含了一个超链接,点击后就跳到修改密码的页面。
感谢您注册央视网! 请点击下面的链接完成注册,快乐畅游央视网和中国网络电视台! http://reg.cctv.com/regist/activationServlet.action?email=web@secus.org&code=579364fdb494ebfd12d0373e0afd26a5&userSeqId=57332762&from=http%3A%2F%2Freg.cctv.com&backurl=http%3A%2F%2Freg.cctv.com%2FforgetPassword%2FfindPassword.action 提示:如果链接无法点击,请将它复制到浏览器的地址栏中打开。 为确保帐号安全,链接 72 小时内有效,若链接失效,请点击这里
类似于以上的链接,这种需要分析一下 token 的构造了。
http://i.360.cn/findpwd/setpwdfromemail?vc=e%2FwljiqD9WGv%2FwDyS93BghveGh%2FDYG4oMjJwcxGlcnSDZP3qIW4deYwnCpkdbCSZ3ByODXHZYDCx32A46l%2FBXxk6qo5oABIr6ZrywAoPB8DZuX81j%2Bb%2F2w%3D%3D&qid=507290669
这里的这封邮件 qid=507290669 就可以看做是一个 ID 参数,构造了相应的链接时就可以重置任意用户的密码。
2. 手机短信找回
身份验证的方式是手机验证码,多 4 位和 6 位,可以采取爆破的方式,从 1-9999 进行列举也不会耗多少时间,有的验证码有效时间是为 30 分钟,足够让你随意枚举。
3. 找回密码逻辑缺陷
在找回密码的时候,用户 A 输入你自己的手机号码找回,收到了验证码不去使用:
然后用户 A 去使用用户 B 的手机号来找回密码
用户 A 在 B 的找回密码处填入刚刚自己收到的验证码
程序验证成功,修改了 B 的用户密码
4. 找回密码逻辑缺陷 2
这种找回密码的逻辑缺陷多存在于以下场景。找回密码验证身份的页面 uid=1 验证成功进行修改密码的页面的 uid=2。直接在找回密码的页面访问验证成功进行修改的页面进行修改。
5. 本地验证的找回密码逻辑缺陷
在找回密码的时候,开 Burp 抓包,抓返回包,返回包里可能有一个 flag 字段,此时返回包的数据是-1,猜测若 flag 的值为 1 则跳转到修改密码的页面,所以只要修改一下 flag 值即可验证身份成功,进行更改密码操作。
验证码在 HTTP 请求里返回。点击获得验证码,有些代码逻辑不严,会把验证码发送到 HTTP 请求里,直接开 burp 捕获验证码即可。
6. HTML 源码
有时候一些验证身份的情况下,他的密保问题答案会出现在 HTML 源码里,你只需要打开 F12 进行查看。
到此,密码找回流程的逻辑漏洞已经概括了大多数了。
越权访问
越权访问也比较容易理解。越权访问通俗点来讲,就是你作为一个普通用户能够访问管理员用户才能访问到的资源。
越权也分水平越权和垂直越权。水平越权,即是相同级别的用户或者同一角色的不同用户之间,可以越权访问修改或者删除等重要功能。
比如我是一个论坛的会员 A ID 号为 2, 而你也是这个论坛的会员 B ID 号为 3, 我点击个人资料的时候,可以访问你的个人资料页面。
例如,http://www.gitbook.cn 提供了用户修改资料的功能,当访问 http://www.gitbook.cn /userinfo.action?id=2时,将会显示自己的信息,并且可以编辑。
在这种情况下,用户 A 访问的时候就会把 ID=3 的用户信息页面显示出来,这就是水平越权。通过枚举 id=? 可以造成论坛大量用户数据泄露的情况。
垂直越权就是普通用户可以访问只有管理员才能访问到的资源,比如,后台网站模块更改等。
来看个例子。
淘宝举报编号任意遍历
http://archer.taobao.com/myservice/report/report_detail.htm?gmtCreate=2013-02-23&id=[任意举报编号]
淘宝的这个漏洞就属于水平越权漏洞。
未授权访问
未授权访问可可有看做就是越权哈,也有这种情况作为一个游客能去访问一个网站根目录下的文件,比如数据库备份文件,直接访问 URL 下载。
支付漏洞
实战:一元购买 iPhone X 支付逻辑漏洞分析
前几天对一个电商网站进行了安全测试,发现存在支付逻辑漏洞,现分享渗透测试思路。
在选购了 iPhone X 的付款页面我进行了抓包,显示结果如上图所示。
POST /Admin/JScript/Common.ashx HTTP/1.1 Host: www.baidu.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: */* Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Referer: http://www.baidu.com Content-Length: 444 Cookie: _hcid=201712081311270935; pgv_pvid=1968087748; _current82664=Gi62U0hbBx8NrSPS4YuxQk%2fUfdHYO%3d%3d; __qc_wId=618; __qc__k=; _sids82664=23671; CheckedId82664=Gi62U0hbBl2td7IvA%3d%3d; _hsid=201712121125440516; _huid=201712121125440573 Connection: close (代码有删除)
在 POST 提交的数据中,CMD 那段,用了 URL 编码把我个人的收货地址,手机号姓名都传输了,同时推测 dataType=1,这里的 1 为商品数量 如果更改成-1 呢?
事实证明我想多了。
HTTP/1.1 200 OK Cache-Control: private Content-Length: 36 Content-Type: text/html; charset=utf-8 Server: Microsoft-IIS/7.5 X-AspNet-Version: 2.0.50727 X-Powered-By: ASP.NET Date: Tue, 12 Dec 2017 03:34:11 GMT Connection: close result":0,"msg":" 购物车为空 "}
修改为-1 后显示购物车为空。那么可以推断 1 为商品数量,因为我修改为-1 进行重放服务端显示购物车为空。
Fuzz test 测试的精髓就在把 HTTP 的请求包参数进行各种更改,然后重放数次看响应即可。
不过这里我只想让这台价值八千的 iPhone X 变成 0.01 购买,那么我们放包,进入支付页面。
在付款页面来了,需要支付 8150 人民币,但账户里并没有那么多钱,我们使用微信支付来试一试。
在点击微信支付后再次抓包,返回信息为:
cmd=UserGoPay&group=order&dataType=1&id=14869&payWay=4&onlineMoney=8150.00&payPwd=
8150.00 就是金额,那么我们尝试一下进行更改。
更改成 0.01 后,重放请求显示:
HTTP/1.1 200 OK Cache-Control: private Content-Length: 51 Content-Type: text/html; charset=utf-8 Server: Microsoft-IIS/7.5 X-AspNet-Version: 2.0.50727 X-Powered-By: ASP.NET Date: Tue, 12 Dec 2017 03:42:04 GMT Connection: close {"result":0,"msg":" 请输入有效的支付密码 "}
Nice,需要支付密码,猜测程序员未做金额效验。
PayMoney=8150.00&OrderId=14869&OrderType=1&PayType=67
截获的请求包就是这串 paymoney=8150.00 猜测可控,进行更改 0.01,修改后放包,OK 返回了微信扫描付款截图页面。手机扫码支付成功。
不做修改的请求页面,一台 iPhone X+MacBook 共计 22886.00 人民币:
进行金额修改后,0.01 元可支付。
购买支付完成。
后台支付成功,进入待发货状态。
该漏洞存在的最大原因就是,程序员未做金额效验,服务端未进行效验,导致了本地金额可控,从而实现 0.01 元购买 iPhone X 逻辑漏洞。
攻击者通过修改交易金额,交易数量等从而实现漏洞的利用,比如像我上文所讲,把金额或者商品修改为负数、无限大,但我进行测试的时候,发现金额负数微信付款二维码是弹不出来的。
因为价格是 0,程序不作支付返回,只能从自己账户里的金额进行 Fuzz 测试。
支付流程逻辑漏洞总结:
支付逻辑漏洞还总的来说存在以下几种情况:
-
支付的时候修改金额,从而实现小金额购买大金额商品,比如我;
-
购买商品数量为无限大,使程序出现错误,实现 0 金额购买;
-
购买商品数量为负数,使程序出错,实现越买钱越多这种情况。
文件上传逻辑漏洞
文件上传漏洞可以 参考一篇文章(http://www.voidcn.com/article/p-psygixsk-rv.html),总结的非常棒,我直接贴地址过来了,换我来讲也许还没对方写的好,所以就不阐述了。
记住最重要的最安全的防攻击者绕过是白名单验证,而不是文件类型验证,也不是黑名单验证。
Web 开发中的逻辑漏洞总结
所以在 Web 开发中,存在逻辑漏洞总结几点下来就是:
-
订单金额任意修改
-
验证码传了本地
-
未进行登陆验证,导致未授权访问
-
ID 号枚举
-
Cookie 设计缺陷
-
水平越权
-
垂直越权
-
找回密码逻辑漏洞
-
验证码爆破
-
文件上传漏洞
以上几个案例基本都囊括了这所有的内容,故此不再进行举例。逻辑漏洞是程序开发者和渗透测试人员必须要留意的地方。