17 KiB
Cookies Hacking
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 你在一个网络安全公司工作吗?你想在HackTricks中看到你的公司广告吗?或者你想获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFTs收藏品——The PEASS Family
- 获取官方PEASS和HackTricks周边产品
- 加入💬 Discord群组或电报群组,或者关注我在Twitter上的🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧。
找到最重要的漏洞,以便您可以更快地修复它们。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个可能的值:
- Strict:cookie不会随请求一起发送给第三方网站。
- Lax:cookie将随第三方网站发起的GET请求一起发送。
- None: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/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 %}
- 可以使用Cookie Smuggling攻击来窃取这些cookie
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
点击上面的链接访问一个页面,解释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字符串中的键值对。
例如,如果浏览器发送了三个cookie,RENDER_TEXT、JSESSIONID和ASDF:
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
这些服务器将它们解释为一个单一的cookie值,而不是三个独立的cookie。
这导致了一个安全风险:如果攻击者获得跨站脚本(XSS)访问权限,他们可以利用这个漏洞窃取敏感的cookie,如HttpOnly cookie。
Cookie注入
许多Web服务器,包括Java的Undertow,Python的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
作为结果,像cherrypy,web.py,aiohttp服务器,bottle和webob(Pyramid,TurboGears)这样的服务器都容易受到这种类型的攻击。
这个问题带来了重大的安全隐患。例如,如果一个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,这种完整性检查可能存在漏洞。
攻击
- 获取用户名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。
参考资料
查找最重要的漏洞,以便您可以更快地修复它们。Intruder跟踪您的攻击面,运行主动威胁扫描,发现整个技术堆栈中的问题,从API到Web应用程序和云系统。立即免费试用。
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 您在网络安全公司工作吗?您想在HackTricks中看到您的公司广告吗?或者您想获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFTs收藏品The PEASS Family
- 获取官方PEASS和HackTricks衣物
- 加入💬 Discord群组或电报群组,或在Twitter上关注我🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享您的黑客技巧。