hacktricks/pentesting-web/hacking-with-cookies/README.md

17 KiB
Raw Blame History

Cookies Hacking

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

找到最重要的漏洞以便您可以更快地修复它们。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.org则cookie在诸如developer.mozilla.org之类的子域上可用。但如果您不这样做cookie将不会发送到子域。

如果子域sub.example.com设置了一个domain属性为.example.com的cookie它将在请求父域发送**。

Path

Path属性指示必须在请求的URL中存在的URL路径,以发送Cookie头。%x2F"/")字符被视为目录分隔符,子目录也匹配。

顺序

当两个cookie具有相同的名称发送的cookie是

  • URL路径匹配最长的那个
  • 如果两个路径相同,则是最新的那个

SameSite

这将告诉浏览器cookie是否可以从其他域发送。它有3个可能的值

  • Strictcookie不会随请求一起发送给第三方网站。
  • Laxcookie将随第三方网站发起的GET请求一起发送。
  • Nonecookie从任何第三方域发送
请求类型 示例代码 发送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攻击

*请注意从Chrome802019年2月开始没有cookie samesite属性的cookie的默认行为将是laxhttps://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

绕过方法

  • 如果页面将cookie作为请求的响应发送例如在PHPinfo页面中可以滥用XSS发送请求到该页面并从响应中窃取cookie(在https://hackcommander.github.io/pentesting-article-1/中查看示例)
  • 可以通过TRACE 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 %}

Secure

只有在通过安全通道(通常是HTTPS传输请求时请求才会发送cookie。

Cookies前缀

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

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

__Host-前缀的cookie不能发送到超域从子域到域或子域从域到子域因此如果要隔离应用程序的cookie使用__Host-作为前缀不是一个坏主意。

Cookies攻击

如果发现某种包含敏感数据会话ID、用户名、电子邮件等的自定义cookie一定要尝试利用它

解码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

浏览器允许使用空名称的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损坏

如果一个Unicode代理代码点在一个设置的cookie中document.cookie 将永久损坏并返回一个空字符串。

document.cookie
// "a=b;"
document.cookie = "\ud800=meep";
document.cookie
// ""

Cookie劫持

一些Web服务器包括Java服务器Jetty、TomCat、Undertow和Python Web框架Zope以及Python Web服务器/框架如cherrypy、web.py、aiohttp server、bottle和webob被发现由于对RFC2965的残留支持而错误解析cookie字符串RFC2965是一种使用RFC2616定义的过时的cookie引用机制。

具体来说,当这些服务器遇到双引号dquoted的cookie值时即使遇到分号它们仍会继续读取cookie字符串。这是有问题的,因为分号应该用于分隔cookie字符串中的键值对

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

RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";

这些服务器将它们解释为一个单一的cookie值而不是三个独立的cookie。

这导致了一个安全风险如果攻击者获得跨站脚本XSS访问权限他们可以利用这个漏洞窃取敏感的cookie如HttpOnly cookie

Cookie注入

许多Web服务器包括Java的UndertowPython的Zope以及使用Python的stdlib http.cookie.SimpleCookie和http.cookie.BaseCookie的服务器被发现错误解析cookie使用错误的分隔符来开始下一个cookie名称/值对。这使得攻击者可以伪造多个cookie同时只控制一个cookie值

Undertow的情况下,它在一个带引号的cookie值结束后立即开始解析下一个cookie而不等待分号

LANGUAGE="en-us" CSRF_TOKEN="SPOOFED_VALUE"

Zope 在下一个 逗号 处开始解析下一个 cookie

LANGUAGE=en-us,CSRF_TOKEN=SPOOFED_VALUE

而Python的SimpleCookie和BaseCookie会立即在空格字符上开始解析下一个cookie

LANGUAGE=en-us CSRF_TOKEN=SPOOFED_VALUE

作为结果,像cherrypyweb.pyaiohttp服务器,bottlewebobPyramidTurboGears这样的服务器都容易受到这种类型的攻击。

这个问题带来了重大的安全隐患。例如如果一个Web应用程序使用基于cookie的CSRF保护攻击者可以注入一个伪造的CSRF令牌cookie来绕过此保护。此外Python的http.cookie包中的最后一个重复的cookie名称会覆盖之前的任何cookie使得这种类型的攻击特别容易。

此外在一个将cookie传递给后端服务器的配置中如果后端服务器容易受到伪造攻击而前端服务器不容易受到伪造攻击cookie注入可能导致授权绕过

额外易受攻击的Cookie检查

基本检查

  • 每次登录时,cookie都是相同的
  • 注销并尝试使用相同的cookie。
  • 使用相同的cookie在2个设备或浏览器上尝试登录同一个账户。
  • 检查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这种完整性检查可能存在漏洞。

攻击

  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

如果使用ECB加密cookie可能存在漏洞。
当您登录时您收到的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" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥