From 6fde4777e52c614155ddfccc97c527cd322d0104 Mon Sep 17 00:00:00 2001 From: saxena-anurag <43585259+saxena-anurag@users.noreply.github.com> Date: Mon, 14 Jun 2021 15:38:42 -0700 Subject: [PATCH] Change ebpfsvc to LocalService (#272) * ebpfsvc should be localservice * cr comments, change sidtype to restricted * pr comments --- docs/GettingStarted.md | 2 +- ebpfcore/ebpf_drv.c | 11 ++++- ebpfsvc/svcmain.cpp | 71 ++++++++++++++++++------------ tests/libs/util/service_helper.cpp | 37 ++++++++++------ 4 files changed, 78 insertions(+), 43 deletions(-) diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index 92153e6a8..e6c3ce9a4 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -69,7 +69,7 @@ On the defender machine, do the following: 9. Do `sc start EbpfCore` 10. Do `sc create NetEbpfExt type=kernel start=boot binpath=%windir%\system32\drivers\netebpfext.sys` 11. Do `sc start NetEbpfExt` -12. Do `sc create ebpfsvc start= auto binpath=%windir%\system32\ebpfsvc.exe type=own` +12. Do `%windir%\system32\ebpfsvc.exe install` 13. Do `sc start ebpfsvc` 14. Do `netsh add helper %windir%\system32\ebpfnetsh.dll` 15. Install [clang](https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/LLVM-11.0.0-win64.exe) diff --git a/ebpfcore/ebpf_drv.c b/ebpfcore/ebpf_drv.c index 1acd44c04..3f974b591 100644 --- a/ebpfcore/ebpf_drv.c +++ b/ebpfcore/ebpf_drv.c @@ -27,6 +27,13 @@ Environment: static DEVICE_OBJECT* _ebpf_driver_device_object; static BOOLEAN _ebpf_driver_unloading_flag = FALSE; +// SID for ebpfsvc (generated using command "sc.exe showsid ebpfsvc"): +// S-1-5-80-3453964624-2861012444-1105579853-3193141192-1897355174 +// +// SDDL_DEVOBJ_SYS_ALL_ADM_ALL + SID for ebpfsvc. +#define EBPF_EXECUTION_CONTEXT_DEVICE_SDDL \ + L"D:P(A;;GA;;;S-1-5-80-3453964624-2861012444-1105579853-3193141192-1897355174)(A;;GA;;;BA)(A;;GA;;;SY)" + #ifndef CTL_CODE #define CTL_CODE(DeviceType, Function, Method, Access) \ (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) @@ -132,6 +139,8 @@ _ebpf_driver_initialize_objects( WDF_DRIVER_CONFIG_INIT(&driver_configuration, WDF_NO_EVENT_CALLBACK); + DECLARE_CONST_UNICODE_STRING(security_descriptor, EBPF_EXECUTION_CONTEXT_DEVICE_SDDL); + driver_configuration.DriverInitFlags |= WdfDriverInitNonPnpDriver; driver_configuration.EvtDriverUnload = _ebpf_driver_unload; @@ -143,7 +152,7 @@ _ebpf_driver_initialize_objects( device_initialize = WdfControlDeviceInitAllocate( *driver, - &SDDL_DEVOBJ_SYS_ALL_ADM_ALL // only kernel/system and administrators. + &security_descriptor // only kernel/system, administrators, and ebpfsvc. ); if (!device_initialize) { status = STATUS_INSUFFICIENT_RESOURCES; diff --git a/ebpfsvc/svcmain.cpp b/ebpfsvc/svcmain.cpp index 922d8d3d0..aac3a0be5 100644 --- a/ebpfsvc/svcmain.cpp +++ b/ebpfsvc/svcmain.cpp @@ -22,7 +22,7 @@ service_init(DWORD argc, PTSTR* argv); void WINAPI service_main(DWORD argc, PTSTR* argv); -void +int service_install(); int __cdecl wmain(ULONG argc, PWSTR* argv) @@ -34,9 +34,8 @@ int __cdecl wmain(ULONG argc, PWSTR* argv) // Otherwise, the service is probably being started by the SCM. if (argc > 1) { - if (wcscmp(argv[1], L"install") == 0) { - service_install(); - return -1; + if (_wcsicmp(argv[1], L"install") == 0) { + return service_install(); } } @@ -54,15 +53,18 @@ int __cdecl wmain(ULONG argc, PWSTR* argv) * @brief Installs a service in the SCM database. * */ -void +int service_install() { - SC_HANDLE scmanager; - SC_HANDLE service; + SC_HANDLE scmanager = nullptr; + SC_HANDLE service = nullptr; TCHAR path[MAX_PATH]; + SERVICE_SID_INFO sid_information = {0}; + int result = ERROR_SUCCESS; if (!GetModuleFileName(nullptr, path, MAX_PATH)) { - return; + result = GetLastError(); + goto Exit; } // Get a handle to the SCM database. @@ -73,33 +75,48 @@ service_install() SC_MANAGER_ALL_ACCESS); // full access rights if (nullptr == scmanager) { - return; + result = GetLastError(); + goto Exit; } - // Create the service + // Create the service as LocalService. service = CreateService( - scmanager, // SCM database - SERVICE_NAME, // name of service - SERVICE_NAME, // service name to display - SERVICE_ALL_ACCESS, // desired access - SERVICE_WIN32_OWN_PROCESS, // service type - SERVICE_DEMAND_START, // start type - SERVICE_ERROR_NORMAL, // error control type - path, // path to service's binary - nullptr, // no load ordering group - nullptr, // no tag identifier - nullptr, // no dependencies - nullptr, // LocalSystem account - nullptr); // no password + scmanager, // SCM database + SERVICE_NAME, // name of service + SERVICE_NAME, // service name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_WIN32_OWN_PROCESS, // service type + SERVICE_DEMAND_START, // start type + SERVICE_ERROR_NORMAL, // error control type + path, // path to service's binary + nullptr, // no load ordering group + nullptr, // no tag identifier + nullptr, // no dependencies + L"NT AUTHORITY\\LocalService", // LocalService account + nullptr); // no password if (service == nullptr) { - CloseServiceHandle(scmanager); - return; + result = GetLastError(); + goto Exit; } - CloseServiceHandle(service); - CloseServiceHandle(scmanager); + // Set service SID type to restricted. + sid_information.dwServiceSidType = SERVICE_SID_TYPE_RESTRICTED; + if (!ChangeServiceConfig2(service, SERVICE_CONFIG_SERVICE_SID_INFO, &sid_information)) { + result = GetLastError(); + goto Exit; + } + +Exit: + if (service != nullptr) { + CloseServiceHandle(service); + } + if (scmanager != nullptr) { + CloseServiceHandle(scmanager); + } + + return result; } /** diff --git a/tests/libs/util/service_helper.cpp b/tests/libs/util/service_helper.cpp index 29ef41897..49db159bc 100644 --- a/tests/libs/util/service_helper.cpp +++ b/tests/libs/util/service_helper.cpp @@ -12,6 +12,7 @@ service_install_helper::initialize() { int error; int retry_count = 0; + SERVICE_SID_INFO sid_information = {0}; if (initialized) { return ERROR_SUCCESS; @@ -35,21 +36,21 @@ QueryService: return error; } - // Install the service + // Install the service as LocalService. service_handle = CreateService( - scm_handle, // SCM database - service_name.c_str(), // name of service - service_name.c_str(), // service name to display - SERVICE_ALL_ACCESS, // desired access - service_type, // service type - SERVICE_AUTO_START, // start type - SERVICE_ERROR_NORMAL, // error control type - file_path, // path to service's binary - nullptr, // no load ordering group - nullptr, // no tag identifier - nullptr, // no dependencies - nullptr, // LocalSystem account - nullptr); // no password + scm_handle, // SCM database + service_name.c_str(), // name of service + service_name.c_str(), // service name to display + SERVICE_ALL_ACCESS, // desired access + service_type, // service type + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + file_path, // path to service's binary + nullptr, // no load ordering group + nullptr, // no tag identifier + nullptr, // no dependencies + L"NT AUTHORITY\\LocalService", // LocalService account + nullptr); // no password if (service_handle == nullptr) { error = GetLastError(); @@ -61,6 +62,14 @@ QueryService: printf("CreateService for %ws failed, 0x%x.\n", service_name.c_str(), error); return error; } + + // Set service SID type to restricted. + sid_information.dwServiceSidType = SERVICE_SID_TYPE_RESTRICTED; + if (!ChangeServiceConfig2(service_handle, SERVICE_CONFIG_SERVICE_SID_INFO, &sid_information)) { + error = GetLastError(); + printf("ChangeServiceConfig2 for %ws failed, 0x%x.\n", service_name.c_str(), error); + return error; + } } else { already_installed = true; printf("Service %ws already installed.\n", service_name.c_str());