본문 바로가기

Hack The Box CBBH

CBBH - Web Attacks[Verb Tampering Prvention]

Verb Tampering은 보통 취약한 서버 구성과 취약한 코드에서 발생한다.

취약한 코드 및 구성을 보고, 이를 수정할 방법을 알아보려 한다.

Insecure Configuration

HTTP Verb Tampering 취약점은 Apache, Tomcat, ASP.NET 등 대부분의 최신 웹 서버에서 발생할 수 있다. 이 취약점은 주로 특정 HTTP Method만 제한하고, 나머지 HTTP Method는 보호하지 않았을 때 발생한다.

Apache 웹 서버의 설정 파일 000-default.conf 또는 .htaccess 파일에서 다음과 같은 구성을 볼 수 있다.

<Directory "/var/www/html/admin">
    AuthType Basic
    AuthName "Admin Panel"
    AuthUserFile /etc/apache2/.htpasswd
    <Limit GET>
        Require valid-user
    </Limit>
</Directory>

위 설정은 /admin 디렉터리에 대한 인증 설정을 정의하고 있다. 하지만 <Limit GET> 을 사용하면 GET 요청에만 인증이 적용되며, POST, HEAD, OPTIONS 등의 다른 HTTP Method는 보호되지 않는다.

 

Tomcat 웹 서버의 설정 파일 web.xml 에서도 비슷한 취약점이 발생할 수 있다.

<security-constraint>
    <web-resource-collection>
        <url-pattern>/admin/*</url-pattern>
        <http-method>GET</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>

위 설정은 /admin/* 경로에서 GET 요청만 보호하며, POST, PUT, DELETE 등의 다른 HTTP Method는 보호되지 않는다.

ASP.NET 웹 애플리케이션의 web.config 파일에서도 같은 문제가 발생할 수 있다.

 

<system.web>
    <authorization>
        <allow verbs="GET" roles="admin">
            <deny verbs="GET" users="*">
        </deny>
        </allow>
    </authorization>
</system.web>

해당 코드에서도 마찬가지로 GET 요청에 대한 접근만 제한하며, POST, HEAD, OPTIONS 등의 다른 Method는 제한되지 않는다.

그렇기 때문에 단일 Method만 설정하는 것은 안전하지 않고 모든 HTTP Method를 항상 허용/거부 해야 한다.

단일 Method를 지정하려면 Apache의 LimitExcept, Tomcat의 HTTP-Method-Nomission과 같은 안전한 키워드를 사용하고 ASP.NET에서는 특정 HTTP Method를 제외한 모든 Method를 포함하거나 제거할 수 있다. 이를 위해 addremove 요소를 활용할 수 있다.

마지막으로 유사한 공격을 피하기 위해 일반적으로 웹에서 필요하지 않는 한 모든 HEAD 요청을 비활성화 및 거부하는 것을 고려해야 한다.

Insecure Coding

웹 서버의 잘못된 설정을 찾아 수정하는 것은 비교적 쉬운 반면, 취약한 코드를 식별하고 패치하는 것은 훨씬 더 어렵다.

그 이유는, 코드에서 이러한 취약점을 찾으려면 함수 전반에 걸쳐 HTTP 매개변수의 사용 일관성을 확인해야 하기 때문이다.

일부 경우에는 이로 인해 보호되지 않은 기능이나 필터가 발생할 수 있다.

다음은 앞에 실습했던 파일 매니저 연습 문제에서 사용된 PHP 코드이다.

if (isset($_REQUEST['filename'])) {
    if (!preg_match('/[^A-Za-z0-9. _-]/', $_POST['filename'])) {
        system("touch " . $_REQUEST['filename']);
    } else {
        echo "Malicious Request Denied!";
    }
}

이 코드에서 Command Injection 취약점만 고려하면 이는 안전할 수 있다. preg_match를 통해 특수 문자를 탐지하고, 입력값에 허용되지 않은 문자가 포함되면 실행되지 않기 때문이다.

그러나 HTTP Method에서 취약점이 발생하게 된다. 해당 필터는 $_POST['filename'] 만 검사하고 있다. 그러나 최종적으로 사용되는 것은 $_REQUEST['filename'] 이므로 GET으로 해당 필터를 우회할 수 있다.

실제 운영되는 웹 애플리케이션에서는 이러한 취약점이 쉽게 발견되지 않을 수 있다. 실제 환경에서는 입력 검증 기능과 파일 생성 기능이 분리되어 있을 가능성이 크다. 따라서 취약점이 코드의 연속된 두 줄에 존재하는 것이 아니라, 여러 함수와 파일에 걸쳐 존재할 가능성이 크다. 그래서 찾아내기가 힘들다.

그래서 이러한 취약점을 방지하려면, 변수 또는 함수에 대한 일관성이 필요하다.

특정 기능에 대해서는 동일한 HTTP Method를 사용해야 한다. 또, 보안 필터를 구현할 때 모든 요청 매개변수를 검사하는 것이 중요하다. 이를 위해 다음과 같은 함수 및 변수를 사용할 수 있다.

PHP $_REQUEST['param']
Java request.getParameter('param')
C# Request['param']