diff --git a/lib/msf/scripts/meterpreter/services.rb b/lib/msf/scripts/meterpreter/services.rb index b07cf03d96..95018c2b4e 100644 --- a/lib/msf/scripts/meterpreter/services.rb +++ b/lib/msf/scripts/meterpreter/services.rb @@ -11,6 +11,7 @@ module Common # These methods should only print output in the case of an error. All code should be tab indented # All methods should follow the naming coventions below (separate words with "_", end queries with a ?, etc) # + #List all Windows Services present. Returns an Array containing the names of the services. def service_list serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services" @@ -70,7 +71,82 @@ def service_change_startup(name,mode) end end +# Function for the creation of a service that runs it's own process. It takes as +# values the service name as string, the display name as string, the path of the +# executable on the host that will execute at startup as string and the startup +# type as an integer of 2 for Auto, 3 for Manual or 4 for Disable, default Auto. +def service_create(name, display_name, executable_on_host,startup=2) + client.core.use("railgun") + adv = client.railgun.advapi32 + manag = adv.OpenSCManagerA(nil,nil,0x13) + if(manag["return"] != 0) + # SC_MANAGER_CREATE_SERVICE = 0x0002 + newservice = adv.CreateServiceA(manag["return"],name,display_name,0x0010,0X00000010,startup,0,executable_on_host,nil,nil,nil,nil,nil) + #SERVICE_START=0x0010 SERVICE_WIN32_OWN_PROCESS= 0X00000010 + #SERVICE_AUTO_START = 2 SERVICE_ERROR_IGNORE = 0 + if newservice["GetLastError"] == 0 + return true + else + return false + end + else + raise "Could not open Service Control Manager, Access Denied" + end +end +# Function for service startup, returns 0 if service started, 1 if service is +# already started and 2 if service is disabled. +def service_start(name) + client.core.use("railgun") + adv = client.railgun.advapi32 + manag = adv.OpenSCManagerA(nil,nil,1) + if(manag["return"] == 0) + raise "Could not open Service Control Manager, Access Denied" + end + #open with SERVICE_START (0x0010) + servhandleret = adv.OpenServiceA(manag["return"],name,0x10) + if(servhandleret["return"] == 0) + adv.CloseServiceHandle(manag["return"]) + raise "Could not Open Service, Access Denied" + end + retval = adv.StartServiceA(servhandleret["return"],0,nil) + adv.CloseServiceHandle(servhandleret["return"]) + adv.CloseServiceHandle(manag["return"]) + if retval["GetLastError"] == 0 + return 0 + elsif retval["GetLastError"] == 1056 + return 1 + elsif retval["GetLastError"] == 1058 + return 2 + end +end + +# Function for stopping a service, returns 0 if service is stopped successfully, +# 1 if service is already stopped or disabled and 2 if the service can not be stopped. +def service_stop(name) + client.core.use("railgun") + adv = client.railgun.advapi32 + manag = adv.OpenSCManagerA(nil,nil,1) + if(manag["return"] == 0) + raise "Could not open Service Control Manager, Access Denied" + end + #open with SERVICE_STOP (0x0020) + servhandleret = adv.OpenServiceA(manag["return"],name,0x30) + if(servhandleret["return"] == 0) + adv.CloseServiceHandle(manag["return"]) + raise "Could not Open Service, Access Denied" + end + retval = adv.ControlService(servhandleret["return"],1,56) + adv.CloseServiceHandle(servhandleret["return"]) + adv.CloseServiceHandle(manag["return"]) + if retval["GetLastError"] == 0 + return 0 + elsif retval["GetLastError"] == 1062 + return 1 + elsif retval["GetLastError"] == 1052 + return 2 + end +end end end end diff --git a/lib/rex/post/meterpreter/extensions/railgun/api.rb b/lib/rex/post/meterpreter/extensions/railgun/api.rb index f1e4d13e3b..874ceed43f 100644 --- a/lib/rex/post/meterpreter/extensions/railgun/api.rb +++ b/lib/rex/post/meterpreter/extensions/railgun/api.rb @@ -9196,102 +9196,215 @@ class ApiDefinitions railgun.add_function( 'kernel32', 'Process32NextW', 'BOOL',[ ["DWORD","hSnapshot","in"], ["PBLOB","lppe","inout"], - ]) + ]) railgun.add_function( 'kernel32', 'Thread32First', 'BOOL',[ - ["DWORD","hSnapshot","in"], - ["PBLOB","lpte","inout"], + ["DWORD","hSnapshot","in"], + ["PBLOB","lpte","inout"], ]) railgun.add_function( 'kernel32', 'Thread32Next', 'BOOL',[ - ["DWORD","hSnapshot","in"], - ["PBLOB","lpte","inout"], + ["DWORD","hSnapshot","in"], + ["PBLOB","lpte","inout"], ]) railgun.add_function( 'kernel32', 'Toolhelp32ReadProcessMemory', 'BOOL',[ - ["DWORD","th32ProcessID","in"], - ["PBLOB","lpBaseAddress","inout"], - ["PBLOB","lpBuffer","inout"], - ["DWORD","cbRead","in"], - ["PDWORD","lpNumberOfBytesRead","in"], + ["DWORD","th32ProcessID","in"], + ["PBLOB","lpBaseAddress","inout"], + ["PBLOB","lpBuffer","inout"], + ["DWORD","cbRead","in"], + ["PDWORD","lpNumberOfBytesRead","in"], ]) railgun.add_dll('Iphlpapi','Iphlpapi') railgun.add_function( 'Iphlpapi', 'CancelIPChangeNotify', 'BOOL',[ - ["PBLOB","notifyOverlapped","in"], + ["PBLOB","notifyOverlapped","in"], ]) railgun.add_function( 'Iphlpapi', 'CreateProxyArpEntry', 'DWORD',[ - ["DWORD","dwAddress","in"], - ["DWORD","dwMask","in"], - ["DWORD","dwIfIndex","in"], + ["DWORD","dwAddress","in"], + ["DWORD","dwMask","in"], + ["DWORD","dwIfIndex","in"], ]) railgun.add_function( 'Iphlpapi', 'DeleteIPAddress', 'DWORD',[ - ["DWORD","NTEContext","in"], + ["DWORD","NTEContext","in"], ]) railgun.add_function( 'Iphlpapi', 'DeleteProxyArpEntry', 'DWORD',[ - ["DWORD","dwAddress","in"], - ["DWORD","dwMask","in"], - ["DWORD","dwIfIndex","in"], + ["DWORD","dwAddress","in"], + ["DWORD","dwMask","in"], + ["DWORD","dwIfIndex","in"], ]) railgun.add_function( 'Iphlpapi', 'FlushIpNetTable', 'DWORD',[ - ["DWORD","dwIfIndex","in"], + ["DWORD","dwIfIndex","in"], ]) railgun.add_function( 'Iphlpapi', 'GetAdapterIndex', 'DWORD',[ - ["PWCHAR","AdapterName","in"], - ["PDWORD","IfIndex","inout"], + ["PWCHAR","AdapterName","in"], + ["PDWORD","IfIndex","inout"], ]) railgun.add_function( 'Iphlpapi', 'GetBestInterface', 'DWORD',[ - ["DWORD","dwDestAddr","in"], - ["PDWORD","pdwBestIfIndex","inout"], + ["DWORD","dwDestAddr","in"], + ["PDWORD","pdwBestIfIndex","inout"], ]) railgun.add_function( 'Iphlpapi', 'GetBestInterfaceEx', 'DWORD',[ - ["PBLOB","pDestAddr","in"], - ["PDWORD","pdwBestIfIndex","inout"], + ["PBLOB","pDestAddr","in"], + ["PDWORD","pdwBestIfIndex","inout"], ]) railgun.add_function( 'Iphlpapi', 'GetFriendlyIfIndex', 'DWORD',[ - ["DWORD","IfIndex","in"], + ["DWORD","IfIndex","in"], ]) railgun.add_function( 'Iphlpapi', 'GetNumberOfInterfaces', 'DWORD',[ - ["PDWORD","pdwNumIf","inout"], + ["PDWORD","pdwNumIf","inout"], ]) railgun.add_function( 'Iphlpapi', 'GetRTTAndHopCount', 'BOOL',[ - ["DWORD","DestIpAddress","in"], - ["PDWORD","HopCount","inout"], - ["DWORD","MaxHops","in"], - ["PDWORD","RTT","inout"], + ["DWORD","DestIpAddress","in"], + ["PDWORD","HopCount","inout"], + ["DWORD","MaxHops","in"], + ["PDWORD","RTT","inout"], ]) railgun.add_function( 'Iphlpapi', 'NotifyAddrChange', 'DWORD',[ - ["PDWORD","Handle","inout"], - ["PBLOB","overlapped","in"], + ["PDWORD","Handle","inout"], + ["PBLOB","overlapped","in"], ]) railgun.add_function( 'Iphlpapi', 'NotifyRouteChange', 'DWORD',[ - ["PDWORD","Handle","inout"], - ["PBLOB","overlapped","in"], + ["PDWORD","Handle","inout"], + ["PBLOB","overlapped","in"], ]) railgun.add_function( 'Iphlpapi', 'SendARP', 'DWORD',[ - ["DWORD","DestIP","in"], - ["DWORD","SrcIP","in"], - ["PDWORD","pMacAddr","inout"], - ["PDWORD","PhyAddrLen","inout"], + ["DWORD","DestIP","in"], + ["DWORD","SrcIP","in"], + ["PDWORD","pMacAddr","inout"], + ["PDWORD","PhyAddrLen","inout"], ]) railgun.add_function( 'Iphlpapi', 'SetIpTTL', 'DWORD',[ - ["DWORD","nTTL","in"], + ["DWORD","nTTL","in"], ]) + railgun.kernel32.LoadLibraryA("Advapi32.dll") + + # Function to open the Service Control Database + railgun.add_function( 'advapi32', 'OpenSCManagerA','DWORD',[ + + [ "PCHAR", "lpMachineName", "inout" ], + + [ "PCHAR", "lpDatabaseName", "inout" ], + + [ "DWORD", "dwDesiredAccess", "in" ] + + ]) + # Function for creating a Service + railgun.add_function( 'advapi32', 'CreateServiceA','DWORD',[ + + [ "DWORD", "hSCManager", "in" ], + + [ "PCHAR", "lpServiceName", "in" ], + + [ "PCHAR", "lpDisplayName", "in" ], + + [ "DWORD", "dwDesiredAccess", "in" ], + + [ "DWORD", "dwServiceType", "in" ], + + [ "DWORD", "dwStartType", "in" ], + + [ "DWORD", "dwErrorControl", "in" ], + + [ "PCHAR", "lpBinaryPathName", "in" ], + + [ "PCHAR", "lpLoadOrderGroup", "in" ], + + [ "PDWORD", "lpdwTagId", "out" ], + + [ "PCHAR", "lpDependencies", "in" ], + + [ "PCHAR", "lpServiceStartName", "in" ], + + [ "PCHAR", "lpPassword", "in" ] + + ]) + + railgun.add_function( 'advapi32', 'OpenServiceA','DWORD',[ + + [ "DWORD", "hSCManager", "in" ], + + [ "PCHAR", "lpServiceName", "in" ], + + [ "DWORD", "dwDesiredAccess", "in" ] + + ]) + + #access rights: SERVICE_CHANGE_CONFIG (0x0002) SERVICE_START (0x0010) + #SERVICE_STOP (0x0020) + + railgun.add_function( 'advapi32', 'StartServiceA','BOOL',[ + + [ "DWORD", "hService", "in" ], + + [ "DWORD", "dwNumServiceArgs", "in" ], + + [ "PCHAR", "lpServiceArgVectors", "in" ] + + ]) + + railgun.add_function( 'advapi32', 'ControlService','BOOL',[ + + [ "DWORD", "hService", "in" ], + + [ "DWORD", "dwControl", "in" ], + + [ "PBLOB", "lpServiceStatus", "out" ] + + ]) + + #SERVICE_CONTROL_STOP = 0x00000001 + + # _SERVICE_STATUS is an array of 7 DWORDS - dwServiceType; + #dwCurrentState; dwControlsAccepted; dwWin32ExitCode; + #dwServiceSpecificExitCode; dwCheckPoint; dwWaitHint; + + railgun.add_function( 'advapi32', 'ChangeServiceConfigA','BOOL',[ + + [ "DWORD", "hService", "in" ], + + [ "DWORD", "dwServiceType", "in" ], + + [ "DWORD", "dwStartType", "in" ], + + [ "DWORD", "dwErrorControl", "in" ], + + [ "PCHAR", "lpBinaryPathName", "in" ], + + [ "PCHAR", "lpLoadOrderGroup", "in" ], + + [ "PDWORD", "lpdwTagId", "out" ], + + [ "PCHAR", "lpDependencies", "in" ], + + [ "PCHAR", "lpServiceStartName", "in" ], + + [ "PCHAR", "lpPassword", "in" ], + + [ "PCHAR", "lpDisplayName", "in" ] + + ]) + + railgun.add_function( 'advapi32', 'CloseServiceHandle','BOOL',[ + + [ "DWORD", "hSCObject", "in" ] + + ]) end # method