.. | ||
cookie-bomb.md | ||
cookie-jar-overflow.md | ||
cookie-tossing.md | ||
README.md |
Cookies 黑客攻击
从零开始学习 AWS 黑客攻击直到成为英雄 htARTE (HackTricks AWS 红队专家)!
支持 HackTricks 的其他方式:
- 如果您想在 HackTricks 中看到您的公司广告或下载 HackTricks 的 PDF,请查看订阅计划!
- 获取 官方 PEASS & HackTricks 商品
- 发现 PEASS 家族,我们的独家 NFTs 收藏
- 加入 💬 Discord 群组 或 telegram 群组 或在 Twitter 🐦 上关注我 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享您的黑客技巧。
找到对您最重要的漏洞,以便更快修复它们。Intruder 跟踪您的攻击面,运行主动威胁扫描,在您的整个技术栈中找到问题,从 API 到 web 应用程序和云系统。今天就免费试用。
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
Cookies 属性
Expires & Max-Age
Expires
设置一个过期日期,用于删除 cookieMax-age
设置时间(以秒为单位),用于删除 cookie (使用这个,现在不是 2009 年了)
Domain
Domain
属性指定哪些主机可以接收 cookie。如果未指定,属性默认为设置 cookie 的同一主机,不包括子域。如果指定了 Domain
,则始终包括子域。因此,指定 Domain
比省略它的限制性更小。然而,当需要在子域之间共享用户信息时,这可能是有帮助的。
例如,如果您设置了 Domain=mozilla.org
,cookie 可以在像 developer.mozilla.org
这样的子域上使用。但如果您不这样做,cookie 将不会发送到子域。
如果一个子域 sub.example.com
设置了一个 cookie,其 domain 属性为 .example.com
,它将在对父域的请求中被发送。
Path
Path
属性指示请求的 URL 中必须存在的 URL 路径以发送 Cookie
头。%x2F
("/") 字符被视为目录分隔符,子目录也会匹配。
顺序
当 2 个 cookie 同名时,发送的是:
- 与 URL 路径匹配的最长路径的那个
- 如果两者路径相同,则是最新的那个
SameSite
这将指示浏览器是否可以从其他域发送 cookie。它有 3 个可能的值:
- Strict:第三方网站发起的请求不会发送 cookie。
- Lax:第三方网站发起的 GET 请求会发送 cookie。
- None:任何第三方域都会发送 cookie
请求类型 | 示例代码 | 发送 Cookies 时 |
---|---|---|
链接 | <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 月)开始,没有 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
)
绕过
- 如果页面在请求的响应中发送 cookies(例如在 PHPinfo 页面中),可以滥用 XSS 向此页面发送请求并从响应中窃取 cookies(在 https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/ 中查看示例)。
- 可以通过 TRACE HTTP 请求绕过,因为服务器的响应(如果此 HTTP 方法可用)将反映发送的 cookies。这种技术称为跨站跟踪。
- 现代浏览器通过不允许从 JS 发送 TRACE 请求来避免这种技术。然而,已经在特定软件中发现了一些绕过方法,比如向 IE6.0 SP2 发送
\r\nTRACE
而不是TRACE
。 - 另一种方法是利用浏览器的零日漏洞。
- 可以通过执行 Cookie Jar 溢出攻击来覆盖 HttpOnly cookies:
{% content-ref url="cookie-jar-overflow.md" %} cookie-jar-overflow.md {% endcontent-ref %}
- 可以使用 Cookie Smuggling 攻击来泄露这些 cookies
Secure
请求将仅在 HTTP 请求通过安全通道(通常是 HTTPS)传输时发送 cookie。
Cookies 前缀
__Secure-
前缀:必须在安全页面(HTTPS)上使用 secure
标志设置。
__Host-
前缀:必须在安全页面(HTTPS)上使用 secure
标志设置,不能指定域(因此,不会发送到子域),路径必须是 /
。
__Host-
前缀的 cookies 不能发送到超级域(从子域到域的 cookies)或子域(从域到子域的 cookies),因此,如果您想隔离应用程序的 cookies,用 __Host-
作为前缀是一个不错的主意。
Cookies 攻击
如果您发现某种自定义 cookie 包含敏感数据(会话 ID、用户名、电子邮件等),您绝对应该尝试利用它
解码 cookie
如果cookie 使用了某种基础编码(如 Base64)或类似的东西,您可能能够解码它,更改 内容 并冒充任意用户。
会话劫持
窃取 cookie 并使用它在应用程序内冒充用户
会话固定
攻击者从网页获取 cookie 并发送链接给受害者,让其使用完全相同的 cookie 登录。如果用户登录时 cookie 没有更改,这可能是有用的,因为攻击者可能能够通过 cookie 冒充用户。
如果您在子域中发现了 XSS 或者您控制一个子域,请阅读:
{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}
会话捐赠
攻击者将自己的会话发送给受害者。受害者会看到他已经登录,并会认为他在自己的账户内,但操作将在攻击者的账户内执行。
如果您在子域中发现了 XSS 或者您控制一个子域,请阅读:
{% content-ref url="cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}
JWT Cookie
点击上一个链接访问解释 JWT 可能漏洞的页面。
空 Cookie
浏览器允许带有空名称的 cookie
document.cookie = "a=v1"
document.cookie = "=test value;" // empty name
document.cookie = "b=v2"
这导致发送了以下cookie头:
a=v1; test value; b=v2;
更有趣的是,如果你有一个向量让你能够设置空的 cookie,你就可以控制任何其他的 cookie:
function setCookie(name, value) {
document.cookie = `${name}=${value}`;
}
setCookie("", "a=b"); // this sets the empty cookie to a=b
虽然在浏览器内部,这被设置为名为空的cookie,它将导致发送的cookie头部:
a=b;
意味着,每个web服务器都会解析它,将cookie a
设置为值 b
。
Chrome Bug - document.cookie损坏
如果在设置cookie时包含了一个unicode代理码点,document.cookie
将会被永久损坏,并返回一个空字符串。
document.cookie
// "a=b;"
document.cookie = "\ud800=meep";
document.cookie
// ""
Cookie走私
多个web服务器,包括Java web服务器Jetty、TomCat、Undertow,以及Python web框架Zope,还有像cherrypy、web.py、aiohttp server、bottle和webob这样的Python web服务器/框架,由于仍支持RFC2965,这是一种过时的cookie引用机制,它使用RFC2616来定义引用字符串,因此被发现错误解析cookie字符串。
具体来说,这些服务器在遇到双引号(dquoted)的cookie值时会继续读取cookie字符串,即使遇到分号也是如此。这是有问题的,因为分号应该用来分隔cookie字符串中的键值对。
例如,如果浏览器发送三个cookie,RENDER_TEXT、JSESSIONID和ASDF:
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
这些服务器将它们解释为单个cookie值,而不是三个独立的cookies。
这导致了一个安全风险:如果攻击者获得了跨站脚本(XSS)访问权限,他们可以利用这个漏洞来窃取敏感cookies,如HttpOnly cookies。
Cookie注入
许多web服务器,包括Java的Undertow、Python的Zope,以及使用Python的stdlib http.cookie.SimpleCookie和http.cookie.BaseCookie的服务器,被发现错误解析cookies,使用错误的分隔符来开始下一个cookie名称/值对。这允许攻击者在只控制一个cookie值的情况下伪造多个cookies。
在Undertow的情况下,它在引号结束的cookie值之后立即开始解析下一个cookie,而不等待分号:
LANGUAGE="en-us" CSRF_TOKEN="SPOOFED_VALUE"
Zope 在遇到逗号时开始解析下一个cookie:
LANGUAGE=en-us,CSRF_TOKEN=SPOOFED_VALUE
And Python's SimpleCookie 和 BaseCookie 会在遇到空格字符时立即开始解析下一个 cookie:
LANGUAGE=en-us CSRF_TOKEN=SPOOFED_VALUE
因此,像是 **cherrypy**、**web.py**、**aiohttp** 服务器、**bottle** 和 **webob**(Pyramid, TurboGears)等服务器都容易受到这种攻击的影响。
这个问题带来了重大的**安全隐患**。例如,如果一个网络应用程序使用基于**cookie的CSRF保护**,攻击者可以**注入**一个伪造的**CSRF-token cookie**来绕过这种保护。此外,在Python的http.cookie包中,最后一个重复的cookie名称会覆盖之前的所有同名cookie,这使得这种攻击尤其容易实施。
此外,**`__Secure-`** 和 **`__Host-`** cookies的**伪造**可以在不安全的环境中被滥用。同时,在将cookies传递到后端服务器的配置中,如果后端服务器容易受到伪造攻击而前端服务器不是,则**cookie注入可能导致授权绕过**。
### 额外的易受攻击的Cookies检查
#### **基本检查**
* 每次**登录**时,**cookie**都是**相同**的。
* 注销后尝试使用相同的cookie。
* 尝试使用2个设备(或浏览器)登录同一个账户,使用相同的cookie。
* 检查cookie中是否有任何信息,并尝试修改它。
* 尝试创建几个用户名几乎相同的账户,检查是否可以看到相似之处。
* 检查是否存在"**记住我**"选项,看看它是如何工作的。如果存在且可能容易受到攻击,始终只使用**记住我**的cookie,不使用任何其他cookie。
* 检查在你更改密码后,之前的cookie是否仍然有效。
#### **高级cookies攻击**
如果登录时cookie保持不变(或几乎不变),这可能意味着cookie与你账户的某个字段(可能是用户名)有关。然后你可以:
* 尝试创建很多用户名非常**相似**的**账户**,并尝试**猜测**算法是如何工作的。
* 尝试**暴力破解用户名**。如果cookie仅作为你用户名的认证方法保存,那么你可以创建一个用户名为"**Bmin**"的账户,并**暴力破解**你cookie的每一个**比特**,因为你尝试的某个cookie将是属于"**admin**"的那个。
* 尝试使用**Padding Oracle**(你可以解密cookie的内容)。使用**padbuster**。
**Padding 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
如果cookie使用ECB加密,它可能会受到威胁。
当您登录时,您收到的cookie应该始终相同。
如何检测和攻击:
创建两个数据几乎相同的用户(用户名、密码、电子邮件等),并尝试在给定的cookie中发现某种模式
例如创建一个叫做 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 的用户,并检查cookie中是否有任何模式(因为ECB使用相同的密钥加密每个块,如果用户名被加密,相同的加密字节可能会出现)。
应该有一个模式(使用块的大小)。所以,知道一堆 "a" 是如何加密的,你可以创建一个用户名:"a"*(块的大小)+"admin"。然后,你可以从cookie中删除一个 "a" 块的加密模式。这样你就会有用户名 "admin" 的cookie。
参考资料
找到对您最重要的漏洞,以便您能更快修复它们。Intruder 跟踪您的攻击面,运行主动威胁扫描,在您的整个技术栈中找到问题,从API到web应用程序和云系统。今天就免费试用。
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
从零开始学习AWS黑客攻击,成为 htARTE (HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
- 如果您想在 HackTricks 中看到您的公司广告或下载HackTricks的PDF,请查看订阅计划!
- 获取官方PEASS & HackTricks商品
- 发现PEASS家族,我们独家的NFTs系列
- 加入 💬 Discord群组 或 telegram群组 或在 Twitter 🐦 上关注我 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github仓库提交PR来分享您的黑客技巧。**