├── .gitignore ├── bin ├── Debug │ └── RemCom.exe └── Release │ └── RemCom.exe ├── ProcComs ├── StdAfx.cpp ├── StdAfx.h ├── ProcComs.dsp ├── ProcComs.cpp └── ProcComs.vcxproj ├── clean.cmd ├── resource.h ├── ProcFunctions.h ├── RemCom.dsw ├── RemComSvc ├── RemComSvc.h ├── RemComSvc.dsp ├── xServer.cpp ├── RemComSvc.vcxproj ├── RemComSvc.cpp └── Service.cpp ├── Remote Command Executor.sln ├── RemCom.h ├── ProcFunctions.cpp ├── README.md ├── RemCom.rc ├── RemCom.dsp ├── RemCom.vcxproj └── RemCom.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | Debug 2 | Release 3 | *.user 4 | *.sdf 5 | *.suo 6 | _Resharper.* 7 | -------------------------------------------------------------------------------- /bin/Debug/RemCom.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kavika13/RemCom/HEAD/bin/Debug/RemCom.exe -------------------------------------------------------------------------------- /bin/Release/RemCom.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kavika13/RemCom/HEAD/bin/Release/RemCom.exe -------------------------------------------------------------------------------- /ProcComs/StdAfx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // ProcComs.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /clean.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rmdir Debug /s /q 4 | rmdir Release /s /q 5 | rmdir RemComSvc\Debug /s /q 6 | rmdir RemComSvc\Release /s /q 7 | 8 | rmdir _ReSharper.Remote~1 /s/q 9 | 10 | rmdir ProcComs\Debug /s /q 11 | rmdir ProcComs\Release /s /q 12 | 13 | del *.ncb /s 14 | del *.opt /s 15 | del *.plg /s 16 | del *.aps /s 17 | del *.clw /s 18 | del *.positions /s 19 | -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Developer Studio generated include file. 3 | // Used by RemCom.rc 4 | // 5 | #define IDR_RemComSVC 101 6 | #define IDR_ProcComs 102 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 113 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1000 15 | #define _APS_NEXT_SYMED_VALUE 103 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /ProcFunctions.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantibility or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | */ 18 | 19 | #ifndef xProcFunctions_H_INCLUDED 20 | #define xProcFunctions_H_INCLUDED 21 | 22 | 23 | #define UNICODE 24 | #define _WIN32_WINNT 0x0500 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | class ProcessHandler{ 31 | 32 | public: 33 | void DisplayError(LPWSTR pszAPI); 34 | void CreatProc(int argc, WCHAR *argv[]); 35 | 36 | }; 37 | #endif -------------------------------------------------------------------------------- /RemCom.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "ProcComs"=".\ProcComs\ProcComs.dsp" - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | }}} 15 | 16 | ############################################################################### 17 | 18 | Project: "RemCom"=".\RemCom.dsp" - Package Owner=<4> 19 | 20 | Package=<5> 21 | {{{ 22 | }}} 23 | 24 | Package=<4> 25 | {{{ 26 | Begin Project Dependency 27 | Project_Dep_Name RemComSvc 28 | End Project Dependency 29 | }}} 30 | 31 | ############################################################################### 32 | 33 | Project: "RemComSvc"=".\RemComSvc\RemComSvc.dsp" - Package Owner=<4> 34 | 35 | Package=<5> 36 | {{{ 37 | }}} 38 | 39 | Package=<4> 40 | {{{ 41 | }}} 42 | 43 | ############################################################################### 44 | 45 | Global: 46 | 47 | Package=<5> 48 | {{{ 49 | }}} 50 | 51 | Package=<3> 52 | {{{ 53 | }}} 54 | 55 | ############################################################################### 56 | 57 | -------------------------------------------------------------------------------- /RemComSvc/RemComSvc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantability or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | $Author: Talha Tariq [ talha.tariq@gmail.com ] 18 | $Revision: Talha Tariq [ talha.tariq@gmail.com ] 19 | $Date: 2006/10/03 09:00:00 $ 20 | $Version History: $ - 21 | $TODO: - Implement Delete Service 22 | $Description: $ - RemCom Service is contained in the parent binary as a local resource which is extracted at runtime from itself 23 | pushed to admin$, installed to the remote service control manager which interacts remotely for local process invocation 24 | 25 | $Workfile: $ - RemComSvc.h 26 | */ 27 | #ifndef RemComSVC_H_INCLUDED 28 | #define RemComSVC_H_INCLUDED 29 | 30 | extern HANDLE hStopServiceEvent; 31 | 32 | void _ServiceMain(void*); 33 | void DeleteSvc(); 34 | 35 | #endif -------------------------------------------------------------------------------- /Remote Command Executor.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 11.00 2 | # Visual Studio 2010 3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProcComs", "ProcComs\ProcComs.vcxproj", "{29548EB7-5E44-21F9-5C82-15DDDC80449A}" 4 | EndProject 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RemCom", "RemCom.vcxproj", "{8CC59FFA-00E0-0AEA-59E8-E780672C3CB3}" 6 | ProjectSection(ProjectDependencies) = postProject 7 | {29548EB7-5E44-21F9-5C82-15DDDC80449A} = {29548EB7-5E44-21F9-5C82-15DDDC80449A} 8 | EndProjectSection 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RemComSvc", "RemComSvc\RemComSvc.vcxproj", "{C7038612-8183-67A7-8A9C-1379C2674156}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Win32 = Debug|Win32 15 | Release|Win32 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {29548EB7-5E44-21F9-5C82-15DDDC80449A}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {29548EB7-5E44-21F9-5C82-15DDDC80449A}.Debug|Win32.Build.0 = Debug|Win32 20 | {29548EB7-5E44-21F9-5C82-15DDDC80449A}.Release|Win32.ActiveCfg = Release|Win32 21 | {29548EB7-5E44-21F9-5C82-15DDDC80449A}.Release|Win32.Build.0 = Release|Win32 22 | {8CC59FFA-00E0-0AEA-59E8-E780672C3CB3}.Debug|Win32.ActiveCfg = Debug|Win32 23 | {8CC59FFA-00E0-0AEA-59E8-E780672C3CB3}.Debug|Win32.Build.0 = Debug|Win32 24 | {8CC59FFA-00E0-0AEA-59E8-E780672C3CB3}.Release|Win32.ActiveCfg = Release|Win32 25 | {8CC59FFA-00E0-0AEA-59E8-E780672C3CB3}.Release|Win32.Build.0 = Release|Win32 26 | {C7038612-8183-67A7-8A9C-1379C2674156}.Debug|Win32.ActiveCfg = Debug|Win32 27 | {C7038612-8183-67A7-8A9C-1379C2674156}.Debug|Win32.Build.0 = Debug|Win32 28 | {C7038612-8183-67A7-8A9C-1379C2674156}.Release|Win32.ActiveCfg = Release|Win32 29 | {C7038612-8183-67A7-8A9C-1379C2674156}.Release|Win32.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /ProcComs/StdAfx.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantability or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | $Author: Talha Tariq [ talha.tariq@gmail.com ] 18 | $Revision: Talha Tariq [ talha.tariq@gmail.com ] 19 | $Date: 2006/11/03 09:00:00 $ 20 | $Version History: $ - Added OpenProcessToken to get the preocess token. 21 | - Fixed the bug for Windows 2000 where Calling LogonUser API needs an SE_TCB_NAME privilege which is not enabled by default 22 | $TODO: - Code Cleanup. - Move the class as UniCode implementation to the RemCom project 23 | $Description: $ - ProcCom binary is contained in the parent binary as a local resource which is extracted at runtime from itself 24 | for local prorcess and user impersonation 25 | $Workfile: $ - ProcComs.h 26 | */ 27 | 28 | 29 | #if !defined(AFX_STDAFX_H__80E97CF6_A64A_4F6A_B036_7E512D741A73__INCLUDED_) 30 | #define AFX_STDAFX_H__80E97CF6_A64A_4F6A_B036_7E512D741A73__INCLUDED_ 31 | 32 | #if _MSC_VER > 1000 33 | #pragma once 34 | #endif // _MSC_VER > 1000 35 | 36 | 37 | // TODO: reference additional headers your program requires here 38 | #define UNICODE 39 | // Works only on windows 2000 and above 40 | #define _WIN32_WINNT 0x0500 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | //{{AFX_INSERT_LOCATION}} 47 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 48 | 49 | #endif // !defined(AFX_STDAFX_H__80E97CF6_A64A_4F6A_B036_7E512D741A73__INCLUDED_) 50 | -------------------------------------------------------------------------------- /RemCom.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantability or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | $Author: Talha Tariq [ talha.tariq@gmail.com ] 18 | uses some code from xCmd by Zoltan Csizmadia 19 | $Revision: Talha Tariq [ talha.tariq@gmail.com ] 20 | $Date: 2006/10/03 09:00:00 $ 21 | $Version History: $ - Added ProcComs binary as a local resource for local process impersonation and communication util 22 | $TODO: - See destructor 23 | $Description: $ - RemCom is RAT [Remote Administration Tool] that lets you execute processes on remote windows systems, copy files, 24 | process there output and stream it back. It allows execution of remote shell commands directly with full interactive console 25 | - Declaration of RemCom Message and Response Classes 26 | $Workfile: $ - RemCom.h 27 | */ 28 | 29 | #ifndef RemCom_H_INCLUDED 30 | #define RemCom_H_INCLUDED 31 | #include 32 | //#include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | //#include 40 | #include 41 | #include "ProcFunctions.h" 42 | //#include 43 | #include "resource.h" 44 | 45 | #define SERVICENAME _T("RemComSvc") 46 | #define LONGSERVICENAME _T("RemCom Service") 47 | 48 | #define RemComSVCEXE _T("RemComSvc.exe") 49 | #define ProcComs _T("ProcComs.bin") 50 | 51 | #define RemComCOMM _T("RemCom_communicaton") 52 | #define RemComSTDOUT _T("RemCom_stdout") 53 | #define RemComSTDIN _T("RemCom_stdin") 54 | #define RemComSTDERR _T("RemCom_stderr") 55 | 56 | #define Out(x) { _ftprintf( stdout, _T("%s"), x); fflush(stdout); } 57 | #define Error(x) { _ftprintf( stderr, _T("%s"), x); fflush(stderr); } 58 | 59 | class RemComMessage 60 | { 61 | public: 62 | TCHAR szCommand[0x1000]; 63 | TCHAR szWorkingDir[_MAX_PATH]; 64 | DWORD dwPriority; 65 | DWORD dwProcessId; 66 | TCHAR szMachine[_MAX_PATH]; 67 | BOOL bNoWait; 68 | }; 69 | 70 | class RemComResponse 71 | { 72 | public: 73 | DWORD dwErrorCode; 74 | DWORD dwReturnCode; 75 | }; 76 | 77 | 78 | #endif -------------------------------------------------------------------------------- /ProcFunctions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantibility or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | */ 18 | #include "ProcFunctions.h" 19 | 20 | void DisplayError(LPWSTR pszAPI) 21 | { 22 | LPVOID lpvMessageBuffer; 23 | 24 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 25 | FORMAT_MESSAGE_FROM_SYSTEM, 26 | NULL, GetLastError(), 27 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 28 | (LPWSTR)&lpvMessageBuffer, 0, NULL); 29 | 30 | // 31 | //... now display this string 32 | // 33 | wprintf(L"ERROR: API = %s.\n", pszAPI); 34 | wprintf(L" error code = %d.\n", GetLastError()); 35 | wprintf(L" message = %s.\n", (LPWSTR)lpvMessageBuffer); 36 | 37 | // 38 | // Free the buffer allocated by the system 39 | // 40 | LocalFree(lpvMessageBuffer); 41 | 42 | ExitProcess(GetLastError()); 43 | } 44 | 45 | void CreatProc(int argc, WCHAR *argv[]) 46 | { 47 | DWORD dwSize; 48 | HANDLE hToken; 49 | LPVOID lpvEnv; 50 | PROCESS_INFORMATION pi = {0}; 51 | STARTUPINFO si = {0}; 52 | WCHAR szUserProfile[256] = L""; 53 | 54 | si.cb = sizeof(STARTUPINFO); 55 | 56 | // 57 | // TO DO: change NULL to '.' to use local account database 58 | // 59 | if (!LogonUser(argv[1], NULL, argv[2], LOGON32_LOGON_INTERACTIVE, 60 | LOGON32_PROVIDER_DEFAULT, &hToken)) 61 | DisplayError(L"LogonUser"); 62 | 63 | //if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE)) DisplayError(L"CreateEnvironmentBlock"); 64 | 65 | // dwSize = sizeof(szUserProfile)/sizeof(WCHAR); 66 | 67 | //if (!GetUserProfileDirectory(hToken, szUserProfile, &dwSize)) DisplayError(L"GetUserProfileDirectory"); 68 | 69 | // 70 | // TO DO: change NULL to '.' to use local account database 71 | // 72 | int bResult; 73 | bResult = CreateProcessWithLogonW(argv[1], NULL, argv[2], 74 | LOGON_WITH_PROFILE, NULL, argv[3], 75 | CREATE_UNICODE_ENVIRONMENT, /*lpvEnv*/ NULL, szUserProfile, &si, &pi); 76 | DWORD dwError; 77 | dwError = ::GetLastError(); 78 | DisplayError(L"CreateProcessWithLogonW"); 79 | 80 | // if (!DestroyEnvironmentBlock(lpvEnv)) DisplayError(L"DestroyEnvironmentBlock"); 81 | 82 | CloseHandle(hToken); 83 | CloseHandle(pi.hProcess); 84 | CloseHandle(pi.hThread); 85 | } 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #RemCom 2 | 3 | This is a fork of [the RemCom project](http://talhatariq.wordpress.com/2006/04/14/the-open-source-psexec/), since that project seems dead, and there are patches to be made. 4 | 5 | For the most "official" documentation of this branch, see [the wiki](https://github.com/kavika13/RemCom/wiki). The rest of this description is a placeholder for now. 6 | 7 | Changes since fork: 8 | 9 | 10 | From their site: 11 | 12 | --- 13 | 14 | **[RemCom - The open source psexec](http://sourceforge.net/projects/rce/)** 15 | 16 | Terminal Services are expensive in terms of bandwidth, Utilities like GotoMyPC and remote control programs like PC Anywhere let you execute programs on remote systems, but they take time to set up and require that you install client software on the remote systems that you wish to access and are extremely costly when it comes to running just some administrative commands over a group of systems. 17 | 18 | **What is RemCom** : RemCom is a small (10KB upx packed) remoteshell / telnet replacement that lets you execute processes on remote windows systems, copy files on remote systems, process there output and stream it back. It allows execution of remote shell commands directly with full interactive console without having to install any client software. On local machines it is also able to impersonate so can be used as a silent replacement for Runas command. 19 | 20 | **Platform and Language** : RemCom is written in C++ and works on NT 4.0, Win2K, Windows XP and Server 2003 including x64 versions of Windows. 21 | 22 | **Project Insipiration** : Mark Russinovich [sysinternals] Psexec. 23 | 24 | Backgound: I started this this project to make my own RAT [Remote Administration Tool]. Before this for numerous tasks i used the sysinternals pstools, but my ability to use / extend it was always limited by its liscensing and usage terms. That is why started of writing my own version of something similar to psexec and RemCom was the result. 25 | 26 | **Some Features** : 27 | 28 | - RemCom is open source :) ([source available here](http://sourceforge.net/projects/rce/)). 29 | - You can run as many remote commands on the machine as you want 30 | - You can execute internal commands (net, netsh, ipconfig) directly : RemCom \\foo-bar-system net start snmp 31 | - You can start a light "telnet" connection with a remote machine without any telnet server : RemCom.exe \\foo-bar-system cmd 32 | - You can also copy any file on the remote machine and receive its output. 33 | - RemCom creates a small ( < 1 KB) service on the remote machine (which it extracts it from itself at runtime). 34 | - All communication is done via named pipes & RPC . 35 | - The application removes its traces of the connection and the service on successful disconnect (neat huh?). 36 | RemCom is also used in OCS Inventory NG. See [this post](http://talhatariq.wordpress.com/2006/11/23/remcom-in-ocs-inventory/). 37 | 38 | **Future Roadmap** : 39 | 40 | - A Pretty UserInterface. 41 | - Multi Consoles in a single session. 42 | - A builtin option for fetching files. 43 | 44 | Any comments, bugs, wishlists: email to: talha [dot] tariq [at] gmail [dot] com 45 | 46 | **Source & Download** : [The most recent version of RemCom is available here](http://sourceforge.net/projects/rce/). 47 | 48 | -------------------------------------------------------------------------------- /RemCom.rc: -------------------------------------------------------------------------------- 1 | //Microsoft Developer Studio generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "windows.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE DISCARDABLE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE DISCARDABLE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE DISCARDABLE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // REMCOMSVC 53 | // 54 | 55 | #ifdef _DEBUG 56 | IDR_RemComSVC REMCOMSVC DISCARDABLE "RemComSvc/Debug/RemComSvc.exe" 57 | #else 58 | IDR_RemComSVC REMCOMSVC DISCARDABLE "RemComSvc/Release/RemComSvc.exe" 59 | #endif 60 | 61 | #ifndef _MAC 62 | ///////////////////////////////////////////////////////////////////////////// 63 | // 64 | // Version 65 | // 66 | 67 | VS_VERSION_INFO VERSIONINFO 68 | FILEVERSION 1,0,0,1 69 | PRODUCTVERSION 1,0,0,1 70 | FILEFLAGSMASK 0x3fL 71 | #ifdef _DEBUG 72 | FILEFLAGS 0x1L 73 | #else 74 | FILEFLAGS 0x0L 75 | #endif 76 | FILEOS 0x40004L 77 | FILETYPE 0x1L 78 | FILESUBTYPE 0x0L 79 | BEGIN 80 | BLOCK "StringFileInfo" 81 | BEGIN 82 | BLOCK "040904b0" 83 | BEGIN 84 | VALUE "Comments", "Remote Command Executor\0" 85 | VALUE "CompanyName", "Talha Tariq - [ talhatariq.wordpress.com ]\0" 86 | VALUE "FileDescription", "Remote Command Executor\0" 87 | VALUE "FileVersion", "1, 0, 0, 1\0" 88 | VALUE "InternalName", "RemCom\0" 89 | VALUE "LegalCopyright", "Copyright � 2006 The WiseGuyz [ talha.tariq@gmail.com ]\0" 90 | VALUE "LegalTrademarks", "http://talhatariq.wordpress.com\0" 91 | VALUE "OriginalFilename", "RemCom.exe\0" 92 | VALUE "PrivateBuild", "\0" 93 | VALUE "ProductName", "Remote System Deployment Util\0" 94 | VALUE "ProductVersion", "0.1\0" 95 | VALUE "SpecialBuild", "\0" 96 | END 97 | END 98 | BLOCK "VarFileInfo" 99 | BEGIN 100 | VALUE "Translation", 0x409, 1200 101 | END 102 | END 103 | 104 | #endif // !_MAC 105 | 106 | 107 | ///////////////////////////////////////////////////////////////////////////// 108 | // 109 | // PROCCOMS 110 | // 111 | 112 | #ifdef _DEBUG 113 | IDR_ProcComs PROCCOMS DISCARDABLE "ProcComs\\Debug\\ProcComs.bin" 114 | #else 115 | IDR_ProcComs PROCCOMS DISCARDABLE "ProcComs\\Release\\ProcComs.bin" 116 | #endif 117 | #endif // English (U.S.) resources 118 | ///////////////////////////////////////////////////////////////////////////// 119 | 120 | 121 | 122 | #ifndef APSTUDIO_INVOKED 123 | ///////////////////////////////////////////////////////////////////////////// 124 | // 125 | // Generated from the TEXTINCLUDE 3 resource. 126 | // 127 | 128 | 129 | ///////////////////////////////////////////////////////////////////////////// 130 | #endif // not APSTUDIO_INVOKED 131 | 132 | -------------------------------------------------------------------------------- /RemCom.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="RemCom" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Application" 0x0101 6 | 7 | CFG=RemCom - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "RemCom.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "RemCom.mak" CFG="RemCom - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "RemCom - Win32 Release" (based on "Win32 (x86) Application") 21 | !MESSAGE "RemCom - Win32 Debug" (based on "Win32 (x86) Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | MTL=midl.exe 30 | RSC=rc.exe 31 | 32 | !IF "$(CFG)" == "RemCom - Win32 Release" 33 | 34 | # PROP BASE Use_MFC 2 35 | # PROP BASE Use_Debug_Libraries 0 36 | # PROP BASE Output_Dir "Release" 37 | # PROP BASE Intermediate_Dir "Release" 38 | # PROP BASE Target_Dir "" 39 | # PROP Use_MFC 0 40 | # PROP Use_Debug_Libraries 0 41 | # PROP Output_Dir "Release" 42 | # PROP Intermediate_Dir "Release" 43 | # PROP Ignore_Export_Lib 0 44 | # PROP Target_Dir "" 45 | # ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c 46 | # ADD CPP /nologo /MD /W4 /GX /Z7 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /FD /c 47 | # SUBTRACT CPP /YX /Yc /Yu 48 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 49 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 50 | # ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" 51 | # ADD RSC /l 0x409 /d "NDEBUG" 52 | BSC32=bscmake.exe 53 | # ADD BASE BSC32 /nologo 54 | # ADD BSC32 /nologo 55 | LINK32=link.exe 56 | # ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 57 | # ADD LINK32 Userenv.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib mpr.lib /nologo /subsystem:console /debug /machine:I386 /out:"bin/RemCom.exe" 58 | # SUBTRACT LINK32 /pdb:none 59 | 60 | !ELSEIF "$(CFG)" == "RemCom - Win32 Debug" 61 | 62 | # PROP BASE Use_MFC 2 63 | # PROP BASE Use_Debug_Libraries 1 64 | # PROP BASE Output_Dir "Debug" 65 | # PROP BASE Intermediate_Dir "Debug" 66 | # PROP BASE Target_Dir "" 67 | # PROP Use_MFC 0 68 | # PROP Use_Debug_Libraries 1 69 | # PROP Output_Dir "Debug" 70 | # PROP Intermediate_Dir "Debug" 71 | # PROP Ignore_Export_Lib 0 72 | # PROP Target_Dir "" 73 | # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c 74 | # ADD CPP /nologo /MDd /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /FD /GZ /c 75 | # SUBTRACT CPP /YX /Yc /Yu 76 | # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 77 | # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 78 | # ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" 79 | # ADD RSC /l 0x409 /d "_DEBUG" 80 | BSC32=bscmake.exe 81 | # ADD BASE BSC32 /nologo 82 | # ADD BSC32 /nologo 83 | LINK32=link.exe 84 | # ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept 85 | # ADD LINK32 userenv.lib advapi32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib mpr.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 86 | # SUBTRACT LINK32 /pdb:none 87 | 88 | !ENDIF 89 | 90 | # Begin Target 91 | 92 | # Name "RemCom - Win32 Release" 93 | # Name "RemCom - Win32 Debug" 94 | # Begin Group "Source Files" 95 | 96 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 97 | # Begin Source File 98 | 99 | SOURCE=.\RemCom.cpp 100 | # End Source File 101 | # Begin Source File 102 | 103 | SOURCE=.\RemCom.rc 104 | # End Source File 105 | # End Group 106 | # Begin Group "Header Files" 107 | 108 | # PROP Default_Filter "*.h" 109 | # Begin Source File 110 | 111 | SOURCE=.\RemCom.h 112 | # End Source File 113 | # Begin Source File 114 | 115 | SOURCE=.\resource.h 116 | # End Source File 117 | # End Group 118 | # Begin Source File 119 | 120 | SOURCE=.\ProcComs\Release\ProcComs.bin 121 | # End Source File 122 | # Begin Source File 123 | 124 | SOURCE=.\RemComSvc\Release\RemComSvc.exe 125 | # End Source File 126 | # End Target 127 | # End Project 128 | -------------------------------------------------------------------------------- /RemComSvc/RemComSvc.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="RemComSvc" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=RemComSvc - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "RemComSvc.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "RemComSvc.mak" CFG="RemComSvc - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "RemComSvc - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "RemComSvc - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "RemComSvc - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Target_Dir "" 43 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 44 | # ADD CPP /nologo /MD /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 46 | # ADD RSC /l 0x409 /d "NDEBUG" 47 | BSC32=bscmake.exe 48 | # ADD BASE BSC32 /nologo 49 | # ADD BSC32 /nologo 50 | LINK32=link.exe 51 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 52 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | 54 | !ELSEIF "$(CFG)" == "RemComSvc - Win32 Debug" 55 | 56 | # PROP BASE Use_MFC 0 57 | # PROP BASE Use_Debug_Libraries 1 58 | # PROP BASE Output_Dir "Debug" 59 | # PROP BASE Intermediate_Dir "Debug" 60 | # PROP BASE Target_Dir "" 61 | # PROP Use_MFC 0 62 | # PROP Use_Debug_Libraries 1 63 | # PROP Output_Dir "Debug" 64 | # PROP Intermediate_Dir "Debug" 65 | # PROP Ignore_Export_Lib 0 66 | # PROP Target_Dir "" 67 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 68 | # ADD CPP /nologo /MDd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 70 | # ADD RSC /l 0x409 /d "_DEBUG" 71 | BSC32=bscmake.exe 72 | # ADD BASE BSC32 /nologo 73 | # ADD BSC32 /nologo 74 | LINK32=link.exe 75 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 76 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | 78 | !ENDIF 79 | 80 | # Begin Target 81 | 82 | # Name "RemComSvc - Win32 Release" 83 | # Name "RemComSvc - Win32 Debug" 84 | # Begin Group "Source Files" 85 | 86 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 87 | # Begin Source File 88 | 89 | SOURCE=.\RemComSvc.cpp 90 | # End Source File 91 | # Begin Source File 92 | 93 | SOURCE=.\Service.cpp 94 | # End Source File 95 | # End Group 96 | # Begin Group "Header Files" 97 | 98 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 99 | # Begin Source File 100 | 101 | SOURCE=.\RemComSvc.h 102 | # End Source File 103 | # End Group 104 | # End Target 105 | # End Project 106 | -------------------------------------------------------------------------------- /ProcComs/ProcComs.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="ProcComs" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=ProcComs - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "ProcComs.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "ProcComs.mak" CFG="ProcComs - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "ProcComs - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "ProcComs - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "ProcComs - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "Release" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c 45 | # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"stdafx.h" /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 userenv.lib Advapi32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Release/ProcComs.bin" 54 | # SUBTRACT LINK32 /pdb:none 55 | 56 | !ELSEIF "$(CFG)" == "ProcComs - Win32 Debug" 57 | 58 | # PROP BASE Use_MFC 0 59 | # PROP BASE Use_Debug_Libraries 1 60 | # PROP BASE Output_Dir "Debug" 61 | # PROP BASE Intermediate_Dir "Debug" 62 | # PROP BASE Target_Dir "" 63 | # PROP Use_MFC 0 64 | # PROP Use_Debug_Libraries 1 65 | # PROP Output_Dir "Debug" 66 | # PROP Intermediate_Dir "Debug" 67 | # PROP Ignore_Export_Lib 0 68 | # PROP Target_Dir "" 69 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c 70 | # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /Yu"stdafx.h" /FD /GZ /c 71 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 72 | # ADD RSC /l 0x409 /d "_DEBUG" 73 | BSC32=bscmake.exe 74 | # ADD BASE BSC32 /nologo 75 | # ADD BSC32 /nologo 76 | LINK32=link.exe 77 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | # ADD LINK32 userenv.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept 79 | # SUBTRACT LINK32 /pdb:none 80 | 81 | !ENDIF 82 | 83 | # Begin Target 84 | 85 | # Name "ProcComs - Win32 Release" 86 | # Name "ProcComs - Win32 Debug" 87 | # Begin Group "Source Files" 88 | 89 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 90 | # Begin Source File 91 | 92 | SOURCE=.\ProcComs.cpp 93 | # End Source File 94 | # Begin Source File 95 | 96 | SOURCE=.\StdAfx.cpp 97 | # ADD CPP /Yc"stdafx.h" 98 | # End Source File 99 | # End Group 100 | # Begin Group "Header Files" 101 | 102 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 103 | # Begin Source File 104 | 105 | SOURCE=.\StdAfx.h 106 | # End Source File 107 | # End Group 108 | # Begin Group "Resource Files" 109 | 110 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 111 | # End Group 112 | # End Target 113 | # End Project 114 | -------------------------------------------------------------------------------- /ProcComs/ProcComs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantability or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | $Author: Talha Tariq [ talha.tariq@gmail.com ] 18 | $Revision: Talha Tariq [ talha.tariq@gmail.com ] 19 | $Date: 2006/11/03 09:00:00 $ 20 | $Version History: $ - Added OpenProcessToken to get the preocess token. 21 | - Fixed the bug for Windows 2000 where Calling LogonUser API needs an SE_TCB_NAME privilege which is not enabled by default 22 | $TODO: - Code Cleanup. - Move the class as UniCode implementation to the RemCom project 23 | $Description: $ - ProcCom binary is contained in the parent binary as a local resource which is extracted at runtime from itself 24 | for local prorcess and user impersonation 25 | $Workfile: $ - ProcComs.cpp 26 | */ 27 | 28 | #include "stdafx.h" 29 | 30 | void ShowLastError(LPWSTR pszAPI) 31 | { 32 | LPVOID lpvMessageBuffer; 33 | 34 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 35 | FORMAT_MESSAGE_FROM_SYSTEM, 36 | NULL, GetLastError(), 37 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 38 | (LPWSTR)&lpvMessageBuffer, 0, NULL); 39 | 40 | // 41 | //... now display this string 42 | // 43 | wprintf(L"ERROR: API = %s.\n", pszAPI); 44 | wprintf(L" error code = %d.\n", GetLastError()); 45 | wprintf(L" message = %s.\n", (LPWSTR)lpvMessageBuffer); 46 | 47 | // 48 | // Free the buffer allocated by the system 49 | // 50 | LocalFree(lpvMessageBuffer); 51 | 52 | ExitProcess(GetLastError()); 53 | } 54 | 55 | BOOL SetPrivilege( 56 | HANDLE hToken, // access token handle 57 | LPCTSTR lpszPrivilege, // name of privilege to enable/disable 58 | BOOL bEnablePrivilege // to enable or disable privilege 59 | ) 60 | { 61 | TOKEN_PRIVILEGES tp; 62 | LUID luid; 63 | 64 | if ( !LookupPrivilegeValue( 65 | NULL, // lookup privilege on local system 66 | lpszPrivilege, // privilege to lookup 67 | &luid ) ) // receives LUID of privilege 68 | { 69 | printf("LookupPrivilegeValue error: %u\n", GetLastError()); 70 | return FALSE; 71 | } 72 | 73 | tp.PrivilegeCount = 1; 74 | tp.Privileges[0].Luid = luid; 75 | if (bEnablePrivilege) 76 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 77 | else 78 | tp.Privileges[0].Attributes = 0; 79 | 80 | // Enable the privilege or disable all privileges. 81 | 82 | if ( !AdjustTokenPrivileges( 83 | hToken, 84 | FALSE, 85 | &tp, 86 | sizeof(TOKEN_PRIVILEGES), 87 | (PTOKEN_PRIVILEGES) NULL, 88 | (PDWORD) NULL) ) 89 | { 90 | printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); 91 | return FALSE; 92 | } 93 | 94 | if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 95 | 96 | { 97 | printf("The token does not have the specified privilege. \n"); 98 | return FALSE; 99 | } 100 | 101 | return TRUE; 102 | } 103 | void wmain(int argc, WCHAR *argv[]) 104 | { 105 | DWORD dwSize; 106 | HANDLE hToken; 107 | LPVOID lpvEnv; 108 | PROCESS_INFORMATION pi = {0}; 109 | STARTUPINFO si = {0}; 110 | WCHAR szUserProfile[256] = L""; 111 | 112 | si.cb = sizeof(STARTUPINFO); 113 | 114 | if (argc != 4) 115 | { 116 | /* wprintf(L"Usage: %s [user@domain] [password] [cmd]", argv[0]); 117 | wprintf(L"\n\n"); */ 118 | // return; 119 | } 120 | 121 | dwSize = sizeof(szUserProfile)/sizeof(WCHAR); 122 | 123 | 124 | OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken); 125 | //ShowLastError(L"OpenProcessToken"); 126 | //SetPrivilege(&hToken, SE_SYSTEMTIME_NAME,TRUE); 127 | // if(!SetPrivilege(hToken, SE_TCB_NAME , TRUE)) printf("Set Privilege Failed");// DisplayError(L"SetPrivilege"); 128 | //if (!LogonUser(argv[1], NULL , argv[2], LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken)) DisplayError(L"LogonUser"); 129 | 130 | if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE)) ShowLastError(L"CreateEnvironmentBlock"); 131 | 132 | dwSize = sizeof(szUserProfile)/sizeof(WCHAR); 133 | 134 | if (!GetUserProfileDirectory(hToken, szUserProfile, &dwSize)) ShowLastError(L"GetUserProfileDirectory"); 135 | // 136 | // TO DO: change NULL to '.' to use local account database 137 | // 138 | if (!CreateProcessWithLogonW(argv[1], NULL, argv[2], LOGON_WITH_PROFILE, NULL, argv[3], CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfile, &si, &pi)) 139 | 140 | ShowLastError(L"CreateProcessWithLogonW"); 141 | 142 | if (!DestroyEnvironmentBlock(lpvEnv)) ShowLastError(L"DestroyEnvironmentBlock"); 143 | 144 | 145 | CloseHandle(hToken); 146 | CloseHandle(pi.hProcess); 147 | CloseHandle(pi.hThread); 148 | } 149 | 150 | -------------------------------------------------------------------------------- /RemComSvc/xServer.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////// 2 | // 3 | // Author: Zoltan Csizmadia, 7/2000 4 | // 5 | // This code is freeware! If you change it, please send me your version! 6 | // 7 | // Email: zoltan_csizmadia@yahoo.com 8 | // 9 | ///////////////////////////////////////////////////////////// 10 | 11 | #include "RemCom.h" 12 | #include 13 | #include 14 | 15 | long dwSvcPipeCount = 0; 16 | HANDLE hPipeThreadExited = 0; 17 | 18 | LPTSTR EmptyStrToNull( LPTSTR str ) 19 | { 20 | return str[0] == _T('\0') ? NULL : str; 21 | } 22 | 23 | HANDLE ConnectToRemoteStdOut( RemComMessage* pMsg ) 24 | { 25 | SECURITY_ATTRIBUTES SecAttrib = {0}; 26 | SECURITY_DESCRIPTOR SecDesc; 27 | InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); 28 | SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, FALSE); 29 | 30 | SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 31 | SecAttrib.lpSecurityDescriptor = &SecDesc;; 32 | SecAttrib.bInheritHandle = TRUE; 33 | 34 | HANDLE hStdOut = INVALID_HANDLE_VALUE; 35 | 36 | hStdOut = CreateFile( 37 | pMsg->szStdOut, 38 | GENERIC_WRITE, 39 | 0, 40 | &SecAttrib, 41 | OPEN_EXISTING, 42 | FILE_ATTRIBUTE_NORMAL, 43 | NULL); 44 | 45 | if ( hStdOut != INVALID_HANDLE_VALUE ) 46 | WaitNamedPipe( pMsg->szStdOut, NULL ); 47 | 48 | return hStdOut; 49 | } 50 | 51 | HANDLE ConnectToRemoteStdIn( RemComMessage* pMsg ) 52 | { 53 | SECURITY_ATTRIBUTES SecAttrib = {0}; 54 | SECURITY_DESCRIPTOR SecDesc; 55 | InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); 56 | SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, FALSE); 57 | 58 | SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 59 | SecAttrib.lpSecurityDescriptor = &SecDesc;; 60 | SecAttrib.bInheritHandle = TRUE; 61 | 62 | HANDLE hStdOut = INVALID_HANDLE_VALUE; 63 | 64 | hStdOut = CreateFile( 65 | pMsg->szStdIn, 66 | GENERIC_READ, 67 | 0, 68 | &SecAttrib, 69 | OPEN_EXISTING, 70 | FILE_ATTRIBUTE_NORMAL, 71 | NULL); 72 | 73 | if ( hStdOut != INVALID_HANDLE_VALUE ) 74 | WaitNamedPipe( pMsg->szStdIn, NULL ); 75 | 76 | return hStdOut; 77 | } 78 | 79 | DWORD Execute( RemComMessage* pMsg ) 80 | { 81 | DWORD rc = 0; 82 | 83 | PROCESS_INFORMATION pi; 84 | STARTUPINFO si; 85 | memset( &si, 0, sizeof(si) ); 86 | si.cb = sizeof(si); 87 | 88 | si.lpTitle = pMsg->szTitle; 89 | si.wShowWindow = pMsg->wShow; 90 | si.dwFlags |= STARTF_USESHOWWINDOW; 91 | 92 | HANDLE hStdOut = ConnectToRemoteStdOut( pMsg ); 93 | 94 | if ( hStdOut == INVALID_HANDLE_VALUE ) 95 | return (DWORD)-1; 96 | 97 | HANDLE hStdIn = ConnectToRemoteStdIn( pMsg ); 98 | 99 | if ( hStdIn == INVALID_HANDLE_VALUE ) 100 | return (DWORD)-2; 101 | 102 | si.dwFlags |= STARTF_USESTDHANDLES; 103 | si.hStdOutput = hStdOut; 104 | si.hStdError = hStdOut; 105 | si.hStdInput = hStdIn; 106 | 107 | TCHAR lpCmd[_MAX_PATH]; 108 | 109 | if ( pMsg->bCmd ) 110 | _stprintf( lpCmd, _T("cmd.exe /c %s"), pMsg->szCommand ); 111 | else 112 | _tcscpy( lpCmd, pMsg->szCommand ); 113 | 114 | if ( CreateProcess( 115 | NULL, 116 | lpCmd, 117 | NULL, 118 | NULL, 119 | TRUE, 120 | pMsg->dwCreationFlag | pMsg->dwPriority, 121 | NULL, 122 | EmptyStrToNull(pMsg->szWorkingDir), 123 | &si, 124 | &pi ) ) 125 | { 126 | HANDLE hProcess = pi.hProcess; 127 | 128 | if ( pMsg->bWait ) 129 | WaitForSingleObject( hProcess, INFINITE ); 130 | 131 | rc = 0; 132 | GetExitCodeProcess( hProcess, &rc ); 133 | } 134 | else 135 | { 136 | rc = 1; 137 | } 138 | 139 | return rc; 140 | } 141 | 142 | void ExecPipeThreadProc( void* pParam ) 143 | { 144 | HANDLE hPipe = (HANDLE)pParam; 145 | RemComMessage msg; 146 | RemComResponse response; 147 | DWORD dwWritten; 148 | DWORD dwRead; 149 | 150 | InterlockedIncrement( &dwSvcPipeCount ); 151 | 152 | if ( !ReadFile( hPipe, &msg, sizeof(msg), &dwRead, NULL ) || dwRead == 0 ) 153 | { 154 | cerr << _T("Error in ExecPipeThreadProc()[ReadFile()] : "); 155 | ShowLastErrorText(); 156 | cerr << endl; 157 | 158 | goto cleanup; 159 | } 160 | 161 | response.dwReturnCode = Execute( &msg ); 162 | 163 | if ( !WriteFile( hPipe, &response, sizeof(response), &dwWritten, NULL ) || dwWritten == 0 ) 164 | { 165 | cerr << _T("Error in ExecPipeThreadProc()[WriteFile()] : "); 166 | ShowLastErrorText(); 167 | cerr << endl; 168 | 169 | goto cleanup; 170 | } 171 | 172 | cleanup: 173 | 174 | DisconnectNamedPipe( hPipe ); 175 | CloseHandle( hPipe ); 176 | 177 | InterlockedDecrement( &dwSvcPipeCount ); 178 | 179 | SetEvent( hPipeThreadExited ); 180 | } 181 | 182 | void PipePoolThread( void* ) 183 | { 184 | HANDLE hPipe = NULL; 185 | 186 | for (;;) 187 | { 188 | SECURITY_ATTRIBUTES SecAttrib = {0}; 189 | SECURITY_DESCRIPTOR SecDesc; 190 | InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); 191 | SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, TRUE); 192 | 193 | SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 194 | SecAttrib.lpSecurityDescriptor = &SecDesc;; 195 | SecAttrib.bInheritHandle = TRUE; 196 | 197 | hPipe = CreateNamedPipe( 198 | _T("\\\\.\\pipe\\")RemComPIPENAME, 199 | PIPE_ACCESS_DUPLEX, 200 | PIPE_TYPE_MESSAGE | PIPE_WAIT, 201 | PIPE_UNLIMITED_INSTANCES, 202 | 0, 203 | 0, 204 | 0xffffffff, 205 | &SecAttrib); 206 | 207 | if ( hPipe != NULL ) 208 | { 209 | ConnectNamedPipe( hPipe, NULL ); 210 | _beginthread(ExecPipeThreadProc, 0, (void*)hPipe); 211 | } 212 | } 213 | } 214 | 215 | DWORD ServerMain( DWORD, LPTSTR* ) 216 | { 217 | DWORD rc = 0; 218 | 219 | dwSvcPipeCount = 0; 220 | 221 | hPipeThreadExited = CreateEvent( NULL, FALSE, FALSE, NULL ); 222 | 223 | _beginthread( PipePoolThread, 0, NULL ); 224 | 225 | while( WaitForSingleObject( hPipeThreadExited, INFINITE ) ) 226 | { 227 | if ( dwSvcPipeCount == 0 ) 228 | break; 229 | } 230 | 231 | CloseHandle( hPipeThreadExited ); 232 | 233 | return rc; 234 | } 235 | -------------------------------------------------------------------------------- /RemComSvc/RemComSvc.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {C7038612-8183-67A7-8A9C-1379C2674156} 15 | RemComSvc 16 | 17 | 18 | 19 | 20 | 21 | Application 22 | false 23 | MultiByte 24 | Windows7.1SDK 25 | 26 | 27 | Application 28 | false 29 | MultiByte 30 | Windows7.1SDK 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | <_ProjectFileVersion>10.0.40219.1 44 | .\Release\ 45 | .\Release\ 46 | false 47 | .\Debug\ 48 | .\Debug\ 49 | false 50 | AllRules.ruleset 51 | 52 | 53 | AllRules.ruleset 54 | 55 | 56 | 57 | 58 | 59 | MaxSpeed 60 | OnlyExplicitInline 61 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 62 | true 63 | MultiThreadedDLL 64 | true 65 | 66 | 67 | .\Release/RemComSvc.pch 68 | .\Release/ 69 | .\Release/ 70 | .\Release/ 71 | Level4 72 | true 73 | 74 | 75 | .\Release/RemComSvc.exe 76 | true 77 | .\Release/RemComSvc.pdb 78 | Console 79 | MachineX86 80 | 81 | 82 | .\Release/RemComSvc.tlb 83 | 84 | 85 | 86 | 87 | NDEBUG;%(PreprocessorDefinitions) 88 | 0x0409 89 | 90 | 91 | 92 | 93 | Disabled 94 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 95 | EnableFastChecks 96 | MultiThreadedDebugDLL 97 | 98 | 99 | .\Debug/RemComSvc.pch 100 | .\Debug/ 101 | .\Debug/ 102 | .\Debug/ 103 | Level4 104 | true 105 | EditAndContinue 106 | 107 | 108 | .\Debug/RemComSvc.exe 109 | true 110 | true 111 | .\Debug/RemComSvc.pdb 112 | Console 113 | MachineX86 114 | 115 | 116 | .\Debug/RemComSvc.tlb 117 | 118 | 119 | 120 | 121 | _DEBUG;%(PreprocessorDefinitions) 122 | 0x0409 123 | 124 | 125 | 126 | 127 | Disabled 128 | %(PreprocessorDefinitions) 129 | EnableFastChecks 130 | MaxSpeed 131 | %(PreprocessorDefinitions) 132 | 133 | 134 | Disabled 135 | %(PreprocessorDefinitions) 136 | EnableFastChecks 137 | MaxSpeed 138 | %(PreprocessorDefinitions) 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /RemComSvc/RemComSvc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantability or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | $Author: Talha Tariq [ talha.tariq@gmail.com ] 18 | uses some code from xCmd by Zoltan Csizmadia 19 | $Revision: Talha Tariq [ talha.tariq@gmail.com ] 20 | $Revision: Andres Ederra 21 | 22 | $Date: 2012/01/24 09:00:00 $ 23 | $Version History: $ - 24 | $TODO: - Implement Delete Service 25 | $Description: $ - RemCom Service is contained in the parent binary as a local resource which is extracted at runtime from itself 26 | pushed to admin$, installed to the remote service control manager which interacts remotely for local process invocation 27 | 28 | $Workfile: $ - RemComSvc.cpp 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "RemComSvc.h" 38 | #include "../RemCom.h" 39 | 40 | void CommunicationPoolThread(PVOID); 41 | void CommunicationPipeThreadProc(PVOID); 42 | DWORD Execute(RemComMessage*, DWORD*); 43 | 44 | LONG dwSvcPipeInstanceCount = 0; 45 | TCHAR szStdOutPipe[_MAX_PATH] = _T(""); 46 | TCHAR szStdInPipe[_MAX_PATH] = _T(""); 47 | TCHAR szStdErrPipe[_MAX_PATH] = _T(""); 48 | 49 | // Service "main" function 50 | void _ServiceMain( void* ) 51 | { 52 | // Start CommunicationPoolThread, which handles the incoming instances 53 | _beginthread( CommunicationPoolThread, 0, NULL ); 54 | 55 | // Waiting for stop the service 56 | while( WaitForSingleObject( hStopServiceEvent, 10 ) != WAIT_OBJECT_0 ) 57 | { 58 | } 59 | 60 | // Let's delete itself, after the service stopped 61 | DeleteSvc(); 62 | 63 | CloseHandle( hStopServiceEvent ); 64 | } 65 | 66 | // Communicaton Thread Pool, handles the incoming RemCom.exe requests 67 | void CommunicationPoolThread(PVOID) 68 | { 69 | HANDLE hPipe = NULL; 70 | 71 | for (;;) 72 | { 73 | SECURITY_ATTRIBUTES SecAttrib = {0}; 74 | SECURITY_DESCRIPTOR SecDesc; 75 | 76 | InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); 77 | SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, TRUE); 78 | 79 | SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 80 | SecAttrib.lpSecurityDescriptor = &SecDesc;; 81 | SecAttrib.bInheritHandle = TRUE; 82 | 83 | // Create communication pipe 84 | hPipe = CreateNamedPipe( 85 | _T("\\\\.\\pipe\\")RemComCOMM, 86 | PIPE_ACCESS_DUPLEX, 87 | PIPE_TYPE_MESSAGE | PIPE_WAIT, 88 | PIPE_UNLIMITED_INSTANCES, 89 | 0, 90 | 0, 91 | (DWORD)-1, 92 | &SecAttrib); 93 | 94 | if ( hPipe != NULL ) 95 | { 96 | // Waiting for client to connect to this pipe 97 | ConnectNamedPipe( hPipe, NULL ); 98 | _beginthread( CommunicationPipeThreadProc, 0, (void*)hPipe); 99 | } 100 | } 101 | } 102 | 103 | // Handles a client 104 | void CommunicationPipeThreadProc( void* pParam ) 105 | { 106 | HANDLE hPipe = (HANDLE)pParam; 107 | 108 | RemComMessage msg; 109 | RemComResponse response; 110 | 111 | DWORD dwWritten; 112 | DWORD dwRead; 113 | 114 | // Increment instance counter 115 | InterlockedIncrement( &dwSvcPipeInstanceCount ); 116 | 117 | ::ZeroMemory( &response, sizeof(response) ); 118 | 119 | // Waiting for communication message from client 120 | if ( !ReadFile( hPipe, &msg, sizeof(msg), &dwRead, NULL ) || dwRead == 0 ) 121 | goto cleanup; 122 | 123 | // Execute the requested command 124 | response.dwErrorCode = Execute( &msg, &response.dwReturnCode ); 125 | 126 | // Send back the response message (client is waiting for this response) 127 | if ( !WriteFile( hPipe, &response, sizeof(response), &dwWritten, NULL ) || dwWritten == 0 ) 128 | goto cleanup; 129 | 130 | cleanup: 131 | 132 | DisconnectNamedPipe( hPipe ); 133 | CloseHandle( hPipe ); 134 | 135 | // Decrement instance counter 136 | InterlockedDecrement( &dwSvcPipeInstanceCount ); 137 | 138 | // If this was the last client, let's stop ourself 139 | if ( dwSvcPipeInstanceCount == 0 ) 140 | SetEvent( hStopServiceEvent ); 141 | 142 | } 143 | 144 | // Creates named pipes for stdout, stderr, stdin 145 | BOOL CreateNamedPipes( RemComMessage* pMsg, STARTUPINFO* psi ) 146 | { 147 | SECURITY_ATTRIBUTES SecAttrib = {0}; 148 | SECURITY_DESCRIPTOR SecDesc; 149 | 150 | InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); 151 | SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, FALSE); 152 | 153 | SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 154 | SecAttrib.lpSecurityDescriptor = &SecDesc;; 155 | SecAttrib.bInheritHandle = TRUE; 156 | 157 | psi->dwFlags |= STARTF_USESTDHANDLES; 158 | psi->hStdOutput = INVALID_HANDLE_VALUE; 159 | psi->hStdInput = INVALID_HANDLE_VALUE; 160 | psi->hStdError = INVALID_HANDLE_VALUE; 161 | 162 | // StdOut pipe name 163 | _stprintf( szStdOutPipe, _T("\\\\.\\pipe\\%s%s%d"), 164 | RemComSTDOUT, 165 | pMsg->szMachine, 166 | pMsg->dwProcessId ); 167 | 168 | // StdIn pipe name 169 | _stprintf( szStdInPipe, _T("\\\\.\\pipe\\%s%s%d"), 170 | RemComSTDIN, 171 | pMsg->szMachine, 172 | pMsg->dwProcessId ); 173 | 174 | // StdError pipe name 175 | _stprintf( szStdErrPipe, _T("\\\\.\\pipe\\%s%s%d"), 176 | RemComSTDERR, 177 | pMsg->szMachine, 178 | pMsg->dwProcessId ); 179 | 180 | // Create StdOut pipe 181 | psi->hStdOutput = CreateNamedPipe( 182 | szStdOutPipe, 183 | PIPE_ACCESS_OUTBOUND, 184 | PIPE_TYPE_MESSAGE | PIPE_WAIT, 185 | PIPE_UNLIMITED_INSTANCES, 186 | 0, 187 | 0, 188 | (DWORD)-1, 189 | &SecAttrib); 190 | 191 | // Create StdError pipe 192 | psi->hStdError = CreateNamedPipe( 193 | szStdErrPipe, 194 | PIPE_ACCESS_OUTBOUND, 195 | PIPE_TYPE_MESSAGE | PIPE_WAIT, 196 | PIPE_UNLIMITED_INSTANCES, 197 | 0, 198 | 0, 199 | (DWORD)-1, 200 | &SecAttrib); 201 | 202 | // Create StdIn pipe 203 | psi->hStdInput = CreateNamedPipe( 204 | szStdInPipe, 205 | PIPE_ACCESS_INBOUND, 206 | PIPE_TYPE_MESSAGE | PIPE_WAIT, 207 | PIPE_UNLIMITED_INSTANCES, 208 | 0, 209 | 0, 210 | (DWORD)-1, 211 | &SecAttrib); 212 | 213 | if ( psi->hStdOutput == INVALID_HANDLE_VALUE || 214 | psi->hStdError == INVALID_HANDLE_VALUE || 215 | psi->hStdInput == INVALID_HANDLE_VALUE ) 216 | { 217 | CloseHandle( psi->hStdOutput ); 218 | CloseHandle( psi->hStdError ); 219 | CloseHandle( psi->hStdInput ); 220 | 221 | return FALSE; 222 | } 223 | 224 | // Waiting for client to connect to this pipe 225 | ConnectNamedPipe( psi->hStdOutput, NULL ); 226 | ConnectNamedPipe( psi->hStdInput, NULL ); 227 | ConnectNamedPipe( psi->hStdError, NULL ); 228 | 229 | return TRUE; 230 | } 231 | 232 | // Execute the requested client command 233 | DWORD Execute( RemComMessage* pMsg, DWORD* pReturnCode ) 234 | { 235 | DWORD rc; 236 | TCHAR szCommand[_MAX_PATH]; 237 | PROCESS_INFORMATION pi; 238 | STARTUPINFO si; 239 | 240 | ::ZeroMemory( &si, sizeof(si) ); 241 | si.cb = sizeof(si); 242 | 243 | // Creates named pipes for stdout, stdin, stderr 244 | // Client will sit on these pipes 245 | if ( !CreateNamedPipes( pMsg, &si ) ) 246 | return 2; 247 | 248 | *pReturnCode = 0; 249 | rc = 0; 250 | 251 | // Initializes command 252 | // cmd.exe /c /q allows us to execute internal dos commands too. 253 | _stprintf( szCommand, _T("%s"), pMsg->szCommand ); 254 | 255 | // Start the requested process 256 | if ( CreateProcess( 257 | NULL, 258 | szCommand, 259 | NULL, 260 | NULL, 261 | TRUE, 262 | pMsg->dwPriority | CREATE_NO_WINDOW, 263 | NULL, 264 | pMsg->szWorkingDir[0] != _T('\0') ? pMsg->szWorkingDir : NULL, 265 | &si, 266 | &pi ) ) 267 | { 268 | HANDLE hProcess = pi.hProcess; 269 | 270 | *pReturnCode = 0; 271 | 272 | // Waiting for process to terminate 273 | if ( !pMsg->bNoWait ) 274 | { 275 | WaitForSingleObject( hProcess, INFINITE ); 276 | GetExitCodeProcess( hProcess, pReturnCode ); 277 | } 278 | } 279 | else 280 | rc = 1; 281 | 282 | return rc; 283 | } 284 | -------------------------------------------------------------------------------- /RemComSvc/Service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006 Talha Tariq [ talha.tariq@gmail.com ] 3 | All rights are reserved. 4 | 5 | Permission to use, copy, modify, and distribute this software 6 | for any purpose and without any fee is hereby granted, 7 | provided this notice is included in its entirety in the 8 | documentation and in the source files. 9 | 10 | This software and any related documentation is provided "as is" 11 | without any warranty of any kind, either express or implied, 12 | including, without limitation, the implied warranties of 13 | merchantibility or fitness for a particular purpose. The entire 14 | risk arising out of use or performance of the software remains 15 | with you. 16 | 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "RemComSvc.h" 25 | #include "../RemCom.h" 26 | 27 | SERVICE_STATUS ServiceStatus; 28 | SERVICE_STATUS_HANDLE ServiceStatusHandle; 29 | 30 | HANDLE hStopServiceEvent = NULL; 31 | 32 | VOID WINAPI RemComStart (DWORD argc, LPTSTR *argv); // prototype for the starting point of the service 33 | VOID WINAPI RemComCtrlHandler (DWORD opcode); // prototype for the control handler callback function of the service 34 | DWORD IsService( BOOL& ); 35 | 36 | int _tmain( int, LPTSTR* ) 37 | { 38 | SERVICE_TABLE_ENTRY DispatchTable[] = { 39 | { SERVICENAME, RemComStart }, 40 | { NULL, NULL } }; 41 | 42 | BOOL bService = TRUE; 43 | 44 | // This process should be a service :) 45 | IsService( bService ); 46 | if ( !bService ) 47 | _tprintf( _T("A service Cannot be started directly.\n") ); 48 | 49 | // Start service 50 | return StartServiceCtrlDispatcher( DispatchTable); 51 | } 52 | 53 | // Deletes service 54 | void DeleteSvc() 55 | { 56 | // Open service manager 57 | SC_HANDLE hSCM = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); 58 | 59 | if (hSCM == NULL) 60 | return; 61 | 62 | // OPen service 63 | SC_HANDLE hService = ::OpenService( hSCM, SERVICENAME, SERVICE_ALL_ACCESS ); 64 | 65 | if (hService == NULL) 66 | { 67 | ::CloseServiceHandle(hSCM); 68 | return; 69 | } 70 | 71 | // Deletes service from service database 72 | DeleteService( hService ); 73 | 74 | // Stop the service 75 | ServiceStatus.dwCurrentState = SERVICE_STOPPED; 76 | ServiceStatus.dwCheckPoint = 0; 77 | ServiceStatus.dwWaitHint = 0; 78 | ServiceStatus.dwWin32ExitCode = 0; 79 | ServiceStatus.dwServiceSpecificExitCode = 0; 80 | SetServiceStatus (ServiceStatusHandle, &ServiceStatus); 81 | 82 | ::CloseServiceHandle(hService); 83 | ::CloseServiceHandle(hSCM); 84 | } 85 | 86 | // Start service 87 | VOID WINAPI RemComStart (DWORD, LPTSTR* ) 88 | { 89 | DWORD status = 0; 90 | DWORD specificError = 0; 91 | 92 | // Prepare the ServiceStatus structure that will be used for the 93 | // comunication with SCM(Service Control Manager). 94 | // If you fully under stand the members of this structure, feel 95 | // free to change these values :o) 96 | ServiceStatus.dwServiceType = SERVICE_WIN32; 97 | ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 98 | ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; 99 | ServiceStatus.dwWin32ExitCode = 0; 100 | ServiceStatus.dwServiceSpecificExitCode = 0; 101 | ServiceStatus.dwCheckPoint = 0; 102 | ServiceStatus.dwWaitHint = 0; 103 | 104 | // Here we register the control handler for our service. 105 | // We tell the SCM about a call back function that SCM will 106 | // call when user tries to Start, Stop or Pause your service. 107 | ServiceStatusHandle = RegisterServiceCtrlHandler( 108 | TEXT("Service"), RemComCtrlHandler ); 109 | 110 | if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) 111 | return; 112 | 113 | // Handle error condition 114 | if (status != NO_ERROR) 115 | { 116 | ServiceStatus.dwCurrentState = SERVICE_STOPPED; 117 | ServiceStatus.dwCheckPoint = 0; 118 | ServiceStatus.dwWaitHint = 0; 119 | ServiceStatus.dwWin32ExitCode = status; 120 | ServiceStatus.dwServiceSpecificExitCode = specificError; 121 | 122 | SetServiceStatus (ServiceStatusHandle, &ServiceStatus); 123 | return; 124 | } 125 | 126 | // Initialization complete - report running status. 127 | ServiceStatus.dwCurrentState = SERVICE_RUNNING; 128 | ServiceStatus.dwCheckPoint = 0; 129 | ServiceStatus.dwWaitHint = 0; 130 | 131 | if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus)) 132 | status = GetLastError(); 133 | else 134 | { 135 | // Start the main thread 136 | hStopServiceEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); 137 | _beginthread( _ServiceMain, 0, NULL ); 138 | } 139 | 140 | return; 141 | } 142 | 143 | // Service Ctrl handler 144 | VOID WINAPI RemComCtrlHandler (DWORD Opcode) 145 | { 146 | DWORD status; 147 | 148 | switch(Opcode) 149 | { 150 | case SERVICE_CONTROL_STOP: 151 | // Signal the event to stop the main thread 152 | SetEvent( hStopServiceEvent ); 153 | 154 | ServiceStatus.dwWin32ExitCode = 0; 155 | ServiceStatus.dwCurrentState = SERVICE_STOPPED; 156 | ServiceStatus.dwCheckPoint = 0; 157 | ServiceStatus.dwWaitHint = 0; 158 | 159 | if (!SetServiceStatus (ServiceStatusHandle, 160 | &ServiceStatus)) 161 | { 162 | status = GetLastError(); 163 | } 164 | return; 165 | 166 | case SERVICE_CONTROL_INTERROGATE: 167 | // Fall through to send current status. 168 | break; 169 | } 170 | 171 | // Send current status. 172 | if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus)) 173 | { 174 | status = GetLastError(); 175 | } 176 | return; 177 | } 178 | 179 | // This process is a service or is not ? 180 | DWORD IsService( BOOL& isService ) 181 | { 182 | DWORD pID = GetCurrentProcessId(); 183 | HANDLE hProcessToken = NULL; 184 | DWORD groupLength = 50; 185 | PTOKEN_GROUPS groupInfo = NULL; 186 | 187 | SID_IDENTIFIER_AUTHORITY siaNt = SECURITY_NT_AUTHORITY; 188 | PSID pInteractiveSid = NULL; 189 | PSID pServiceSid = NULL; 190 | 191 | DWORD dwRet = NO_ERROR; 192 | 193 | // reset flags 194 | BOOL isInteractive = FALSE; 195 | isService = FALSE; 196 | 197 | DWORD ndx; 198 | 199 | HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pID ); 200 | 201 | // open the token 202 | if (!::OpenProcessToken( hProcess, TOKEN_QUERY, &hProcessToken) ) 203 | { 204 | dwRet = ::GetLastError(); 205 | goto closedown; 206 | } 207 | 208 | // allocate a buffer of default size 209 | groupInfo = (PTOKEN_GROUPS)::LocalAlloc(0, groupLength); 210 | if (groupInfo == NULL) 211 | { 212 | dwRet = ::GetLastError(); 213 | goto closedown; 214 | } 215 | 216 | // try to get the info 217 | if (!::GetTokenInformation(hProcessToken, TokenGroups, 218 | groupInfo, groupLength, &groupLength)) 219 | { 220 | // if buffer was too small, allocate to proper size, otherwise error 221 | if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) 222 | { 223 | dwRet = ::GetLastError(); 224 | goto closedown; 225 | } 226 | 227 | ::LocalFree(groupInfo); 228 | 229 | groupInfo = (PTOKEN_GROUPS)::LocalAlloc(0, groupLength); 230 | if (groupInfo == NULL) 231 | { 232 | dwRet = ::GetLastError(); 233 | goto closedown; 234 | } 235 | 236 | if (!GetTokenInformation(hProcessToken, TokenGroups, 237 | groupInfo, groupLength, &groupLength)) 238 | { 239 | dwRet = ::GetLastError(); 240 | goto closedown; 241 | } 242 | } 243 | 244 | // create comparison sids 245 | if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_INTERACTIVE_RID, 246 | 0, 0, 0, 0, 0, 0, 0, &pInteractiveSid)) 247 | { 248 | dwRet = ::GetLastError(); 249 | goto closedown; 250 | } 251 | 252 | if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_SERVICE_RID, 253 | 0, 0, 0, 0, 0, 0, 0, &pServiceSid)) 254 | { 255 | dwRet = ::GetLastError(); 256 | goto closedown; 257 | } 258 | 259 | // try to match sids 260 | for (ndx = 0; ndx < groupInfo->GroupCount ; ndx += 1) 261 | { 262 | SID_AND_ATTRIBUTES sanda = groupInfo->Groups[ndx]; 263 | PSID pSid = sanda.Sid; 264 | 265 | if (::EqualSid(pSid, pInteractiveSid)) 266 | { 267 | isInteractive = TRUE; 268 | isService = FALSE; 269 | break; 270 | } 271 | else if (::EqualSid(pSid, pServiceSid)) 272 | { 273 | isService = TRUE; 274 | isInteractive = FALSE; 275 | break; 276 | } 277 | } 278 | 279 | if ( !( isService || isInteractive ) ) 280 | isService = TRUE; 281 | 282 | closedown: 283 | if ( pServiceSid ) 284 | ::FreeSid( pServiceSid ); 285 | 286 | if ( pInteractiveSid ) 287 | ::FreeSid( pInteractiveSid ); 288 | 289 | if ( groupInfo ) 290 | ::LocalFree( groupInfo ); 291 | 292 | if ( hProcessToken ) 293 | ::CloseHandle( hProcessToken ); 294 | 295 | if ( hProcess ) 296 | ::CloseHandle( hProcess ); 297 | 298 | return dwRet; 299 | } 300 | -------------------------------------------------------------------------------- /RemCom.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {8CC59FFA-00E0-0AEA-59E8-E780672C3CB3} 15 | RemCom 16 | 17 | 18 | 19 | 20 | 21 | Application 22 | false 23 | MultiByte 24 | Windows7.1SDK 25 | 26 | 27 | Application 28 | false 29 | MultiByte 30 | Windows7.1SDK 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | <_ProjectFileVersion>10.0.40219.1 44 | Release 45 | Release 46 | false 47 | Debug 48 | Debug 49 | false 50 | AllRules.ruleset 51 | 52 | 53 | AllRules.ruleset 54 | 55 | 56 | 57 | 58 | 59 | Full 60 | OnlyExplicitInline 61 | Size 62 | NDEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions) 63 | true 64 | MultiThreadedDLL 65 | true 66 | .\Release/RemCom.pch 67 | .\Release/ 68 | .\Release/ 69 | .\Release/ 70 | true 71 | Level4 72 | true 73 | OldStyle 74 | 75 | 76 | odbc32.lib;odbccp32.lib;mpr.lib;%(AdditionalDependencies) 77 | bin/Release/RemCom.exe 78 | true 79 | true 80 | .\Release/RemCom.pdb 81 | Console 82 | MachineX86 83 | 84 | 85 | NDEBUG;%(PreprocessorDefinitions) 86 | true 87 | true 88 | Win32 89 | .\Release/RemCom.tlb 90 | 91 | 92 | 93 | 94 | NDEBUG;%(PreprocessorDefinitions) 95 | 0x0409 96 | 97 | 98 | 99 | 100 | Disabled 101 | _DEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions) 102 | EnableFastChecks 103 | MultiThreadedDebugDLL 104 | .\Debug/RemCom.pch 105 | .\Debug/ 106 | .\Debug/ 107 | .\Debug/ 108 | true 109 | Level4 110 | true 111 | EditAndContinue 112 | 113 | 114 | odbc32.lib;odbccp32.lib;mpr.lib;%(AdditionalDependencies) 115 | bin/Debug/RemCom.exe 116 | true 117 | true 118 | .\Debug/RemCom.pdb 119 | Console 120 | MachineX86 121 | 122 | 123 | _DEBUG;%(PreprocessorDefinitions) 124 | true 125 | true 126 | Win32 127 | .\Debug/RemCom.tlb 128 | 129 | 130 | 131 | 132 | _DEBUG;%(PreprocessorDefinitions) 133 | 0x0409 134 | 135 | 136 | 137 | 138 | Disabled 139 | %(PreprocessorDefinitions) 140 | EnableFastChecks 141 | true 142 | MinSpace 143 | %(PreprocessorDefinitions) 144 | true 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | {c7038612-8183-67a7-8a9c-1379c2674156} 160 | false 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /ProcComs/ProcComs.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {29548EB7-5E44-21F9-5C82-15DDDC80449A} 15 | ProcComs 16 | 17 | 18 | 19 | 20 | 21 | Application 22 | false 23 | MultiByte 24 | Windows7.1SDK 25 | 26 | 27 | Application 28 | false 29 | MultiByte 30 | Windows7.1SDK 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | <_ProjectFileVersion>10.0.40219.1 44 | .\Release\ 45 | .\Release\ 46 | false 47 | .\Debug\ 48 | .\Debug\ 49 | false 50 | AllRules.ruleset 51 | 52 | 53 | AllRules.ruleset 54 | 55 | 56 | 57 | 58 | 59 | MaxSpeed 60 | OnlyExplicitInline 61 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 62 | true 63 | MultiThreaded 64 | true 65 | Use 66 | stdafx.h 67 | .\Release/ProcComs.pch 68 | .\Release/ 69 | .\Release/ 70 | .\Release/ 71 | true 72 | Level3 73 | true 74 | 75 | 76 | userenv.lib;%(AdditionalDependencies) 77 | Release/ProcComs.bin 78 | true 79 | .\Release/ProcComs.pdb 80 | Console 81 | MachineX86 82 | 83 | 84 | .\Release/ProcComs.tlb 85 | 86 | 87 | 88 | 89 | NDEBUG;%(PreprocessorDefinitions) 90 | 0x0409 91 | 92 | 93 | 94 | 95 | Disabled 96 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 97 | EnableFastChecks 98 | MultiThreadedDebug 99 | Use 100 | stdafx.h 101 | .\Debug/ProcComs.pch 102 | .\Debug/ 103 | .\Debug/ 104 | .\Debug/ 105 | true 106 | Level3 107 | true 108 | EditAndContinue 109 | 110 | 111 | userenv.lib;%(AdditionalDependencies) 112 | Debug/ProcComs.bin 113 | true 114 | true 115 | .\Debug/ProcComs.pdb 116 | Console 117 | MachineX86 118 | 119 | 120 | .\Debug/ProcComs.tlb 121 | 122 | 123 | 124 | 125 | _DEBUG;%(PreprocessorDefinitions) 126 | 0x0409 127 | 128 | 129 | 130 | 131 | Disabled 132 | %(PreprocessorDefinitions) 133 | EnableFastChecks 134 | Create 135 | true 136 | MaxSpeed 137 | %(PreprocessorDefinitions) 138 | Create 139 | true 140 | 141 | 142 | Disabled 143 | %(PreprocessorDefinitions) 144 | EnableFastChecks 145 | true 146 | MaxSpeed 147 | %(PreprocessorDefinitions) 148 | true 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /RemCom.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2006-2012 Talha Tariq [ talha.tariq@gmail.com ] 3 | Luke Suchocki 4 | Merlyn Morgan-Graham 5 | Andres Ederra 6 | All rights are reserved. 7 | 8 | Permission to use, copy, modify, and distribute this software 9 | for any purpose and without any fee is hereby granted, 10 | provided this notice is included in its entirety in the 11 | documentation and in the source files. 12 | 13 | This software and any related documentation is provided "as is" 14 | without any warranty of any kind, either express or implied, 15 | including, without limitation, the implied warranties of 16 | merchantability or fitness for a particular purpose. The entire 17 | risk arising out of use or performance of the software remains 18 | with you. 19 | 20 | $Author: Talha Tariq [ talha.tariq@gmail.com ] 21 | uses some code from xCmd by Zoltan Csizmadia 22 | $Revision: Talha Tariq [ talha.tariq@gmail.com ] 23 | $Revision: Luke Suchocki (patched rc) 24 | $Revision: Merlyn Morgan-Graham (handle spaces in the filename) 25 | $Revision: Andres Ederra (support for 64bits targets, send 26 | remcom outout to stderr, support for longer 27 | parameters, escape special characters in command 28 | parameters, detailed error codes) 29 | 30 | $Date: 2012/01/24 09:00:00 $ 31 | 32 | $Version History: $ - Refactored and Restructured Code - Deleted Unnecessary variables and Functions for Memory Consumption and Optimisation. 33 | - Added Function StartLocalProcessAsUser for local user impersonation 34 | - Added Start Local Process for launching external commands 35 | - Added GetAdminSid, GetLocalSid, GetLogonSID, FreeLogonSid for getting tokens to pass on for logon impersonation 36 | - Added IsLaunchedFromAdmin to get the local admin sid 37 | - Added ExtractLocalBinaryResource to extract the local binary resource for local process impersonation 38 | - Added ProcComs to implement local process functionality 39 | - Added RemCom to implement remote process functionality 40 | - Patched to give the correct return code 41 | - Patched to handle spaces in the filename. 42 | - Modified to handle longer command parameters 43 | - Changed directory to copy executables to \\ADMIN$ instead of \\ADMIN$\system32 in order to support 64 bits targets 44 | - Changed RemCom output to be sent to stderr while the remote command writes to stdout 45 | - Allow to scape '/' character to use it as part of remote command and its parameters. 46 | - Reclassified error return codes. Now RemCom returns its own return code, and the remote program return code is show at the stdout. 47 | //Return Codes: 48 | // 49 | // (-1) Incorrect parameters 50 | // (-2) Malformed credentials 51 | // (-3) Invalid target name 52 | // (-4) Bad credentials 53 | // (-5) Could not connect to target 54 | // (-6) Error copying executable 55 | // (-7) Error copying service 56 | // (-8) Error executing service 57 | // (-9) Error connecting to remote service 58 | - Patched to handle spaces in the filename (FIXED). 59 | - Tested with: win2k, winxp(32bits), win2003(32&64), win2008R2(32&64), win7(32&64). 60 | 61 | $TODO: - Add Getopt to parse command line parametres more effectively. 62 | - Implemement cleanup and disconnect remote share command 63 | 64 | $Description: $ - RemCom is RAT [Remote Administration Tool] that lets you execute processes on remote windows systems, copy files, 65 | process there output and stream it back. It allows execution of remote shell commands directly with full interactive console 66 | 67 | $Workfile: $ - RemCom.cpp 68 | */ 69 | 70 | 71 | #define _WIN32_WINNT 0x0500 //Will work only on W2K and above 72 | 73 | #include "RemCom.h" 74 | 75 | #define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \ 76 | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \ 77 | DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \ 78 | DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED) 79 | 80 | #define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \ 81 | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES | \ 82 | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | \ 83 | WINSTA_READSCREEN | STANDARD_RIGHTS_REQUIRED) 84 | 85 | #define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL) 86 | 87 | // Constant Definitions 88 | #define SIZEOF_BUFFER 0x500 89 | 90 | // Local Machine Settings 91 | TCHAR szThisMachine[SIZEOF_BUFFER] = _T(""); 92 | TCHAR szPassword[SIZEOF_BUFFER] = _T(""); 93 | TCHAR szArguments[SIZEOF_BUFFER] = _T(""); 94 | TCHAR szConsoleTitle[SIZEOF_BUFFER] = _T(""); 95 | TCHAR szLocalBinPath[_MAX_PATH] = _T(""); 96 | 97 | // Windows Default Windows Path 98 | LPCTSTR lpszSystemRoot = "%SystemRoot%"; 99 | LPCTSTR lpszLocalMachine = "\\\\localhost"; 100 | LPCTSTR lpszLocalIP = "\\\\127.0.0.1"; 101 | 102 | // Remote Parameters 103 | LPCTSTR lpszMachine = NULL; 104 | LPCTSTR lpszPassword = NULL; 105 | LPCTSTR lpszUser = NULL; 106 | LPCTSTR lpszDomain = NULL; 107 | LPCTSTR lpszCommandExe = NULL; 108 | 109 | // Named Pipes for Input and Output 110 | HANDLE hCommandPipe = INVALID_HANDLE_VALUE; 111 | HANDLE hRemoteOutPipe = INVALID_HANDLE_VALUE; 112 | HANDLE hRemoteStdInputPipe = INVALID_HANDLE_VALUE; 113 | HANDLE hRemoteErrorPipe = INVALID_HANDLE_VALUE; 114 | 115 | //Method Declarations 116 | BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid); 117 | BOOL AddAceToDesktop(HDESK hdesk, PSID psid); 118 | 119 | 120 | // Show the last error's description 121 | DWORD ShowLastError() 122 | { 123 | LPVOID lpvMessageBuffer; 124 | DWORD rc = GetLastError(); 125 | 126 | FormatMessage( 127 | FORMAT_MESSAGE_ALLOCATE_BUFFER | 128 | FORMAT_MESSAGE_FROM_SYSTEM | 129 | FORMAT_MESSAGE_IGNORE_INSERTS, 130 | NULL, 131 | rc, 132 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 133 | (LPTSTR) &lpvMessageBuffer, 134 | 0, 135 | NULL 136 | ); 137 | 138 | //Error( _T("Error code = %d.\n", rc) ); 139 | //_ftprintf( stderr, "Error code = %d.\n", rc); 140 | Error( (LPCTSTR)lpvMessageBuffer ); 141 | Error( _T("\n") ); 142 | 143 | LocalFree (lpvMessageBuffer); 144 | //ExitProcess(GetLastError()); 145 | return rc; 146 | } 147 | 148 | //Gets the SID for Admin 149 | void* GetAdminSid() 150 | { 151 | SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY; 152 | 153 | void* psid = 0; 154 | 155 | if ( !AllocateAndInitializeSid( &ntauth, 2, 156 | SECURITY_BUILTIN_DOMAIN_RID, 157 | DOMAIN_ALIAS_RID_ADMINS, 158 | 0, 0, 0, 0, 0, 0, &psid ) ) 159 | 160 | ShowLastError(); 161 | 162 | return psid; 163 | } 164 | 165 | // Gets the SID for System Account 166 | void* GetLocalSystemSid() 167 | { 168 | SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY; 169 | 170 | void* psid = 0; 171 | 172 | if ( !AllocateAndInitializeSid( &ntauth, 1, 173 | SECURITY_LOCAL_SYSTEM_RID, 174 | 0, 0, 0, 0, 0, 0, 0, &psid ) ) 175 | 176 | ShowLastError(); 177 | 178 | return psid; 179 | } 180 | 181 | // Checks if the launching process parent is local administrator 182 | BOOL IsLaunchedFromAdmin() 183 | { 184 | bool bIsAdmin = false; 185 | 186 | HANDLE hToken = 0; 187 | 188 | if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken ) ){ 189 | ShowLastError(); 190 | } 191 | 192 | DWORD cb = 0; 193 | 194 | GetTokenInformation( hToken, TokenGroups, 0, 0, &cb ); 195 | 196 | TOKEN_GROUPS* pTokenGroups = (TOKEN_GROUPS*)malloc( cb ); 197 | 198 | if ( !pTokenGroups ) 199 | ShowLastError(); 200 | 201 | if ( !GetTokenInformation( hToken, TokenGroups, pTokenGroups, cb, &cb ) ) 202 | ShowLastError(); 203 | 204 | void* pAdminSid = GetAdminSid(); 205 | 206 | SID_AND_ATTRIBUTES* const end = pTokenGroups->Groups + pTokenGroups->GroupCount; 207 | SID_AND_ATTRIBUTES* it; 208 | 209 | for ( it = pTokenGroups->Groups; end != it; ++it ) 210 | if ( EqualSid( it->Sid, pAdminSid ) ) 211 | break; 212 | 213 | bIsAdmin = end != it; 214 | 215 | FreeSid( pAdminSid ); 216 | free( pTokenGroups ); 217 | CloseHandle( hToken ); 218 | 219 | return bIsAdmin; 220 | } 221 | 222 | bool IsLocalSystem() 223 | { 224 | bool bIsLocalSystem = false; 225 | HANDLE htok = 0; 226 | 227 | if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &htok ) ) 228 | ShowLastError(); 229 | 230 | BYTE userSid[256]; 231 | 232 | DWORD cb = sizeof userSid; 233 | 234 | if ( !GetTokenInformation( htok, TokenUser, userSid, cb, &cb ) ) 235 | ShowLastError(); 236 | 237 | TOKEN_USER* ptu = (TOKEN_USER*)userSid; 238 | 239 | void* pLocalSystemSid = GetLocalSystemSid(); 240 | 241 | bIsLocalSystem = EqualSid( pLocalSystemSid, ptu->User.Sid ) ? true : false; 242 | 243 | FreeSid( pLocalSystemSid ); 244 | CloseHandle( htok ); 245 | 246 | return bIsLocalSystem; 247 | } 248 | 249 | VOID FreeLogonSID (PSID *ppsid) 250 | { 251 | HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); 252 | } 253 | 254 | BOOL GetLogonSID (HANDLE hToken, PSID *ppsid) 255 | { 256 | BOOL bSuccess = FALSE; 257 | DWORD dwIndex; 258 | DWORD dwLength = 0; 259 | PTOKEN_GROUPS ptg = NULL; 260 | 261 | // Verify the parameter passed in is not NULL. 262 | if (NULL == ppsid) 263 | goto Cleanup; 264 | 265 | // Get required buffer size and allocate the TOKEN_GROUPS buffer. 266 | 267 | if (!GetTokenInformation( 268 | hToken, // handle to the access token 269 | TokenGroups, // get information about the token's groups 270 | (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer 271 | 0, // size of buffer 272 | &dwLength // receives required buffer size 273 | )) 274 | { 275 | if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 276 | goto Cleanup; 277 | 278 | ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), 279 | HEAP_ZERO_MEMORY, dwLength); 280 | 281 | if (ptg == NULL) 282 | goto Cleanup; 283 | } 284 | 285 | // Get the token group information from the access token. 286 | 287 | if (!GetTokenInformation( 288 | hToken, // handle to the access token 289 | TokenGroups, // get information about the token's groups 290 | (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer 291 | dwLength, // size of buffer 292 | &dwLength // receives required buffer size 293 | )) 294 | { 295 | goto Cleanup; 296 | } 297 | 298 | // Loop through the groups to find the logon SID. 299 | 300 | for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++) 301 | if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) 302 | == SE_GROUP_LOGON_ID) 303 | { 304 | // Found the logon SID; make a copy of it. 305 | 306 | dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid); 307 | *ppsid = (PSID) HeapAlloc(GetProcessHeap(), 308 | HEAP_ZERO_MEMORY, dwLength); 309 | if (*ppsid == NULL) 310 | goto Cleanup; 311 | if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid)) 312 | { 313 | HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); 314 | goto Cleanup; 315 | } 316 | break; 317 | } 318 | 319 | bSuccess = TRUE; 320 | 321 | Cleanup: 322 | 323 | // Free the buffer for the token groups. 324 | 325 | if (ptg != NULL) 326 | HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); 327 | 328 | return bSuccess; 329 | } 330 | 331 | 332 | // Check the command line arguments 333 | BOOL IsCmdLineParameter( LPCTSTR lpszParam ) 334 | { 335 | for( int i = 1; i < __argc; i++ ) 336 | { 337 | if ( __targv[i][0] == _T('\\') ) 338 | continue; 339 | else 340 | { 341 | if ( __targv[i][0] == _T('/') ) 342 | { 343 | if ( _tcsicmp( __targv[i] + 1, lpszParam ) == 0 ) 344 | return TRUE; 345 | } 346 | else 347 | return FALSE; 348 | } 349 | } 350 | return FALSE; 351 | } 352 | 353 | LPCTSTR GetParamValue( LPCTSTR lpszParam ) 354 | { 355 | DWORD dwParamLength = _tcslen( lpszParam ); 356 | 357 | for( int i = 1; i < __argc; i++ ){ 358 | if ( __targv[i][0] == _T('\\') || __targv[i][0] == _T('.')) 359 | continue; 360 | else{ 361 | if ( __targv[i][0] == _T('/') ) 362 | { 363 | if ( _tcsnicmp( __targv[i] + 1, lpszParam, dwParamLength ) == 0 ) 364 | return __targv[i] + dwParamLength + 1; 365 | 366 | } 367 | else 368 | return NULL; 369 | } 370 | } 371 | 372 | return NULL; 373 | } 374 | 375 | LPCTSTR GetNthParameter( DWORD n, DWORD& argvIndex ) 376 | { 377 | DWORD index = 0; 378 | 379 | for( int i = 1; i < __argc; i++ ) 380 | { 381 | 382 | DWORD dwParamLength = _tcslen( __targv[i] ); 383 | 384 | bool bIsEscaped=false; 385 | 386 | if ( __targv[i][0] != _T('/') ){ 387 | index++; 388 | }else{ 389 | if( dwParamLength > 1 && ( __targv[i][1] == _T('/') ) ){ 390 | bIsEscaped=true; 391 | index++; 392 | } 393 | } 394 | 395 | if ( index == n ) 396 | { 397 | argvIndex = i; 398 | 399 | return bIsEscaped ? ( __targv[i] + sizeof(__targv[i][0]) ) : __targv[i]; 400 | } 401 | } 402 | 403 | return NULL; 404 | } 405 | 406 | // Gets the arguments parameter 407 | void GetRemoteCommandArguments( LPTSTR lpszCommandArguments ) 408 | { 409 | DWORD dwIndex = 0; 410 | lpszCommandArguments[0] = _T('\0'); 411 | 412 | if ( GetNthParameter( 3, dwIndex ) != NULL ) 413 | for( int i = dwIndex; i < __argc; i++ ) 414 | { 415 | DWORD dwParamLen = _tcslen( __targv[i] ); 416 | if ( (__targv[i][0] == '/') && (dwParamLen>1 && __targv[i][1] == '/') ){ 417 | _tcscat( lpszCommandArguments, __targv[i]+sizeof(__targv[i][0]) ); 418 | }else{ 419 | _tcscat( lpszCommandArguments, __targv[i] ); 420 | } 421 | if ( i + 1 < __argc ) 422 | _tcscat( lpszCommandArguments, _T(" ") ); 423 | } 424 | } 425 | 426 | // Gets the remote machine parameter 427 | LPCTSTR GetRemoteMachineName() 428 | { 429 | DWORD dwIndex = 0; 430 | LPCTSTR lpszMachine = GetNthParameter( 1, dwIndex ); 431 | 432 | if ( lpszMachine == NULL ) 433 | // return NULL; 434 | return lpszLocalIP; 435 | 436 | if ( _tcsnicmp( lpszMachine, _T(" "), 2 ) == 0 ) 437 | return lpszLocalIP; 438 | 439 | if ( _tcsnicmp( lpszMachine, _T("\\\\"), 2 ) == 0 ) 440 | return lpszMachine; 441 | // If a dot is entered we take it as localhost 442 | if ( _tcsnicmp( lpszMachine, _T("."), 2 ) == 0 ) 443 | return lpszLocalIP; 444 | 445 | 446 | return NULL; 447 | } 448 | 449 | // Turns off the echo on a console input handle - Used for hiding password typing 450 | BOOL EnableEcho( HANDLE handle, BOOL bEcho ) 451 | { 452 | DWORD mode; 453 | 454 | if ( !GetConsoleMode( handle, &mode ) ) 455 | return FALSE; 456 | 457 | if ( bEcho ) 458 | mode |= ENABLE_ECHO_INPUT; 459 | else 460 | mode &= ~ENABLE_ECHO_INPUT; 461 | 462 | return SetConsoleMode( handle, mode ); 463 | } 464 | 465 | // Gets the password 466 | BOOL PromptForPassword( LPTSTR lpszPwd ) 467 | { 468 | HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); 469 | DWORD dwRead = 0; 470 | 471 | Out( _T("Enter Password: ") ); 472 | 473 | // Turn off echo 474 | if ( EnableEcho( hInput, FALSE ) ) 475 | { 476 | // Read password from console 477 | ::ReadConsole( hInput, lpszPwd, SIZEOF_BUFFER, &dwRead, NULL ); 478 | 479 | // Ignore ENTER (0x0D0A) 480 | lpszPwd[max( dwRead-2, 0 )] = _T('\0'); 481 | 482 | // Turn echo on 483 | EnableEcho( hInput, TRUE ); 484 | 485 | Out( _T("\n\n") ); 486 | } 487 | else 488 | { 489 | //Console input doesn't support echo on/off 490 | Out( _T("\n") ); 491 | Error( _T("Couldn't turn off echo to hide password chars.\n") ); 492 | } 493 | 494 | return TRUE; 495 | } 496 | 497 | BOOL SetConnectionCredentials( BOOL bPromptForPassword ) 498 | { 499 | // Check the command line 500 | lpszPassword = GetParamValue( _T("pwd:") ); 501 | lpszUser = GetParamValue( _T("user:") ); 502 | 503 | if ( lpszUser != NULL && lpszPassword != NULL && !bPromptForPassword ) 504 | if ( _tcscmp( lpszPassword, _T("*") ) == 0 ) 505 | // We found user name, and * as password, which means prompt for password 506 | bPromptForPassword = TRUE; 507 | 508 | if ( bPromptForPassword ) 509 | { 510 | // We found user name, and * as password, which means prompt for password 511 | lpszPassword = szPassword; 512 | if ( !PromptForPassword( szPassword ) ) 513 | return FALSE; 514 | } 515 | 516 | return TRUE; 517 | } 518 | 519 | // Establish Connection to Remote Machine 520 | BOOL EstablishConnection( LPCTSTR lpszRemote, LPCTSTR lpszResource, BOOL bEstablish ) 521 | { 522 | TCHAR szRemoteResource[_MAX_PATH]; 523 | 524 | DWORD rc; 525 | 526 | // Remote resource, \\remote\ipc$, remote\admin$, ... 527 | _stprintf( szRemoteResource, _T("%s\\%s"), lpszRemote, lpszResource ); 528 | 529 | // 530 | // disconnect or connect to the resource, based on bEstablish 531 | // 532 | if ( bEstablish ) 533 | { 534 | NETRESOURCE nr; 535 | nr.dwType = RESOURCETYPE_ANY; 536 | nr.lpLocalName = NULL; 537 | nr.lpRemoteName = (LPTSTR)&szRemoteResource; 538 | nr.lpProvider = NULL; 539 | 540 | //Establish connection (using username/pwd) 541 | rc = WNetAddConnection2( &nr, lpszPassword, lpszUser, FALSE ); 542 | 543 | switch( rc ) 544 | { 545 | 546 | case ERROR_ACCESS_DENIED: 547 | case ERROR_INVALID_PASSWORD: 548 | case ERROR_LOGON_FAILURE: 549 | 550 | case ERROR_SESSION_CREDENTIAL_CONFLICT: 551 | 552 | // Prompt for password if the default(NULL) was not good 553 | if ( lpszUser != NULL && lpszPassword == NULL ) 554 | { 555 | Out( _T("Invalid password\n\n") ); 556 | SetConnectionCredentials( TRUE ); 557 | Out( _T("Connecting to remote service ... ") ); 558 | //Establish connection (using username/pwd) again 559 | rc = WNetAddConnection2( &nr, lpszPassword, lpszUser, FALSE ); 560 | } 561 | break; 562 | } 563 | } 564 | else 565 | // Disconnect 566 | rc = WNetCancelConnection2( szRemoteResource, 0, NULL ); 567 | 568 | if ( rc == NO_ERROR ) 569 | return TRUE; // indicate success 570 | 571 | SetLastError( rc ); 572 | 573 | return FALSE; 574 | } 575 | 576 | // Copies the command's exe file to remote machine (\\remote\ADMIN$) 577 | // This function called, if the /c option is used 578 | BOOL CopyBinaryToRemoteSystem() 579 | { 580 | if ( !IsCmdLineParameter(_T("c")) ) 581 | return TRUE; 582 | 583 | TCHAR drive[_MAX_DRIVE]; 584 | TCHAR dir[_MAX_DIR]; 585 | TCHAR fname[_MAX_FNAME]; 586 | TCHAR ext[_MAX_EXT]; 587 | TCHAR szRemoteResource[_MAX_PATH]; 588 | 589 | // Gets the file name and extension 590 | _tsplitpath( lpszCommandExe, drive, dir, fname, ext ); 591 | 592 | _stprintf( szRemoteResource, _T("%s\\ADMIN$\\%s%s"), lpszMachine, fname, ext ); 593 | 594 | // Copy the Command's exe file to \\remote\ADMIN$ 595 | return CopyFile( lpszCommandExe, szRemoteResource, FALSE ); 596 | } 597 | 598 | // Copies the Local Process Launcher Executable from Self Resource -> Copies to Current Path 599 | BOOL ExtractLocalBinaryResource() 600 | { 601 | DWORD dwWritten = 0; 602 | 603 | HMODULE hInstance = ::GetModuleHandle(NULL); 604 | 605 | // Find the binary file in resources 606 | HRSRC hLocalBinRes = ::FindResource( 607 | hInstance, 608 | MAKEINTRESOURCE(IDR_ProcComs), 609 | _T("ProcComs") ); 610 | 611 | HGLOBAL hLocalBinary = ::LoadResource( 612 | hInstance, 613 | hLocalBinRes ); 614 | 615 | LPVOID pLocalBinary = ::LockResource( hLocalBinary ); 616 | 617 | if ( pLocalBinary == NULL ) 618 | return FALSE; 619 | 620 | DWORD dwLocalBinarySize = ::SizeofResource( 621 | hInstance, 622 | hLocalBinRes ); 623 | GetCurrentDirectory(MAX_PATH , szLocalBinPath); 624 | 625 | _stprintf( szLocalBinPath, _T("%s\\%s"), szLocalBinPath, ProcComs ); 626 | 627 | HANDLE hFileLocalBinary = CreateFile( 628 | szLocalBinPath, 629 | GENERIC_WRITE, 630 | 0, 631 | NULL, 632 | CREATE_ALWAYS, 633 | FILE_ATTRIBUTE_NORMAL, 634 | NULL ); 635 | if ( hFileLocalBinary == INVALID_HANDLE_VALUE ) 636 | return FALSE; 637 | 638 | WriteFile( hFileLocalBinary, pLocalBinary, dwLocalBinarySize, &dwWritten, NULL ); 639 | // Out( _T("File Written ...\n") ); 640 | // Sleep(10000); 641 | CloseHandle( hFileLocalBinary ); 642 | 643 | return dwWritten == dwLocalBinarySize; 644 | } 645 | 646 | // Extracts the Service Executable from Self Resource -> Pushes to the remote machine 647 | BOOL CopyServiceToRemoteMachine() 648 | { 649 | DWORD dwWritten = 0; 650 | 651 | HMODULE hInstance = ::GetModuleHandle(NULL); 652 | 653 | // Find the binary file in resources 654 | HRSRC hSvcExecutableRes = ::FindResource( 655 | hInstance, 656 | MAKEINTRESOURCE(IDR_RemComSVC), 657 | _T("RemComSVC") ); 658 | 659 | HGLOBAL hSvcExecutable = ::LoadResource( 660 | hInstance, 661 | hSvcExecutableRes ); 662 | 663 | LPVOID pSvcExecutable = ::LockResource( hSvcExecutable ); 664 | 665 | if ( pSvcExecutable == NULL ) 666 | return FALSE; 667 | 668 | DWORD dwSvcExecutableSize = ::SizeofResource( 669 | hInstance, 670 | hSvcExecutableRes ); 671 | 672 | TCHAR szSvcExePath[_MAX_PATH]; 673 | 674 | _stprintf( szSvcExePath, _T("%s\\ADMIN$\\System32\\%s"), lpszMachine, RemComSVCEXE ); 675 | 676 | // Copy binary file from resources to \\remote\ADMIN$\System32 677 | HANDLE hFileSvcExecutable = CreateFile( 678 | szSvcExePath, 679 | GENERIC_WRITE, 680 | 0, 681 | NULL, 682 | CREATE_ALWAYS, 683 | FILE_ATTRIBUTE_NORMAL, 684 | NULL ); 685 | 686 | if ( hFileSvcExecutable == INVALID_HANDLE_VALUE ) 687 | return FALSE; 688 | 689 | WriteFile( hFileSvcExecutable, pSvcExecutable, dwSvcExecutableSize, &dwWritten, NULL ); 690 | 691 | CloseHandle( hFileSvcExecutable ); 692 | 693 | return dwWritten == dwSvcExecutableSize; 694 | } 695 | 696 | // Installs and starts the remote service on remote machine 697 | BOOL InstallAndStartRemoteService() 698 | { 699 | // Open remote Service Manager 700 | SC_HANDLE hSCM = ::OpenSCManager( lpszMachine, NULL, SC_MANAGER_ALL_ACCESS); 701 | 702 | if (hSCM == NULL) 703 | return FALSE; 704 | 705 | // Maybe it's already there and installed, let's try to run 706 | SC_HANDLE hService =::OpenService( hSCM, SERVICENAME, SERVICE_ALL_ACCESS ); 707 | 708 | // Creates service on remote machine, if it's not installed yet 709 | if ( hService == NULL ) 710 | hService = ::CreateService( 711 | hSCM, SERVICENAME, LONGSERVICENAME, 712 | SERVICE_ALL_ACCESS, 713 | SERVICE_WIN32_OWN_PROCESS, 714 | SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 715 | _T("%SystemRoot%\\system32\\")RemComSVCEXE, 716 | NULL, NULL, NULL, NULL, NULL ); 717 | 718 | if (hService == NULL) 719 | { 720 | ::CloseServiceHandle(hSCM); 721 | return FALSE; 722 | } 723 | 724 | // Start service 725 | if ( !StartService( hService, 0, NULL ) ) 726 | return FALSE; 727 | 728 | ::CloseServiceHandle(hService); 729 | ::CloseServiceHandle(hSCM); 730 | 731 | return TRUE; 732 | } 733 | 734 | // Connects to the remote service 735 | BOOL ConnectToRemoteService( DWORD dwRetry, DWORD dwRetryTimeOut ) 736 | { 737 | TCHAR szPipeName[_MAX_PATH] = _T(""); 738 | 739 | // Remote service communication pipe name 740 | _stprintf( szPipeName, _T("%s\\pipe\\%s"), lpszMachine, RemComCOMM ); 741 | 742 | SECURITY_ATTRIBUTES SecAttrib = {0}; 743 | SECURITY_DESCRIPTOR SecDesc; 744 | InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); 745 | SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, TRUE); 746 | 747 | SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 748 | SecAttrib.lpSecurityDescriptor = &SecDesc;; 749 | SecAttrib.bInheritHandle = TRUE; 750 | 751 | // Connects to the remote service's communication pipe 752 | while( dwRetry-- ) 753 | { 754 | if ( WaitNamedPipe( szPipeName, 5000 ) ) 755 | { 756 | hCommandPipe = CreateFile( 757 | szPipeName, 758 | GENERIC_WRITE | GENERIC_READ, 759 | 0, 760 | &SecAttrib, 761 | OPEN_EXISTING, 762 | FILE_ATTRIBUTE_NORMAL, 763 | NULL ); 764 | 765 | break; 766 | } 767 | else 768 | // Try Again 769 | Sleep( dwRetryTimeOut ); 770 | } 771 | 772 | return hCommandPipe != INVALID_HANDLE_VALUE; 773 | } 774 | 775 | // Fill the communication message structure 776 | // This structure will be transferred to remote machine 777 | BOOL BuildMessageStructure( RemComMessage* pMsg ) 778 | { 779 | LPCTSTR lpszWorkingDir = GetParamValue( _T("d:") ); 780 | 781 | // Info 782 | pMsg->dwProcessId = GetCurrentProcessId(); 783 | _tcscpy( pMsg->szMachine, szThisMachine ); 784 | 785 | // Cmd 786 | if ( !IsCmdLineParameter(_T("c")) ) 787 | _stprintf( pMsg->szCommand, _T("%s %s"), lpszCommandExe, szArguments ); 788 | else 789 | { 790 | TCHAR drive[_MAX_DRIVE]; 791 | TCHAR dir[_MAX_DIR]; 792 | TCHAR fname[_MAX_FNAME]; 793 | TCHAR ext[_MAX_EXT]; 794 | 795 | _tsplitpath( lpszCommandExe, drive, dir, fname, ext ); 796 | 797 | _stprintf( pMsg->szCommand, _T("%s%s %s"), fname, ext, szArguments ); 798 | } 799 | 800 | // Priority 801 | if ( IsCmdLineParameter( _T("realtime") ) ) 802 | pMsg->dwPriority = REALTIME_PRIORITY_CLASS; 803 | else 804 | if ( IsCmdLineParameter( _T("high") ) ) 805 | pMsg->dwPriority = HIGH_PRIORITY_CLASS; 806 | else 807 | if ( IsCmdLineParameter( _T("idle") ) ) 808 | pMsg->dwPriority = IDLE_PRIORITY_CLASS; 809 | else 810 | pMsg->dwPriority = NORMAL_PRIORITY_CLASS; // default 811 | 812 | // No wait 813 | pMsg->bNoWait = IsCmdLineParameter( _T("nowait") ); 814 | 815 | if ( lpszWorkingDir != NULL ) 816 | _tcscpy( pMsg->szWorkingDir, lpszWorkingDir ); 817 | 818 | // Console Title 819 | _stprintf( szConsoleTitle, _T("%s : %s"), lpszMachine, pMsg->szCommand ); 820 | SetConsoleTitle( szConsoleTitle ); 821 | 822 | return TRUE; 823 | } 824 | 825 | // Listens the remote stdout pipe 826 | // Remote process will send its stdout to this pipe 827 | void ListenRemoteOutPipeThread(void*) 828 | { 829 | HANDLE hOutput = GetStdHandle( STD_OUTPUT_HANDLE ); 830 | TCHAR szBuffer[SIZEOF_BUFFER]; 831 | DWORD dwRead; 832 | 833 | for(;;) 834 | { 835 | if ( !ReadFile( hRemoteOutPipe, szBuffer, SIZEOF_BUFFER, &dwRead, NULL ) || 836 | dwRead == 0 ) 837 | { 838 | DWORD dwErr = GetLastError(); 839 | if ( dwErr == ERROR_NO_DATA) 840 | break; 841 | } 842 | 843 | // Handle CLS command, just for fun :) 844 | switch( szBuffer[0] ) 845 | { 846 | case 12: //cls 847 | { 848 | DWORD dwWritten; 849 | COORD origin = {0,0}; 850 | CONSOLE_SCREEN_BUFFER_INFO sbi; 851 | 852 | if ( GetConsoleScreenBufferInfo( hOutput, &sbi ) ) 853 | { 854 | FillConsoleOutputCharacter( 855 | hOutput, 856 | _T(' '), 857 | sbi.dwSize.X * sbi.dwSize.Y, 858 | origin, 859 | &dwWritten ); 860 | 861 | SetConsoleCursorPosition( 862 | hOutput, 863 | origin ); 864 | } 865 | } 866 | continue; 867 | break; 868 | } 869 | 870 | szBuffer[ dwRead / sizeof(TCHAR) ] = _T('\0'); 871 | 872 | // Send it to our stdout 873 | Out( szBuffer ); 874 | } 875 | 876 | CloseHandle( hRemoteOutPipe ); 877 | 878 | hRemoteOutPipe = INVALID_HANDLE_VALUE; 879 | 880 | ::ExitThread(0); 881 | } 882 | 883 | // Listens the remote stderr pipe 884 | // Remote process will send its stderr to this pipe 885 | void ListenRemoteErrorPipeThread(void*) 886 | { 887 | TCHAR szBuffer[SIZEOF_BUFFER]; 888 | DWORD dwRead; 889 | 890 | for(;;) 891 | { 892 | if ( !ReadFile( hRemoteErrorPipe, szBuffer, SIZEOF_BUFFER, &dwRead, NULL ) || 893 | dwRead == 0 ) 894 | { 895 | DWORD dwErr = GetLastError(); 896 | if ( dwErr == ERROR_NO_DATA) 897 | break; 898 | } 899 | 900 | szBuffer[ dwRead / sizeof(TCHAR) ] = _T('\0'); 901 | 902 | // Write it to our stderr 903 | Error( szBuffer ); 904 | } 905 | 906 | CloseHandle( hRemoteErrorPipe ); 907 | 908 | hRemoteErrorPipe = INVALID_HANDLE_VALUE; 909 | 910 | ::ExitThread(0); 911 | } 912 | 913 | // Listens our console, and if the user types in something, 914 | // we will pass it to the remote machine. 915 | // ReadConsole return after pressing the ENTER 916 | void ListenRemoteStdInputPipeThread(void*) 917 | { 918 | HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); 919 | TCHAR szInputBuffer[SIZEOF_BUFFER] = _T(""); 920 | DWORD nBytesRead; 921 | DWORD nBytesWrote; 922 | 923 | for(;;) 924 | { 925 | // Read our console input 926 | if ( !ReadConsole( hInput, szInputBuffer, SIZEOF_BUFFER, &nBytesRead, NULL ) ) 927 | { 928 | DWORD dwErr = GetLastError(); 929 | if ( dwErr == ERROR_NO_DATA) 930 | break; 931 | } 932 | 933 | // Send it to remote process' stdin 934 | if ( !WriteFile( hRemoteStdInputPipe, szInputBuffer, nBytesRead, &nBytesWrote, NULL ) ) 935 | break; 936 | } 937 | 938 | CloseHandle( hRemoteStdInputPipe ); 939 | 940 | hRemoteStdInputPipe = INVALID_HANDLE_VALUE; 941 | 942 | ::ExitThread(0); 943 | } 944 | 945 | // Start listening stdout, stderr and stdin 946 | void ListenToRemoteNamedPipes() 947 | { 948 | // StdOut 949 | _beginthread( ListenRemoteOutPipeThread, 0, NULL ); 950 | 951 | // StdErr 952 | _beginthread( ListenRemoteErrorPipeThread, 0, NULL ); 953 | 954 | // StdIn 955 | _beginthread( ListenRemoteStdInputPipeThread, 0, NULL ); 956 | } 957 | 958 | // Connects to the remote processes stdout, stderr and stdin named pipes 959 | BOOL ConnectToRemotePipes( DWORD dwRetryCount, DWORD dwRetryTimeOut ) 960 | { 961 | TCHAR szStdOut[_MAX_PATH]; 962 | TCHAR szStdIn[_MAX_PATH]; 963 | TCHAR szStdErr[_MAX_PATH]; 964 | 965 | 966 | SECURITY_ATTRIBUTES SecAttrib = {0}; 967 | SECURITY_DESCRIPTOR SecDesc; 968 | 969 | InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION); 970 | SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, FALSE); 971 | 972 | SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 973 | SecAttrib.lpSecurityDescriptor = &SecDesc;; 974 | SecAttrib.bInheritHandle = TRUE; 975 | 976 | hRemoteOutPipe = INVALID_HANDLE_VALUE; 977 | hRemoteStdInputPipe = INVALID_HANDLE_VALUE; 978 | hRemoteErrorPipe = INVALID_HANDLE_VALUE; 979 | 980 | // StdOut pipe name 981 | _stprintf( szStdOut, _T("%s\\pipe\\%s%s%d"), 982 | lpszMachine, 983 | RemComSTDOUT, 984 | szThisMachine, 985 | GetCurrentProcessId() ); 986 | 987 | // StdErr pipe name 988 | _stprintf( szStdIn, _T("%s\\pipe\\%s%s%d"), 989 | lpszMachine, 990 | RemComSTDIN, 991 | szThisMachine, 992 | GetCurrentProcessId() ); 993 | 994 | // StdIn pipe name 995 | _stprintf( szStdErr, _T("%s\\pipe\\%s%s%d"), 996 | lpszMachine, 997 | RemComSTDERR, 998 | szThisMachine, 999 | GetCurrentProcessId() ); 1000 | 1001 | while( dwRetryCount-- ) 1002 | { 1003 | // Connects to StdOut pipe 1004 | if ( hRemoteOutPipe == INVALID_HANDLE_VALUE ) 1005 | if ( WaitNamedPipe( szStdOut, NULL ) ) 1006 | hRemoteOutPipe = CreateFile( 1007 | szStdOut, 1008 | GENERIC_READ, 1009 | 0, 1010 | &SecAttrib, 1011 | OPEN_EXISTING, 1012 | FILE_ATTRIBUTE_NORMAL, 1013 | NULL ); 1014 | 1015 | // Connects to Error pipe 1016 | if ( hRemoteErrorPipe == INVALID_HANDLE_VALUE ) 1017 | if ( WaitNamedPipe( szStdErr, NULL ) ) 1018 | hRemoteErrorPipe = CreateFile( 1019 | szStdErr, 1020 | GENERIC_READ, 1021 | 0, 1022 | &SecAttrib, 1023 | OPEN_EXISTING, 1024 | FILE_ATTRIBUTE_NORMAL, 1025 | NULL ); 1026 | 1027 | // Connects to StdIn pipe 1028 | if ( hRemoteStdInputPipe == INVALID_HANDLE_VALUE ) 1029 | if ( WaitNamedPipe( szStdIn, NULL ) ) 1030 | hRemoteStdInputPipe = CreateFile( 1031 | szStdIn, 1032 | GENERIC_WRITE, 1033 | 0, 1034 | &SecAttrib, 1035 | OPEN_EXISTING, 1036 | FILE_ATTRIBUTE_NORMAL, 1037 | NULL ); 1038 | 1039 | if ( hRemoteOutPipe != INVALID_HANDLE_VALUE && 1040 | hRemoteErrorPipe != INVALID_HANDLE_VALUE && 1041 | hRemoteStdInputPipe != INVALID_HANDLE_VALUE ) 1042 | break; 1043 | 1044 | // One of the pipes failed, try it again 1045 | Sleep( dwRetryTimeOut ); 1046 | } 1047 | 1048 | if ( hRemoteOutPipe == INVALID_HANDLE_VALUE || 1049 | hRemoteErrorPipe == INVALID_HANDLE_VALUE || 1050 | hRemoteStdInputPipe == INVALID_HANDLE_VALUE ) 1051 | { 1052 | CloseHandle( hRemoteOutPipe ); 1053 | CloseHandle( hRemoteErrorPipe ); 1054 | CloseHandle( hRemoteStdInputPipe ); 1055 | 1056 | return FALSE; 1057 | } 1058 | 1059 | // Start listening these pipes 1060 | ListenToRemoteNamedPipes(); 1061 | 1062 | return TRUE; 1063 | } 1064 | 1065 | // 1. Send the message to remote service 1066 | // 2. Connects to remote pipes 1067 | // 3. Waiting for finishing remote process 1068 | BOOL ExecuteRemoteCommand() 1069 | { 1070 | DWORD dwTemp = 0; 1071 | RemComMessage msg; 1072 | RemComResponse response; 1073 | 1074 | ::ZeroMemory( &msg, sizeof(msg) ); 1075 | ::ZeroMemory( &response, sizeof(response) ); 1076 | 1077 | BuildMessageStructure( &msg ); 1078 | 1079 | // Send message to service 1080 | WriteFile( hCommandPipe, &msg, sizeof(msg), &dwTemp, NULL ); 1081 | 1082 | // Connects to remote pipes (stdout, stdin, stderr) 1083 | if ( ConnectToRemotePipes( 5, 1000 ) ) 1084 | { 1085 | Error( _T("Ok\n\n") ); 1086 | 1087 | // Waiting for response from service 1088 | 1089 | Error( _T("Remote program Stderr start:\n") ); 1090 | 1091 | ReadFile( hCommandPipe, &response, sizeof(response), &dwTemp, NULL ); 1092 | 1093 | Error( _T("Remote program Stderr end.\n") ); 1094 | } 1095 | else 1096 | Error( _T("Failed\n\n") ); 1097 | 1098 | if ( response.dwErrorCode == 0 ) 1099 | _ftprintf( stderr, _T("\nRemote command returned %d(0x%X)\n"), 1100 | response.dwReturnCode ); 1101 | else 1102 | _ftprintf( stderr, _T("\nRemote command failed to start. Returned error code is %d(0x%X)\n"), 1103 | response.dwErrorCode ); 1104 | 1105 | return response.dwErrorCode; 1106 | } 1107 | 1108 | BOOL WINAPI ConsoleCtrlHandler( DWORD dwCtrlType ) 1109 | { 1110 | switch( dwCtrlType ) 1111 | { 1112 | case CTRL_C_EVENT: 1113 | case CTRL_BREAK_EVENT: 1114 | break; 1115 | } 1116 | 1117 | return FALSE; 1118 | } 1119 | 1120 | 1121 | void ShowCopyRight() 1122 | { 1123 | Error( _T("\n") ); 1124 | Error( _T(" Remote Command Executor\n") ); 1125 | Error( _T(" Copyright 2006-2012 [ https://github.com/kavika13/RemCom ] \n") ); 1126 | Error( _T(" Author: Talha Tariq [talha.tariq@gmail.com]\n") ); 1127 | Error( _T(" Contributor: Luke Suchocki\n") ); 1128 | Error( _T(" Contributor: Merlyn Morgan-Graham\n") ); 1129 | Error( _T(" Contributor: Andres Ederra\n") ); 1130 | 1131 | Error( _T("\n") ); 1132 | } 1133 | 1134 | void ShowUsage() 1135 | { 1136 | Out( _T("------------------------------------------------------------------\n") ); 1137 | Out( _T("| Usage: RemCom.exe [\\\\computer] [options] [cmd/exe arguments] |\n") ); 1138 | Out( _T("------------------------------------------------------------------\n") ); 1139 | Out( _T("\n") ); 1140 | Out( _T("Options:\n") ); 1141 | Out( _T("\n") ); 1142 | Out( _T(" /user:UserName\t\tUserName for Remote Connection\n") ); 1143 | Out( _T(" /pwd:[password|*]\tPassword. * will delay the input (if required)\n") ); 1144 | Out( _T("\n") ); 1145 | Out( _T(" /d:directory\t\tSet working directory\n") ); 1146 | Out( _T("\t\t\t(Default: \\\\RemoteSystem\"%SystemRoot%\\System32\")\n\n") ); 1147 | Out( _T(" [/idle | /normal | /high | /realtime]\tPriority class (use only one)\n") ); 1148 | Out( _T(" /nowait\t\tDon't wait for remote process to terminate\n") ); 1149 | Out( _T("\n") ); 1150 | Out( _T(" /c\t\t\tCopy the specified program to the remote machine's\n") ); 1151 | Out( _T(" \t\t\t\"%SystemRoot%\" directory\n") ); 1152 | Out( _T(" \t\t\tCommand's exe file must be absolute to local machine\n") ); 1153 | Out( _T("\n") ); 1154 | Out( _T(" .........................................................................\n") ); 1155 | Out( _T("\n") ); 1156 | Out( _T("Examples:\n") ); 1157 | Out( _T("\n") ); 1158 | Out( _T(" RemCom.exe \\\\remote cmd\t[Starts a \"telnet\" client]\n") ); 1159 | Out( _T(" RemCom.exe \\\\remote /user:Username /pwd:Password cmd.exe\t[Starts a \"telnet\" client]\n") ); 1160 | Out( _T(" RemCom.exe \\\\localhost /user:Username /pwd:Password \"C:\\InstallMe.bat\"\t[A replacement for RunAs Command]\"\n") ); 1161 | Out( _T(" RemCom.exe \\\\localhost /user:Username /pwd:Password \"cmd.exe /c dir c:\\\"\t[Executes a cmd.exe, for intance \"dir c:\\\"]\"\n") ); 1162 | Out( _T("\n") ); 1163 | Out( _T(" .........................................................................\n") ); 1164 | Out( _T("\n") ); 1165 | Out( _T("Notes:\n") ); 1166 | Out( _T("\n") ); 1167 | Out( _T("- A \".\" for Machine Name will be treated as localhost.\n") ); 1168 | Out( _T("- Input is passed to remote machine when you press the ENTER.\n") ); 1169 | Out( _T("- Ctrl-C terminates the remote process.\n") ); 1170 | Out( _T("- Command and file path arguments have to be absolute to remote machine.\n") ); 1171 | Out( _T("- If you are using /c option, command exe file path must be absolute to\n") ); 1172 | Out( _T(" local machine, but the arguments must be absolute to remote machine\n") ); 1173 | Out( _T("- A dot . for machine name is taken as localhost.\n") ); 1174 | Out( _T("- Not providing any credentials, the Process will (impersonate and) run\n") ); 1175 | Out( _T(" in the context of your account on the remote system, but will not have\n") ); 1176 | Out( _T(" access to network resources.\n") ); 1177 | Out( _T("- Specify a valid user name in the Domain\\User syntax if the remote process\n") ); 1178 | Out( _T(" requires access to network resources or to run in a different account. \n") ); 1179 | Out( _T("- The password is transmitted in clear text to the remote system.\n") ); 1180 | Out( _T("- You can enclose applications that have spaces in their name with \n") ); 1181 | Out( _T(" quotation marks e.g. RemCom \\\\computername \"c:\\long name app.exe\".\n") ); 1182 | Out( _T("- Input is only passed to the remote system when you press the enter key.\n") ); 1183 | Out( _T("- Typing Ctrl-C terminates the remote process.\n") ); 1184 | Out( _T("- Error codes from the applications you execute are shown as part of remcom output.\n") ); 1185 | Out( _T("- RemCom error code list can be found at the documentation and sources.\n") ); 1186 | Out( _T(" \n") ); 1187 | Out( _T(" .........................................................................\n") ); 1188 | 1189 | } 1190 | 1191 | 1192 | BOOL StartInteractiveClientProcess ( 1193 | LPTSTR lpszUsername, // client to log on 1194 | LPTSTR lpszDomain, // domain of client's account 1195 | LPTSTR lpszPassword, // client's password 1196 | LPTSTR lpCommandLine // command line to execute 1197 | ) 1198 | { 1199 | HANDLE hToken; 1200 | HDESK hdesk = NULL; 1201 | HWINSTA hwinsta = NULL, hwinstaSave = NULL; 1202 | PROCESS_INFORMATION pi; 1203 | PSID pSid = NULL; 1204 | STARTUPINFO si; 1205 | BOOL bResult = FALSE; 1206 | 1207 | // Log the client on to the local computer. 1208 | 1209 | if (!LogonUser( 1210 | lpszUsername, 1211 | lpszDomain, 1212 | lpszPassword, 1213 | LOGON32_LOGON_INTERACTIVE, 1214 | LOGON32_PROVIDER_DEFAULT, 1215 | &hToken) ) 1216 | { 1217 | goto Cleanup; 1218 | } 1219 | 1220 | // Save a handle to the caller's current window station. 1221 | 1222 | if ( (hwinstaSave = GetProcessWindowStation() ) == NULL) 1223 | goto Cleanup; 1224 | 1225 | // Get a handle to the interactive window station. 1226 | 1227 | hwinsta = OpenWindowStation( 1228 | "winsta0", // the interactive window station 1229 | FALSE, // handle is not inheritable 1230 | READ_CONTROL | WRITE_DAC); // rights to read/write the DACL 1231 | 1232 | if (hwinsta == NULL) 1233 | goto Cleanup; 1234 | 1235 | // To get the correct default desktop, set the caller's 1236 | // window station to the interactive window station. 1237 | 1238 | if (!SetProcessWindowStation(hwinsta)) 1239 | goto Cleanup; 1240 | 1241 | // Get a handle to the interactive desktop. 1242 | 1243 | hdesk = OpenDesktop( 1244 | "default", // the interactive window station 1245 | 0, // no interaction with other desktop processes 1246 | FALSE, // handle is not inheritable 1247 | READ_CONTROL | // request the rights to read and write the DACL 1248 | WRITE_DAC | 1249 | DESKTOP_WRITEOBJECTS | 1250 | DESKTOP_READOBJECTS); 1251 | 1252 | // Restore the caller's window station. 1253 | 1254 | if (!SetProcessWindowStation(hwinstaSave)) 1255 | goto Cleanup; 1256 | 1257 | if (hdesk == NULL) 1258 | goto Cleanup; 1259 | 1260 | // Get the SID for the client's logon session. 1261 | 1262 | if (!GetLogonSID(hToken, &pSid)) 1263 | goto Cleanup; 1264 | 1265 | // Allow logon SID full access to interactive window station. 1266 | 1267 | //TODO 1268 | // if (! AddAceToWindowStation(hwinsta, pSid) ) 1269 | // goto Cleanup; 1270 | 1271 | // Allow logon SID full access to interactive desktop. 1272 | 1273 | if (! AddAceToDesktop(hdesk, pSid) ) 1274 | goto Cleanup; 1275 | 1276 | // Impersonate client to ensure access to executable file. 1277 | 1278 | if (! ImpersonateLoggedOnUser(hToken) ) 1279 | goto Cleanup; 1280 | 1281 | // Initialize the STARTUPINFO structure. 1282 | // Specify that the process runs in the interactive desktop. 1283 | 1284 | ZeroMemory(&si, sizeof(STARTUPINFO)); 1285 | si.cb= sizeof(STARTUPINFO); 1286 | 1287 | // si.lpDesktop = TEXT("winsta0\\default"); 1288 | // si.wShowWindow 1289 | si.hStdOutput = hRemoteOutPipe; 1290 | si.hStdError = hRemoteOutPipe; 1291 | 1292 | // Launch the process in the client's logon session. 1293 | 1294 | bResult = CreateProcessAsUser( 1295 | hToken, // client's access token 1296 | NULL, // file to execute 1297 | lpCommandLine, // command line 1298 | NULL, // pointer to process SECURITY_ATTRIBUTES 1299 | NULL, // pointer to thread SECURITY_ATTRIBUTES 1300 | FALSE, // handles are not inheritable 1301 | NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, // creation flags 1302 | NULL, // pointer to new environment block 1303 | NULL, // name of current directory 1304 | &si, // pointer to STARTUPINFO structure 1305 | &pi // receives information about new process 1306 | ); 1307 | 1308 | 1309 | 1310 | // End impersonation of client. 1311 | ShowLastError(); 1312 | RevertToSelf(); 1313 | 1314 | if (bResult && pi.hProcess != INVALID_HANDLE_VALUE) 1315 | { 1316 | WaitForSingleObject(pi.hProcess, INFINITE); 1317 | CloseHandle(pi.hProcess); 1318 | //ShowLastError(); 1319 | } 1320 | 1321 | if (pi.hThread != INVALID_HANDLE_VALUE) 1322 | CloseHandle(pi.hThread); 1323 | 1324 | Cleanup: 1325 | 1326 | if (hwinstaSave != NULL) 1327 | SetProcessWindowStation (hwinstaSave); 1328 | 1329 | // Free the buffer for the logon SID. 1330 | 1331 | if (pSid) 1332 | FreeLogonSID(&pSid); 1333 | 1334 | // Close the handles to the interactive window station and desktop. 1335 | 1336 | if (hwinsta) 1337 | CloseWindowStation(hwinsta); 1338 | 1339 | if (hdesk) 1340 | CloseDesktop(hdesk); 1341 | 1342 | // Close the handle to the client's access token. 1343 | 1344 | if (hToken != INVALID_HANDLE_VALUE) 1345 | CloseHandle(hToken); 1346 | 1347 | return bResult; 1348 | } 1349 | 1350 | BOOL StartProcessWithUserLogon() 1351 | { 1352 | HANDLE hToken; 1353 | // LPVOID lpvEnv; 1354 | PROCESS_INFORMATION pi = {0}; 1355 | STARTUPINFOW si = {0}; 1356 | // TCHAR szUserProfile[SIZEOF_BUFFER] = _T(""); 1357 | 1358 | // Initialize the STARTUPINFO structure. 1359 | // Specify that the process runs in the interactive desktop. 1360 | 1361 | ZeroMemory(&si, sizeof(STARTUPINFOW)); 1362 | si.cb= sizeof(STARTUPINFOW); 1363 | 1364 | si.hStdOutput = hRemoteOutPipe; 1365 | si.hStdError= hRemoteOutPipe; 1366 | // CreateEnvironmentBlock(&lpvEnv, hToken, TRUE); 1367 | 1368 | if (!LogonUser(lpszUser, NULL, lpszPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken)) 1369 | { 1370 | ShowLastError(); 1371 | return false; 1372 | } 1373 | 1374 | //(LPCWSTR) 1375 | int bResult; 1376 | 1377 | /* bResult = CreateProcessWithLogonW( (LPCWSTR)lpszUser, (LPCWSTR)lpszDomain, (LPCWSTR)lpszPassword, LOGON_WITH_PROFILE, 1378 | NULL, (LPWSTR) lpszCommandExe, CREATE_UNICODE_ENVIRONMENT, NULL, NULL, 1379 | &si, 1380 | &pi 1381 | ); 1382 | */ 1383 | 1384 | bResult = CreateProcessWithLogonW( 1385 | (LPCWSTR)lpszUser, 1386 | NULL, 1387 | (LPCWSTR)lpszPassword, 1388 | LOGON_WITH_PROFILE, 1389 | NULL, 1390 | (LPWSTR) lpszCommandExe, 1391 | CREATE_UNICODE_ENVIRONMENT, /*lpvEnv*/ NULL, (LPCWSTR) "%SYSTEMROOT%\\system32", 1392 | &si, 1393 | &pi 1394 | ); 1395 | 1396 | ShowLastError(); 1397 | 1398 | // if (!DestroyEnvironmentBlock(lpvEnv)) DisplayError(L"DestroyEnvironmentBlock"); 1399 | 1400 | CloseHandle(hToken); 1401 | CloseHandle(pi.hProcess); 1402 | CloseHandle(pi.hThread); 1403 | 1404 | 1405 | return bResult; 1406 | } 1407 | 1408 | 1409 | BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid) 1410 | { 1411 | ACCESS_ALLOWED_ACE *pace; 1412 | ACL_SIZE_INFORMATION aclSizeInfo; 1413 | BOOL bDaclExist; 1414 | BOOL bDaclPresent; 1415 | BOOL bSuccess = FALSE; 1416 | DWORD dwNewAclSize; 1417 | DWORD dwSidSize = 0; 1418 | DWORD dwSdSizeNeeded; 1419 | PACL pacl = 0; 1420 | PACL pNewAcl = 0; 1421 | PSECURITY_DESCRIPTOR psd = NULL; 1422 | PSECURITY_DESCRIPTOR psdNew = NULL; 1423 | PVOID pTempAce; 1424 | SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; 1425 | unsigned int i; 1426 | 1427 | __try 1428 | { 1429 | // Obtain the DACL for the window station. 1430 | 1431 | if (!GetUserObjectSecurity( 1432 | hwinsta, 1433 | &si, 1434 | psd, 1435 | dwSidSize, 1436 | &dwSdSizeNeeded) 1437 | ) 1438 | if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1439 | { 1440 | psd = (PSECURITY_DESCRIPTOR)HeapAlloc( 1441 | GetProcessHeap(), 1442 | HEAP_ZERO_MEMORY, 1443 | dwSdSizeNeeded); 1444 | 1445 | if (psd == NULL) 1446 | __leave; 1447 | 1448 | psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( 1449 | GetProcessHeap(), 1450 | HEAP_ZERO_MEMORY, 1451 | dwSdSizeNeeded); 1452 | 1453 | if (psdNew == NULL) 1454 | __leave; 1455 | 1456 | dwSidSize = dwSdSizeNeeded; 1457 | 1458 | if (!GetUserObjectSecurity( 1459 | hwinsta, 1460 | &si, 1461 | psd, 1462 | dwSidSize, 1463 | &dwSdSizeNeeded) 1464 | ) 1465 | __leave; 1466 | } 1467 | else 1468 | __leave; 1469 | 1470 | // Create a new DACL. 1471 | 1472 | if (!InitializeSecurityDescriptor( 1473 | psdNew, 1474 | SECURITY_DESCRIPTOR_REVISION) 1475 | ) 1476 | __leave; 1477 | 1478 | // Get the DACL from the security descriptor. 1479 | 1480 | if (!GetSecurityDescriptorDacl( 1481 | psd, 1482 | &bDaclPresent, 1483 | &pacl, 1484 | &bDaclExist) 1485 | ) 1486 | __leave; 1487 | 1488 | // Initialize the ACL. 1489 | 1490 | ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); 1491 | aclSizeInfo.AclBytesInUse = sizeof(ACL); 1492 | 1493 | // Call only if the DACL is not NULL. 1494 | 1495 | if (pacl != NULL) 1496 | { 1497 | // get the file ACL size info 1498 | if (!GetAclInformation( 1499 | pacl, 1500 | (LPVOID)&aclSizeInfo, 1501 | sizeof(ACL_SIZE_INFORMATION), 1502 | AclSizeInformation) 1503 | ) 1504 | __leave; 1505 | } 1506 | 1507 | // Compute the size of the new ACL. 1508 | 1509 | dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + 1510 | (2*GetLengthSid(psid)) - (2*sizeof(DWORD)); 1511 | 1512 | // Allocate memory for the new ACL. 1513 | 1514 | pNewAcl = (PACL)HeapAlloc( 1515 | GetProcessHeap(), 1516 | HEAP_ZERO_MEMORY, 1517 | dwNewAclSize); 1518 | 1519 | if (pNewAcl == NULL) 1520 | __leave; 1521 | 1522 | // Initialize the new DACL. 1523 | 1524 | if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) 1525 | __leave; 1526 | 1527 | // If DACL is present, copy it to a new DACL. 1528 | 1529 | if (bDaclPresent) 1530 | { 1531 | // Copy the ACEs to the new ACL. 1532 | if (aclSizeInfo.AceCount) 1533 | { 1534 | for (i=0; i < aclSizeInfo.AceCount; i++) 1535 | { 1536 | // Get an ACE. 1537 | if (!GetAce(pacl, i, &pTempAce)) 1538 | __leave; 1539 | 1540 | // Add the ACE to the new ACL. 1541 | if (!AddAce( 1542 | pNewAcl, 1543 | ACL_REVISION, 1544 | MAXDWORD, 1545 | pTempAce, 1546 | ((PACE_HEADER)pTempAce)->AceSize) 1547 | ) 1548 | __leave; 1549 | } 1550 | } 1551 | } 1552 | 1553 | // Add the first ACE to the window station. 1554 | 1555 | pace = (ACCESS_ALLOWED_ACE *)HeapAlloc( 1556 | GetProcessHeap(), 1557 | HEAP_ZERO_MEMORY, 1558 | sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - 1559 | sizeof(DWORD)); 1560 | 1561 | if (pace == NULL) 1562 | __leave; 1563 | 1564 | pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; 1565 | pace->Header.AceFlags = CONTAINER_INHERIT_ACE | 1566 | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; 1567 | pace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + 1568 | GetLengthSid(psid) - sizeof(DWORD); 1569 | pace->Mask = GENERIC_ACCESS; 1570 | 1571 | if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid)) 1572 | __leave; 1573 | 1574 | if (!AddAce( 1575 | pNewAcl, 1576 | ACL_REVISION, 1577 | MAXDWORD, 1578 | (LPVOID)pace, 1579 | pace->Header.AceSize) 1580 | ) 1581 | __leave; 1582 | 1583 | // Add the second ACE to the window station. 1584 | 1585 | pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE; 1586 | pace->Mask = WINSTA_ALL; 1587 | 1588 | if (!AddAce( 1589 | pNewAcl, 1590 | ACL_REVISION, 1591 | MAXDWORD, 1592 | (LPVOID)pace, 1593 | pace->Header.AceSize) 1594 | ) 1595 | __leave; 1596 | 1597 | // Set a new DACL for the security descriptor. 1598 | 1599 | if (!SetSecurityDescriptorDacl( 1600 | psdNew, 1601 | TRUE, 1602 | pNewAcl, 1603 | FALSE) 1604 | ) 1605 | __leave; 1606 | 1607 | // Set the new security descriptor for the window station. 1608 | 1609 | if (!SetUserObjectSecurity(hwinsta, &si, psdNew)) 1610 | __leave; 1611 | 1612 | // Indicate success. 1613 | 1614 | bSuccess = TRUE; 1615 | } 1616 | __finally 1617 | { 1618 | // Free the allocated buffers. 1619 | 1620 | if (pace != NULL) 1621 | HeapFree(GetProcessHeap(), 0, (LPVOID)pace); 1622 | 1623 | if (pNewAcl != NULL) 1624 | HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); 1625 | 1626 | if (psd != NULL) 1627 | HeapFree(GetProcessHeap(), 0, (LPVOID)psd); 1628 | 1629 | if (psdNew != NULL) 1630 | HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); 1631 | } 1632 | 1633 | return bSuccess; 1634 | 1635 | } 1636 | 1637 | BOOL AddAceToDesktop(HDESK hdesk, PSID psid) 1638 | { 1639 | ACL_SIZE_INFORMATION aclSizeInfo; 1640 | BOOL bDaclExist; 1641 | BOOL bDaclPresent; 1642 | BOOL bSuccess = FALSE; 1643 | DWORD dwNewAclSize; 1644 | DWORD dwSidSize = 0; 1645 | DWORD dwSdSizeNeeded; 1646 | PACL pacl; 1647 | PACL pNewAcl; 1648 | PSECURITY_DESCRIPTOR psd = NULL; 1649 | PSECURITY_DESCRIPTOR psdNew = NULL; 1650 | PVOID pTempAce; 1651 | SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; 1652 | unsigned int i; 1653 | 1654 | __try 1655 | { 1656 | // Obtain the security descriptor for the desktop object. 1657 | 1658 | if (!GetUserObjectSecurity( 1659 | hdesk, 1660 | &si, 1661 | psd, 1662 | dwSidSize, 1663 | &dwSdSizeNeeded)) 1664 | { 1665 | if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1666 | { 1667 | psd = (PSECURITY_DESCRIPTOR)HeapAlloc( 1668 | GetProcessHeap(), 1669 | HEAP_ZERO_MEMORY, 1670 | dwSdSizeNeeded ); 1671 | 1672 | if (psd == NULL) 1673 | __leave; 1674 | 1675 | psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( 1676 | GetProcessHeap(), 1677 | HEAP_ZERO_MEMORY, 1678 | dwSdSizeNeeded); 1679 | 1680 | if (psdNew == NULL) 1681 | __leave; 1682 | 1683 | dwSidSize = dwSdSizeNeeded; 1684 | 1685 | if (!GetUserObjectSecurity( 1686 | hdesk, 1687 | &si, 1688 | psd, 1689 | dwSidSize, 1690 | &dwSdSizeNeeded) 1691 | ) 1692 | __leave; 1693 | } 1694 | else 1695 | __leave; 1696 | } 1697 | 1698 | // Create a new security descriptor. 1699 | 1700 | if (!InitializeSecurityDescriptor( 1701 | psdNew, 1702 | SECURITY_DESCRIPTOR_REVISION) 1703 | ) 1704 | __leave; 1705 | 1706 | // Obtain the DACL from the security descriptor. 1707 | 1708 | if (!GetSecurityDescriptorDacl( 1709 | psd, 1710 | &bDaclPresent, 1711 | &pacl, 1712 | &bDaclExist) 1713 | ) 1714 | __leave; 1715 | 1716 | // Initialize. 1717 | 1718 | ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); 1719 | aclSizeInfo.AclBytesInUse = sizeof(ACL); 1720 | 1721 | // Call only if NULL DACL. 1722 | 1723 | if (pacl != NULL) 1724 | { 1725 | // Determine the size of the ACL information. 1726 | 1727 | if (!GetAclInformation( 1728 | pacl, 1729 | (LPVOID)&aclSizeInfo, 1730 | sizeof(ACL_SIZE_INFORMATION), 1731 | AclSizeInformation) 1732 | ) 1733 | __leave; 1734 | } 1735 | 1736 | // Compute the size of the new ACL. 1737 | 1738 | dwNewAclSize = aclSizeInfo.AclBytesInUse + 1739 | sizeof(ACCESS_ALLOWED_ACE) + 1740 | GetLengthSid(psid) - sizeof(DWORD); 1741 | 1742 | // Allocate buffer for the new ACL. 1743 | 1744 | pNewAcl = (PACL)HeapAlloc( 1745 | GetProcessHeap(), 1746 | HEAP_ZERO_MEMORY, 1747 | dwNewAclSize); 1748 | 1749 | if (pNewAcl == NULL) 1750 | __leave; 1751 | 1752 | // Initialize the new ACL. 1753 | 1754 | if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) 1755 | __leave; 1756 | 1757 | // If DACL is present, copy it to a new DACL. 1758 | 1759 | if (bDaclPresent) 1760 | { 1761 | // Copy the ACEs to the new ACL. 1762 | if (aclSizeInfo.AceCount) 1763 | { 1764 | for (i=0; i < aclSizeInfo.AceCount; i++) 1765 | { 1766 | // Get an ACE. 1767 | if (!GetAce(pacl, i, &pTempAce)) 1768 | __leave; 1769 | 1770 | // Add the ACE to the new ACL. 1771 | if (!AddAce( 1772 | pNewAcl, 1773 | ACL_REVISION, 1774 | MAXDWORD, 1775 | pTempAce, 1776 | ((PACE_HEADER)pTempAce)->AceSize) 1777 | ) 1778 | __leave; 1779 | } 1780 | } 1781 | } 1782 | 1783 | // Add ACE to the DACL. 1784 | 1785 | if (!AddAccessAllowedAce( 1786 | pNewAcl, 1787 | ACL_REVISION, 1788 | DESKTOP_ALL, 1789 | psid) 1790 | ) 1791 | __leave; 1792 | 1793 | // Set new DACL to the new security descriptor. 1794 | 1795 | if (!SetSecurityDescriptorDacl( 1796 | psdNew, 1797 | TRUE, 1798 | pNewAcl, 1799 | FALSE) 1800 | ) 1801 | __leave; 1802 | 1803 | // Set the new security descriptor for the desktop object. 1804 | 1805 | if (!SetUserObjectSecurity(hdesk, &si, psdNew)) 1806 | __leave; 1807 | 1808 | // Indicate success. 1809 | 1810 | bSuccess = TRUE; 1811 | } 1812 | __finally 1813 | { 1814 | // Free buffers. 1815 | 1816 | if (pNewAcl != NULL) 1817 | HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); 1818 | 1819 | if (psd != NULL) 1820 | HeapFree(GetProcessHeap(), 0, (LPVOID)psd); 1821 | 1822 | if (psdNew != NULL) 1823 | HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); 1824 | } 1825 | 1826 | return bSuccess; 1827 | } 1828 | 1829 | // xecutes a local process under the local user account who launched the process 1830 | BOOL StartLocalProcess(LPTSTR szCommandName){ 1831 | 1832 | SECURITY_ATTRIBUTES secAttrib; 1833 | ZeroMemory(&secAttrib,sizeof(secAttrib)); 1834 | secAttrib.nLength = sizeof(secAttrib); 1835 | secAttrib.bInheritHandle = TRUE; 1836 | 1837 | STARTUPINFO si; 1838 | PROCESS_INFORMATION pi; 1839 | 1840 | ZeroMemory( &si, sizeof(si) ); 1841 | si.cb = sizeof(si); 1842 | ZeroMemory( &pi, sizeof(pi) ); 1843 | 1844 | si.hStdInput = hRemoteStdInputPipe; 1845 | si.hStdOutput = hRemoteOutPipe; 1846 | si.hStdError = hRemoteOutPipe; 1847 | 1848 | // Start the child process. 1849 | if( !CreateProcess( NULL, // No module name (use command line) 1850 | szCommandName, // Command line 1851 | NULL, // Process handle not inheritable 1852 | NULL, // Thread handle not inheritable 1853 | FALSE, // Set handle inheritance to FALSE 1854 | 0, // No creation flags 1855 | NULL, // Use parent's environment block 1856 | NULL, // Use parent's starting directory 1857 | &si, // Pointer to STARTUPINFO structure 1858 | &pi ) // Pointer to PROCESS_INFORMATION structure 1859 | ) 1860 | { 1861 | ShowLastError(); 1862 | return false; 1863 | } 1864 | else{ 1865 | // printf("CreateProcess Success (%d).\n", GetLastError()); 1866 | } 1867 | // Wait until child process exits. 1868 | WaitForSingleObject( pi.hProcess, INFINITE ); 1869 | 1870 | CloseHandle( pi.hProcess ); 1871 | CloseHandle( pi.hThread ); 1872 | 1873 | return true; 1874 | } 1875 | 1876 | BOOL StartLocalProcessAsUser(){ 1877 | 1878 | HANDLE hToken; 1879 | PSID pSid = NULL; 1880 | 1881 | SECURITY_ATTRIBUTES secAttrib; 1882 | ZeroMemory(&secAttrib,sizeof(secAttrib)); 1883 | secAttrib.nLength = sizeof(secAttrib); 1884 | secAttrib.bInheritHandle = TRUE; 1885 | 1886 | STARTUPINFO si; 1887 | PROCESS_INFORMATION pi; 1888 | LPTSTR szCmdline= (LPTSTR)lpszCommandExe; 1889 | 1890 | ZeroMemory( &si, sizeof(si) ); 1891 | si.cb = sizeof(si); 1892 | ZeroMemory( &pi, sizeof(pi) ); 1893 | 1894 | si.hStdOutput = hRemoteOutPipe; 1895 | si.hStdError = hRemoteOutPipe; 1896 | 1897 | // Log the client on to the local computer. 1898 | 1899 | if (!LogonUser((LPTSTR)lpszUser, (LPTSTR)lpszDomain, (LPTSTR)lpszPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken) ) 1900 | { 1901 | printf( "User Logon failed (%d).\n", GetLastError() ); 1902 | //goto Cleanup; 1903 | ShowLastError(); 1904 | return false; 1905 | } 1906 | 1907 | if (!GetLogonSID(hToken, &pSid)) { 1908 | ShowLastError(); 1909 | return false; 1910 | } 1911 | 1912 | // Impersonate client to ensure access to executable file. 1913 | 1914 | if (! ImpersonateLoggedOnUser(hToken) ) { 1915 | ShowLastError(); 1916 | return false; 1917 | } 1918 | 1919 | 1920 | // Start the child process. 1921 | if( !CreateProcessAsUser( 1922 | hToken, //Security Token 1923 | NULL, // No module name (use command line) 1924 | szCmdline, // Command line 1925 | NULL, // Process handle not inheritable 1926 | NULL, // Thread handle not inheritable 1927 | FALSE, // Set handle inheritance to FALSE 1928 | 0, // No creation flags 1929 | NULL, // Use parent's environment block 1930 | NULL, // Use parent's starting directory 1931 | &si, // Pointer to STARTUPINFO structure 1932 | &pi ) // Pointer to PROCESS_INFORMATION structure 1933 | ) 1934 | { 1935 | printf( "CreateProcess failed (%d).\n", GetLastError() ); 1936 | ShowLastError(); 1937 | printf("User %s Password %s Command %s ", lpszUser, lpszPassword, szCmdline ); 1938 | return false; 1939 | }else{ 1940 | 1941 | printf("User Impersonation Success"); 1942 | } 1943 | 1944 | // Wait until child process exits. 1945 | WaitForSingleObject( pi.hProcess, INFINITE ); 1946 | // Close process and thread handles. 1947 | 1948 | CloseHandle( pi.hProcess ); 1949 | CloseHandle( pi.hThread ); 1950 | 1951 | return true; 1952 | } 1953 | 1954 | // Main function 1955 | //Return Codes: 1956 | // 1957 | // (-1) Incorrect parameters 1958 | // (-2) Malformed credentials 1959 | // (-3) Invalid target name 1960 | // (-4) Bad credentials 1961 | // (-5) Could not connect to target 1962 | // (-6) Error copying executable 1963 | // (-7) Error copying service 1964 | // (-8) Error executing service 1965 | // (-9) Error connecting to remote service 1966 | int _tmain( DWORD, TCHAR**, TCHAR** ) 1967 | { 1968 | int rc = 0; 1969 | DWORD dwTemp = SIZEOF_BUFFER; 1970 | DWORD dwIndex = 0; 1971 | 1972 | lpszMachine = GetRemoteMachineName(); 1973 | 1974 | lpszCommandExe = GetNthParameter( 2, dwIndex ); 1975 | 1976 | GetRemoteCommandArguments( szArguments ); 1977 | 1978 | ShowCopyRight(); 1979 | 1980 | // Show help, if parameters are incorrect, or /?,/h,/help 1981 | if ( IsCmdLineParameter( _T("h") ) || 1982 | IsCmdLineParameter( _T("?") ) || 1983 | IsCmdLineParameter( _T("help") ) || 1984 | lpszCommandExe == NULL || 1985 | lpszMachine == NULL ) 1986 | { 1987 | ShowUsage(); 1988 | return -1; 1989 | } 1990 | 1991 | 1992 | // Initialize console's title 1993 | _stprintf( szConsoleTitle, _T("%s : Starting Connection to: "), lpszMachine ); 1994 | SetConsoleTitle( szConsoleTitle ); 1995 | 1996 | // Sets our Ctrl handler 1997 | SetConsoleCtrlHandler( ConsoleCtrlHandler, TRUE ); 1998 | 1999 | // Gets our computer's name 2000 | if ( !GetComputerName( szThisMachine, &dwTemp ) ) 2001 | { 2002 | Error( _T("GetComputerName() failed. Use a valid name! :)\n") ); 2003 | return -3; 2004 | } 2005 | 2006 | // Check the user/pwd from command line, and prompts 2007 | // for the password if needed 2008 | if ( !SetConnectionCredentials( FALSE ) ) 2009 | { 2010 | rc = -2; 2011 | goto cleanup; 2012 | } 2013 | 2014 | // If the Remote Machine is localhost or 127.0.0.1 or '.' Do not connect to the ADMIN$ or IPC$ 2015 | // Instead try to use the credentials provided to RUNAS command 2016 | if( ( _tcsnicmp(lpszMachine, lpszLocalMachine, 16) == 0) || (_tcsnicmp(lpszMachine, lpszLocalIP, 16) == 0) || (_tcsnicmp(lpszMachine, ".", 2) == 0) ) 2017 | { 2018 | if(IsLaunchedFromAdmin()){ 2019 | Error( _T("Local Admin\n\n") ); 2020 | } 2021 | Out( _T("Localhost entered for Target Machine .. Going to RunAs Command\n\n") ); 2022 | lpszMachine = "\\\\127.0.0.1"; 2023 | 2024 | if(ExtractLocalBinaryResource()){ 2025 | Error( _T("Launching Local Process ...\n") ); 2026 | TCHAR szExeCmdAsUser[MAX_PATH] = _T(""); 2027 | _stprintf( szExeCmdAsUser, _T("%s %s %s %s"), szLocalBinPath, lpszUser, lpszPassword, lpszCommandExe ); 2028 | /* printf("lpszUser is %s \n",lpszUser); 2029 | printf("lpszPassword is %s \n",lpszPassword); 2030 | printf("lpszCommandExe is %s \n",lpszCommandExe); 2031 | printf("szExeCmdAsUser is %s \n",szExeCmdAsUser); 2032 | */ 2033 | if(!StartLocalProcess(szExeCmdAsUser)){ 2034 | Error( _T("Create Local Process Failed. Illegal Command") ); 2035 | } 2036 | DeleteFile(szLocalBinPath); 2037 | } 2038 | else{ 2039 | Error( _T("Cannot Extract Local Resources. Please check write access to local tmp filesystem\n") ); 2040 | 2041 | Out( _T("Create Process as User Failed. Trying to run the process with the current user\n\n") ); 2042 | StartLocalProcess((LPTSTR) lpszCommandExe); // Creates a Run As Command 2043 | } 2044 | 2045 | // if(! StartInteractiveClientProcess((LPTSTR)lpszUser, (LPTSTR)lpszDomain, (LPTSTR)lpszPassword, (LPTSTR)lpszCommandExe)) 2046 | // if(!StartProcessWithUserLogon()) { } 2047 | // StartLocalProcessAsUser(); 2048 | 2049 | } 2050 | 2051 | else 2052 | //Remote Machine 2053 | { 2054 | Error( _T("Initiating Connection to Remote Service . . . ") ); 2055 | // Connect to remote machine's ADMIN$ 2056 | if ( !EstablishConnection( lpszMachine, _T("ADMIN$"), TRUE ) ) 2057 | { 2058 | switch(GetLastError( )){ 2059 | case ERROR_ACCESS_DENIED: 2060 | case ERROR_INVALID_PASSWORD: 2061 | case ERROR_LOGON_FAILURE: 2062 | case ERROR_SESSION_CREDENTIAL_CONFLICT: 2063 | rc = -4; 2064 | Error( _T("Failed\n\n") ); 2065 | Error( _T("Couldn't connect to ") ) 2066 | Error( lpszMachine ); 2067 | Error( _T("\\ADMIN$\n") ); 2068 | Error( _T("Bad credentials.\n") ); 2069 | 2070 | break; 2071 | 2072 | default: 2073 | rc = -5; 2074 | Error( _T("Failed\n\n") ); 2075 | Error( _T("Couldn't connect to ") ) 2076 | Error( lpszMachine ); 2077 | Error( _T("\\ADMIN$\n") ); 2078 | Error( _T("Connection failed.\n") ); 2079 | 2080 | break; 2081 | } 2082 | 2083 | ShowLastError(); 2084 | goto cleanup; 2085 | 2086 | } 2087 | 2088 | // Connect to remote machine IPC$ 2089 | if ( !EstablishConnection( lpszMachine, _T("IPC$"), TRUE ) ) 2090 | { 2091 | 2092 | switch(GetLastError( )){ 2093 | case ERROR_ACCESS_DENIED: 2094 | case ERROR_INVALID_PASSWORD: 2095 | case ERROR_LOGON_FAILURE: 2096 | case ERROR_SESSION_CREDENTIAL_CONFLICT: 2097 | rc = -4; 2098 | Error( _T("Failed\n\n") ); 2099 | Error( _T("Couldn't connect to ") ) 2100 | Error( lpszMachine ); 2101 | Error( _T("\\IPC$\n") ); 2102 | Error( _T("Bad credentials.\n") ); 2103 | 2104 | break; 2105 | 2106 | default: 2107 | rc = -5; 2108 | Error( _T("Failed\n\n") ); 2109 | Error( _T("Couldn't connect to ") ) 2110 | Error( lpszMachine ); 2111 | Error( _T("\\ADMIN$\n") ); 2112 | Error( _T("Connection failed.\n") ); 2113 | 2114 | break; 2115 | } 2116 | 2117 | ShowLastError(); 2118 | goto cleanup; 2119 | } 2120 | 2121 | 2122 | // Copy the command's exe file to remote machine (if using /c) 2123 | if ( !CopyBinaryToRemoteSystem() ) 2124 | { 2125 | rc = -6; 2126 | Error( _T("Failed\n\n") ); 2127 | Error( _T("Couldn't copy ") ); 2128 | Error( lpszCommandExe ); 2129 | Error( _T(" to ") ); 2130 | Error( lpszMachine ); 2131 | Error( _T("\\ADMIN$\n") ); 2132 | ShowLastError(); 2133 | goto cleanup; 2134 | } 2135 | 2136 | // Connects to remote service, maybe it's already running :) 2137 | if ( !ConnectToRemoteService( 1, 0 ) ) 2138 | { 2139 | //We couldn't connect, so let's install it and start it 2140 | 2141 | // Copy the service executable to \\remote\ADMIN$ 2142 | 2143 | if ( !CopyServiceToRemoteMachine() ) 2144 | { 2145 | rc = -7; 2146 | Error( _T("Failed\n\n") ); 2147 | Error( _T("Couldn't copy service to ") ); 2148 | Error( lpszMachine ); 2149 | //Error( _T("\\ADMIN$\\System32\n") ); 2150 | Error( _T("\\ADMIN$\n") ); 2151 | ShowLastError(); 2152 | goto cleanup; 2153 | } 2154 | 2155 | // Install and start service on remote machine 2156 | if ( !InstallAndStartRemoteService() ) 2157 | { 2158 | rc = -8; 2159 | Error( _T("Failed\n\n") ); 2160 | Error( _T("Couldn't start remote service\n") ); 2161 | ShowLastError(); 2162 | goto cleanup; 2163 | } 2164 | 2165 | // Try to connect again 2166 | if ( !ConnectToRemoteService( 5, 1000 ) ) 2167 | { 2168 | rc = -9; 2169 | Error( _T("Failed\n\n") ); 2170 | Error( _T("Couldn't connect to remote service\n") ); 2171 | ShowLastError(); 2172 | goto cleanup; 2173 | } 2174 | } 2175 | 2176 | // Send the message to remote service to start the remote process 2177 | rc = ExecuteRemoteCommand(); 2178 | 2179 | } 2180 | 2181 | cleanup: 2182 | 2183 | // Disconnect from remote machine 2184 | EstablishConnection( lpszMachine, _T("IPC$"), FALSE ); 2185 | EstablishConnection( lpszMachine, _T("ADMIN$"), FALSE ); 2186 | 2187 | return rc; 2188 | } 2189 | 2190 | --------------------------------------------------------------------------------