17 KiB
Cookies Hacking
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)!
支持HackTricks的其他方式:
- 如果您想看到您的公司在HackTricks中做广告或下载PDF格式的HackTricks,请查看订阅计划!
- 获取官方PEASS & HackTricks周边产品
- 探索PEASS家族,我们的独家NFT收藏品
- 加入 💬 Discord群 或 电报群 或在Twitter上关注我们 🐦 @carlospolopm。
- 通过向HackTricks和HackTricks Cloud github仓库提交PR来分享您的黑客技巧。
发现最重要的漏洞,以便更快地修复它们。Intruder跟踪您的攻击面,运行主动威胁扫描,发现整个技术堆栈中的问题,从API到Web应用程序和云系统。立即免费试用。
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
Cookie属性
Cookie带有几个属性,控制它们在用户浏览器中的行为。以下是这些属性的概述,使用更加被动的语气:
过期时间和Max-Age
Cookie的过期日期由Expires
属性确定。相反,Max-age
属性定义了直到删除Cookie的时间(以秒为单位)。选择Max-age
,因为它反映了更现代的实践。
域
Domain
属性指定接收Cookie的主机。默认情况下,这设置为发出Cookie的主机,不包括其子域。但是,当显式设置Domain
属性时,它也包括子域。这使得指定Domain
属性成为一个不太限制的选项,适用于需要在子域之间共享Cookie的情况。例如,设置Domain=mozilla.org
会使Cookie在其子域(如developer.mozilla.org
)上可访问。
路径
Path
属性指示必须在请求的URL中存在的特定URL路径,以便发送Cookie
头。此属性将/
字符视为目录分隔符,允许在子目录中进行匹配。
排序规则
当两个Cookie具有相同的名称时,选择要发送的Cookie基于:
- 请求URL中匹配最长路径的Cookie。
- 如果路径相同,则选择最近设置的Cookie。
SameSite
SameSite
属性规定了Cookie是否在来自第三方域的请求上发送。它提供三种设置:- Strict:限制Cookie在第三方请求中发送。
- Lax:允许Cookie随第三方网站发起的GET请求发送。
- None:允许从任何第三方域发送Cookie。
请记住,在配置Cookie时,了解这些属性可以帮助确保它们在不同情况下的行为符合预期。
请求类型 | 示例代码 | 发送Cookie的情况 |
---|---|---|
链接 | <a href="..."></a> | NotSet*, Lax, None |
预渲染 | <link rel="prerender" href=".."/> | NotSet*, Lax, None |
表单 GET | <form method="GET" action="..."> | NotSet*, Lax, None |
表单 POST | <form method="POST" action="..."> | NotSet*, None |
iframe | <iframe src="..."></iframe> | NotSet*, None |
AJAX | $.get("...") | NotSet*, None |
图片 | <img src="..."> | NetSet*, None |
表格来源于Invicti,稍作修改。
具有_SameSite_属性的Cookie将减轻需要登录会话的CSRF攻击。
*请注意,从Chrome80(2019年2月)开始,没有Cookie SameSite属性的Cookie的默认行为将是lax (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)。
请注意,临时地,在应用此更改后,Chrome中没有SameSite策略的Cookie在前2分钟内将被视为None,然后对于顶级跨站点POST请求将被视为Lax。
Cookies标志
HttpOnly
这可以防止客户端访问Cookie(例如通过Javascript:document.cookie
)
绕过方式
- 如果页面将Cookie作为响应的一部分发送(例如在PHPinfo页面中),可以利用XSS发送请求到此页面并从响应中窃取Cookie(在https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/中查看示例)。
- 可以通过TRACE HTTP请求绕过此限制,因为服务器的响应(如果此HTTP方法可用)将反映发送的Cookie。这种技术称为跨站点跟踪。
- 现代浏览器通过不允许从JS发送TRACE请求来避免此技术。然而,已经在特定软件中发现了对此的一些绕过方法,例如向IE6.0 SP2发送
\r\nTRACE
而不是TRACE
。 - 另一种方法是利用浏览器的零/日漏洞。
- 可以通过执行Cookie Jar溢出攻击覆盖HttpOnly Cookie:
{% content-ref url="cookie-jar-overflow.md" %} cookie-jar-overflow.md {% endcontent-ref %}
- 可以使用Cookie Smuggling攻击来突破这些Cookie
Secure
只有在通过安全通道传输请求时(通常是HTTPS)请求才会发送Cookie。
Cookies前缀
以__Secure-
为前缀的Cookie必须与受HTTPS保护的页面一起设置secure
标志。
对于以__Host-
为前缀的Cookie,必须满足几个条件:
- 必须使用
secure
标志设置。 - 必须来自通过HTTPS保护的页面。
- 禁止指定域,防止将其传输到子域。
- 这些Cookie的路径必须设置为
/
。
重要的是要注意,以__Host-
为前缀的Cookie不允许发送到超级域或子域。此限制有助于隔离应用程序Cookie。因此,将__Host-
前缀用于所有应用程序Cookie可以被视为增强安全性和隔离的良好实践。
Cookies攻击
如果自定义Cookie包含敏感数据,请检查它(特别是在玩CTF时),因为它可能存在漏洞。
解码和操纵Cookie
始终应仔细检查Cookie中嵌入的敏感数据。经Base64或类似格式编码的Cookie通常可以解码。此漏洞允许攻击者更改Cookie的内容,并通过将修改后的数据重新编码到Cookie中来冒充其他用户。
会话劫持
此攻击涉及窃取用户的Cookie以未经授权地访问其帐户。通过使用窃取的Cookie,攻击者可以冒充合法用户。
会话固定
在这种情况下,攻击者欺骗受害者使用特定Cookie登录。如果应用程序在登录时不分配新Cookie,则拥有原始Cookie的攻击者可以冒充受害者。此技术依赖于受害者使用攻击者提供的Cookie登录。
如果您在子域中发现了XSS或者您控制一个子域,请阅读:
{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}
会话捐赠
在这种情况下,攻击者说服受害者使用攻击者的会话Cookie。受害者认为他们已登录到自己的帐户中,将无意中在攻击者的帐户上执行操作。
如果您在子域中发现了XSS或者您控制一个子域,请阅读:
{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}
JWT Cookies
单击上面的链接访问解释JWT中可能存在的漏洞的页面。
在Cookie中使用的JSON Web Tokens(JWT)也可能存在漏洞。为了深入了解潜在的漏洞以及如何利用它们,建议访问有关黑客JWT的链接文档。
跨站点请求伪造(CSRF)
此攻击强制已登录用户在当前已认证的Web应用程序上执行不需要的操作。攻击者可以利用自动随每个请求发送到易受攻击站点的Cookie。
空Cookie
(在原始研究中查看更多细节) 浏览器允许创建没有名称的Cookie,可以通过JavaScript演示如下:
document.cookie = "a=v1"
document.cookie = "=test value;" // Setting an empty named cookie
document.cookie = "b=v2"
发送的cookie头中的结果是 a=v1; test value; b=v2;
。有趣的是,如果设置了一个空名称cookie,就可以操纵cookie,通过将空cookie设置为特定值,潜在地控制其他cookie:
function setCookie(name, value) {
document.cookie = `${name}=${value}`;
}
setCookie("", "a=b"); // Setting the empty cookie modifies another cookie's value
这会导致浏览器发送一个名为 a
值为 b
的 cookie 的 cookie 头,被每个 Web 服务器解释为一个名为 a
值为 b
的 cookie。
Chrome Bug: Unicode Surrogate Codepoint Issue
在 Chrome 中,如果一个 Unicode 代理码点是一个设置的 cookie 的一部分,document.cookie
会变得损坏,随后返回一个空字符串:
document.cookie = "\ud800=meep";
这导致 document.cookie
输出一个空字符串,表明永久性损坏。
由于解析问题导致的Cookie走私
(请查看原始研究中的更多细节) 包括Java(Jetty,TomCat,Undertow)和Python(Zope,cherrypy,web.py,aiohttp,bottle,webob)在内的几个Web服务器,由于过时的RFC2965支持,会错误处理Cookie字符串。即使包含分号,它们也会将双引号括起的Cookie值视为单个值,而分号通常应该分隔键值对:
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
Cookie注入漏洞
(请查看原始研究中的更多细节)
服务器(尤其是Undertow、Zope以及使用Python的http.cookie.SimpleCookie
和http.cookie.BaseCookie
)对cookie的解析不正确,为cookie注入攻击创造了机会。这些服务器未能正确界定新cookie的开始,允许攻击者伪造cookie:
- Undertow期望在带引号的值后立即出现新cookie,而无需分号。
- Zope寻找逗号以开始解析下一个cookie。
- Python的cookie类在空格字符上开始解析。
这种漏洞在依赖基于cookie的CSRF保护的Web应用程序中尤为危险,因为它允许攻击者注入伪造的CSRF令牌cookie,可能绕过安全措施。问题在于Python处理重复cookie名称时的方式,最后一次出现会覆盖先前的出现。它还引发了对不安全环境中__Secure-
和__Host-
cookie的担忧,并且当cookie传递给容易受到欺骗的后端服务器时,可能导致授权绕过。
额外易受攻击的Cookie检查
基本检查
- cookie 每次 登录 都是 相同 的。
- 注销并尝试使用相同的cookie。
- 尝试使用两台设备(或浏览器)使用相同的cookie登录同一帐户。
- 检查cookie中是否有任何信息,并尝试修改它。
- 尝试创建几个几乎相同用户名的帐户,并检查是否存在相似之处。
- 检查是否存在“记住我”选项,看看它是如何工作的。如果存在且可能存在漏洞,请始终只使用“记住我”cookie,而不使用其他cookie。
- 检查即使更改密码后,先前的cookie是否仍然有效。
高级cookie攻击
如果在登录时cookie保持不变(或几乎不变),这可能意味着cookie与您帐户的某个字段相关(可能是用户名)。然后您可以:
- 尝试创建许多非常相似的用户名帐户,并尝试猜测算法是如何工作的。
- 尝试暴力破解用户名。如果cookie仅保存为您的用户名的身份验证方法,则可以创建一个用户名为“Bmin”的帐户,并尝试暴力破解您cookie的每一位,因为您尝试的cookie之一将属于“admin”。
- 尝试填充 Oracle(您可以解密cookie的内容)。使用padbuster。
填充Oracle - Padbuster示例
padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
# When cookies and regular Base64
padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies auth=u7bvLewln6PJPSAbMb5pFfnCHSEd6olf
# If Base64 urlsafe or hex-lowercase or hex-uppercase --encoding parameter is needed, for example:
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2
Padbuster将尝试多次,并询问您哪个条件是错误条件(即无效条件)。
然后它将开始解密cookie(可能需要几分钟)
如果攻击成功执行,那么您可以尝试加密您选择的字符串。例如,如果您想要加密 user=administrator
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
这个执行将给出正确加密和编码的 cookie,其中包含字符串 user=administrator。
CBC-MAC
也许一个 cookie 可能会有一些值,并且可以使用 CBC 进行签名。然后,值的完整性是使用相同值使用 CBC 创建的签名。由于建议使用一个空向量作为 IV,这种完整性检查可能会有漏洞。
攻击
- 获取用户名 administ 的签名 = t
- 获取用户名 rator\x00\x00\x00 XOR t 的签名 = t'
- 在 cookie 中设置值 administrator+t'(t' 将是 (rator\x00\x00\x00 XOR t) XOR t 的有效签名 = rator\x00\x00\x00
ECB
如果使用 ECB 加密 cookie,可能会有漏洞。
当您登录时,收到的 cookie 必须始终相同。
如何检测和攻击:
创建两个几乎相同数据的用户(用户名、密码、电子邮件等),并尝试发现给定 cookie 中的某种模式
创建一个名为例如 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 的用户,并检查 cookie 中是否有任何模式(由于 ECB 使用相同的密钥加密每个块,如果用户名被加密,则相同的加密字节可能会出现)。
应该有一个模式(与使用的块大小相同)。因此,知道一堆 "a" 是如何加密的,您可以创建一个用户名:"a"*(块的大小)+"admin"。然后,您可以从 cookie 中删除一个块的加密模式 "a",然后您将得到用户名为 "admin" 的 cookie。
参考资料
- https://blog.ankursundara.com/cookie-bugs/
- https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd
找到最重要的漏洞,以便更快地修复它们。Intruder 跟踪您的攻击面,运行主动威胁扫描,发现整个技术堆栈中的问题,从 API 到 Web 应用程序和云系统。立即免费试用 今天。
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家)!
支持 HackTricks 的其他方式:
- 如果您想在 HackTricks 中看到您的 公司广告 或 下载 PDF 版本的 HackTricks,请查看 订阅计划!
- 获取 官方 PEASS & HackTricks 商品
- 发现 PEASS 家族,我们的独家 NFT 收藏品
- 加入 💬 Discord 群组 或 电报群组 或 关注 我们的 Twitter 🐦 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享您的黑客技巧。