본문 바로가기
분류 전/CTF

[R3CTF 2025] web-evalgelist 풀이

by jwcs 2025. 7. 13.
728x90
반응형

기능 분석

/

 

<body>
    <div class="container">
        <h1>🔒 Evalgelist - Try secure eval function</h1>
        
        <div class="warning">
            <strong>⚠️ Security Notice:</strong> This system uses advanced filtering to prevent malicious code execution. 
            Only safe PHP functions are allowed.
        </div>

        <form method="GET" action="">
            <div class="input-group">
                <label for="code">Enter PHP function name to validate:</label>
                <input type="text" id="code" name="input" placeholder="e.g., phpinfo, strlen, time">
            </div>
            <button type="submit">🔍 Validate Function</button>
        </form>

        <?php
        if (isset($_GET['input'])) {
            echo '<div class="output">';

            $filtered = str_replace(['$', '(', ')', '`', '"', "'", "+", ":", "/", "!", "?"], '', $_GET['input']);
            $cmd = $filtered . '();';
            
            echo '<strong>After Security Filtering:</strong> <span class="filtered">' . htmlspecialchars($cmd) . '</span>' . "\n\n";
            
            echo '<strong>Execution Result:</strong>' . "\n";
            echo '<div style="border-left: 3px solid #007bff; padding-left: 15px; margin-left: 10px;">';
            
            try {
                ob_start();
                eval($cmd);
                $result = ob_get_clean();
                
                if (!empty($result)) {
                    echo '<span class="success">✅ Function executed successfully!</span>' . "\n";
                    echo htmlspecialchars($result);
                } else {
                    echo '<span class="success">✅ Function executed (no output)</span>';
                }
            } catch (Error $e) {
                echo '<span class="error">❌ Error: ' . htmlspecialchars($e->getMessage()) . '</span>';
            } catch (Exception $e) {
                echo '<span class="error">❌ Exception: ' . htmlspecialchars($e->getMessage()) . '</span>';
            }
            
            echo '</div>';
            echo '</div>';
        }
        ?>
</body>

코드와 함께 분석해보면, 입력값에 대한 필터링이 이루어지고 있다. 그리고 `.();` 을 붙여서 eval을 시켜주는 모습이다.

 

$와 소괄호를 필터링하면서 인자를 받아서 사용하는 함수는 사용을 못하고 있다.

 

phpinfo

테스트를 해보면 phpinfo만 붙이면 서버에서 `.();`를 붙여서 phpinfo();가 실행되고 있다.

 

취약점 분석

version: '3'
services:
  evalgelist:
    build: ../
    environment:
      FLAG: "R3CTF{g00d_j0b_my_fr13nd}"
    ports:
      - 8080:80
    restart: unless-stopped

flag는 환경 변수에 저장되고 있다.

 

#!/bin/sh

rm -f /docker-entrypoint.sh

user=$(ls /home)

if [ "$DASFLAG" ]; then
    INSERT_FLAG="$DASFLAG"
    export DASFLAG=no_FLAG
    DASFLAG=no_FLAG
elif [ "$FLAG" ]; then
    INSERT_FLAG="$FLAG"
    export FLAG=no_FLAG
    FLAG=no_FLAG
elif [ "$GZCTF_FLAG" ]; then
    INSERT_FLAG="$GZCTF_FLAG"
    export GZCTF_FLAG=no_FLAG
    GZCTF_FLAG=no_FLAG
else
    INSERT_FLAG="flag{TEST_Dynamic_FLAG}"
fi

echo $INSERT_FLAG | tee /flag

chmod 744 /flag

php-fpm & nginx &

echo "Running..."

tail -F /var/log/nginx/access.log /var/log/nginx/error.log

우리는 flag 환경변수가 저장되는 것을 확인했다. 따라서 elif ["$FLAG"]에서 true가 되어 R3CTF{g00d_j0b_my_fr13nd}가 /flag로 저장되는 것을 알 수 있다. 그럼 우리는 /flag에 접근하면 될 것이다.

 

1. include DIRECTORY_SEPARATOR . flag;#

2. include [__FILE__][0][0] . flag; time

 

1. include DIRECTORY_SEPARATOR . flag;#

  • include

include는 파일을 포함시키고 실행시킨다. 에러와 함께 flag가 나오는 것을 볼 수 있는데 php 구문인줄 알았으나 그렇지 않아서 발생하는 에러이다.

 

  • DIRECTORY_SEPARATOR

`/`를 의미하는 php 내장 상수이다. PATH_SEPARATOR나 PHP_VERSION 등도 있다.

 

  • .

`.`을 통해 문자열을 이어줄 수 있다.

 

  • flag

앞선 문자열들과 합쳐져서 `include /flag`가 된다.

 

  • #

주석으로 동작한다.

test - 1
test - 2

주석으로 동작하기 때문에 위와 같이 # 뒤에 아무런 값이나 입력해도 아무런 에러가 발생하지 않는 것을 확인할 수 있다.

 

2. include [__FILE__][0][0] . flag; time

여기서는 [__FILE__][0][0]과 time에 대해서만 설명하겠다.

 

  • [__FILE__][0][0]

__FILE__은 현재 파일의 위치를 나타내는 매직 상수이다. 이것 외에도 __DIR__도 있다. __DIR__을 사용해도 동일하게 flag를 얻을 수 있다.

배열이니 뒤에 [0]을 붙여서 첫 번째 요소를 가져오자.

 

그럼 현재 경로가 담긴 요소가 나온다. 여기서 또 대괄호를 이용해서 각 문자열에 접근할 수 있다.

 

위와 같이 `/`를 얻을 수 있다. 만약 1을 사용하면 `/var`의 v를 얻을 수 있다.

 

__DIR__을 사용해도 똑같은 결과를 얻을 수 있다.

 

같은 것을 확인할 수 있다.

 

  • time

에러가 발생하지 않게 아무런 내장 함수를 사용한 것이다. #을 사용해도 되고 큰 상관 없다.

 

flag

R3CTF{g00d_j0b_my_fr13nd}

짜잔

 

728x90
반응형

'분류 전 > CTF' 카테고리의 다른 글

[L3ak CTF 2025] BrainCalc 풀이  (0) 2025.07.15
[L3ak CTF 2025] Flag L3ak 풀이  (0) 2025.07.15
[cubectf] Legal Snacks 풀이  (1) 2025.07.08
[IERAE CTF 2025][WEB] Warmdown 풀이  (0) 2025.06.22
[2024 IS_LAB CTF] meta-data 풀이  (0) 2024.02.07