0x00 背景
在开展渗透测试项目时,渗透测试工程师会使用大量的渗透测试框架以及工具,如Cobalt Strike。它提供了灵活性强、可用性高、可高度定制的攻击开发和执行环境,同时其具备端口扫描和木马生成等功能。通常在获取系统控制权后,测试人员需根据具体的渗透测试目的和实际测试场景选择使用恰当的方式进行测试,此时需调用相对应的命令。这些命令背后都有其运行原理,掌握其原理可在一定程度上提高渗透效率,降低未知风险。
0x01 Make_Token
克隆当前的访问令牌,并将其设置为在与网络资源交互时传递指定的用户名和口令。此命令不验证您提供的凭据,并且对本地操作没有影响。
Use:
make_token [DOMAIN\user] [password]
效果展示:
演示环境:Windows 7
测试机地址:172.16.203.138
首先,我们假设目标已经成功上线,当前用户为 cc,接着使用命令
shell dir \\172.16.203.146\c 去访问目标网络共享资源的目录,发现提示登录失败。如下图所示:
然后,我们尝试使用 make_token admin admin 命令去克隆一个合法用户的访问令牌,接着使用命令 shell dir \\172.16.203.218\c 列出目标网络共享资源的目录,发现依然提示登录失败。如下图所示:
最后经过尝试,我们使用命令 make_token test test 和 shell dir \\172.16.203.218\c,发现可以成功列出共享目录。这说明,test/test 是网络共享主机的合法用户。并且此时再执行命令 whoami ,依然是最初的用户 cc 。如下图所示:
原理说明:
由上述的效果展示部分,可明显看出 make_token 并不会做用户和口令的验证,且不影响本地用户的操作。但是在与网络资源交互时,会传递设置的用户名和口令。通过抓包也可看出多次访问共享资源的时候,SMB2 协议中的 NTLM 认证用户的不同,如下图所示:
使用当前用户与第一次克隆的 admin/admin 访问令牌,在访问共享资源的时候,均认证失败;
最后一次克隆的 test/test 的合法用户口令,认证成功。
0x02 Steal_Token
获取指定进程的访问令牌。
Use:
steal_token [pid]
效果展示:
演示环境:Windows Server 2008 R2
测试机地址:192.168.3.133
Cobalt Strike 地址:192.168.3.136
本地创建一个系统用户 stinky 。
用户名:stinky
口 令:admin123!@#
command:
net user stinky admin123!@# /add
利用 stinky 用户运行 notepad.exe 程序。
command:
runas /noprofile /user:stinky notepad.exe
查看进程信息确认 notepad.exe 程序由 stinky 用户运行。
尝试获取 notepad.exe 程序 token ,通过查询发现权限不足。
command:
steal_token 2424
使用 Cobalt Strike 进行权限提升,并获取 notepad.exe 进程 token 信息。
command:
elevate ms14-058
获取 notepad.exe 进程 token 信息,利用该 token 重新运行 notepad.exe 程序。查看进程信息时存在两个以 stinky 用户运行的 notepad.exe 程序。
command:
steal_token 2424
execute C:\Windows\System32\notepad.exe
原理说明:
先简单介绍一下什么是令牌,令牌来表示一个进程或线程的安全环境,安全环境中包含的信息描述了与该进程活现场相关联的账户,组和特权。
OpenProcess:函数用来打开一个已存在的进程对象,并返回进程的句柄。
OpenProcessToken:函数用来打开与进程相关联的访问令牌。
DuplicateTokenEx:函数可以实现以其他用户身份起一个进程,利用OpenProcessToken获取到的令牌产生一个新的令牌。
CreateProcessWithTokenW:创建一个新进程及其主线程。新进程可以选择加载指定用户的令牌。
下图是 Windows API 调用流程,利用此流程可以用来窃取进程访问令牌,并使用获取到的令牌运行新程序。
工具演示:
演示环境:windows 10
本地创建一个系统用户 stinky_a 并登陆。
用户名:stinky_a
口 令:admin123!@#
command:
net user stinky_a admin123!@# /add
net localgroup administrators stinky_a /add
本地创建一个系统用户 stinky_b 并登陆。
用户名:stinky_b
口 令:admin456!@#
command:
net user stinky_b admin456!@# /add
使用 stinky_b 开启记事本。
command:
runas /noprofile /user:stinky_b notepad.exe
找到 notepad 进程对应的 PID 并确认其运行用户权限为 stinky_b。
command:
tasklist -V | findstr stinky_b
获取进程 token 并使用该 token 起一个 cmd.exe 程序。
command:
token.exe 5060
工具下载地址:
https://pan.baidu.com/s/1ya1nCWT0p2qM_2HywOl5Jw
0x03 RunAs
尝试以另一个用户的身份执行程序。
Use:
runas [DOMAIN\user] [password] [command] [arguments]
RunAs 命令执行的原理是利用 Windows 的 LogonUser 函数来生成一个令牌,然后将该令牌传递给 Windows 的 CreateProcessAsUser 函数,从而用它来创建一个新的进程,同时新的进程运行在通过 LogonUser 函数来登陆的用户安全环境中。CreateProcessAsUser:可以被 system 账户或者用户账户的普通权限调用,创建具有用户帐户普通权限的进程。
效果展示:
演示环境:Windows Server 2008 R2
测试机地址:192.168.3.133
Cobalt Strike 地址:192.168.3.136
利用 stinky 运行 notepad.exe 程序。
command:
runas stinky admin123!@# notepad.exe
工具下载地址:
https://pan.baidu.com/s/1kE9vqe2PH9cN9w8PTvcIQw
https://pan.baidu.com/s/1K3_fuQAq3XOZrFb5dQ3XMw
0x04 参考文章
https://github.com/antonioCoco/RunasCs
https://github.com/0xbadjuju/Tokenvator/blob/master/Tokenvator/Tokens.cs
https://posts.specterops.io/understanding-and-defending-against-access-token-theft-finding-alternatives-to-winlogon-exe-80696c8a73b
https://github.com/slyd0g/PrimaryTokenTheft