<1/2>웹해킹 5주차 과제 뚜두두두두두두둥 [XSS]
(1) https://www.youtube.com/watch?v=DoN7bkdQBXU
XSS 공격은 공격에 대한 보안이 되어있지 않은 웹사이트에 할 수 있는 공격
script 태그로 감싼 코드가 게시판과 같은 곳에 글로 올라갔을때 웹브라우저가 이를 그냥 문자열로 인식하지 않고 자바스크립트 코드로 인식하게 됨으로써 공격 성공!
나동빈님 목소리는 신기하다
(2)https://dreamhack.io/lecture/curriculums/1
클라이언트 사이드 취약점의 주 목적
공격자는 사용자로부터 본인을 식별하기 위한 사용자 정보(쿠키, 쿠키에 저장된 세션 아이디)를 탈취해 사용자 권한을 얻거나, 사용자의 브라우저에서 공격자가 작성한 JS코드를 실행 또는 특별한 행위를 수행하도록 하여 사용자가 보낸 것처럼 서버에 요청을 전송하는 것
<= 웹 브라우저는 Stateful한 상태를 유지하기 위해 모든 HTPP요청에 쿠키를 함께 보내기 때문에 발생하는 취약점
서로 다른 사이트(dreamhack.io / theori.io)에서 dreamhack.io/resource1으로 요청을 보내지만 맨 아래의 쿠키는 같은 것을 확인할 수 있다.
이 이유는 웹브라우저는 HTTP 요청을 생설할 때 시작주소(Referer, 위의 예에서는 dreamhack.io와 theori.io)와 상관없이 대상 호스트(Host, 위의 예에서는 dreamhack.io)가 발급한 쿠키를 삽입하기 때문에 그렇당!
자바스크립트로 외부 리소스를 불러오는 엘리먼트들(iframe, img, video)을 관리할 수 있다면 사용자의 동의 없이 해당 내용을 읽거나 변조할 수 있게 된당. 예를 들어 특정 웹사이트에 접속할때 그 사이트에 iframe으로 페이스북 등이 불러와져 있다면!? 사용자의 쿠키가 전송되게 되고!? 공격자는 웹 브라우저 사용자 권한으로 나쁜 짓 가능!
이와 같은 공격에서 사용자를 보호하기 위해 Same Origin Policy(SOP) 정책이 존재.
오리진은 프로토콜(protocol, scheme), 포트(port), 호스트(host)로 구성되는데 이 3박자가 쿵짝쿵짝 맞아줘야 동일한 오리진으로 인식.
프로토콜, 포트, 호스트 3박자가 모두 쿵짝 맞기에 이는 동일한 오리진으로 인식한다.
뒤에 path만 다른 오리진이다. path는 오리진의 구성요소에 들어가지 않기에 나머지가 같다면 동일한 오리진으로 인식한당.
기존의 오리진의 포트값은 443인데 8080포트로 접속을 시도하자 다른 오리진으로 인식한다.
scheme을 바꿔줬는데 포트도 다르게 인식한다!? 왜징, https는 443포트였는데 http로 바꾸자 80번 포트로 접속을 시도한다.
<iframe src="" id="my-frame"></iframe>
<script>
let myFrame = document.getElementById('my-frame')
myFrame.onload = () => {
try {
let secretValue = myFrame.contentWindow.document.getElementById('secret-element').innerText;
console.log({ secretValue });
} catch(error) {
console.log({ error });
}
}
/*13번라인*/const fn1 = () => { myFrame.src = 'https://same-origin.com/frame.html'; }
const fn2 = () => { myFrame.src = 'https://cross-origin.com/frame.html'; }
</script>
<button onclick=fn1()>same origin</button><br>
<button onclick=fn2()>cross origin</button>
<!-- frame.html -->
<div id="secret-element">treasure</div>
위와 같은 코드에서 13번 라인은 same origin 페이지를 불러오는 역할을 한다. 성공적으로 iframe에 로드되면 onload 핸들러가 해당 iframe의 secret-element 값을 가져온당. 14번 라인도 비슷한 역할을 하지만 이는 same origin이 아닌 cross origin 페이지를 불러온다.
따라서 fn1()을 실행하게 되면 콘솔 창에 secret value인 treasure가 출력되고, cross origin을 로드하는 fn2()을 실행하게 되면 익셉션(예외)이 출력된다.
하지만 개발 또는 운영의 목적으로 다른 오리진들과 리소스를 공유해야 하는 상황이 발생하면서, SOP가 적용된 상태에서도 리소스를 공유하는 방법도 생겨났다!
postMessage
메시지를 주고받기 위한 이벤트 핸들러를 이용해 리소스를 공유한다.
JSONP
스크립트 태그를 통해 외부 자바스크립트 코드를 호출하면 현재 오리진에서 해당 코드가 실행된다는 점을 이용한 방법
스크립트 태그를 통해 다른 오리진의 리소스를 요청하고, 그에 따른 응답 데이터를 현재의 오리진의 callback 함수에서 다루는 방식
Cross Origin Resource Sharing(CORS) 헤더 사용
다른 오리진이 허용하는 설정 등을 HTTP 헤더를 통해 확인한 후, 허용하는 요청을 보내 리소스 공유(무단으로 사용이 안댐)
Cross Site Scripting(XSS)
서버의 응답에 공격자가 삽입한 악성 스크립트(대표적으로 HTML ,JS 등)를 받은 사용자의 웹 브라우저에서 그 악성 스크립트가 실행되는 취약점을 의미
아래의 2가지 조건을 충족해야 XSS 공격을 성공적으로 수행 가능.
1.입력 데이터에 대한 충분한 검증 과정이 없어야한다.
-악성 스크립트가 개발자가 설정해놓은 검증 과정을 통과해야 삽입될 수 있으므로 충분한 검증이 이루어지지 않아야 확률 업!
2.서버의 응답 데이터가 웹 브라우저 내 페이지에 출력시 충분한 검증 과정이 없어야 한다.
-응답 데이터 출력 시 악성 스크립트가 웹 브라우저의 랜더링 과정에 성공적으로 포함되어야 한다!
<XSS with Javascript>
주로 script 태그를 이용하는 방식을 사용=> 공격자가 입력 데이터로 script 태그를 전송해 다른 사용자의 응답에 포함되면, 공격자의 자바스크립트가 실행된다!
on* 이벤트(특정 상황에서 발생)를 이용하는 방식도 존재
공격자의 주소로 현재 페이지의 쿠키를 요청하는 코드!(아직 잘 모르겠당ㅎㅎ)
페이지가 출력하고 있는 데이터를 변조시킨다.
공격자가 정해놓은 웹사이트로 이동하게끔 함
XSS는 두가지 방법으로 나뉜다.(근본적인 공격 방법은 같음)
Stored XSS 와 Reflected XSS
<Stored XSS>
Stored XSS는 이름에서 대충 유추가능 하듯이 악성 스크립트가 서버 내에 존재하는 DB 또는 파일 등의 형태로 저장되어 있다가(stored) 사용자가 저장된 악성 스크립트를 조회하는 순간 발생하는 형태의 XSS. ex)게시판에 작성된 게시물을 조회하는 순간 악성 스크립트 실행
위와 같이 작성된 게시물은 사용자가 조회하는 순간! 기분 나쁜 문구가 경고창으로 출력된다.
<Reflected XSS>
Reflected XSS는 악성 스크립트가 사용자의 요청 시 전송되는 형태이다. 사용자의 요청 데이터가 서버의 응답에 포함되는 과정에서 악성스크립트가 그대로 출력되어 두두두둥 발생.
사용자의 요청 데이터에 의해 취약점이 발생한다는 특징 때문에, 변조된 데이터가 사용자의 요청으로 전송되는 형태를 유도하여야한다.
ex) 사용자가 게시물 조회를 요청 시 서버는 해당 요청에 대하여 조회한 결과를 응답에 출력하는데, 이 과정에서 편의성을 위해 사용자가 조회한 내용을 응답에 그대로 포함시킨다. 이때 조회한 내용이 악성 스크립트라면 이는 페이지를 출력 시 반영(Reflect)되므로 XSS로 이어진다.
이런 XSS를 막기 위한 방어 기술들이 많다. 브라우저 단에서 방어하는 기술뿐만 아니라 서버 내부에 저장하는 시점 혹은 저장된 데이터를 꺼내와 출력하는 시점에서 입력값을 올바르게 가공하는 방식으로 XSS를 막곤 한다.
방어 기술에는 Server-side Mitigations, HTTPOnly 플래그 사용, Content Security Policy 사용, X-XSS-Protection 등이 존재
<Server-side Mitigations>
XSS를 유발할 수 있는 태그(script 태그) 삽입을 방지하기 위해 서버 단에서 검증하는 방법
사용자의 입력값이 HTML 코드 형태를 지원할 필요가 없다면, 태그에 사용되는 꺽쇠(<,>), 따옴표(",')와 같은 특수 문자를 HTML Entity Encoding을 이용해 태그로써 인식이 안되도록 할 수 있다.!
HTML 코드 형태를 지원해야 한다면, 화이트리스트 필터링을 해야한다.
화이트리스트 필터링이란!? 허용해도 안전한 일부 태그, 속성을 제외한 모든 값을 필터링 하는것
사용자의 인풋을 필터링 할때 요청의 URL Query 값이나 POST Body 값만 필터링 할 것이 아니라 User-Agent, Referer와 같은 헤더도 모두 포함하여 사용자로부터 온 값에 모두 적용해야 함을 유의하자!!
<HTTPOnly Flag>
서버 측에서 응답 헤더에 Set-Cookie 헤더를 전송해 쿠키를 생성할 때 옵션으로 설정 가능하며 자바스크립트에서 해당 쿠키에 접근 하는 것을 금지한당. 이렇게 하면 XSS취약점이 발생해도 공격자가 알아낼 수 없는 쿠키값이기 때문에 이 방법 추천!
< Content Security Policy(CSP) >
CSP는 응답 헤더나 메타 태그를 통해 위와 같이 선언&사용 가능하며, 각각의 지시어를 적용하여 사이트에서 로드하는 리소스들의 출처 제한 가능
위와 같이 설정된 CSP는 모든 리소스들의 출처가 현재 도메인(self)이거나 *dreamhack.io 도메인이 출처인 경우만 허용
script-src를 선언해 자바스크립트 코드의 출처도 제한, 외부에 업로드된 자바스크립트 파일을 호출 또는 직접 코드 작성 등의 행동을 막을 수도 있음
script 태그 안의 자바스크립트 코드의 해시를 미리 구해 CSP를 설정한 후, alert(1)을 성공적으로 호출하는 코드다.
<X-XSS-Protection Header> <--요즘은 사용 안하는 추세-->
이는 웹 브라우저에 내장된 XSS Filter를 활성화할 것인지를 설정한다. XSS Filter는 웹 브라우저에서 전송된 Request 값이 XSS 공격코드와 유사하게 생겼고, Response에 해당 공격코드가 포함되었을 경우에 XSS 공격이 수행되었다고 판단, 유저에게 이 사실을 알리고 차단한다. Request 값과 Response 값을 비교해 판단함으로 Reflected XSS 공격을 막는데에는 적합, but 다른 공격 방법에는 영,,
해당 Header를 선언하지 않았을 때의 브라우저 기본값은 1=> 기본으로 작동. 0은 사용 X
값이 1일때 XSS 공격이 감지되면 해당 부분만 제거한 후 나머지 부분은 그대로 출력
mode=block일 경우 XSS공격이 감지되면 페이지 전체의 렌더링 중단
report를 선언할 경우 XSS공격이 감지된 사실을 미리 설정된 주소에 신고하여 운영자가 대처하기 쉽도록 도와줄 수 있다.
댓글
이 글 공유하기
다른 글
-
웹해킹 5주차 과제 모음 뚜둥
웹해킹 5주차 과제 모음 뚜둥
2020.05.15 -
<2/2> 웹해킹 5주차 과제 뚜두두두두두두두두둥 [XSS]
<2/2> 웹해킹 5주차 과제 뚜두두두두두두두두둥 [XSS]
2020.05.15 -
웹해킹 4주차 [ PHP 학습 & 워 게임~]
웹해킹 4주차 [ PHP 학습 & 워 게임~]
2020.04.16 -
웹해킹 스터디 3주차 과제(Javascript 학습 & 워게임)
웹해킹 스터디 3주차 과제(Javascript 학습 & 워게임)
2020.04.07