본문 바로가기
Webhacking/버그바운티

오픈 리디렉션(Open Redirect) 취약점

by Mina-Han 2022. 4. 7.

오픈 리디렉션

오픈 리디렉션은 특정 도메인의 신뢰 관계를 악용해 공격 대상을 악성 웹 사이트로 유인한다.

피싱 공격에서 사실은 사용자 정보가 악성 사이트로 전송되는 중이지만 신뢰하는 사이트로 정보를 전송하고 있다고 사용자를 속이려 리디렉션을 활용할 수도 있다.

오픈 리디렉션을 다른 공격과 함께 활용하면 공격자가 악성 사이트에서 멀웨어를 배포하거나 OAuth 토큰을 훔칠 수 있다.

애플리케이션 보안에 중점을 두며 웹 애플리케이션 분야에서 가장 핵심적인 보안 결함 목록을 관리하는 커뮤니티인 OWASP(Open Web Application Security Project)에서는 2017년 상위 10개 취약점 목록에서 오픈 리디렉션을 제외했다.

오픈 리디렉션은 영향력이 적은 취약점이지만 브라우저가 일반적으로 리디렉션을 처리하는 방법을 배우는 데 유용하다.


오픈 리디렉션 작동 방식

오픈 리디렉션은 공격자가 조작하는 입력값을 개발자가 맹신해 일반적으로 URL 파라미터, HTML <meta> 새로 고침 태그 또는 DOM 윈도우 위치 속성을 통해 사용자를 다른 사이트로 이동하게 만든다.

다수의 웹 사이트가 기존 URL에서 목표 URL을 파라미터로 배치해 의도적으로 다른 사이트로 사용자를 리디렉션한다.

해당 애플리케이션은 이 파라미터를 사용해 브라우저가 목표 URL로 GET 요청을 보내도록 지시한다.

예를 들어 구글에서 다음 URL을 방문해 사용자를 Gmail로 리디렉션할 수 있는 기능이 있다고 가정해보자.

https://www.google.com/?redirect_to=https://www.gmail.com

이 시나리오에서 위의 URL에 방문하면 구글은 GET HTTP 요청을 수신하고 redirect_to 파라미터의 값을 사용해 브라우저에게 리디렉션하려는 위치를 전달한다.

그런 다음 구글 서버는 브라우저에 사용자를 리디렉션하도록 지시하는 상태 코드와 함께 HTTP 응답을 반환한다.

이 HTTP 응답 코드는 브라우저가 페이지를 찾았지만 HTTP 응답의 Location 헤더에 표시된 redirect_to 파라미터 값인 https://www.gmail.com/에 GET요청을 보내도록 브라우저에 지시한다. 

Location 헤더는 GET 요청을 리디렉션할 위치를 지정한다.

 

이제 공격자가 원본 URL을 다음과 같이 조작했다고 가정해보자

https://www.google.com/?redirect_to=https://www.attacker.com

구글이 redirect_to 파라미터가 방문자를 보내려는 올바른 사이트에 속하는지 검증하지 않으면 공격자는 이 파라미터를 공격자의 URL로 변경할 수 있다.

결과적으로 HTTP 응답으로 브라우저가 https://www.<attacker>.com/에 GET 요청을 보내도록 지시할 수 있다.

공격자는 악성 사이트를 방문하게 만든 다음 후속 공격을 할 수 있다.

이러한 취약점을 찾을 때는 url=, redirect=, next= 등과 같은 특정 이름을 포함하는 URL 파라미터를 주의 깊게 살펴봐야 한다.

이 파라미터는 사용자가 리디렉션될 URL을 나타낼 수 있다. 또한 리디렉션 파라미터의 이름이 항상 명확하게 지정되는 것은 아니며, 이 파라미터의 이름은 사이트마다 또는 같은 사이트 안에서도 다르다.

경우에 따라 파라미터를 r= 또는 u=와 같은 단일 문자로 이름 붙인 것을 볼 수 있다.

 

파라미터 기반 공격 외에도 HTML <meta> 태그와 자바스크립트를 사용해 브라우저를 리디렉션할 수도 있다.

HTML <meta> 태그는 브라우저가 웹 페이지를 새로 고치고 태그의 content 속성에 정의된 URL에 GET 요청을 보내도록 지시할 수 있다. 예를 들면 다음과 같다.

<meta http-equiv="refresh" content="0; url=https://www.google.com/">

content 속성은 브라우저가 두 가지 방법으로 HTTP 요청을 하는 방법을 정의한다.

첫째, content 속성은 URL에 HTTP 요청을 보내기 이전에 브라우저가 대기하는 시간을 정의한다. 이번 예제에서는 0초다.

둘째, content 속성은 브라우저가 GET 요청을 하는 웹 사이트의 URL 파라미터를 지정한다.

이번 예제에서는 https://www.google.com이다. 공격자는 <meta> 태그의 content 속성을 제어하거나 다른 취약점으로 태그를 주입할 수 있는 상황에서 이러한 리디렉션 동작을 사용할 수 있다.

 

공격자는 자바스크립트를 사용해 DOM(Document Object Model)으로 window의 location 속성을 수정해 사용자를 리디렉션할 수도 있다.

DOM은 개발자가 웹 페이지의 구조, 스타일, 콘텐츠를 수정할 수 있게 해주는 HTML과 XML 문서용 API다.

location 속성은 요청을 리디렉션해야 하는 위치를 나타내기 때문에, 브라우저는 이 자바스크립트를 즉시 해석하고 지정된 URL로 리디렉션한다.

공격자는 다음 자바스크립트 중 하나를 사용해 window의 location 속성을 수정할 수 있다.

window.location = https://www.google.comm/
window.location.href = https://www.google.com
window.location.replace(https://www.google.com)

일반적으로 window.location 값을 설정할 수 있는 기회는 오로지 공격자가 크로스사이트 스크립팅(cross-site scripting) 취약점을 통해 자바스크립트를 실행할 수 있거나 웹 사이트에서 리디렉션하려는 URL을 정의하도록 허용한 경우에만 발생한다.

오픈 리디렉션 취약점을 탐색할 때에는 일반적으로 테스트 중인 사이트로 전송된 GET 요청으로 URL 리디렉션을 지정하는 파라미터가 포함된 프록시 기록을 모니터링한다.


쇼피파이 테마 설치 오픈 리디렉션

난이도: 낮음
URL: https://apps.shopify.com/services/google/themes/preview/supply--blue?domain_name=<임의의 도메인>
출처: https://www.hackerone.com/reports/101962 
보고 날짜: 2015년 11월 25일
포상금: 500달러

쇼피파이는 이용자가 인터넷 상점을 만들고 상품을 판매할 수 있도록 지원하는 커머스 플랫폼이다.

쇼피파이는 관리자가 테마를 변경해 스토어의 모양과 느낌을 사용자가 수정할 수 있는 기능을 제공했다.

이러한 기능의 일부로 쇼피파이는 스토어 소유자를 URL로 리디렉션해 테마 미리 보기 기능을 제공했다.

리디렉션 URL 형식은 다음과 같다.

https://app.shopify.com/services/google/themes/preview/supply--blue?domain_name=attacker.com

URL 마지막에 있는 domain_name 파라미터는 사용자의 스토어 도메인으로 리디렉션하고 URL의 끝에 /admin을 추가한다. 쇼피파이는 domain_name이 항상 사용자의 상점일 것으로 예상하고 쇼피파이 도메인의 일부에 해당하는지 검증하지 않았다.

결과적으로 공격자는 이 파라미터를 악용해 대상을 악의적인 공격자가 다른 공격을 수행할 수 있는 http://<attacker>.com/admin/으로 리디렉션할 수 있다.

 

이 오픈 리디렉션의 취약점은 domain_name 파라미터를 외부 사이트로 변경하면 사용자를 쇼피파이에서 다른 사이트로 리디렉션했다.

 


쇼피파이 로그인 열기 리디렉션

난이도: 낮음
URL: https://mystore.myshopify.com/account/login/
출처: https://www.hacker.com/reports/103772/
보고 날짜: 2015년 12월 6일
포상금: 500달러

오픈 리디렉션의 두 번째 예제는 첫 번째 쇼피파이 예제와 유사하지만 쇼피파이의 파라미터는 사용자를 URL 파라미터로 지정된 도메인으로 리디렉션하지 않고 파라미터의 값을 쇼피파이 서브도메인의 마지막에 붙이는 차이점이 있다.

일반적으로 이 기능은 사용자를 지정된 스토어의 특정 페이지로 리디렉션하는 데 사용된다.

그러나 공격자는 URL의 의미를 변경하려고 문자를 추가해 이러한 URL을 조작해 브라우저를 쇼피파이의 서브도메인에서 벗어나 공격자의 웹 사이트로 리디렉션 하도록 조작할 수 있다.

 

이 버그에서 쇼피파이는 사용자가 로그인한 이후 checkout_url 파라미터를 사용해 사용자를 리디렉션한다.

예를 들어 공격 대상이 이 URL을 방문했다고 가정해보자.

http://mystore.myshopify.com/account/login?checkout_url=.attacker.com

공격 대상은 쇼피파이 도메인이아닌 http://mystore.myshopify.com.<attacker>.com/ URL으로 리디렉션됐을 것이다. 

URL은 .<attacker>.com으로 끝나고 DNS 조회는 가장 오른쪽 도메인 레이블을 사용하기 때문에 <attacker>.com 도메인으로 리디렉션된다. 따라서 http://mystore.myshopify.com.<attacker>.com/을  조회하려고 전달하면 의도한 것과 달리 myshopify.com이 아닌 쇼피파이가 소유하지 않은 <attacker>.com과 일치하게 된다.

공격자가 자유롭게 공격 대상을 임의의 사이트로 보낼 수는 없지만 마침표와 같은 특수 문자를 조작할 수 있는 값에 추가해 사용자를 다른 도메인으로 보낼 수 있다.

 

사이트에서 사용하는 최종 URL의 일부만 제어할 수 있는 경우 특수 URL 문자를 추가하면 URL의 의미가 변경되고 사용자를 다른 도메인으로 리디렉션할 수 있다.

checkout_url 파라미터 값만 제어할 수 있으며, 또한 이 파라미터는 스토어 URL(http://mystore.myshopify.com/)과 같이 사이트 백엔드의 하드 코딩된 URL과 결합되는 것을 알 수 있다.

리디렉션된 위치를 제어할 수 있는지 테스트하려면 마침표나 @ 기호와 같은 특수 URL 문자를 추가하자.

 


해커원 진입 페이지 리디렉션

난이도: 낮음
URL: 해당 없음
출처: https://www.hackerone.com/reports/1119
보고 날짜: 2016년 1월 20일
포상금: 500달러

일부 웹 사이트에서는 예정된 콘텐츠 이전에 진입 웹 페이지를 표시하도록 구현해 오픈 리디렉션 취약점으로부터 보호하려고 한다.

사용자를 URL로 리디렉션할 때마다 사용자에게 현재 도메인을 떠나고 있음을 설명하는 메시지가 포함된 진입 웹 페이지를 보여줄 수 있다. 그 결과 리디렉션 페이지에 가짜 로그인이 나타나거나 마치 신뢰할 수 있는 도메인인 것처럼 속이면 사용자는 리디렉션 중인 것을 알아차리게 될 것이다.

이는 예를 들어 제출한 보고서의 링크를 따라갈 때와 같이 해커원 사이트의 URL 대부분을 따라갈 때 해커원이 취하는 접근 방법이다.

 

진입 웹 페이지를 사용해 리디렉션 취약점을 피할 수 있지만 사이트 간 상호작용 방식의 복잡성 때문에 링크가 손상될 가능성이 있다.

해커원에서는 https://support.hackerone.com/ 서브도메인에 고객 서비스 지원 발권 시스템인 Zendesk를 사용한다.

이전에는 /zendesk_session을 사용해 hackerone.com을 따라가면 hackerone.com 도메인이 포함된 URL이 신뢰할 수 있는 링크이기 때문에 진입 페이지 없이 브라우저가 해커원 플랫폼에서 해커원의 Zendesk 플랫폼으로 리디렉션됐다.

그러나 임의의 사용자가 사용자 지정 Zendesk 계정을 생성해 /redirect_to_account?state=파라미터로 전달할 수 있다. 그러면 이 사용자 지정 Zendesk 계정은 Zendesk나 해커원이 소유하지 않은 다른 웹 사이트로 리디렉션될 수 있다.

Zendesk는 진입 페이지 없이 계정 간 리디렉션을 허용했기 때문에 사용자는 별도의 경고 없이 신뢰할 수 없는 사이트로 이동할 수 있다. 이에 대한 해결책으로 해커원은 zendesk_session을 포함하는 링크를 외부 링크로 식별해 클릭했을 때 진입 경고 페이지를 화면에 보여준다.

 

이 취약점을 확인하려고 해커인 마흐무드 자말은 Zendesk에서 http://compayn.zendesk.com이라는 서브도메인으로 계정을 만들었다. 그런 다음 관리자가 Zendesk 사이트의 모양과 느낌을 지정할 수 있는 Zendesk 테마 편집기를 사용해 헤더 파일에 다음 자바스크립트 코드를 추가했다.

<script>document.location.href = ?http://evil.com?;</script>

이 자바스크립트를 사용해 자말은 브라우저가 http://evil.com을 방문하도록 지시했다.

<script> 태그는 HTML 코드를 나타내며 document는 Zendesk에서 반환하는 전체 HTML 문서(웹 페이지 정보)를 나타낸다.

document 다음에 나오는 점과 이름은 document의 속성에 해당한다.

속성에는 객체를 기술하거나 객체를 변경하려고 조작할 수 있는 정보와 값이 있다.

따라서 location 속성을 사용해 브라우저가 표시하는 웹 페이지를 제어하고 href 하위 속성(location의 속성)을 사용해 브라우저를 정의한 웹 사이트로 리디렉션할 수 있다.

다음 링크를 방문하면 공격 대상이 자말의 Zendesk 서브도메인으로 리디렉션돼 대상의 브라우저가 자말의 스크립트를 실행하고 http://evil.com로 리디렉션됐다.

https://hackerone.com/zendesk_session?locale_id=1&return_to=https://support.hackerone.com/ping/redirect_to_account?state=compayn:/

링크에 hackerone.com 도메인이 포함되어 있기 때문에 진입 웹 페이지가 표시되지 않으며, 사용자가 방문한 페이지가 안전하지 않은 것을 사용자는 눈치 채지 못할 것이다.

 

취약점을 탐색할 때 사이트에서 사용 중인 서비스는 각각 새로운 공격 경로로 활용할 수 있기 때문에 유심히 살펴보자.

이 해커원 취약점은 Zendesk를 사용하는 것과 해커원에서 허용하는 리디렉션을 결합함으로써 가능한 취약점이었다.

 


요약

  • 공격자는 오픈 리디렉션으로 사람들이 눈치 채지 못하게 악성 웹 사이트로 리디렉션할 수 있다.
  • 리디렉션 파라미터는 redirect_to=, domain_name, checkout_url=와 같은 이름을 보고 쉽게 찾을 수 있다. 다른 예로 r=, u= 등과 같은 명확하지 않은 이름을 사용할 수도 있다.
  • 오픈 리디렉션 취약점은 공격 대상이 알고 있는 사이트를 방문한다고 생각하는 동안 공격자의 사이트를 방문하도록 속임으로써 신뢰를 악용한다.
  • 취약할 가능성이 있는 파라미터를 발견하면 URL의 일부가 하드 코딩됐는지 마침표와 같은 특수 문자를 추가해 파라미터를 철저히 테스트해야 한다.

 

 

 

**피터 야로스키, Real-World Bug Hunting(실전 버그 바운티)를 참고하여 작성

'Webhacking > 버그바운티' 카테고리의 다른 글

CSRF(Cross-Site Request Forgery) 공격  (1) 2022.04.13
HTTP 파라미터 오염  (0) 2022.04.08
버그 바운티 기본 사항  (0) 2022.04.04

댓글