Blog to Blog

[Webhacking] SOP(Same Origin Policy) 소개와 DNS rebinding을 이용한 우회법(실습 포함) 본문

Hacking/Study

[Webhacking] SOP(Same Origin Policy) 소개와 DNS rebinding을 이용한 우회법(실습 포함)

kookhh0827 2019. 8. 21. 16:31

XSS나 CSRF를 시도하다 보면 마주치게 되는 웹 보안 정책이 두가지가 있습니다.

SOP(Same Origin Policy)와 CSP(Content Security Policy)가 바로 그 대상입니다.

 

이 둘은 기초적인 웹 보안 정책이면서, XSS나 CSRF를 막아주는 중요한 녀석들입니다.

CTF와 같은 실전에서 이를 우회하기 위해서는 이 정책들을 정확하게 알고, 대처하는 방법을 알아두는 것이 좋습니다.

이번 포스트에서는 이 둘중 SOP를 소개하고,

이를 우회하는 방법으로 잘 알려진 DNS rebinding을 자세하게 알려드리도록 하겠습니다.

 

목차

1. SOP(Same Origin Policy)란?

2. DNS Rebinding Attack 소개

3. DNS Rebinding Attack을 위한 DNS Server 소개

4. 실습

5. 결론

 

 

SOP(Same Origin Policy)란?
다른 출처 간 자원 접근 차단 정책

Same Origin Policy를 이해하기 위해서는 먼저 여기서 말하는 Origin이 무엇인지 정확하게 알고 있어야 합니다.

 

웹보안 정책에서 Origin(출처)는 Scheme, Host, Port 이 세가지로 구성되어 있습니다.

이에 대한 것은 Mozilla의 문서에서도 확인할 수 있습니다(https://developer.mozilla.org/ko/docs/Web/Security/Same-origin_policy)

 

먼저 Scheme은 http://나 https://나 ftp://와 같은 URI의 맨 앞에 붙는 문자열을 의미합니다.

이는 클라이언트에서 이를 처리하는 방식을 지정해줍니다. http가 붙으면 해당 프로토콜로 작동하는 것처럼요.

 

다음으로 Host는 "www.tistory.com"이나 "www.google.com"과 같은 도메인을 의미합니다.

이 뒤에 붙는 /index.html과 같은 PATH는 Host에 포함되지 않습니다.

 

마지막으로 Port는 말 그대로 포트입니다. 도메인은 IP와 대응되고, 이 뒤에 포트를 지정해 줄 수 있죠.

"www.tistory.com:8081"과 같이 도메인 뒤에 붙여 접속할 포트번호를 지정할 수 있습니다.

 

아래는 이와 관련된 예제입니다. 이를 보시면 쉽게 이해하실 수 있습니다.

 

기본 출처 : http://kookhh.ml (80포트)

1번 : http://kookhh.ml/some_dir/index.php -> O
2번 : https://kookhh.ml -> X (Scheme이 다름)
3번 : http://google.com -> X (Host가 다름)
4번 : http://kookhh.ml:4301 -> X (Port가 다름)

 

만약 같은 출처가 아닌데 A라는 사이트에서 B라는 사이트로 요청을 보내면 브라우저에서 응답을 읽을 수 없도록 막습니다.

 

A라는 사이트에 있는 script
<script>
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() { 
    if (xhr.readyState === xhr.DONE) { 
      if (xhr.status === 200 || xhr.status === 201) {
        console.log(xhr.responseText);
      } else {
        console.error(xhr.responseText);
      }
    }
  };
  xhr.open('GET', 'https://www.naver.com');
  xhr.send();
</script>

 

A라는 사이트에 위와같은 스크립트가 있다고 생각해 봅시다.

"www.naver.com"이라는 사이트에 XMLHttpRequest로 그냥 요청을 보내서 응답을 console에 뿌려주는 간단한 스크립트에요.

 

만약 이 페이지에 접속하면 브라우저(크롬 기준)는 아래와 같은 에러메세지를 내뱉습니다.

 

kookhh.ml에서 www.naver.com로 요청해도 응답 안줌!

CORS(Cross Orgin Resource Sharing) policy 때문에 XMLHttpRequest가 차단되었다는 메세지입니다.

 

API같은걸 만드는 개발자 입장에서는 이를 해결하기 위해서는 위의 에러 메세지에 적힌 것과 같이 Access-Control-Allow-Origin 헤더를 보내서, 접근을 허용하는 Origin을 정해주면 됩니다.

또는 JSONP를 이용하거나, 서브도메인 간의 접근을 위해서는 document.domain을 이용하는 방법도 있습니다.

하지만 이런 내용은 해킹과는 크게 연관이 없기 때문에 여기에서 다루지는 않겠습니다.

(참고1 : https://sjh836.tistory.com/93, "크로스 도메인 이슈(SOP, CORS)")

(참고2 : https://kingbbode.tistory.com/26, "JSONP 알고쓰자")

 

 

 

 

 

DNS Rebinding Attack 소개
강력한 SOP 우회법

XSS를 할 때는 SOP는 별로 문제가 되지 않을 수 있지만,

CTF에서는 XSS 되는 곳과, 플래그가 숨겨진 곳의 Origin이 다를 때도 있습니다.

이는 Defcon CTF 2019 Quals의 ooops라는 문제에서도 등장한 적이 있습니다(해당 문제 라이트업 : https://ctftime.org/task/8528)

 

사실 CSRF 공격에서도 문제가 되지 않을 때가 있습니다.

그냥 요청만 보내는 것은 SOP에서 막지 않기 때문이에요, 게시글 수정, 삭제, 비밀번호 변경 등의 요청은 이 정책에 구애받지 않고 할수 있어요.

 

하지만 CSRF 토큰을 이용해서 막아뒀다거나, 다른사이트의 쿠키값같은걸 들고오고 싶다면(DOM에 접근하고 싶다면) 당연히 SOP를 우회해서 공격해야 합니다. 

 

여기서 보통 일반적으로 생각할 수 있는 방법이 DNS Rebinding 공격입니다.

DNS Rebinding Attack
악의적인 사이트의 도메인에 할당된 IP를 잠재적인 희생자가 사이트에 들어와있는 동안 공격하고자 하는 사이트의 IP로 바꾸어 Same Origin Policy를 우회하는 방법

이 공격을 하기 위해서는 악의적인 DNS 서버를 하나 파서,

낮은 주기의 TTL로 A라는 도메인에 할당된 아이피가 a라는 IP와 b라는 IP 사이를 왔다갔다 해야합니다.

 

간단한 공격 순서도

 

위 사진이 공격 순서입니다.

 

먼저 희생자(Victim)이 Domain A로 연결합니다. 브라우저는 이 Domain A의 IP를 얻기 위해 DNS 서버에 요청을 보냅니다.

그러면 악의적인 DNS 서버에서 이에 대한 IP가 111.111.111.111이라고 알려줍니다.

이 IP는 우리가 만든 악의적인 스크립트가 심어진 악의적인 페이지입니다.

 

여기서 잠시 뒤에 스크립트가 실행됩니다. 이 스크립트는 Domain A로 요청을 보내고, 응답을 읽어들입니다.

하지만 Domain A에 대한 ttl이 낮아서, 다시한번 브라우저는 IP를 얻기 위해 DNS 서버에 요청을 보냅니다.

 

이번에는 악의적인 DNS 서버에서 이 도메인의 IP가 222.222.222.222라고 알려줍니다.

이제 브라우저가 스크립트를 실행시키는데, Domain A의 IP가 222.222.222.222로 바뀌었기 때문에 실제로 요청은 희생양이 될 사이트로 보내지게 됩니다.

 

브라우저 입장에서는 Domain은 A로 똑같기 때문에, Same Origin Policy에 위배되지 않는다고 생각하고 응답을 읽어들일 수 있도록 허용해줍니다. scheme이나 port는 당연히 똑같이 맞춰줘야겠죠.

 

이렇게 해서 희생자가 사이트에 들어가는 순간의 Domain A에 할당된 IP가 111.111.111.111,

악성 스크립트가 동작하는 순간의 Domain A의 IP가 222.222.222.222로 브라우저에게 인식된다면 공격 성공입니다.

 

 

 

 

 

DNS Rebinding Attack을 위한 DNS Server 소개
whonow, rbndr

이제 이걸 배웠으니 실습을 해보고 싶은데 dns 서버를 직접 파는것은 굉장히 귀찮은 일입니다.

 

그래서 이미 똑똑한 사람들이 이 공격을 쉽게 할 수 있도록 dns 서버를 만들어 놨습니다.

사용법도 굉장히 간단합니다.

 

먼저 whonow입니다.

# respond to DNS queries for this domain with 34.192.228.43 the first time
# it is requested and then 192.168.1.1 every time after that
A.34.192.228.43.1time.192.168.1.1.forever.rebind.network

# respond first with 34.192.228.43, then 192.168.1.1 the next five times,
# and then start all over again (1, then 5, forever...)
A.34.192.228.43.1time.192.168.1.1.5times.repeat.rebind.network

관련 소스는 https://github.com/brannondorsey/whonow 에서 확인할 수 있습니다.

 

A.<ip-address>.<rule>[.<ip-address>.<rule>[.<ip-address>.<rule>]][.uuid/random-string].example.com

사용법은 위와같이 굉장히 간단합니다.

 

A.127.0.0.1.1time.172.217.31.174.1time.repeat.[내 uuid].rebind.network

테스트로 위와 같은 도메인을 확인해보겠습니다.

 

127.0.0.1과 172.217.31.174가 반복된다

 

whonow는 사용법이 조금 더 복잡한 대신 작동하는 방식을 원하는대로 고를 수 있습니다.

 

다음으로 소개드릴 rbndr은 주기적으로 두개의 IP를 응답해서 보내는 것만 지원하지만,

사용법은 매우 간단합니다.

 

base16으로 ip 두개만 넣어주면 된다

관련 소스는 https://github.com/taviso/rbndr 에서 확인할 수 있습니다.

 

<ipv4 in base-16>.<ipv4 in base-16>.rbndr.us

사용법은 위와 같은데 base16을 자동으로 계산해서 url을 만들어주는 사이트도 있습니다.

https://lock.cmpxchg8b.com/rebinder.html

7f000001.acd91fae.rbndr.us

테스트로 위와 같은 도메인을 resolving 해보겠습니다.

 

172.217.31.174와 127.0.0.1이 반복된다

두 서비스 모두 아주 잘 동작하고 있는 것을 알 수 있습니다.

 

 

 

 

실습
브라우저의 캐시와 같은 환경을 고려해야 한다

DNS Rebinding은 상황에 따라 아주 강력한 공격법이 될 수 있습니다.

 

하지만 그전에 항상 간단하게 SOP를 우회할 방법이 있지 않을까 생각해봐야 합니다.

 

예를들어 2019 사이버작전 경연대회에 나온 The Camp라는 문제도 CSP(Content Security Policy)때문에 object 같은걸로 외부의 스크립트를 끌어와서 문제 사이트를 방문하는 봇의 쿠키를 털어야 했는데,

문제 사이트 내에서 특정 페이지에는 이 CSP가 작동하지 않아서 쉽게 해결할 수 있었거든요(해당 문제 라이트업 : https://kookhh0827.tistory.com/6)

 

그리고 앞서 말씀드린 Defcon CTF 2019 qulas - ooops 에서도 문제의 특수한 환경(프록시) 때문에 같은 도메인에 스크립트를 심어서 SOP를 우회하는 방법이 있었습니다.

 

이렇게 말하는 이유는 상황에 따라 공격이 어려울 수 있기 때문입니다.

 

주요한 원인이 브라우저의 캐시인데, 크롬 브라우저는 1분 정도 DNS 캐시를 유지한다고 합니다.

(참고 : https://stackoverflow.com/questions/36917513/how-long-google-chrome-and-firefox-cache-dns-records)

 

DNS 서버에서 바로바로 IP를 바꾸더라도 실제 적용은 1분 뒤에 되기 때문에, 시간적인 제약이 따릅니다.

 

실습을 위해 이를 실제로 실험해봤습니다.

 

<script>
function sleep(ms) { //sleep을 위한 함수
  return new Promise(resolve=>setTimeout(resolve, ms));
}


var count = 0;
async function send_test() {
	await sleep(5000); //5초 기다림
	var xhr = new XMLHttpRequest(); //새로운 XML요청 객체 생성
	xhr.onreadystatechange = function() { //응답이 왔을때 실행될 함수
		if (xhr.readyState === xhr.DONE) { 
			if (xhr.status === 200 || xhr.status === 201) {
				console.log(xhr.responseText); //응답을 콘솔에 찍는다
				count += 1;
				if(count < 30){send_test();}
			} else {
				console.error(xhr.responseText);
				count += 1;
				if(count < 30){send_test();}
			}
		}
	};
	xhr.open('GET', '/'); //본인 host의 '/'로 요청
	xhr.send(); //요청 보냄
} 
send_test();

</script>

간단한 소스코드입니다.

 

5초마다 XMLHttpRequest로 본인의 도메인에 '/'로 요청을 보내서 응답을 읽어옵니다.

총 30번정도 시도하도록 했습니다.

 

whonow를 이용해서 시도했고,

테스트는 제 개인 서버인 kookhh.ml(119.202.94.170)로 했으며

DNS Rebinding으로 정보를 긁어오는 곳은 google.com(172.217.31.174)입니다.

 

A.119.202.94.170.1time.172.217.31.174.1time.repeat.[내 UUID].rebind.network

 

이런식으로 만들어서 테스트했습니다.

 

처음엔 119.202.94.170으로 연결된다
11번 뒤(약 1분 뒤)에 172.217.31.174로 바뀌었다

그 결과 크롬 브라우저(버전 76.0.3809.100(공식 빌드) (64비트)) 에서 약 1분정도 뒤에 IP가 바뀌어 구글로 요청이 보내지는 것을 알 수 있었습니다.

 

그리고 해당 사이트의 응답 또한 console에 잘 찍힙니다.

이 말은 SOP를 우회하고, 희생자의 로컬에서 제가 원하는 동작을 마음껏 하게 한 뒤

응답값까지 정상적으로 읽어올 수 있다는 것입니다.

 

단 1분만 사용자가 악의적인 사이트에 접속해 있도록 하면 됩니다.

 

 

 

 

결론
오래된 기술, 그러나 강력한 공격법

DNS Rebinding 공격은 아주 오래 전에 보고된 기술입니다.

 

하지만 아직도 실제 세계에서도 수많은 기업이 위험에 처해있을정도로 강력한 기술입니다

(http://www.boannews.com/media/view.asp?idx=71611, "전세계 거의 모든 기업들, DNS 리바인딩 공격에 노출되어 있다", 보안뉴스)

 

특히 IOT 기술을 활용한 기기들이 늘어나면서, 로컬 IP를 스캔해서 취약한 기기를 찾고, 해당 기기에 접근해서 정보를 빼오거나 개개인의 집에 침투하는 등의 공격이 가능해졌습니다.

(https://medium.com/@brannondorsey/attacking-private-networks-from-the-internet-with-dns-rebinding-ea7098a2d325, "Attacking Private Networks from the Internet with DNS Rebinding", Brannon Dorsey)

 

그러므로 해킹을 공부하는 입장에서 SOP와 이를 우회하는 DNS Rebinding 공격을 잘 알고있는 것이 중요하다고 생각합니다.

 

이번 포스트가 CTF 문제 풀이나, 화이트해킹에 도움이 되었으면 좋겠습니다.

 

잘못된 부분이나 추가해야 할 부분이 있다면 댓글로 알려주시길 바랍니다.

감사합니다.

 

Comments