The Internet is a very dangerous place to be. This is true for everyone, from your humble user right up to a boutique security firm specialising in writing nation-state grade espionage platforms.
Last Sunday the Italian firm ‘Hacking Team’, famous for selling espionage software to repressive governments, got hacked.
The hackers proceded to leak 400GB of internal sensitive data from Hacking Team’s networks. If the irony has not yet sunk in, here’s a leaked email referencing the hack of Gamma Group (Another company not known for it’s pre-sales vetting process). The Gamma Group hacker (who goes by the name of “Phineas Fisher”) has since claimed responsibility for hacking ‘Hacking Team’.
Whilst reading emails and documentation is all well and good, of more interest is source code and binaries contained within the dump. Hacking Team’s primary product is the ‘Galileo Remote Control System’ or RCS for short, and pretty much the entire source code has been released. Why are we looking through another company’s internal documents? As network defenders we face a constant battle against threat actors who write highly complex tools to achieve their malicious objectives. Malicious actors will take the source code from this leak and use it to create new tools (similar to the leak of the Zeus source code); as defenders we therefore want to understand the capabilities of these pieces of software, and how to create defences against them.
For most malware authors, their operations are shut down when Kaspersky/Sophos/Symantec releases a report after having painstakingly reverse-engineered their malware. In Hacking Team’s case, we have clear source code and helpful English/Italian comments. We even have installers, designed for the end user (government) to run on their servers.
In comparison to traditional malware platforms, the RCS backend has a very modular architecture. Whilst traditional platforms such as Zeus will use a single server as a command and control (C2) server, the RCS has a separate master database, ‘collector’ instance and console interfaces.
RCS Architecture from the leaked Sysadmin manual
Another interesting element are the ‘anonymizers’, essentially proxies that compromised machines talk through to get back to the C2 setup.
If you’re interested in how they work, don’t worry, the source code is all there:
Unfortunately the latest version of the RCS (9.6) requires a hardware dongle in order to use. We’ll just have to settle with extracting the raw files. After extracting the agent cores, we can see the RCS supports a large variety of devices.
We’ll focus on the windows agents for now, and try to see exactly what features they support. Straight away we can see there are three levels of agent - Scout, Soldier and Elite. Each level adds more features above the previous level. This is consistent with threat actors such as Duqu, who will install a small backdoor to validate that the target is interesting before deploying the full espionage platform.
The Scout agent is designed as a lightweight agent to be dropped with an exploit. It gathers system information and screenshots, before sending them back to the operator. The ‘Scout’ will then be upgraded to a ‘Soldier’ or ‘Elite’ implant based on an operators decision. All of the agents check if they’re running in a virtualised environment before continuing.
BOOL AntiVM()
{
AntiCuckoo();
BOOL bVMWare = AntiVMWare();
BOOL bVBox = AntiVBox();
if (bVMWare || bVBox)
return TRUE;
return FALSE;
}
Of particular interest is the AntiCuckoo() function, which does some pointer magic to confuse the Cuckoo Sandbox.
VOID AntiCuckoo()
{
LPDWORD pOld, pFake;
pFake = (LPDWORD) malloc(4096*100);
memset(pFake, 1, 4096*100);
__asm
{
mov eax, fs:[0x44] // save old value
mov pOld, eax
mov eax, pFake // replace with fake value
mov fs:[0x44], eax
}
// this will not be logged nor executed.
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Sleep, (LPVOID) 1000, 0, NULL);
__asm
{
mov eax, pOld // restore old value, not reached if cuckoo
mov fs:[0x44], eax
}
free(pFake);
}
Following the virtualisation check, the agents try to determine if there what pieces of software are running on the machine using WMI queries. These are compared against a blacklist, and the agent terminates if it finds any of these:
360杀毒
360安全卫士
AdAware
AVG
Bitdefender
Comodo
Dr.Web
Emsisoft
G Data
IObit Malware Fighter
Касперского
Kaspersky
Online Armor
Outpost
Roboscan
Sophos
There’s also a set of analysis tools that are blacklisted
Explorer Suite$ # CFF Explorer Suite
IDA Pro v # IDA Pro vx.xx
Wireshark # Wireshark x.x.x
API Monitor # Api Monitor vx
VMWare Tools # Virtual Machine
WinPcap # Network analyzer
^Syser # Syser x.xx
.NET Reflector # .NET Reflector Desktop
^PE Explorer # PE Explorer 1.xx Rx
^SysAnalyzer # SysAnalyzer 1.x
Python .* volatility # Volatilty
VirtualBox Guest Additions # Virtual Machine
Process Hacker # Process Hacker x.xx
Mandiant Red Curtain #
^OSForensics #
Unusually, the agents use shared memory to determine if other implants are running on the same machine, this is different to the normal malware technique of using Mutexes.
// first check for elite presence
BOOL bVM = AntiVM();
BOOL bElite = ExistsEliteSharedMemory();
if (bVM || bElite)
{
#ifdef _DEBUG
OutputDebugString(L"[+] An ELITE backdoor is already installed here!\n");
#endif
if (bElite && AmIFromStartup()) // FIXME: questo nn puo' essere..
DeleteAndDie(FALSE);
if (uMelted)
{
*uSynchro = 1;
ExitThread(0);
}
else
return 0;
}
// check if I'm already running
if (ExistsScoutSharedMemory()) // FIXME - mi deleto perche' puo' essere il soldier, tanto se trova la shared mem vuol dire che c'e' un altro scout
{
#ifdef _DEBUG
OutputDebugString(L"[+] Scout already active\n");
#endif
if (uMelted)
{
*uSynchro = 1;
ExitThread(0);
}
else
return 0;
}
The function to create this shared memory mapping uses a variable called ‘CLIENT_KEY’ that is defined in the configuration file. Unfortunately, this means it’s not suitable to create an indicator of compromise.
PCHAR GetScoutSharedMemoryName()
{
CHAR strFormat[] = { '%', '0', '2', 'X', '%', '0', '2', 'X', '%', '0', '2', 'X', '%', '0', '2', 'X', '%', '0', '2', 'X', '%', '0', '2', 'X', '%', '0', '2', 'X', '' };
PCHAR pName = (PCHAR) malloc(20);
if(pName == NULL)
return NULL;
memset(pName, 0x0, 20);
_snprintf_s(pName,
20,
_TRUNCATE,
strFormat,
pServerKey[2], pServerKey[4], pServerKey[3], pServerKey[5], pServerKey[4], pServerKey[0], pServerKey[1]);
return pName;
}
So what capabilities do these implants actually have? The three levels are summarised below:
Scout:
- Gather Device Information
- Get Screenshots of device
- Get Webcam photos
- Get Social Networking Information
Soldier:
- Gather Addressbooks Gmail, Yahoo Mail, Facebook, Twitter (Following).
- Enumerate Applications
- Gather Camera Data
- Gather Clipboard Data
- Gather Google Drive Data
- Gather Twitter, Gmail, Yahoo (mail e chat), Facebook (Chat) messages
- Gather IE, Chrome, Firefox passwords
- Gather Photos
- Get Position Data
- Get Screenshots
- Get Visited URLs from Firefox, TOR Browser
- Upload/Download Files
- Upgrade to Elite
And finally the ‘Elite’ agent.
- Gather Skype Calls
- Access the Filesystem
- Record Keystrokes
- Gather email from Outlook/WindowsMail/LiveMail, Gmail webmail, Yahoo.
- Gather audio from the microphone
- Gather Financial Data
- Gather mouse movements and clicks
- Gather passwords from Internet Explorer, Firefox, Chrome, Opera, Outlook, PalTalk, Thunderbird, Trillian.
We can see that these implants are primarily designed to gather ’evidence’ on a target system, and don’t include any of the spreading or network discovery elements of full espionage platforms such as Duqu 2.0 or Regin. This is still a large feature set however, and it is self-evident how this information could be used by a government or state entity.
Moving forward, the next stage of analysis is to build these agents ourselves, and see if we can control them using the leaked backend code. In the meantime, you can enjoy browsing the document set yourselves.