본 포스팅은 DreamHack 사이트의 Client-Side Advanced 강의 내용을 요약한 것입니다.
자세한 내용은 사이트에 들어가셔서 보시기 바랍니다.
https://dreamhack.io/
해커들의 놀이터, DreamHack
해킹과 보안에 대한 공부를 하고 싶은 학생, 안전한 코드를 작성하고 싶은 개발자, 보안 지식과 실력을 업그레이드 시키고 싶은 보안 전문가까지 함께 공부하고 연습하며 지식을 나누고 실력 향상을 할 수 있는 공간입니다.
dreamhack.io
이 강의에서는 Client-Side에서 발생하는 취약점들을 잘못 방어한 사례에 대해서 알아보고 공격하는 방법을 다룹니다.
1. Cross-Site Scripting (XSS)
XSS를 막기 위한 최고의 방법에는 HTML태그나 엔티티 자체를 입력받지 못하게 하고 평문으로 취급하는 것입니다. 하지만 이 경우 다양한 서식을 허용할 수 없게 됩니다. 이를 위해 화이트리스트 필터링을 사용할 것을 권장하나 제대로 이루어지지 않을 경우 우회해서 공격할 수 있게 됩니다.
태그 및 속성 필터링
기본적으로 코드를 실행할 수 있는 HTML 요소는 <script> 이외에도 on과 같이 이벤트 핸들러를 지정하는 속성 등 상당수 존재합니다.
많이 사용되는 on 속성의 종류는 load와 error가 있습니다.
<img src="valid.jpg" onload="alert(document.domain)">
이미지를 제대로 불러옴, onload 실행
<img src="about:invalid" onload="alert(document.domain)">
이미지를 제대로 불러오지 못함, onload 실행 X
<img src="about:invalid" onerror="alert(document.domain)">
이미지를 제대로 불러오지 못함, onerror 실행
<input type="text" id="imputID" onfocus="alert(document.domain)" autofocus>
input 테그에 포커스가 맞춰지면 onfocus 실행
대충 이런 방식들로 사용할 수 있습니다. (이것 말고도 매우 다양한 이벤트가 존재합니다.)
요소의 속성값에서도 <와 같은 HTML 엔티티를 포함할 수 있어서 본래 코드를 숨길 때 사용될 수 있습니다.
*HTML 엔티티: html에서 표기의 혼란을 막기 위해 사용하는 방식입니다.
JavaScript 함수 및 키워드 필터링
JavaScript는 Unicode escape sequence, Computed member access등 코드를 난독화할 수 있는 다양한 기능들을 가지고 있습니다. 그리고 atob, decodeURI와 같은 함수를 사용하여 키워드 등을 부호화해 필터를 우회할 수 있습니다.
*Unicode escape sequence: JS에서 사용가능한 문자열에서 유니코드 문자를 코드포인트로 나타낼 수 있는 표기
*Computed member access: 객체의 특정 속성을 접근할 때 속성 이름을 동적으로 계산함
*atob, decodeURI: 각각 Base64, URI로 인코딩 된 데이터를 디코딩함
문자열 치환
의심되는 XSS구문을 단순히 치환하거나 제거하는 방식입니다. 이 방식은 필터링 되는 문자열 사이에 필터링 되어 사라지는 문자열을 집어넣으면 최종적으로 처음 문자열이 그대로 나타나 필터가 무력화되는 문제점과, 웹 응용 방화벽 등에서 탐지하지 못하는 문제점이 발생합니다.
이를 보완하여 문자열 전체에 변화가 없을 때까지 치환하는 방식이 사용되곤 하지만 미처 고려하지 못한 구문, 방화벽 무력화 등 문제점이 동일하게 존재할 수 있습니다.
활성 하이퍼링크
HTML 하이퍼링크에서 javascript:라는 스키마를 사용하여 URL이 로드되었을 때 해당 코드를 실행할 수 있도록 합니다.
디코딩 전 필터링 (Double encoding 등)
본래의 입력 검증은 디코딩과 같은 모든 전처리 작업 후 이루어져야 합니다. 하지만 일부 웹 응용은 웹 방화벽 등의 필터링 기능에 의존하거나, 데이터를 개별 요소를 추출하기 전 전체 데이터에 필터링하는 경우가 있습니다.
이 경우를 노릴 수 있습니다.
길이제한
삽입될 수 있는 코드의 길이에 제한이 있을 때 다른 경로로 실행할 코드를 URL Fragment와 같이 삽입 후 삽입 지점에는 짧은 코드를 사용하는 방식입니다. 이외에도 쿠키에 페이로드를 저장하는 방식과 import와 같은 외부 자원을 스크립트로 로드하는 방법 또한 사용할 수 있습니다.
2. Content Security Policy (CSP)
XSS가 발생했을 때 그 피해를 줄이고 웹 관리자가 공격 시도를 보고받을 수 있도록 하는 기술입니다. 웹 페이지에 사용될 수 있는 자원에서 위치 등에 제약을 걸어 공격자가 웹 사이트에 본래 있지 않던 스크립트를 삽입하거나 공격자에게 권한이 있는 서버 등에 요청을 보내지 못하도록 막을 수 있습니다. 완전히 무력화할 수는 없으므로 자체적인 방어가 함께 진행되어야 합니다.
CSP 우회- 신뢰하는 도메인에 업로드
CSP를 이용해 특정 웹 사이트에서만 자원을 불러오게끔 할 수 있습니다. 만약 그 특정 웹사이트가 업로드 및 다운로드 기능을 지원한다면 공격자는 해당 사이트에 스크립트 등을 업로드하고 다운로드 주소로 사용하여 우회할 수 있습니다.
이를 해결하기 위해서는 도메인 Origin 대신 해쉬나 nonce 등을 이용하는 방법이 있습니다.
CSP 우회- nonce 예측 가능
nonce를 생성하는 알고리즘이 취약하여 결과를 예측할 수 있다면 공격자는 이를 유추하여 자신의 스크립트를 웹 사이트에 삽입할 수 있습니다. 이를 막기 위해서는 보안상 안전한 의사 난수 생성기(CSPRNG)를 사용하는 것이 좋습니다.
CSP 우회- base-uri 미지정
HTML에 <base> 요소를 사용하면 상대 경로를 지정할 수 있습니다. 즉 어떤 주소가 들어오면 <base>로 지정해 준 주소를 기준으로 해석하게 되는 것이죠. 만일 공격자가 <base href="주소">와 같은 마크업을 사용하게 된다면, 이후 상대경로를 사용하는 모든 주소는 공격자가 지정한 주소를 중심으로 가리키게 되며 이를 통해 임의의 스크립트를 삽입할 수 있습니다.
이를 막기 위해서는 <base> 의 사용을 차단하고 사용하지 않는 방법이 있습니다.
3. Cross-Site Request Forgery (CSRF)
CSRF token은 같은 Origin 내에서만 접근 가능한 형태로 특정 토큰을 저장해 제 3자가 아닌 사용자로부터 요청이 왔다는 것을 인증할 수 있는 방법입니다. 이 방식은 CAPTCHA 또는 암호방식과 달리 추가적인 사용자 상호작용이 불필요하다는 장점을 가지고 있지만 여러가지 보안 문제의 원인이 되고 있습니다.
짧은 CSRF Token
CSRF Token은 충분히 길어야 예측할 수 없습니다.
예측 가능한 CSRF Token
충분히 길어도 예측 가능하면 안됩니다.
CSRF Token 유출
다른 경로로 이 토큰이 제 3자에게 노출되면 안됩니다.
4. Cross-Origin Resource Sharing (CORS)
SOP를 우회하기 위해 설계된 만큼 CORS는 잘못 사용될 경우 사이트 간 공격이 가능해지는 취약점이 발생할 수 있습니다.
현재 사이트에서 다른 사이트로 정보 유출 (기밀성)
CORS는 특정 대상에게만 자원을 공유하고자 하는 사이트에서도 사용될 수 있습니다. CORS 요청을 받을 때 그 Origin에 대한 검사가 진행되지 않고 응답하거나 Origin에 제약이 없는 경우 민감한 정보가 다른 사이트에 유출될 수 있습니다.
다른 사이트에서 현재 사이트 변조 (무결성)
CORS 요청의 Origin이 신뢰할 수 있는 출처인지 확인 또는 제한하지 않거나 CORS 응답을 그대로 사용할 경우 XSS 등 보안 문제가 발생할 수 있습니다.
Window.postMessage API
SOP가 도입되면서 서로 다른 Origin들은 직접적으로 데이터를 공유하지 못하게 되었습니다. 이를 해결하기 위해 고안된 것이 postMessage 메소드입니다.
Window.postMessage API - Origin 미확인 취약점
해당 API를 사용할 때 Origin을 명확히 지정하고 검사해야 합니다. 특정 윈도우는 모든 Origin에서 오는 메시지를 수신할 수 있는데, 이때 message 이벤트 핸들러에서 origin 속성을 검사하지 않고 메시지의 내용을 신뢰하면 보안 문제가 발생할 수 있습니다.
Window.postMessage API - Origin 전환 경합 조건
postMessage를 사용할 때 기억해야 할 점은 메시지를 보내는 대상이 웹 문서가 아닌 창(윈도우)라는 것입니다.
웹 문서는 그 출처가 보통 고정되어 있지만, 윈도우 같은 경우 사용자가 하이퍼링크를 방문하거나 스크립트가 다른 문서로 Redirect 시켜서 들어있는 문서가 바뀔 수 있습니다. 이 상태에서 메시지를 보내면 의도하지 않은 Origin에 메시지가 누출되는 보안 문제가 발생할 수 있습니다.
이를 해결하기 위해서는 postMessage의 두 번째 매개변수인 targetOrigin 에 Origin을 명시하면 됩니다.
JSONP
JSON with Padding의 준말이며 CORS 기술이 도입되기 이전 SOP를 우회하기 위해 흔히 쓰였던 방식입니다. API 제공자의 코드를 그래도 웹 문서에서 실행하기 때문에 API 서버가 침해되면 이를 사용하는 문서 역시 자동으로 XSS 공격에 취약해진다는 단점이 있어 신뢰할 수 있는 API 서버가 아닌 이상 최근에는 그 사용이 줄어들고 있습니다.
이 방식으로 인해 발생할 수 있는 취약점은 다음과 같습니다.
1) Origin 검사 부재로 인한 CSRF
JSONP는 전적으로 HTTP GET 메소드에 의존하기 때문에 CSRF 공격에 더 취약합니다.
2) 콜백 함수면 검증 부재로 인한 제공자 XSS
JSONP 다수는 사용자가 콜백 함수명을 직접 지정할 수 있도록 하고 있습니다. 만일 콜백명에 HTML 코드를 작성한다면 브라우저는 이를 HTML로 인식할 수 있고 XSS가 발생할 수 있습니다.
3) JSONP API 침해 사고 발생 시 사용자 XSS
JSONP API가 침해 사고를 당해 악의적인 응답이 들어온다면 이를 사용하는 모든 사이트는 XSS 공격을 받게 됩니다.
5. Exploit Techniques
XSS 공격과 연계할 수 있는 방법들입니다.
Relative Path Overwrite(RPO)
특정 URL의 하위 경로로 접근해도 같은 웹 페이지가 출력되는 것이 이용해 페이지에서 참조된 상대 경로 URL의 기준점을 바꿀 수 있습니다. 일부 CGI 형태의 웹 스크립트에서 스크립트명 이하의 경로를 지정해도 같은 페이지가 조회되나 상대 경로 자원 참조는 이에 따라 변하지 않는 경우를 이용한 공격입니다.
DOM Clobbering
제 3자에 의해 HTML 마크업이 제공될 때, id나 name과 같은 속성을 이용하여 JS에서 접근할 수 있는 전역변수 공간 또는 객체 속성 공간 상에서 원하는 이름으로 임의의 DOM 객체를 삽입하는 공격입니다. third-party 라이브러리(jQuery 등)과의 상호 작용에서 취약점이 발생할 가능성이 높습니다.
Template / DOM XSS
서버측 XSS 공격과 유사하나 JS에서 innerHTML 등 마크업을 해석하는 속성을 사용하거나 템플릿 라이브러리를 사용할 때 그 마크업 또는 템플릿을 제 3자가 제공 가능할 때 이를 이용해 스크립트를 삽입하는 공격입니다.
CSS Injection
다른 태그들의 사용이 불가능하고, style태그 또는 style속성에 대해서 변조가 가능할 때 사용할 수 있는 방법입니다. CSS의 Attribute Selectors와 HTTP 요청을 생성할 수 있는 문법들을 이용해 현재 문서의 정보를 획득하거나, CSRF 공격으로 연계할 수 있습니다.
자 여기까지 Client-Side Advanced 강의 내용의 요약이었습니다.
자세한 내용은 DreamHack 강의에서 보시기 바랍니다. 그곳엔 예제까지 준비되어 있답니다 ^^
'Hacking-기초 > WebHacking' 카테고리의 다른 글
| 파일 업로드/다운로드 취약점 공격 (0) | 2020.05.27 |
|---|---|
| OWASP Top 10 (0) | 2020.04.26 |
| Server-Side Basic (0) | 2020.04.22 |
| Client-side Basic (0) | 2020.04.21 |
| Introduction of Webhacking (0) | 2020.04.18 |