diff --git a/tools/MultiRelay.py b/tools/MultiRelay.py index 5a45085..8a046f2 100755 --- a/tools/MultiRelay.py +++ b/tools/MultiRelay.py @@ -59,6 +59,16 @@ Mimikatzx86Filename = "./MultiRelay/bin/mimikatz_x86.exe" RunAsFileName = "./MultiRelay/bin/Runas.exe" SysSVCFileName = "./MultiRelay/bin/Syssvc.exe" +def color(txt, code = 1, modifier = 0): + return "\033[%d;3%dm%s\033[0m" % (modifier, code, txt) + +if os.path.isfile(SysSVCFileName) is False: + print(color("[!]MultiRelay/bin/ folder is empty. You need to run these commands:\n",1,1)) + print(color("apt-get install gcc-mingw-w64-x86-64",2,1)) + print(color("x86_64-w64-mingw32-gcc ./MultiRelay/bin/Runas.c -o ./MultiRelay/bin/Runas.exe -municode -lwtsapi32 -luserenv",2,1)) + print(color("x86_64-w64-mingw32-gcc ./MultiRelay/bin/Syssvc.c -o ./MultiRelay/bin/Syssvc.exe -municode",2,1)) + print(color("\nAdditionally, you can add your custom mimikatz executables (mimikatz.exe and mimikatz_x86.exe)\nin the MultiRelay/bin/ folder for the mimi32/mimi command.",3,1)) + sys.exit() def UserCallBack(op, value, dmy, parser): args=[] @@ -92,7 +102,7 @@ if options.ExtraPort is None: options.ExtraPort = 0 if not os.geteuid() == 0: - print((color("[!] MultiRelay must be run as root."))) + print(color("[!] MultiRelay must be run as root.")) sys.exit(-1) OneCommand = options.OneCommand @@ -105,10 +115,6 @@ Cmd = [] ShellOpen = [] Pivoting = [2] - -def color(txt, code = 1, modifier = 0): - return "\033[%d;3%dm%s\033[0m" % (modifier, code, txt) - def ShowWelcome(): print(color('\nResponder MultiRelay %s NTLMv1/2 Relay' %(__version__),8,1)) print('\nSend bugs/hugs/comments to: laurent.gaffie@gmail.com') diff --git a/tools/MultiRelay/bin/Runas.c b/tools/MultiRelay/bin/Runas.c new file mode 100644 index 0000000..2918cfa --- /dev/null +++ b/tools/MultiRelay/bin/Runas.c @@ -0,0 +1,100 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : https://creativecommons.org/licenses/by/4.0/ +*/ +#include +#include +#include + +int wmain(int argc, wchar_t * argv[]); +void WINAPI ServiceMain(DWORD argc, LPWSTR *argv); +void WINAPI ServiceCtrlHandler(DWORD Opcode); + +SERVICE_STATUS m_ServiceStatus = {SERVICE_WIN32_OWN_PROCESS, SERVICE_STOPPED, 0, NO_ERROR, 0, 0, 0}; +SERVICE_STATUS_HANDLE m_ServiceStatusHandle = NULL; +HANDLE m_pyrsvcRunning; +PWCHAR z_cmdLine, z_logFile; +const WCHAR PYRSVC_NAME[] = L"pyrsvc", PYRSVC_PRE_CMD[] = L"cmd.exe /c \"", PYRSVC_POST_CMD[] = L"\" > ", PYRSVC_END_CMD[] = L" 2>&1"; + +int wmain(int argc, wchar_t * argv[]) +{ + int status = ERROR_SERVICE_NOT_IN_EXE; + const SERVICE_TABLE_ENTRY DispatchTable[]= {{(LPWSTR) PYRSVC_NAME, ServiceMain}, {NULL, NULL}}; + if(argc == 3) + { + if(z_cmdLine = _wcsdup(argv[1])) + { + if(z_logFile = _wcsdup(argv[2])) + { + if(m_pyrsvcRunning = CreateEvent(NULL, TRUE, FALSE, NULL)) + { + if(StartServiceCtrlDispatcher(DispatchTable)) + status = ERROR_SUCCESS; + else status = GetLastError(); + CloseHandle(m_pyrsvcRunning); + } + free(z_logFile); + } + free(z_cmdLine); + } + } + return status; +} + +void WINAPI ServiceMain(DWORD argc, LPWSTR *argv) +{ + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi; + PWCHAR arguments; + DWORD size; + HANDLE hUser; + LPVOID env; + si.cb = sizeof(STARTUPINFO); + if(m_ServiceStatusHandle = RegisterServiceCtrlHandler(PYRSVC_NAME, ServiceCtrlHandler)) + { + m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); + m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; + m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); + + size = ((ARRAYSIZE(PYRSVC_PRE_CMD) - 1) + lstrlen(z_cmdLine) + (ARRAYSIZE(PYRSVC_POST_CMD) - 1) + lstrlen(z_logFile) + (ARRAYSIZE(PYRSVC_END_CMD) - 1) + 1) * sizeof(WCHAR); + if(arguments = (PWCHAR) malloc(size)) + { + memset(arguments, '\0', size); + wcscat_s(arguments, size, PYRSVC_PRE_CMD); + wcscat_s(arguments, size, z_cmdLine); + wcscat_s(arguments, size, PYRSVC_POST_CMD); + wcscat_s(arguments, size, z_logFile); + wcscat_s(arguments, size, PYRSVC_END_CMD); + if(WTSQueryUserToken(WTSGetActiveConsoleSessionId(), &hUser)) + { + if(CreateEnvironmentBlock(&env, hUser, FALSE)) + { + if(CreateProcessAsUser(hUser, NULL, arguments, NULL, NULL, FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi)) + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + DestroyEnvironmentBlock(env); + } + CloseHandle(hUser); + } + free(arguments); + } + WaitForSingleObject(m_pyrsvcRunning, INFINITE); + m_ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); + } +} + +void WINAPI ServiceCtrlHandler(DWORD Opcode) +{ + if((Opcode == SERVICE_CONTROL_STOP) || (Opcode == SERVICE_CONTROL_SHUTDOWN)) + { + m_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus); + SetEvent(m_pyrsvcRunning); + } +} diff --git a/tools/MultiRelay/bin/Runas.exe b/tools/MultiRelay/bin/Runas.exe deleted file mode 100644 index 64abf0e..0000000 Binary files a/tools/MultiRelay/bin/Runas.exe and /dev/null differ diff --git a/tools/MultiRelay/bin/Syssvc.c b/tools/MultiRelay/bin/Syssvc.c new file mode 100644 index 0000000..3d3c9d6 --- /dev/null +++ b/tools/MultiRelay/bin/Syssvc.c @@ -0,0 +1,90 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : https://creativecommons.org/licenses/by/4.0/ +*/ +#include + +int wmain(int argc, wchar_t * argv[]); +void WINAPI ServiceMain(DWORD argc, LPWSTR *argv); +void WINAPI ServiceCtrlHandler(DWORD Opcode); + +SERVICE_STATUS m_ServiceStatus = {SERVICE_WIN32_OWN_PROCESS, SERVICE_STOPPED, 0, NO_ERROR, 0, 0, 0}; +SERVICE_STATUS_HANDLE m_ServiceStatusHandle = NULL; +HANDLE m_pyrsvcRunning; +PWCHAR z_cmdLine, z_logFile; +const WCHAR PYRSVC_NAME[] = L"pyrsvc", PYRSVC_PRE_CMD[] = L"cmd.exe /c \"", PYRSVC_POST_CMD[] = L"\" > ", PYRSVC_END_CMD[] = L" 2>&1"; + +int wmain(int argc, wchar_t * argv[]) +{ + int status = ERROR_SERVICE_NOT_IN_EXE; + const SERVICE_TABLE_ENTRY DispatchTable[]= {{(LPWSTR) PYRSVC_NAME, ServiceMain}, {NULL, NULL}}; + if(argc == 3) + { + if(z_cmdLine = _wcsdup(argv[1])) + { + if(z_logFile = _wcsdup(argv[2])) + { + if(m_pyrsvcRunning = CreateEvent(NULL, TRUE, FALSE, NULL)) + { + if(StartServiceCtrlDispatcher(DispatchTable)) + status = ERROR_SUCCESS; + else status = GetLastError(); + CloseHandle(m_pyrsvcRunning); + } + free(z_logFile); + } + free(z_cmdLine); + } + } + return status; +} + +void WINAPI ServiceMain(DWORD argc, LPWSTR *argv) +{ + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi; + PWCHAR arguments; + DWORD size; + si.cb = sizeof(STARTUPINFO); + if(m_ServiceStatusHandle = RegisterServiceCtrlHandler(PYRSVC_NAME, ServiceCtrlHandler)) + { + m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); + m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; + m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); + + size = ((ARRAYSIZE(PYRSVC_PRE_CMD) - 1) + lstrlen(z_cmdLine) + (ARRAYSIZE(PYRSVC_POST_CMD) - 1) + lstrlen(z_logFile) + (ARRAYSIZE(PYRSVC_END_CMD) - 1) + 1) * sizeof(WCHAR); + if(arguments = (PWCHAR) malloc(size)) + { + memset(arguments, '\0', size); + wcscat_s(arguments, size, PYRSVC_PRE_CMD); + wcscat_s(arguments, size, z_cmdLine); + wcscat_s(arguments, size, PYRSVC_POST_CMD); + wcscat_s(arguments, size, z_logFile); + wcscat_s(arguments, size, PYRSVC_END_CMD); + + if(CreateProcess(NULL, arguments, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + + free(arguments); + } + WaitForSingleObject(m_pyrsvcRunning, INFINITE); + m_ServiceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); + } +} + +void WINAPI ServiceCtrlHandler(DWORD Opcode) +{ + if((Opcode == SERVICE_CONTROL_STOP) || (Opcode == SERVICE_CONTROL_SHUTDOWN)) + { + m_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus); + SetEvent(m_pyrsvcRunning); + } +} diff --git a/tools/MultiRelay/bin/Syssvc.exe b/tools/MultiRelay/bin/Syssvc.exe deleted file mode 100644 index 629ec68..0000000 Binary files a/tools/MultiRelay/bin/Syssvc.exe and /dev/null differ diff --git a/tools/MultiRelay/bin/mimikatz.exe b/tools/MultiRelay/bin/mimikatz.exe deleted file mode 100644 index 2ecbf00..0000000 Binary files a/tools/MultiRelay/bin/mimikatz.exe and /dev/null differ diff --git a/tools/MultiRelay/bin/mimikatz_x86.exe b/tools/MultiRelay/bin/mimikatz_x86.exe deleted file mode 100644 index 7a17145..0000000 Binary files a/tools/MultiRelay/bin/mimikatz_x86.exe and /dev/null differ