카테고리 없음

[Dreamhack] Apache htaccess

부산영롱 2024. 2. 8. 10:02

 .htaccess란? 

"hypertext access"의 약자로, 파일명 앞의 점은 숨긴파일을 뜻한다.

해당 파일은 디렉토리에 대한 설정 옵션을 제공한다.

즉, 아파치 같은 웹 서버에서 브라우저 같은 클라이언트에서 접근할 시 어떤 식으러 서비스를 제공할지 apache2.conf와 sites-enabled 가상 호스트 설정 파일을 통해 결정하는데, 이 때 서비스할 파일이 위치한 곳의 디렉토리 경로를 지정하게 된다. 그리고 디렉토리의 접근을 허용하는 여부와 어떻게 보여줄지 등을 정하게 된다.

 

sites-enabled에 있는 파일에서 <Directory>블록을 통해 이것을 지정하게 되는데 .htaccess 파일은 이것과 같은 역할을 수행한다. <Directory>블럭을 통한 서버의 전역 설정이 있는 상태에서 .htaccess파일을 사용하면 .htaccess가 위치한 디렉토리에 대한 허용 규칙을 오버라이드(덮어쓰기)하게 된다.


 .htaccess 단점 

아파치 공식 문서에 따르면, 가급적 사용하지 않는 것을 권한다.

htaccess대신 <Directory>항목 설정을 사용할 것을 권하고 있다.

 

.htaccess는 해당 파일이 존재여부를 탐색하기 위해 속도가 느려질 뿐 아니라, 무분별하게 사용하면 소스가 있는 디렉토리에 접근 권한을 클라이언트에게 넘기는 위험한 일이 일어날 수 있기 때문이다.


 .htaccess 장점 

일시적으로 어떤 요청을 기반하여, 웹서버가 동작해야 하는 경우 필요하다.

<Directory>설정은 웹 서버를 재시작할 때만 적용된다.

 

하지만 .htaccess경우, 권한 없는 사용자가 서버 전체에 접근하도록 하지 않고 일시적으로 최소한의 필요 권한만 주기 때문에 요청 작업을 처리할 때에 유용하게 사용된다.


 .htaccess 용도 

허가, 인증, URL재작성, 스팸봇 차단, SSL, 디렉토리 리스팅, 에러 응답 커스터마이징 등

<?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 코드이다. php 확장자 필터링을 하고 있는데 이를 우회하여 웹쉘을 업로드하고 실행해야한다.

다양한 php 확장자 중에 php7은 필터링이 되어 있지 않다는 것을 발견하고 웹쉘 확장자를 .php7으로 지정한 뒤 업로드 해보았다.

필터링에 걸리지 않아 정상적으로 업로드되었지만 웹쉘에 접근해서 명령어를 입력해도 결과가 나오지 않았다.

 확장자 필터링은 우회했지만 .php7 확장자의 php코드가 제대로 실행되고 있지 않는 듯 했다.

 

.htaccess 파일을 통해 정의되지 않은 확장자를 php로 작동하게 만들 수 있다는 사실을 알고 아래 코드를 넣어 업로드했다.

정의되지 않은 .php7과 아예 php계열이 아닌 .txt도 php로 작동되게끔 설정해보았고 두 확장자 모두 업로드 후 명령어가 잘 작동되는 것을 확인했다.

find 명령어를 통해 /flag 파일을 확인했고 실행 권한만 있는 것을 확인하고 아래와 같이 실행하여 플래그를 얻을 수 있었다.