25/10/2011

Some news, TDL4, IDA

Introduction

I received several mail asking me, if I was still active on my blog.
And the answer is YES!, i'm just (very) busy by my internship, and some personal projetcs.
So today I give you some news.

TDL4

I'm sorry for my english readers (if there are), but my draft article about all reverse stuff from tdl4 is written in French. But you can use Google Translate !
So here is the link to the article.
Be careful this is an oldschool version ( 0.3 ), I'm currently studying new version.

TDL4 (New version)

And we will start with a tricks for detecting Virtual Machine, apparently the new loader do this check, instead of the loader from my article.
Maybe for you it will not be new, but for me it is, I'm a beginner in malware analysis.
It will use WQL language to query Windows Management Instrumentation.
I will not bore you with disassembly code, but with a picture, that will show you a little script that I wrote for defeating unicode string obfuscation :

plugin_ida_deounicode.png

And source code of idc script (I'm maybe doing it wrong, but it's my first) :

#include <idc.idc>

static String(ea)
{
    auto s,b,i;
    s = ""; 
	i = 0;
    while(i < 2) 
	{
		b = Byte(ea);
		if (b)
		{
			s = s + form("%c", b);
			ea = ea + 2;
		}
		i++;
    }
    return s; 
}

static main()
{
	auto ea;
	auto op;
	auto str;
	auto s;
    
	ea = SelStart();
	str = "";
	while (ea < SelEnd())
	{
		if(GetMnem(ea) != "mov")
			break;
		if (GetOpType(ea, 1) == 1)
			break;
		s = String(ea + 7);
		str = str + s;
		ea = FindCode(ea, SEARCH_DOWN | SEARCH_NEXT);
	}
	Message("%s\n", str);
}

So with this script I was able to see all this interesting stuff :

Win32_BIOS
Win32_Process
Win32_DiskDrive
Win32_Processor
Win32_SCSIController
Name
Model
Manufacturer
Xen
QEMU
Bochs
Red Hat
Citrix
VMware
Virtual HDVBOX
CaptureClient.exe
SELECT * FROM %s WHERE %s LIKE "%%%s%%"
SELECT * FROM %s WHERE %s = "%s"
First it will gather all the information about your pc and send this to a C&C.
And after for example, it will check if in process list there is "CaptureClient.exe", or execute the request "SELECT * FROM Win32_DiskDevice WHERE Manufacturer = "VMware", etc...
This is how they can detect that you are in virtualized or emulated environment.
I didn't know how WQL work, so I decided to develop someshit :
#include <windows.h>
#include <objbase.h>
#include <atlbase.h>
#include <iostream>
#include <wbemidl.h>
#include <comutil.h>

int main(void)
{
	HRESULT hr;
	
	hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
	if (hr < 0)
	{
		std::cerr << "[-] COM initialization failed" << std::endl;
		return (-1);
	}

	hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
								RPC_C_AUTHN_LEVEL_DEFAULT,
								RPC_C_IMP_LEVEL_IMPERSONATE,
								NULL,
								EOAC_NONE,
								NULL );
	if (hr < 0)
	{
		std::cerr << "[-] Security initialization failed" << std::endl;
		return (-1);
	}

	CComPtr<IWbemLocator> locator;
	hr = CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL,
							CLSCTX_INPROC_SERVER,
							IID_IWbemLocator, reinterpret_cast< void** >( &locator ));
	if (hr < 0)
	{
		std::cerr << "[-] Instantiation of IWbemLocator failed" << std::endl;
		return (-1);
	}
	CComPtr<IWbemServices> service;
	hr = locator->ConnectServer(L"root\\cimv2", NULL, NULL, NULL,
								WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &service);

	CComPtr< IEnumWbemClassObject > enumerator;
	hr = service->ExecQuery( L"WQL", L"SELECT * FROM Win32_Process", WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator );
	//hr = service->ExecQuery( L"WQL", L"SELECT * FROM Win32_DiskDrive WHERE Model LIKE \"%VMware%\"", WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator );
	if (hr < 0)
	{
		std::cerr << "[-] ExecQuey() Failed" << std::endl;
		return (-1);
	}
	CComPtr< IWbemClassObject > processor = NULL;
	ULONG retcnt;
	hr = enumerator->Next(WBEM_INFINITE, 1L, reinterpret_cast<IWbemClassObject**>( &processor ), &retcnt);
	while ( SUCCEEDED(hr) && retcnt > 0) 
	{
		if ( retcnt > 0 )
		{
				_variant_t var_val;
				hr = processor->Get( L"Name", 0, &var_val, NULL, NULL );
				if (hr >= 0)
				{
						_bstr_t str = var_val;
						std::cout << "[+] Name: " << str << std::endl;
				}
				else
				{
						std::cerr << "[-] IWbemClassObject::Get failed" << std::endl;
						//result = -1;
				}
                hr = enumerator->Next( WBEM_INFINITE, 1L, reinterpret_cast<IWbemClassObject**>( &processor ), &retcnt );
		}
		else
		{
			std::cout << "[-] Enumeration empty" << std::endl;
		}
	}
}

That's all for today :].