23/11/2011

Studying Cidox

Introduction

When I saw article from Xylitol's blog about Tracking Cyber Crime: Malwox (Win32/Cidox Affiliate) Mayachok.1, I asked my irc bot to scan each hour files dropped by this site to make some stats about repacking interval ( you can see a screenshot of statistics in next part).
It's cool to have a lot of samples but it's more funny to study them.

Statistics

stats_cidox.png

As you can see it is repacked approximately each 5 / 6 hours to avoid AV detections.
At the moment the bot is in beta test, and many logout occur every time I have to recompile it, so stats are approximate.

Dropper

Here, I will not study packer, but just the method of infection which is not very interesting (and old school ?).

call    ds:GetCommandLineA
push    offset aChk     ; " /chk"
call    strcmp
pop     ecx
test    eax, eax
jz      short if_arg_not_chk
Finding this test was funny, if the unpacked executable found "/chk" on his command line argument, it will exit directly, maybe for testing their repack routine (~5hours).
If it don't find this argument, it will generate a random dll name using this routine :
void generate_name(void)
{
	char	SysPath[256];
	char	VolumeName[256];
	char	SystemName[256];
	char	DLLName[256] = {0};
	DWORD	SerialNumber;
	DWORD	MaxFileName;
	DWORD	SysFlags;
	int		i;
	unsigned int		a;

	GetSystemDirectoryA(SysPath, 256);
	GetVolumeInformationA("c:\\", VolumeName, 256, &SerialNumber, &MaxFileName, &SysFlags, SystemName, 256);
	for (i = 0; i < 8; i++)
	{
		SerialNumber *= 0xD;
		SerialNumber += 0x12D687;
		SerialNumber = _byteswap_ulong(SerialNumber);
	}
	for (i = 0; i < 7; i++)
	{
		a = SerialNumber;
		SerialNumber /= 0x1A;
		DLLName[i] = a % 0x1A + 97;
	}
}

For example :

SerialNumber = 1880116967
Dll name = avjemfc.dll

The dll is then decrypted using custom TEA Algorithm ( we will study it in next part ), and written into %SYSTEMROOT%/system32.
Next it sets into a registry key the AppInit_Dlls value which is the path to this dll, in order that each process using user32.dll will load this dll.
Before restarting your computer with ExitWindowsEx(), it will delete all files present into :

They use SHGetSpecialFolderPath() with csidl argument equal to CSIDL_COOKIES and CSIDL_INTERNET_CACHE to delete them.
Maybe for cleaning traces of infection.

DLL

As you can imagine the dll is also packed.

The DLLMain graph looks like this :

graph_dllmain.png

As you can see there are four branches depending of the fwdReason argument of DLLMain function.
The first one, DLL_PROCESS_ATTACH, will be called when the dll is loaded in each process using user32.dll ( AppInit_Dlls ).
This branch is just here for allocating memory, and unpacking the real stuff of the dll.
It just unpacks the dll, but it will not execute the unpacked code.
It will be executed when fwdReason == DLL_THREAD_ATTACH, so when the process uses CreateThread() for example.
The other branches are not interesting.
After unpacking this stuff, I was able to work with IDA without problem.
There are three branches of different execution flow based on the process name the dll is into :

graph_branch.png

They use an hashing algorithm, in order to test if they are in a browser process or not, and they do the same thing to detect vm processes and av names into program files folder.
So here is a complete test program to test all their hash table :

#include <stdio.h>


int hash_process_vm[] = { 0x99DD4432, 0x1F413C1F, 0x0B2CE5FDE, 0x3BFFF885, 0x64340DCE, 0x63C54474, 0 };
int hash_program_files[] = { 0x0F7C386B2, 0x9E46A936, 0x74B36500, 0x0B6E7E008, 0x65149B58, 0x1CE7528E,
							0x1A704388, 0x4C9EECB5, 0x0D3749631, 0x756ABC4D, 0x3E6A4D93,
							0x812EAFC4, 0x1433DC7E, 0x0C1364B22, 0x5BBE66BD, 0x4965900D,
							0x0E8406786, 0x62F204B9, 0x31A89D7B, 0x0E8AB39EA, 0x0C093AB43,
							0x983757A0, 0x0D5B274B0, 0x2B7F9687, 0x585834DD, 0x0A53C3B2D,
							0x1E519C8D, 0x28388EC6, 0x37A4DB47, 0x2AA1E9D7, 0x83B99225,
							0x6A057127, 0x0D119C72B, 0x5D614D4B, 0x5436485D, 0x45490640,
							0x0E38FAD29, 0 };

int hash_executable_name[] = {0x244CC8B2, 0x9DC03F1E, 0x66B49B77, 0x7207B507, 0x80D1F7CF, 0x37965AFA, 0x9006A423, 0};

char *process_name[] = {"\\IEXPLORE.EXE", "\\FIREFOX.EXE", "\\CHROME.EXE", "\\SAFARI.EXE",
						"\\OPERA.EXE", "\\SVCHOST.EXE", "\\NETSCAPE.EXE", "\\MOZILLA.EXE", 0 };

char *av_program_files[] = {"AVIRA", "AV", "AntiVir", "Synaptics", "Avast", "Alwil Software", "AVG", 
							"BitDefender", "ByteHero", "clamAV", "Commtouch", "Comodo", "DrWeb", 
							"Emsisoft Anti-Malware", "eSafe", "eSafeMNG", "eTrust EZ Antivirus", "FSI",
							"FRISK Software", "F-Secure", "Fortinet", "G Data", "ikarus", "Jiangmin", 
							"k7 computing", "Kaspersky Lab", "McAfee", "ESET", "ESET NOD32 Antivirus", 
							"Norman", "Norton SystemWorks", "Panda Software", "Panda Security", 
							"PC Tools", "PREVX", "Rising", "RAV", "Sophos", "SUPERAntiSpyware", 
							"Symantec AntiVirus", "Symantec", "Trend Micro", "VBA32", "VIPRE", 
							"VIPRE Antivirus", "Sunbelt Software", "ViRobot", "VirusBuster", 0};

char *processvm_name[] = {"vmtoolsd.exe", "VMUpgradeHelper.exe", "TPAutoConnSvc.exe", "VMwareTray.exe", "VMwareUser.exe", 
							"vmacthlp.exe", 0 };

int cidox_hash_func(char *name)
{
	int sum = -1, i, is;
	int actual_chr;

	while (*name)
	{
		actual_chr = *name;
		if (actual_chr >= 0x41 && actual_chr <= 0x5a)
			actual_chr += 0x20;
		sum = actual_chr ^ sum;
		for (i = 0; i < 8; i++)
		{
			is = sum & 0x1;
			sum = (unsigned int)sum >> 1;
			if (is)
				sum ^= 0xEDB88320;
		}
		name++;
	}
	return (~sum);
}

int is_in_list_hash(int *list_hash, int hash)
{
	while (*list_hash)
	{
		if (*list_hash == hash)
			return (1);
		list_hash++;
	}
	return (0);
}

int length_list_hash(int *list_hash)
{
	int	nb = 0;

	while (*list_hash)
	{
		nb++;
		list_hash++;
	}
	return (nb);
}

void check(char **list_to_check, int *list_hash, int (*generate_hash)(char *name), char *wat)
{
	int		hash;
	int		len_list = 0;
	int		found = 0;
	
	printf("\t[+] Now checking .: %s :.\n\n", wat);
	len_list = length_list_hash(list_hash);
	while (*list_to_check)
	{
		hash = generate_hash(*list_to_check);
		if (is_in_list_hash(list_hash, hash))
		{
			printf("%s\t\tis present with Hash ( 0x%08x )\n", *list_to_check, hash);
			found++;
		}
		list_to_check++;
	}
	printf("\n\t[+] Result .: %d Found / %d Total (%d%%) :.\n\n", found, len_list, (found * 100 / len_list * 100) / 100); 
}

void launch_check()
{
	check(process_name, hash_executable_name, cidox_hash_func, "\"Process Name\"");
	check(av_program_files, hash_program_files, cidox_hash_func, "\"AV Program Files\"");
	check(processvm_name, hash_process_vm, cidox_hash_func, "\"Process VM Name\"");
}

Here is an output from the program to test which browser was in this table :

\IEXPLORE.EXE           is present with Hash ( 0x244cc8b2 )
\FIREFOX.EXE            is present with Hash ( 0x9dc03f1e )
\CHROME.EXE             is present with Hash ( 0x66b49b77 )
\SAFARI.EXE             is present with Hash ( 0x7207b507 )
\OPERA.EXE              is present with Hash ( 0x80d1f7cf )
\SVCHOST.EXE            is present with Hash ( 0x9006a423 )

As you can see, I just found 6 process name on the 7 hash, so if you have some idea, you can leave me a comment :], but it's not very important.
The main thing this dll does is hooking several functions from ws2_32.dll :

Theses hooks are setup for redirecting you on phising website when you go on :

Each time your browser window name changes, it will try to contact their command and control server (C&C), to update an interesting configuration file, that you can find into : "C:Documents and SettingsAll UsersApplication Data" under the name "cf".
At the end of this post you can find a toolz to decrypt this configuration file :

GJD747310F000C29177C1B0000...............................................................................
....................................................................................................................
....................................................................................................................
....................................................................................................................
....................................................................................................................
.........30.yandexapps.com/loPtfdn3dSasoicn/get.php?key=.&id=.&os=.&av=.&vm=.&al=.&p=.&z=351.gcoglestats.com/loPtfdn
3dSasoicn/get.php?key=.&id=.&os=.&av=.&vm=.&al=.&p=.&z=351.msn-dns.com/loPtfdn3dSasoicn/get.php?key=.&id=.&os=.&av=.
&vm=.&al=.&p=.&z=351.94.102.49.64/loPtfdn3dSasoicn/get.php?key=.&id=.&os=.&av=.&vm=.&al=.&p=.&z=351......youtube.com.t/ter
ms..0.yandexapps.com/yt_lxegvj4efc/tube.php?uid=.&id=.&url=...help.vkontakte.ru...0.yandexapps.com/lo_nhyg38deijiwsx
/vhelp.php?uid=.&id=.&url=...help.mail.ru...0.yandexapps.com/ma_ghjkmnbgvfrt/mail.php?uid=.&id=.&url=...admin.vkonta
kte.ru...0.yandexapps.com/lo_nhyg38deijiwsx/kr_vnhuirw43/vadmin.php?uid=.&id=.&url=...update.microsoft.com...0.yande
xapps.com/bt_pdfn3skxler/index.php?uid=.&id=.&url=...update.mozilla.org...0.yandexapps.com/bt_pdfn3skxler/index.php?
uid=.&id=.&url=...download.opera.com...0.yandexapps.com/bt_pdfn3skxler/index.php?uid=.&id=.&url=...chrome.google.com
...0.yandexapps.com/bt_pdfn3skxler/index.php?uid=.&id=.&url=...official.odnoklassniki.ru...0.yandexapps.com/od_xafhu
y2ed/ohelp.php?uid=.&id=.&url=...rushotgirls.com...0.yandexapps.com/bn_9iknfbcgtl/index.php?uid=.&id=.&url=...intern
et.com...0.yandexapps.com/in_xbvgyui3vf/index.php?uid=.&id=.&url=...*.co.cc...0.www.yandex.ru/...yandexapps.com/loPt
fdn3dSasoicn/post.php?id=.&form=.&url=...!CFG............

My toolz is written in assembly language, so for those who are not familiar with this language, here is their custom TEA algo :

int fEKey[4] = {0xB440b08B, 0xACFA7304, 0x9FCAEAEA, 0x1546b9A5};

void TeaDecipher(unsigned int* buf) 
{
    unsigned int second, first; 
	unsigned int key = 0xC6EF3720;

	second = _byteswap_ulong(buf[1]);
	first = _byteswap_ulong(buf[0]);

    for (int i = 0; i < 32; i++) 
	{
        second -= (((first >> 5) ^ (first << 4)) + first)
                ^ (fEKey[(key >> 11) & 3] + key);
        key += 0x61C88647;
        first -= (((second >> 5) ^ (second << 4)) + second)
               ^ (fEKey[key & 3] + key);
    }

	second = _byteswap_ulong(second);
	first = _byteswap_ulong(first);

    buf[0] = first ^ buf[-2];
    buf[1] = second ^ buf[-1];
}

void decy(unsigned char *buf, int size)
{
	int i;

	for (i = size / 4; i > 0; i -= 2)
		TeaDecipher((unsigned int*)(buf + i * 4));
}

When the dll is inside a svchost process, the infection remains persistant, by checking if the configuration file exist, or if AppInits_DLL is set ; but they failed on one thing, the dll file, for desinfecting your pc you have just to rename the dll (my toolz checks if you are infected too and generate for you the name of the dll), and reboot your computer ( not my toolz ;) ).

A last thing that I wasn't able to study is the fact that some times, command and control drops a new executable, and createprocess() after decyphering it.
But it didn't drop me this PE, its name is "ru", because I saw his name when it try to write it at location : "C:\Documents and Settings\All Users\Application Data".

Toolz

cidox_toolz.png

Link Source.rar.

Conclusion

This version of Cidox was not very interesting, 6 months ago, they used VBR infection and dropped a driver, maybe I will study this version soon for having more fun :].