Dreamhack | php-1
Dreamhack php-1
본 문제는 Dreamhack을 통해서 풀어 보실 수 있습니다.
해답을 이해하며 생각을 해보면서 풀이 해보시길 바랍니다.
문제 내용
이번 문제는 LFI 취약점을 이용하여 플래그를 획득하는 문제이다.
LFI 취약점은 Local File Inclusion으로 공격 대상이 되는 서버에 존재하고 있는 파일을 가져와 정보 유출이 가능한 공격이다.
서버에서 include() 사용 시 유저 입력에 대해 적절한 필터링이 이루어지지 않을 때 로컬 파일을 사용할 수 있게 된다.
문제 풀이
<img src ="https://user-images.githubusercontent.com/78135526/236100414-dd4ca156-a400-49bf-a891-f7dcdf75e9b9.png" width = 80%>
해당 페이지에 접속하게 되면 flag.php, hello.json 이 두 링크에 접속이 가능한데 위 사진은 hello.json에 접속했을 때 사진입니다.
URL을 보면 ?page=view&file=../uploads/hello.json 이렇게 구성되어있고, view 페이지를 이용해 입력받는 file의 내용을 보여주는 것으로 보여진다.
하지만 flag.php를 들어가게 되면 Permission denied 허가 거부가 되는 것을 확인할 수 있습니다.
view.php 파일을 보게 되면
<h2>View</h2>
<pre><?php
$file = $_GET['file']?$_GET['file']:'';
if(preg_match('/flag|:/i', $file)){
exit('Permission denied');
}
echo file_get_contents($file);
?>
</pre>
file 파라미터는 flag word를 대소문자 구분하지 않고 필터링 하며, : 콜론마저 필터링하는 것을 알 수 있습니다.
index.php파일을 보면
<div class="container">
<?php
include $_GET['page']?$_GET['page'].'.php':'main.php';
?>
</div>
이 존재하는 것을 알 수 있는데 LFI 취약점은 흔히 include() 사용시 필터링 부재로 인해 종종 일어난다고 말했으나 필터링이 존재하지 않다는 것을 확인할 수 있습니다.
플래그의 위치는 /var/www/uploads/flag.php라 했고 index.php에서 .php확장자를 붙여주기에 page에 /var/www/uploads/flag를 넣어보면 아래와 같다.
<img src ="https://user-images.githubusercontent.com/78135526/236110240-a016290f-88d2-470a-9a91-a591e532c602.png" width = 50%>
글자가 숨어 있는데 해당 문구는 can you see $flag?
해당 방법으로는 볼 수 없는 것으로 보이고 PHP의 변수 타입인 $를 이용하여 $flag를 볼 수 있냐는 것은 파일 내의 변수를 확인하라는 것으로 보인다.
이를 확인하는 방법으로는 PHP Wrapper가 있는데 이는
-
주석, 변수, 등 파일의 전체 내용을 확인해야 할 경우
-
system 커멘드를 사용해야 할 경우
-
zip파일의 압축을 풀고 해당 파일을 실행시켜야 할 경우
이럴때 주로 사용하게 된다.
첫번째 방법을 이용하게 되는데 이는 php://filter를 이용해 서버에의 문서를 인코딩, 디코딩하여 내용을 출력할 수 있다.
www.[희생자 사이트].index.php?page=php://filter/convert.base64-encode/resource=/etc/passwd
이와 같은 링크를 Dreamhack 문제 URL에 입력하여 진행하면
PD9waHAKCSRmbGFnID0gJ0RIe2JiOWRiMWYzMDNjYWNmMGYzYzkxZTBhYmNhMTIyMWZmfSc7Cj8+CmNhbiB5b3Ugc2VlICRmbGFnPw==
값이 나오는데 해당 값을 base64 디코딩을 하게 되면 아래처럼 플래그가 나온다.
<?php
$flag = 'DH{XXXXXXXXXXXXXXXXXXXXXX}';
?>
can you see $flag?