hacktricks/pentesting-web/hacking-with-cookies
2024-01-10 17:05:27 +00:00
..
cookie-bomb.md Translated ['pentesting-web/hacking-with-cookies/cookie-bomb.md', 'pente 2024-01-10 17:05:27 +00:00
cookie-jar-overflow.md Translated ['pentesting-web/hacking-with-cookies/cookie-bomb.md', 'pente 2024-01-10 17:05:27 +00:00
cookie-tossing.md Translated ['pentesting-web/hacking-with-cookies/cookie-bomb.md', 'pente 2024-01-10 17:05:27 +00:00
README.md Translated ['pentesting-web/deserialization/nodejs-proto-prototype-pollu 2024-01-01 18:40:45 +00:00

Cookies 黑客攻击

从零开始学习 AWS 黑客攻击直到成为英雄 htARTE (HackTricks AWS 红队专家)

支持 HackTricks 的其他方式:

找到对您最重要的漏洞以便更快修复它们。Intruder 跟踪您的攻击面,运行主动威胁扫描,在您的整个技术栈中找到问题,从 API 到 web 应用程序和云系统。今天就免费试用

{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}


Cookies 属性

Expires & Max-Age

  • Expires 设置一个过期日期,用于删除 cookie
  • Max-age 设置时间(以秒为单位),用于删除 cookie (使用这个,现在不是 2009 年了)

Domain

Domain 属性指定哪些主机可以接收 cookie。如果未指定,属性默认设置 cookie 的同一主机不包括子域如果指定了 Domain,则始终包括子域。因此,指定 Domain 比省略它的限制性更小。然而,当需要在子域之间共享用户信息时,这可能是有帮助的。

例如,如果您设置了 Domain=mozilla.orgcookie 可以在像 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 攻击,其中需要登录会话。

*注意,从 Chrome802019 年 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例如通过 Javascriptdocument.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 %}

Secure

请求将在 HTTP 请求通过安全通道(通常是 HTTPS)传输时发送 cookie。

Cookies 前缀

__Secure- 前缀必须在安全页面HTTPS上使用 secure 标志设置。

__Host- 前缀必须在安全页面HTTPS上使用 secure 标志设置,不能指定域(因此,不会发送到子域),路径必须是 /

__Host- 前缀的 cookies 不能发送到超级域(从子域到域的 cookies或子域从域到子域的 cookies因此如果您想隔离应用程序的 cookies__Host- 作为前缀是一个不错的主意。

Cookies 攻击

如果您发现某种自定义 cookie 包含敏感数据(会话 ID、用户名、电子邮件等您绝对应该尝试利用它

如果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

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字符串中的键值对

例如,如果浏览器发送三个cookieRENDER_TEXT、JSESSIONIDASDF

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 SimpleCookieBaseCookie 会在遇到空格字符时立即开始解析下一个 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这种完整性检查可能会受到威胁。

攻击

  1. 获取用户名 administ 的签名 = t
  2. 获取用户名 rator\x00\x00\x00 XOR t 的签名 = t'
  3. 在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的其他方式