Dreamhack - php-1 (LFI 취약점)

·2025년 7월 28일

Dreamhack-Writeups

목록 보기
28/52
post-thumbnail

php-1

문제 링크

https://dreamhack.io/wargame/challenges/46

문제 설명

php로 작성된 Back Office 서비스입니다.
LFI 취약점을 이용해 플래그를 획득하는 문제입니다. 플래그는 /var/www/uploads/flag.php에 있습니다.

  • LFI 취약점이란?
    • 웹 에플리케이션이 사용자 입력을 기반으로 서버의 파일을 불러올 때, 이를 제대로 검증하지 않아서 의도하지 않은 서버 내부 파일까지 열람할 수 있게 되는 보안 취약점입니다.
    • 예를 들어 아무런 보안 장치가 없을 때, ../../../../etc/passwd 를 입력하면 민감한 파일인 비밀번호 정보를 열람할 수 있는 것입니다.
  • PHP Wrapper 란?
    • PHP 파일을 읽거나 쓸 때, 단순한 파일 경로 뿐 아니라 특정한 프로토콜 형식을 사용할 수 있습니다. 이를 stream wrapper 라 부릅니다.
    • LFI 취약점이 있을 때 PHP Wrapper를 조합하면 더 많은 공격이 가능해집니다.
    1. php://filter – 소스 코드 보기
      http://example.com/index.php?page=php://filter/convert.base64-encode/resource=[파일 이름]
      => [파일 이름] 파일의 내용을 Base64로 인코딩해서 출력하게 합니다. 보통 PHP 설정에서 display_source = Off 되어 있으면 직접 소스코드가 안 보이는데, 우회할 수 있는 방법입니다.
    2. zip:// – 압축 파일 안의 파일 접근
      http://example.com/index.php?page=zip://uploads/something.zip#shell.php
      => something.zip 의 압축을 풀고, 안에 있는 shell.php를 실행시킵니다.

풀이과정

  1. /var/www/uploads/flag.php에 플래그가 있다는 문제 설명을 보고, 바로 http://host1.dreamhack.games:9132/var/www/uploads/flag.php 로 접근을 시도하였지만 404 오류가 떴습니다. 역시 다른 방법이 필요함을 알 수 있습니다.

  2. 주어진 index.php를 확인해 보았습니다.

        <?php
         include $_GET['page'] ? $_GET['page'] . '.php' : 'main.php';
         ?>
    • 사용자가 URL에 page 라는 GET 파라미터를 넣으면 include '입력값.php' 을, page 파라미터가 없으면 include 'main.php'을 싫행합니다.
    • 사용자가 .php 파일명을 조작할 수 있기에 LFI 취약점이 발생합니다.
  3. view.php 를 확인해 보았습니다.

        <?php
         $file = $_GET['file'] ? $_GET['file'] : '';
         if(preg_match('/flag|:/i', $file)){
    • 사용자가 file이라는 GET 파라미터를 주면 해당 값을 $file에 저장합니다.
    • $file 안에 flag나 :가 포함되어 있으면 차단 (Permission denied)합니다. 아니라면, file_get_contents()로 파일 내용을 읽어서 화면에 출력합니다.
    • file_get_contents() 에서 flag: 를 필터링 했지만, 우회 가능하기에 LFI 취약점이 발생합니다.
  4. 문제에서 LFI 취약점 을 이용하라는 힌트가 있었기에, 활용하여 문제를 풀어줍니다. 위에서 설명한 PHP Wrapper 를 사용하면 flag를 획득할 수 있습니다.

  5. 플래그 값을 구해야 하기에, Base64 형태로 소스코드를 볼 수 있는 php://filter 를 이용합니다.

     http://host1.dreamhack.games:9132/index.php?page=php://filter/convert.base64-encode/resource=/var/www/uploads/flag
    • http://example.com/index.php?page=php://filter/convert.base64-encode/resource=[파일 이름] 형식에서 [파일 이름] 에 flag값이 있는 /var/www/uploads/flag.php 에 이동할 수 있도록 경로를 설정합니다.
  6. 파일의 내용을 Base64로 인코딩 한 상태가 나타났습니다.

  7. Base64 변환 프로그램을 통해 플래그를 획득할 수 있었습니다.


배운점

  • 웹 에플리케이션이 서버의 파일을 불러올 때, 제대로 검증하지 않아서 서버 내부 파일까지 열람할 수 있게 되는 LFI 취약점에 대해 알게 되었습니다.
  • 아무런 검증 없이 사용자의 입력을 URL 등에서 사용하면 보안상의 취약점이 생길 수 있음을 알게 되었습니다.
  • LFI 취약점이 있을 때 PHP Wrapper를 사용하면 더 많은 공격이 가능해짐을 알게 되었습니다.
  • 보안을 하는 입장에서, LFI 취약점뿐만 아니라 PHP Wrapper 공격이 가능하지 않게 보안하는 것이 중요함을 알게 되었습니다.

Summary (English)

  • The challenge involves a web service vulnerable to LFI (Local File Inclusion).
  • Key vulnerability: User input (page) is directly included as a PHP file using include, enabling arbitrary file inclusion.
  • Another file (view.php) uses file_get_contents() with minimal filtering (flag and :), still allowing for bypass.
  • PHP Wrappers were used to exploit the LFI:
    • php://filter/convert.base64-encode/resource=[file] allowed viewing the contents of /var/www/uploads/flag.php as base64.
  • By decoding the base64 content, the flag was successfully retrieved.
  • Key learning
    • LFI occurs when user input is included as-is in file operations without proper validation.
    • PHP Wrappers can extend the impact of LFI (e.g., source code disclosure).
    • Effective input validation and restricting file access are crucial for secure PHP development.
profile
CTF 풀이 및 실습 중심 학습을 기록합니다.

0개의 댓글