pear / Archive_Tar

Home Page:http://pear.php.net/package/Archive_Tar

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple vulnerabilities through filename manipulation (CVE-2020-28948 and CVE-2020-28949)

xorathustra opened this issue · comments

I have submitted this to the PEAR bug tracker as well as the PEAR group mailing list, and I'm not sure if either has gone through, so opening an issue here with the hope that this is the right place for it.

While auditing a separate application which uses Archive_Tar internally, I found that Archive_Tar is vulnerable to object injection through Phar unserialization as well as to local file overwriting by crafting the 'filename' of a file in a tar archive.

Phar unserialization

There was a BlackHat talk by Sam Thomas on exploiting PHP's Phar metadata unserialization behavior a couple of years ago, called "It`s a PHP unserialization vulnerability Jim, but not as we know it", which you can look at for more information.[1][2]

Archive_Tar attempts to defend against this kind of an attack with the following code:

private function _maliciousFilename($file)
{
    if (strpos($file, 'phar://') === 0) {
        return true;
    }
    if (strpos($file, '../') !== false || strpos($file, '..\\') !== false) {
        return true;
    }
    return false;
}

This is easily bypassable with a crafted tar archive containing a malicious filename specified as PHAR://malicious_file.phar (scheme in capital letters).

I have attached a fully functional exploit that you can run to confirm this vulnerability, download exploit.zip and run as follows (requires phar.readonly to be disabled in php.ini):

$ unzip exploit.zip -d exploit

$ cd ./exploit/phar_poc/

$ chmod 0755 steps.sh

$ ./steps.sh

Local File Overwrite

While Archive_Tar at least attemps to defend against Phar unserialization, other stream wrappers are left unchecked. This allows us to create a crafted tar archive containing a malicious filename specified as file://path/to/file/to/be/overwritten.

If the PHP process is running under a privileged user, this would allow an attacker to even overwrite files like /etc/passwd or /etc/shadow.

I have attached a fully functional exploit that you can run to confirm this vulnerability, download exploit.zip and run as follows:

$ unzip exploit.zip -d exploit

$ cd ./exploit/file_poc/

$ chmod 0755 steps.sh

$ ./steps.sh

Countermeasure

Change private function _maliciousFilename($file) as follows:

private function _maliciousFilename($file)
{
    if (strpos($file, '://') !== false) {
        return true;
    }
    if (strpos($file, '../') !== false || strpos($file, '..\\') !== false) {
        return true;
    }
    return false;
}

This ensures that along with preventing the above attacks, crafted filenames such as compress.bzip2://phar://exploit.phar also don't pass through. This is a safe check to use because if a filename contains scheme://, it most likely is a malicious file.

It would be great if you could fix and also request a CVE ID?

Attachments: exploit.zip

Thanks for the report! I'll commit your suggested fix and roll out a new release.