관리 메뉴

Information Security

CORS 본문

Web Security/Bee-Box

CORS

HackingPractice 2019. 11. 30. 19:20

1. CORS (Cross Origin Resource Sharing)

  • 현재 웹 페이지가 이 페이지를 불러온 서버가 아닌 다른 서버의 자원을 호출하는 것을 의미

  • 지정된 도메인 외부에 있는 리소스에 대한 액세스를 제어할 수 있는 브라우저 메커니즘

  • 다른 도메인에서 실행 중인 Web Application에서 선택된 자원에 대한 접근 권한을 부여

 

  • 기존의 XML HTTP Request의 경우 보안상의 이유로 자신과 동일한 도메인으로의 요청만 가능하도록 제한되어 있었지만 웹 개발과 사용 편의성을 높이기 위해 Cross-domain의 필요성을 느껴 만들어진 것이 CORS이다.

  • 자바스크립트의 API에 대한 호출은 SOP의 제약을 받는다. 자바스크립트와 같이 웹 브라우저에서 동작하는 프로그래밍 언어에서, 웹 브라우저에서 동작하는 프로그램은 해당 프로그램이 로딩된 위치에 있는 리소스만 접근이 가능하다. 이를 해결하는 방법으로 CORS라는 방법을 사용한다.
  • CORS 설정은 코드에서 직접 구현할 수 도 있지만 nginx에서 설정을 통해 간단하게 처리가 가능하고 Spring 프레임워크에서 지원을 하고 있어 간단하게 구현이 가능하다.

 

 

XML HTTP Request

- HTTP를 통해서 쉽게 데이터를 주고받을 수 있게 해주는 오브젝트

 

Same-Origin

- 자바스크립트(XML Http Request)로 다른 웹 페이지에 접근할 때는 같은 출처(Same Origin)의 페이지에만 접근이 가능하다. 프로토콜, 호스트 명, 포트가 같다는 것을 의미

 

기준 URL: http://test.company.com/dir/test.html

URL

SOP

Why?

http://test.company.com/dir2/test1.html

O

경로만 다르기 때문에

http://test.company.com/dir/dir2/test2.html

O

경로만 다르기 때문에

https://test.company.com/abc.html

X

프로토콜이 다름

http://test.company.com:81/dir/abc.html

X

포트가 다름

http://abc.company.com/dir/test.html

X

호스트가 다름

3. CORS 보안 위협

  1. 해당 페이지 내의 스크립트 코드 중에 취약점 또는 노출되어 있는 정보를 해커가 만든 사이트로 전송할 수 있음

  2. 내부 네트워크에 존재하는 웹 사이트 Access-Control-Allow-Origin 응답 헤더를 잘못 정의했을 경우 공격자는 외부에서 직접 접근할 수 없는 내부 네트워크에 접속 가능

  3. 사용자의 세션을 탈취할 수 있는 위험이 존재

4. CORS 요청 종류

CORS 요청은 Simple Request, Preflight Request, Credential Request, Non-Credential Request 4가지가 존재한다. 

 

4.1 Simple request(일반적인 Request)

  • GET, HEAD, POST 방식 중 한 가지를 사용해야한다

  • POST 방식일 경우 Content-type이 아래 셋 중의 하나를 선택해야 한다.
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain (지정 없을 시 default)
  • 사용자 지정 헤더를 사용할 수 없다.

 

HTTP Request는 arunranga.com로부터 온 요청이다.

 

 

HTTP Response는 arunranga.com로부터 온 응답이다.

(Access-Control-Allow-Origin: http://arunranga.com)

 

 

 

 

4.2 Preflight Request

서버에 먼저 예비 요청(Preflight Request)를 위해 OPTIONS 메소드를 보내고 서버는 예비 요청에 대해 응답하고, 그 다음에 본 요청(Actual Request)을 서버에 보내고, 서버도 본 요청에 대해 응답을 한다.

  • GET, HEAD, POST 외의 다른 방식으로 요청을 보낼 수 있다.

  • Application/xml처럼 다른 Content-type으로 요청을 보낼 수 있다.

  • 사용자 지정한 헤더를 사용할 수 있다.

4.2.1 Preflight Request 통신

 

예비 요청

 

 

예비 응답

 

 

본 요청

 

 

본 응답

 

 

Request Header

  • Access-Control-Request-Method: 실제 요청 때 사용하는 메소드
  • Access-Control-Request-Headers: 브라우저가 실제 요청을 보낼 때 헤더에 추가할 정의한 속성 

Response Header

  • Access-Control-Allow-Origin: 요청을 허용하는 출처
  •  Access-Control-Allow-Credentials: 클라이언트 요청 쿠키를 통해서 자격 증명을 해야 하는 경우에 true 사용한다. (true 의미는 응답 받은 클라이언트는 실제 요청 시 서버에서 정의된 규격의 인증 값이 담긴 쿠키를 같이 보내야 한다.) 
  • Access-Control-Expose-Headers: 클라이언트 요청에 포함되어 있는 사용자 정의한 헤더
  • Access-Control-Max-Age: 클라이언트에서 preflight의 요청 결과를 지정할 수 있는 시간 (해당 시간 동안은 preflight 요청을 다시 하지 않는다.) 
  • Access-Control-Allow-Methods: 요청을 허용하는 메소드. 기본 값은 GET, POST다.
  • Access-Control-Allow-Headers: 요청을 허용하는 헤더

 

nginx에서 CORS 구성할 때 소스코드 예시

 

 

 

Spring boot에서 CORS 구성할 때 소스코드 예시

 

 

4.3 Credential Request

  • HTTP Cookie HTTP Authentication 정보를 인식할 수 있게 해주는 요청이다. 요청 시 xhr.withCredentials=true로 지정해야 하며, 요청 받은 서버가 Access-Control-Allow-Credentials: true로 반응하지 않으면, 응답을 무시하며 웹 페이지를 사용할 수 없다

  • Access-Control-Allow-Credentials: true  설정이 false 라면 브라우저는 이 요청을 거부를 뜻하고 response 값에 어떠한 메시지도 전달하지 않는다.

4.3.1 Credential Request 통신

 

 

Access-Control-Allow-Credentials: true

 

 

4.4 Non-Credential

withCredentials 플래그는 디폴트 값이 false 이므로 Crendential 요청에서 같이 처리해주지 않는다면 모든 요청이 Non-Credential에 해당된다고 볼 수 있다.

 

4.4.1 Non-Credential 통신

 

 

Credential 통신과 다른 응답 값을 보여준다.

 

 

 

5. CORS 실습

[Cross-Origin Resource Sharing (AJAX) – 난이도(하)]

악의적인 사이트의 AJAX를 이용하여 Neo 계정의 secret을 획득하라는 메시지가 보인다.

 

 

[secret] 클릭 시 Neo 계정의 secret이 출력되는 사이트로 이동하게 된다.

 

 

시나리오 구성

칼리 리눅스를 통해 악성 페이지를 만들어 bee-box NEO계정의 secret 값을 악성 페이지에서 탈취한다.

 

환경구성

칼리 리눅스 [공격자]

192.168.136.130

비박스 [희생자]

192.168.212.112

브라우저의 XSS 필터 옵션을 해제

칼리 리눅스에서 만든 악성 페이지다.

 

 

악성 페이지에 접속을 하면 NEO 계정의 secret 값이 노출되는 것을 알 수 있다.

 

 

비박스 소스코드를 보면 header (‘Access-Control-Allow-Origin: *’) CORS 설정 코드인데 어떤 URL에서든 페이지에 접근이 가능하다는 것을 뜻한다.

 

 

XSS 필터 옵션을 설정하면 아래와 같이 브라우저에서 자동으로 차단하는 것을 알 수 있다.

 

 

[Cross-Origin Resource Sharing (AJAX) – 난이도(중)]

NEO 계정이 아닌 Wolverine 계정의 secret 값을 악성 사이트를 통해 탈취하라는 메시지가 보이고 힌트로, 오직 intranet.itsecgames.com로부터의 요청으로 secret 값을 알 수 있다고 되어 있다.

 

 

Wolverine 계정의 secret 값이 출력되지 않는 것을 알 수 있다.

 

 

악성 페이지에서 Wolverine 계정의 secret 값을 출력되지 않는 것을 알 수 있다.

 

 

소스코드를 보면 $_SERVER[“HTTP_ORIGIN”] 변수를 통해 요청한 URL이

http://intranet.itsecgames.com 인지 확인하고, CORS 설정한 뒤에 Wolverine의 secret 값을 출력해 주는 것을 알 수 있다.

 

 

[Cross-Origin Resource Sharing (AJAX) – 난이도(상)]

Johnny 계정의 secret 값을 탈취하라고 되어 있고 힌트로는 intranet zone을 사용하지 말라는 것을 알 수 있다.

 

 

[secret] 클릭 시 Jonny 계정의 secret 값이 노출되는 것을 알 수 있다.

 

 

악성 페이지에서도 Jonny 계정의 secret 값이 노출되는 것을 알 수 있다.

 

 

소스코드를 보면 CORS 설정이 되어 있지 않는 것을 알 수 있다.

header(‘Access-Control-Allow-Origin: *’); 설정과 같다는 것을 뜻한다.

 

 

XSS 필터링을 설정하면 아래와 같이 브라우저에서 자동으로 차단하고 있다.

 

 

'Web Security > Bee-Box' 카테고리의 다른 글

XML External Entity Attacks (XXE)  (0) 2019.09.21
Remote & Local File Inclusion (RFI/LFI)  (0) 2019.09.21
Directory Traversal – Directories  (0) 2019.09.21
Heartbleed Vulnerability  (0) 2019.09.21
Clear Text HTTP (Credentials)  (0) 2019.09.21