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",
currentDirectory);
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]);
}
else{
InstallDriver (schSCManager, argv[1], argv[2]);
StartDriver (schSCManager, argv[1]);
OpenDevice (argv[1]);
}
CloseServiceHandle (schSCManager);
}

BOOL InstallDriver(
IN SC_HANDLE SchSCManager,
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_DEMAND_START, // start 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();
if (err == ERROR_SERVICE_EXISTS){
// A common cause of failure (easier to read than an error code)
printf ("failure: CreateService, ERROR_SERVICE_EXISTS\n");
}
else{
printf ("failure: CreateService (0x%02x)\n", err);
}
return FALSE;
}
else{
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");
}
else{
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");
}
else{
err = GetLastError();
if (err == ERROR_SERVICE_ALREADY_RUNNING){
// A common cause of failure (easier to read than an error code)
printf ("failure: StartService, ERROR_SERVICE_ALREADY_RUNNING\n");
}
else{
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");
}
else{
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,
GENERIC_READ GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == ((HANDLE)-1)){
printf ("Can't get a handle to %s\n", completeDeviceName);
ret = FALSE;
}
else{
printf ("CreateFile SUCCESS\n");
CloseHandle (hDevice);
ret = TRUE;
}
return ret;
}


/*
http://www-user.tu-chemnitz.de/~heha/viewzip.cgi/hs_freeware/gerald.zip/INSTDRV.C?auto=C
http://www-user.tu-chemnitz.de/~heha/hs_freeware/
*/