Authentication bypass on What.CD's Gazelle
Fri 13 October 2023 — download

What.CD has been dead since 2016, and hopefully nobody is using Gazelle, their "web framework geared towards private BitTorrent tracker" anymore. I've been sitting on this one for years, I know I wasn't the only one, and it's not the only low-hanging vulnerability lurking there.

Rolling your own blunt is alright, rolling your own authentication scheme less so: there is a trivial padding oracle in the homegrown crypto scheme:

public function decrypt($CryptStr, $Key = ENCKEY) {
    if ($CryptStr != '') {
        $IV = substr(base64_decode($CryptStr), 0, 16);
        $CryptStr = substr(base64_decode($CryptStr), 16);
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $Key, $CryptStr, MCRYPT_MODE_CBC, $IV));
    } else {
        return '';
    }
}

leading to an authentication bypass via a SQL injection:

if (isset($_COOKIE['session'])) {
    $LoginCookie = $Enc->decrypt($_COOKIE['session']);
}
if (isset($LoginCookie)) {
    list($SessionID, $UserID) = explode("|~|", $Enc->decrypt($LoginCookie));

    if (!$UserID || !$SessionID) {
        die('Not logged in!');
    }

    if (!$Enabled = $Cache->get_value("enabled_$UserID")) {
        require(SERVER_ROOT.'/classes/mysql.class.php'); //Require the database wrapper
        $DB = NEW DB_MYSQL; //Load the database wrapper
        $DB->query("
            SELECT Enabled
            FROM users_main
            WHERE ID = '$UserID'");
        list($Enabled) = $DB->next_record();
        $Cache->cache_value("enabled_$UserID", $Enabled, 0);
    }
} else {
    die('Not logged in!');
}

Conveniently, the oracle doesn't touch the database, is completely stateless, and only shows up in the httpd/reverse-proxy's logs, which shouldn't log the cookies' content, making forensic analysis nigh impossible. Once you're admin, there are a bunch of available SQL injections, like in takerevolve.php. From there, remote code execution is doable, but left as an exercise for the reader.