# 쿠키 해킹 {% hint style="success" %} AWS 해킹 배우기 및 연습하기:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ GCP 해킹 배우기 및 연습하기: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
HackTricks 지원하기 * [**구독 계획**](https://github.com/sponsors/carlospolop) 확인하기! * **💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 참여하거나 **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**를 팔로우하세요.** * **[**HackTricks**](https://github.com/carlospolop/hacktricks) 및 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.**
{% endhint %} **Try Hard Security Group**
{% embed url="https://discord.gg/tryhardsecurity" %} *** ## 쿠키 속성 쿠키는 사용자의 브라우저에서 동작을 제어하는 여러 속성을 가지고 있습니다. 다음은 이러한 속성에 대한 설명입니다: ### 만료 및 최대 연령 쿠키의 만료 날짜는 `Expires` 속성에 의해 결정됩니다. 반대로, `Max-age` 속성은 쿠키가 삭제될 때까지의 시간을 초 단위로 정의합니다. **더 현대적인 관행을 반영하는 `Max-age`를 선택하세요.** ### 도메인 쿠키를 받을 호스트는 `Domain` 속성에 의해 지정됩니다. 기본적으로 이는 쿠키를 발급한 호스트로 설정되며, 하위 도메인은 포함되지 않습니다. 그러나 `Domain` 속성이 명시적으로 설정되면 하위 도메인도 포함됩니다. 이는 하위 도메인 간의 쿠키 공유가 필요한 경우 유용한 덜 제한적인 옵션입니다. 예를 들어, `Domain=mozilla.org`로 설정하면 `developer.mozilla.org`와 같은 하위 도메인에서도 쿠키에 접근할 수 있습니다. ### 경로 `Cookie` 헤더가 전송되기 위해 요청된 URL에 반드시 존재해야 하는 특정 URL 경로는 `Path` 속성에 의해 표시됩니다. 이 속성은 `/` 문자를 디렉토리 구분자로 간주하여 하위 디렉토리에서도 일치를 허용합니다. ### 정렬 규칙 두 개의 쿠키가 동일한 이름을 가질 때, 전송할 쿠키는 다음에 따라 선택됩니다: * 요청된 URL에서 가장 긴 경로와 일치하는 쿠키. * 경로가 동일할 경우 가장 최근에 설정된 쿠키. ### SameSite * `SameSite` 속성은 쿠키가 제3자 도메인에서 발생한 요청에 대해 전송되는지를 결정합니다. 세 가지 설정을 제공합니다: * **Strict**: 제3자 요청에서 쿠키가 전송되지 않도록 제한합니다. * **Lax**: 제3자 웹사이트에서 시작된 GET 요청과 함께 쿠키가 전송될 수 있도록 허용합니다. * **None**: 모든 제3자 도메인에서 쿠키가 전송될 수 있도록 허용합니다. 쿠키를 구성할 때 이러한 속성을 이해하면 다양한 시나리오에서 쿠키가 예상대로 동작하도록 보장할 수 있습니다. | **요청 유형** | **예제 코드** | **쿠키 전송 시** | | ---------------- | ---------------------------------- | --------------------- | | 링크 | \\ | NotSet\*, Lax, None | | 프리렌더 | \ | NotSet\*, Lax, None | | 폼 GET | \
| NotSet\*, Lax, None | | 폼 POST | \ | NotSet\*, None | | iframe | \ | NotSet\*, None | | AJAX | $.get("...") | NotSet\*, None | | 이미지 | \ | NetSet\*, None | [Invicti](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/)에서 가져온 표이며 약간 수정되었습니다.\ _**SameSite**_ 속성이 있는 쿠키는 **CSRF 공격을 완화**합니다. **\*Chrome80(2019년 2월)부터 쿠키에 SameSite 속성이 없는 경우 기본 동작은 lax**입니다 ([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)).\ 이 변경을 적용한 후, Chrome에서 **SameSite 정책이 없는 쿠키는** **처음 2분 동안 None으로 처리되고, 이후에는 최상위 교차 사이트 POST 요청에 대해 Lax로 처리됩니다.** ## 쿠키 플래그 ### HttpOnly 이 속성은 **클라이언트**가 쿠키에 접근하는 것을 방지합니다 (예: **Javascript**를 통해: `document.cookie`). #### **우회 방법** * 페이지가 요청의 응답으로 쿠키를 **전송하는 경우** (예: **PHPinfo** 페이지에서), XSS를 악용하여 이 페이지에 요청을 보내고 응답에서 **쿠키를 훔칠 수 있습니다** ([https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/](https://hackcommander.github.io/posts/2022/11/12/bypass-httponly-via-php-info-page/)에서 예시 확인). * **TRACE** **HTTP** 요청으로 우회할 수 있으며, 서버의 응답은 전송된 쿠키를 반영합니다. 이 기술은 **Cross-Site Tracking**이라고 합니다. * 이 기술은 **모던 브라우저에서 JS로 TRACE 요청을 전송하는 것을 허용하지 않음으로써 방지됩니다.** 그러나 IE6.0 SP2와 같은 특정 소프트웨어에서 `\r\nTRACE`를 전송하여 우회하는 방법이 발견되었습니다. * 또 다른 방법은 브라우저의 제로/데이 취약점을 악용하는 것입니다. * 쿠키 항아리 오버플로우 공격을 수행하여 **HttpOnly 쿠키를 덮어쓸 수 있습니다**: {% content-ref url="cookie-jar-overflow.md" %} [cookie-jar-overflow.md](cookie-jar-overflow.md) {% endcontent-ref %} * [**쿠키 밀수**](./#cookie-smuggling) 공격을 사용하여 이러한 쿠키를 유출할 수 있습니다. ### Secure 요청은 **HTTP** 요청에서만 쿠키를 전송하며, 요청이 보안 채널(일반적으로 **HTTPS**)을 통해 전송될 때만 가능합니다. ## 쿠키 접두사 `__Secure-`로 접두사가 붙은 쿠키는 HTTPS로 보호된 페이지와 함께 `secure` 플래그가 설정되어야 합니다. `__Host-`로 접두사가 붙은 쿠키는 여러 조건을 충족해야 합니다: * `secure` 플래그와 함께 설정되어야 합니다. * HTTPS로 보호된 페이지에서 유래해야 합니다. * 도메인을 지정할 수 없으며, 하위 도메인으로의 전송이 금지됩니다. * 이러한 쿠키의 경로는 `/`로 설정되어야 합니다. `__Host-`로 접두사가 붙은 쿠키는 슈퍼도메인이나 하위 도메인으로 전송될 수 없다는 점에 유의해야 합니다. 이 제한은 애플리케이션 쿠키를 격리하는 데 도움이 됩니다. 따라서 모든 애플리케이션 쿠키에 대해 `__Host-` 접두사를 사용하는 것은 보안 및 격리를 강화하는 좋은 관행으로 간주될 수 있습니다. ### 쿠키 덮어쓰기 `__Host-` 접두사가 붙은 쿠키의 보호 중 하나는 하위 도메인에서 덮어쓰는 것을 방지하는 것입니다. 예를 들어 [**쿠키 토스 공격**](cookie-tossing.md)을 방지합니다. [**Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities**](https://www.youtube.com/watch?v=F\_wAzF4a7Xg) ([**논문**](https://www.usenix.org/system/files/usenixsecurity23-squarcina.pdf))에서 하위 도메인에서 __HOST- 접두사가 붙은 쿠키를 설정할 수 있는 방법이 제시되었습니다. 예를 들어, 시작 부분이나 끝 부분에 "="를 추가하여 파서를 속이는 방법입니다:
또는 PHP에서는 쿠키 이름의 **시작 부분에 다른 문자를 추가하여** **밑줄** 문자로 대체되도록 하여 `__HOST-` 쿠키를 덮어쓸 수 있었습니다:
## 쿠키 공격 사용자 정의 쿠키에 민감한 데이터가 포함되어 있는 경우 확인하세요 (특히 CTF를 진행 중이라면), 취약할 수 있습니다. ### 쿠키 디코딩 및 조작 쿠키에 포함된 민감한 데이터는 항상 면밀히 검토해야 합니다. Base64 또는 유사한 형식으로 인코딩된 쿠키는 종종 디코딩할 수 있습니다. 이 취약점은 공격자가 쿠키의 내용을 변경하고 수정된 데이터를 다시 쿠키에 인코딩하여 다른 사용자를 가장할 수 있게 합니다. ### 세션 하이재킹 이 공격은 사용자의 쿠키를 훔쳐 애플리케이션 내에서 그들의 계정에 무단으로 접근하는 것입니다. 훔친 쿠키를 사용하여 공격자는 합법적인 사용자를 가장할 수 있습니다. ### 세션 고정 이 시나리오에서 공격자는 피해자를 특정 쿠키를 사용하여 로그인하도록 속입니다. 애플리케이션이 로그인 시 새로운 쿠키를 할당하지 않으면, 원래 쿠키를 가진 공격자는 피해자를 가장할 수 있습니다. 이 기술은 피해자가 공격자가 제공한 쿠키로 로그인하는 데 의존합니다. 하위 도메인에서 **XSS를 발견했거나** 하위 도메인을 **제어하는 경우**, 읽어보세요: {% content-ref url="cookie-tossing.md" %} [cookie-tossing.md](cookie-tossing.md) {% endcontent-ref %} ### 세션 기부 여기서 공격자는 피해자가 공격자의 세션 쿠키를 사용하도록 설득합니다. 피해자는 자신의 계정에 로그인했다고 믿고, 공격자의 계정 맥락에서 무의식적으로 작업을 수행하게 됩니다. 하위 도메인에서 **XSS를 발견했거나** 하위 도메인을 **제어하는 경우**, 읽어보세요: {% content-ref url="cookie-tossing.md" %} [cookie-tossing.md](cookie-tossing.md) {% endcontent-ref %} ### [JWT 쿠키](../hacking-jwt-json-web-tokens.md) 이전 링크를 클릭하여 JWT의 가능한 결함을 설명하는 페이지에 접근하세요. 쿠키에서 사용되는 JSON 웹 토큰(JWT)도 취약점을 가질 수 있습니다. 잠재적인 결함 및 이를 악용하는 방법에 대한 심층 정보를 얻으려면 JWT 해킹에 대한 링크된 문서를 참조하는 것이 좋습니다. ### 교차 사이트 요청 위조 (CSRF) 이 공격은 로그인된 사용자가 현재 인증된 웹 애플리케이션에서 원하지 않는 작업을 수행하도록 강요합니다. 공격자는 취약한 사이트에 대한 모든 요청과 함께 자동으로 전송되는 쿠키를 악용할 수 있습니다. ### 빈 쿠키 (자세한 내용은 [원본 연구](https://blog.ankursundara.com/cookie-bugs/)를 참조하세요) 브라우저는 이름이 없는 쿠키 생성을 허용하며, 이는 JavaScript를 통해 다음과 같이 시연할 수 있습니다: ```js document.cookie = "a=v1" document.cookie = "=test value;" // Setting an empty named cookie document.cookie = "b=v2" ``` 전송된 쿠키 헤더의 결과는 `a=v1; test value; b=v2;`입니다. 흥미롭게도, 이는 빈 이름 쿠키가 설정된 경우 쿠키를 조작할 수 있게 하며, 빈 쿠키를 특정 값으로 설정함으로써 다른 쿠키를 제어할 수 있습니다: ```js function setCookie(name, value) { document.cookie = `${name}=${value}`; } setCookie("", "a=b"); // Setting the empty cookie modifies another cookie's value ``` 이로 인해 브라우저는 모든 웹 서버에서 `a`라는 이름의 쿠키와 `b`라는 값으로 해석되는 쿠키 헤더를 전송하게 됩니다. #### Chrome 버그: 유니코드 대리 코드 포인트 문제 Chrome에서 유니코드 대리 코드 포인트가 설정된 쿠키의 일부인 경우, `document.cookie`가 손상되어 이후에 빈 문자열을 반환합니다: ```js document.cookie = "\ud800=meep"; ``` 이로 인해 `document.cookie`가 빈 문자열을 출력하여 영구적인 손상을 나타냅니다. #### 파싱 문제로 인한 쿠키 스머글링 (자세한 내용은 [원본 연구](https://blog.ankursundara.com/cookie-bugs/)를 참조하십시오) Java(Jetty, TomCat, Undertow) 및 Python(Zope, cherrypy, web.py, aiohttp, bottle, webob)에서 제공하는 여러 웹 서버는 구식 RFC2965 지원으로 인해 쿠키 문자열을 잘못 처리합니다. 이들은 세미콜론이 포함되어 있어도 이중 인용된 쿠키 값을 단일 값으로 읽으며, 이는 일반적으로 키-값 쌍을 구분해야 합니다: ``` RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end"; ``` #### 쿠키 주입 취약점 (자세한 내용은 [원본 연구](https://blog.ankursundara.com/cookie-bugs/)를 참조하세요) 서버가 쿠키를 잘못 파싱하는 경우, 특히 Undertow, Zope 및 Python의 `http.cookie.SimpleCookie`와 `http.cookie.BaseCookie`를 사용하는 경우 쿠키 주입 공격의 기회를 제공합니다. 이러한 서버는 새로운 쿠키의 시작을 적절히 구분하지 못하여 공격자가 쿠키를 스푸핑할 수 있게 합니다: * Undertow는 세미콜론 없이 인용된 값 바로 뒤에 새로운 쿠키가 오는 것을 기대합니다. * Zope는 다음 쿠키를 파싱하기 위해 쉼표를 찾습니다. * Python의 쿠키 클래스는 공백 문자에서 파싱을 시작합니다. 이 취약점은 쿠키 기반 CSRF 보호에 의존하는 웹 애플리케이션에서 특히 위험합니다. 공격자가 스푸핑된 CSRF 토큰 쿠키를 주입할 수 있어 보안 조치를 우회할 수 있습니다. 이 문제는 Python의 중복 쿠키 이름 처리로 인해 악화되며, 마지막 발생이 이전 것을 덮어씁니다. 또한 불안전한 컨텍스트에서 `__Secure-` 및 `__Host-` 쿠키에 대한 우려를 불러일으키며, 쿠키가 스푸핑에 취약한 백엔드 서버로 전달될 때 권한 우회를 초래할 수 있습니다. ### 추가 취약한 쿠키 검사 #### **기본 검사** * **로그인**할 때마다 **쿠키**가 **같은**지 확인합니다. * 로그아웃하고 동일한 쿠키를 사용해 보세요. * 두 개의 장치(또는 브라우저)로 동일한 계정에 동일한 쿠키로 로그인해 보세요. * 쿠키에 정보가 있는지 확인하고 수정해 보세요. * 거의 동일한 사용자 이름으로 여러 계정을 생성하고 유사성을 확인해 보세요. * "**기억하기**" 옵션이 있는지 확인하고 어떻게 작동하는지 살펴보세요. 존재하고 취약할 수 있는 경우, 다른 쿠키 없이 항상 **기억하기** 쿠키를 사용하세요. * 비밀번호를 변경한 후에도 이전 쿠키가 작동하는지 확인하세요. #### **고급 쿠키 공격** 로그인할 때 쿠키가 동일하게 유지되거나 거의 동일하다면, 이는 쿠키가 귀하의 계정의 일부 필드(아마도 사용자 이름)와 관련이 있음을 의미합니다. 그런 다음 다음을 시도할 수 있습니다: * 매우 **유사한** 사용자 이름으로 많은 **계정**을 생성하고 알고리즘이 어떻게 작동하는지 **추측**해 보세요. * **사용자 이름을 브루트포스**해 보세요. 쿠키가 사용자 이름에 대한 인증 방법으로만 저장된다면, 사용자 이름 "**Bmin**"으로 계정을 생성하고 쿠키의 모든 **비트**를 **브루트포스**할 수 있습니다. 시도할 쿠키 중 하나는 "**admin**"에 속하는 쿠키가 될 것입니다. * **패딩 오라클**을 시도해 보세요(쿠키의 내용을 복호화할 수 있습니다). **패드버스터**를 사용하세요. **패딩 오라클 - 패드버스터 예제** ```bash padbuster # 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는 여러 번 시도하며 어떤 조건이 오류 조건인지(유효하지 않은 조건) 물어봅니다. 그런 다음 쿠키를 해독하기 시작합니다(몇 분이 걸릴 수 있습니다). 공격이 성공적으로 수행되면, 원하는 문자열을 암호화해 볼 수 있습니다. 예를 들어, **encrypt** **user=administrator**를 원한다면. ``` padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator ``` 이 실행은 문자열 **user=administrator**가 포함된 쿠키를 올바르게 암호화하고 인코딩합니다. **CBC-MAC** 쿠키가 어떤 값을 가질 수 있고 CBC를 사용하여 서명될 수 있습니다. 그러면 값의 무결성은 동일한 값을 사용하여 CBC로 생성된 서명입니다. IV로 널 벡터를 사용하는 것이 권장되므로, 이러한 유형의 무결성 검사는 취약할 수 있습니다. **공격** 1. 사용자 이름 **administ**의 서명 가져오기 = **t** 2. 사용자 이름 **rator\x00\x00\x00 XOR t**의 서명 가져오기 = **t'** 3. 쿠키에 값 **administrator+t'** 설정하기 (**t'**는 **(rator\x00\x00\x00 XOR t) XOR t**의 유효한 서명이 됩니다 = **rator\x00\x00\x00**) **ECB** 쿠키가 ECB를 사용하여 암호화된 경우 취약할 수 있습니다.\ 로그인할 때 수신하는 쿠키는 항상 동일해야 합니다. **탐지 및 공격 방법:** 거의 동일한 데이터(사용자 이름, 비밀번호, 이메일 등)를 가진 2명의 사용자를 생성하고 주어진 쿠키 내에서 어떤 패턴을 발견하려고 시도합니다. 예를 들어 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"라는 사용자를 생성하고 쿠키에서 패턴이 있는지 확인합니다(ECB는 모든 블록을 동일한 키로 암호화하므로, 사용자 이름이 암호화되면 동일한 암호화된 바이트가 나타날 수 있습니다). 사용된 블록의 크기로 패턴이 있어야 합니다. 따라서 "a"의 암호화된 묶음이 어떻게 되는지 알면 사용자 이름을 생성할 수 있습니다: "a"\*(블록의 크기)+"admin". 그런 다음 쿠키에서 "a" 블록의 암호화된 패턴을 삭제할 수 있습니다. 그러면 사용자 이름 "admin"의 쿠키를 얻게 됩니다. ## References * [https://blog.ankursundara.com/cookie-bugs/](https://blog.ankursundara.com/cookie-bugs/) * [https://www.linkedin.com/posts/rickey-martin-24533653\_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd](https://www.linkedin.com/posts/rickey-martin-24533653\_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd) **Try Hard Security Group**
{% embed url="https://discord.gg/tryhardsecurity" %} {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}