【预防思路】php
订单须要多重效验,以下图所演示。
前端
水平越权指的是攻击者尝试访问与他拥有相同权限的用户的资源,怎么理解呢?好比某系统中有我的资料这个功能,A帐号和B帐号均可以访问这个功能,可是A帐号的我的信息和B帐号的我的信息不一样,能够理解为A帐号和B帐号我的资料这个功能上具有水平权限的划分。此时,A帐号经过攻击手段访问了B帐号的我的资料,这就是水平越权漏洞。web
系统中全部具有水平权限划分的功能,都存在水平越权的风险,如下是常出现的水平越权的功能的几种场景:算法
1. 基于用户身份ID安全
在使用某个功能时经过用户提交的身份ID(用户ID、帐号、手机号、证件号等用户惟一标识)来访问或操做对应的数据。服务器
举个栗子:cookie
①某航空公司存在水平越权漏洞,提交订单后抓取数据包。
②能够发现请求中有蛮多ID信息,一般状况下,咱们通常会挨个测试,是否存在越权漏洞,其中passenger1d1是伺机人,contactId联系人。
③经测试可发现这两个参数修改后,可查看到其余伺机人的身份证及联系人信息。
2. 基于对象IDsession
在使用某个功能时经过用户提交的对象ID(如订单号、记录号)来访问或操做对应的数据。app
举个栗子:svg
①某系统存在水平越权漏洞。
②抓取订单提交的数据包,发现有一个oid很可疑。
③尝试进行测试发现,可遍历订单号,查看他人待付款订单信息。
3.基于文件名
在使用某个功能时经过文件名直接访问文件,最多见于用户上传文件的场景。
举个栗子:
①某系统存在水平越权漏洞。
②遍历fileid能够下载到数十万的资质文件:http://**.**.**.**/sFile-image.action?fileid=9316
越权访问:http://**.**.**.**/sFile-image.action?fileid=39316
垂直越权指的是一个低级别攻击者尝试访问高级别用户的资源。好比说某个系统分为普通用户和管理员,管理员有系统管理功能,而普通用户没有,那咱们就能够理解管理功能具有垂直权限划分,若是普通用户能利用某种攻击手段访问到管理功能,那咱们就称之为垂直越权。
垂直越权主要如下两种攻击场景:
1.未认证帐户访问无需认证后能访问该功能
举个栗子:
①某站点后台仅使用js跳转来限制未受权的用户访问。
②去掉js能够成功访问后台,且能够进行操做。
2. 不具有某个功能权限的帐户认证后成功访问该功能
举个栗子:
①使用default用户名和密码:useradmin / admin!@#$%^登陆系统。
②成功登陆后台。
③依次点击“对象管理——>用户管理——>编辑‘useradmin’——>获得URL:.../cgi-bin/webif/Objset-users.sh?edituser=edituser&id=5”
④修改参数id为:id=4,成功垂直越权telecomadmin。
⑤查看源码,可读取telecomadmin密码:telecomadmin34224223,至此已得到最高管理员权限,能够彻底对该设备进行操做。
⑥由下图可判断出telecomadmini为高权限用户。
用户的cookie数据加密应严格使用标准加密算法,并注意密钥管理。但有一些厂商为了图方便,没有对用户的cookie作太多的加密工做,仅仅是单纯的作一个静态加密就完事了。我以前就碰到一个,能够为你们还原一下当时的场景。
当时我看到cookie中有个access token参数,看到value后面是两个等号,习惯性的给丢去base64解码里面,发现解出来后是个人用户名。所以只要知道一我的的用户名就能够伪造对方的cookie,登录他人帐户。
有些web对于cookie的生成过于单一或者简单,致使黑客能够对Cookie的效验值进行一个枚举,以下图所示:
根据上图,咱们能够分析出,这家网站对于cookie的效验只单纯的采用了一组数字,而且数值为常量,不会改变,这样很是容易遭到黑客的枚举。甚至有一些网站作的更简单,直接以用户名,邮箱号或者用户ID等来做为cookie的判断标准。
通常来讲,当你们更改密码之后,以前的cookie值是不可以继续使用的,须要用户从新登录帐号。Black Hat对本身的APP安全好像颇有信心,因此在用户更改密码后,以前的cookie值还能一直使用。WTF?!没错,就是这样。解释清楚一点就是,假设A的帐号被B盗取了,而且登录在B的手机上。这个时候,A重置了本身的Black Hat帐号的密码。可是只要B不退出A的帐号,B就能够一直查看A的Balck 帐号全部信息。我继续用一张图片演示一下。
更多会话ID的漏洞,请访问:Web安全-会话ID漏洞。
【原理】经过手机找回密码,响应包中包含短信验证码
【案例】某网站选择用手机找回密码:
点击发送按钮,拦截回包,能够查看到短信验证码,以下图所示:
【修复建议】 响应包中去掉短信验证码。
【原理】
经过手机找回密码是通常须要短信验证码验证(这里能够尝试爆破或绕过),当咱们输入正确的手机号和正确的短信验证码,而后进入重置密码的最后一步,也就是输入新的密码,输入密码后提交到服务端的post数据包须要包含当前用户的身份信息,而通常网站是经过用户名或用户ID来标识用户身份的,若是这个用户名或用户ID没有和当前手机号、短信验证码进行绑定,也就是说服务端只验证用户名、ID是否存在,而不去验证用户和当前手机号是否匹配,那么咱们就能够经过修改用户名、ID去修改其余用户的密码了。固然能够修改的地方不限于找回密码的数据包,好比修改资料的地方也可能存在这样的漏洞。
【案例】
以某网站修改任意用户资料致使修改任意帐号密码为例,截取的数据包为:
POST /user/info_do HTTP/1.1 Host: www.XXX.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:59.0) Gecko/20100101 Firefox/59.0 Accept: */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Referer: http://www.XXX.com/user/info_view Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 211 Cookie: yunsuo_session_verify=9341a54b945886e9485ff54a17650468; PHPSESSID=sgbibaqe7f8f6okerps8jip916; sdrcUserlockcount=1; sdrcUseruserid=14943 Connection: keep-alive password=A123456&email=1%40qq.com&address=1&postcode=1&mobile=13888888888&sex=man&birthday=0000-00-00°ree=collegeLT&testsite=1&post=1&__hash__=b0b15b067dea00bd34fd39421b7ef684_efc2399e5c4b2071f261e75fe3362d4fa
经分析与尝试,发现数据包中的sdrcUseruserid的值是用来标识当前用户身份的,那么咱们就想到这个id能否任意修改呢?答案是确定的,咱们修改id的值为14942是能够成功的,截图以下:
【修复建议】
有些业务的接口,由于缺乏了对用户的登录凭证的效验或者是验证存在缺陷,致使黑客能够未经受权访问这些敏感信息甚至是越权操做。
常见案例:
一、某电商后台主页面,直接在管理员web路径后面输入main.php之类的便可进入。
二、某电子认证中心敏感文件下载:
三、不一样角色的帐号登陆系统后,仅经过隐藏操做菜单的方式来实现权限控制:
实际上还有不少案例,这里就不一一例举了,可是他们都存在一个共同的特性,就是没有对用户的登录凭证进行效验,以下图为例。
【预防思路】
对敏感数据存在的接口和页面作cookie,ssid,token或者其它验证,以下图所示。
经过邮箱找回密码时,邮件中将出现一个含有 token 的重置 URL,该 token 即为重置凭证。从经验来看,开发人员习惯以时间戳、递增序号、关键字段(如邮箱地址)等三类信息之一做为因子,采用某种加密算法或编码生成 token,攻击者能够基于能收集到的关键字段,用常见加密算法计算一遍,以判断是否能够预测出 token。
案例1:基于关键字段生成的 token
某网站密码找回功能,请求含有三个参数:
username 是邮箱、rvcode 图片验证码、sid 未知,登陆邮箱查看重置 URL:
key 参数为重置凭证,尝试分析生成方式。直接将其放入 md5 在线破解网站无果,尝试用 username、rvcode、sid 等三个参数的排列组合进行 md5,当尝试到 md5(username + sid) 时发现生成结果与邮件中的凭证一致:
猜想出其 key 的生成算法,那么,后续将毫无压力地重置任意帐号的密码了。
相似的还有,带凭证的重置连接为 http://mysite.com/sms.php?k=a18f057d5aF
,屡次获取重置连接发现,凭证 f198a79b9cF 末尾的 F 恒定不变,前面 10 位字符疑似 md5 加密,尝试对不一样参数的排列组合进行 md5 加密,当尝试到 md5(手机号+图片验证码) 时发现生成结果与邮件中的凭证一致:
案例2:基于递增序号生成的 token
金蝶云之家密码找回,带凭证的密码找回连接以下:
从参数名猜想,u 可能为 username、t 为 token,为减小复杂性,测试发现,删掉 u 参数及值也可正常重置密码,因此,可忽略 u 参数,重点关注 t 参数。
连续 5 次获取重置连接,从邮件中提取 5 个 t 参数值以下:
仔细观察发现变化点以下:
能够看出,t 参数值的 5~8位、最后 4 位,按 2 的增量呈现递增变化。
分析清楚凭证的变化规律,要重置任意帐号就轻松了。好比,要重置普通帐号 admin 的密码,能够先触发找回攻击者帐号的密码,获取 t 为 52df773f24ac5b651d288d42,而后触发找回 admin 的密码,t 未知,再次触发找回攻击者帐号的密码,获取 t 为 52df774d24ac5b651d288d54,根据前面分析得知的变化规律,普通帐号的 t 的 5~8 位必定是 [7740, 774c] 间的偶数,后 4 位范围必定在 [8d44, 8d52] 间的偶数。几回枚举即可得有效 t 参数值:
案例3:基于时间戳生成的 token
是一道在线 CTF 题目:
“忘记密码”功能是攻击点,尝试重置 admin 的密码:
对应请求与应答为:
除了提示已发送重置邮件外,并没有其余信息。尝试重置其余帐号 yangyangwithgnu:
得到重置 URL 信息 http://lab1.xseclab.com/password1_dc178aa12e73cfc184676a4100e07dac/reset.php?sukey=8135f8b07653b2cbc3ec05c781a29591&username=yangyangwithgnu
,访问后提示重置成功。那么,如今的状况是,admin 的重置 URL 无显示,其余帐号的 URL 有显示,只要拿到 admin 的重置 URL,极可能就能看到 flag。
上面重置 URL 中 sukey 参数引发个人注意,显然它就是重置凭证。将其值 8135f8b07653b2cbc3ec05c781a29591
先用 base64 解码无果,后将其进行 MD5 解密获得明文 1530342360:
貌似 unix 时间戳,验证之:
果真,重置凭证是对当前 unix 时间戳进行 MD5 加密所得。
那么,能够设计这样一种攻击模型,达到重置任意帐号密码的目的:
经过以上思路1-3步骤,得到 admin 的时间戳在 [1530347130, 1530347161] 中,基于以前得到的重置 URL 格式,咱们能够构造出 admin 的密码重置 URL 相似 http://lab1.xseclab.com/password1_dc178aa12e73cfc184676a4100e07dac/reset.php?sukey={md5(unix_timestamp)}&username=admin
。接下来,我将该 URL 放入 intruder 中进行暴破,将 unix_timestamp 定义为枚举变量:
以 [1530347130, 1530347161] 为字典,并设置 MD5 加密算法做为载荷预处理:
很快暴破出 admin 的重置 URL,并成功拿到 flag:
密码找回流程通常包括获取短信验证码、校验短信验证码是否有效、设置新密码等三个步骤。在第二步,校验短信验证码是否有效的结果应保存在服务端,某些网站未在服务端保存而是错误地将结果状态值下发客户端,后续又依靠前端 JS 判断是否能够进入第三步,那么,更改应答包中的状态值,可重置其余用户的密码。
这个漏洞常常出如今APP中,其主要缘由是对于重置密码的的验证是看response数据包,因为以前的案例没有截图,只能画个流程图给你们演示一下。
【案例】
下面是找回密码的一个流程,输入正确的用户名,跳到第二步,这时须要输入短信验证码,这里咱们随意输入一个短信验证码:123456,而后抓取服务端返回的信息以下所示。
简单分析发现,验证码校验经过时服务端并未向客户端 set-cookie,猜想服务端并未记录校验状态,是否进入设置新密码页面彻底是由前端 JS 基于应答状态决定的,那么,即使我没有短信验证码,经过将服务端下发给客户端的校验状态从“失败”改成“成功”,也能成功重置找回帐号密码。
把回包中false改成true后,便可绕太短信验证码验证,结果以下图所示。
【修复建议】
此处为了深刻理解漏洞原理和修复方案,咱们来了解下两个概念:
服务端跳转
和客户端跳转
。
【场景描述】
你到一个机关办事,一个是办事窗口的那我的很不客气地说,这个事你别找我,你找xxx窗口,而后你本身跑到xxx窗口,那个窗口的人直接给你办了;还有一个是窗口的人和你说,你等下,他本身跑去找另外一我的沟通一番,而后跑回来给你办了。
此处前者就是redirect重定向(客户端跳转),后者即是forward转发(服务端跳转)。
【概念解析】
服务器端跳转:又称为内部跳转,当客户端向服务器发送一个请求,请求当前资源时,这个资源在服务器内部跳转到另外一个资源,再向客户端发送一个响应(即客户端只产生了一次请求)。
(服务端)JSP重定向格式:
response.sendRedirect("path");
客户端跳转:又称为外部跳转,当客户端向服务器发送一个请求,请求当前资源时,这个资源向客户端发送一个去请求其余地址的回应。客户端再根据这个地址去进行下一次请求(即客户端产生了两次请求)。
(客户端)JSP转发格式:
request.getRequestDispatcher("path").forward(response,request)
【总结】进行登陆密码验证、密码重置等系统核心高风险操做的时候,在验证成功后须要跳转页面的状况下,要尽量在服务器端控制页面跳转!不要将页面跳转的逻辑代码部署在客户端JS代码中,不然可能被非法用户经过篡改服务器响应包从而绕过验证!简而言之,不要分步校验,服务器一旦验证成功,直接跳转进入下一步操做,不要等待客户端的信息进一步回传!