출처: dreamhack webhacking 2강 client-side basic
https://dreamhack.io/lecture/courses/7
<Client-side Attack>
공격자는 사용자로부터 본인을 식별하기 위한 사용자 정보, 즉 쿠키나 세션에 저장된 세션 아이디를 탈취해 사용자 권한을 얻거나, 사용자의 브라우저에서 자바스크립트를 실행하는 등의 특별한 행위를 수행해 사용자가 요청을 보낸 것처럼 하는 것이 클라이언트 사이드 취약점의 주 목적입니다.
위와 같은 클라이언트 사이드 취약점이 발생할 수 있는 이유는 웹 브라우저는 Stateful한 상태를 유지하기 위해 모든 HTTP 요청에 쿠키를 함께 보냅니다. 아래는 웹 브라우저가 리소스를 요청할 때 보내는 HTTP 패킷입니다.
GET /resource1 HTTP/1.1Host: dreamhack.ioConnection: keep-aliveUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://dreamhack.io/sandbox
Accept-Encoding: gzip, deflateAccept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: cookie=choco_poco; user_id=adminGET /resource1
HTTP/1.1Host: dreamhack.ioConnection: keep-aliveUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://theori.io
Accept-Encoding: gzip, deflateAccept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: cookie=choco_poco; user_id=admin
>>서로 다른 사이트인 dreamhack.io 와 theori.io에서 dreamhack.io/resource1 에 요청을 보내지만,
동일한 쿠키(cookie=choco_poco; user_id=admin)가 함께 전송되는 것을 확인할 수 있습니다.
웹 브라우저는 HTTP 요청을 생성할 때 시작 주소(Referer)와 상관없이 대상 호스트(Host, A사이트/B사이트..)가 발급한 쿠키를 삽입합니다.
<Same Origin Policy>
"Introduction of Webhacking" 강의에서 자바스크립트를 이용해 페이지 내에 있는 요소들을 관리할 수 있다고 배웠습니다. 또한 웹 브라우저를 통해 대상 호스트에 요청 시 사용자의 정보를 담고 있는 쿠키도 함께 전송되기 때문에 외부 리소스를 불러오는 엘리먼트(iframe, img, video)를 자바스크립트로 관리할 수 있다면 사용자의 동의 없이 해당 내용을 읽거나 변조할 수 있습니다.
예를 들면 dreamhack.io에서 자바스크립트 또는 HTML 태그들을 이용하여 페이스북의 메시지를 보거나, 지메일의 내용을 보는 행위 등을 웹 브라우저 내 사용자의 권한으로 사용할 수 있게 됩니다.
xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.facebook.com/');
xhr.onreadystatechange = function(e){ console.log(e.target.response); };
xhr.send();
>>웹 브라우저가 위와 같은 공격으로부터 사용자를 보호하기 위해 Same Origin Policy(SOP) 정책을 만들었습니다. 이 정책은 서로 다른 오리진의 문서 또는 스크립트 들의 상호 작용을 제한합니다.
오리진은 프로토콜(protocol, scheme), 포트(port)와 호스트(host)로 구성 됩니다. 구성 요소가 모두 일치해야 동일한 오리진이라 할 수 있습니다.
https://same-origin.com/frame.html | same origin | path만 다름 |
http://same-origin.com/frame.html | cross origin | scheme이 다름 |
https://cross.same-origin.com/ | cross origin | host가 다름 |
https://same-origin.com:1234/ | cross origin | port가 다름 |
동일한 오리진이 아닌 경우 웹 브라우저가 사용자를 보호하기 위해 문서 또는 스크립트의 내용을 읽지 못하게 하는 것이 SOP의 대표적인 예시입니다.
SOP 보호 예제
<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 }); }}
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>
CORS (Cross Origin Resource Sharing)
개발 또는 운영의 목적으로 다른 오리진들과 리소스를 공유해야하는 상황이 있을 수 있습니다. 때문에 SOP가 적용된 상태에서도 리소스를 공유하는 방법이 존재합니다.
- postMessage
- 메시지를 주고받기 위한 이벤트 핸들러를 이용해 리소스를 공유합니다.
- JSONP
- 스크립트 태그를 통해 외부 자바스크립트 코드를 호출하면 현재 오리진에서 해당 코드가 실행된다는 점을 이용한 방법입니다. 스크립트 태그를 통해 다른 오리진의 리소스를 요청하고, 응답 데이터를 현재 오리진의 Callback 함수에서 다루는 방식으로 리소스를 공유합니다.
- Cross Origin Resource Sharing (CORS) 헤더 사용
- 다른 오리진이 허용하는 설정 등을 HTTP 헤더를 통해 확인한 후 허용하는 요청을 보내 리소스를 공유하는 방식입니다.
- --CORS 헤더 이용 시 두 오리진이 각각 HTTP, HTTPS 와 같이 서로 다른 스킴을 사용하게 되면 웹 브라우저에서 허용하지 않을 수도 있습니다.
'보안공부 > 배운내용정리' 카테고리의 다른 글
dreamhack03 *0517 update *0528 코드 파헤치기 (0) | 2021.05.14 |
---|---|
dreamhack2-2 (0) | 2021.05.14 |
dreamhack01-2 *0514 (0) | 2021.05.14 |
0507 chapter03.웹 해킹의 기초--비번0000 (0) | 2021.05.07 |
0507 인터넷해킹과보안 chapter2.웹의 이해--비번0000 (0) | 2021.05.07 |