渗透技巧——程序的降权启动
0x00 前言
在渗透测试中,常常会遇到需要改变程序启动权限(分为提权和降权)的情况。
提权包含从普通用户权限到管理员权限和从管理员权限到 system 权限,而渗透测试中的降权通常是指从 system 权限降到普通用户权限(从管理员权限降到普通用户权限比较简单,方法很多),往往是为了操作当前用户的文件内容(如捕获桌面、操作注册表等)
本文将会介绍具体的降权方法(从 system 权限降到普通用户权限),理清其中的重点,并且开源一个小工具,用于判断进程权限
0x01 简介
本文将要介绍以下内容:
- 为什么要降权
- 从管理员权限降到普通用户权限的方法
- 从 system 权限降到普通用户权限的方法
- 利用 SelectMyParent 实现提权和降权
注: 测试系统: Win7
0x02 为什么要降权
使用 sytem 权限的进程可能会遇到以下问题:
1、无法获得当前用户的文件内容
例如无法捕获用户的屏幕
2、环境变量有差异
比如以下环境变量:
- APPDATA
- Temp
- Tmp
- USERDOMAIN
- USERNAME
- USERPROFILE
cmd 下可通过 echo 查看环境变量,例如查看环境变量 APPDATA 的命令为:
echo %appdata%
system 权限下,查询到的环境变量 APPDATA 为 C:\Windows\system32\config\systemprofile\AppData\Roaming
管理员权限下,查询到的环境变量 APPDATA 为 C:\Users\a\AppData\Roaming
如下图
通过 API SHGetSpecialFolderPath 获取指定的系统路径,如 APPDATA,也能发现权限不同导致的区别
c++代码如下:
#include <windows.h>
#include <Shlobj.h>
bool IsSystemPrivilegeCmp()
{
static bool isSystemPrivilege = false;
char *flag="C:\\Windows";
if (isSystemPrivilege)
{
return isSystemPrivilege;
}
char szPath[MAX_PATH] = {0};
if (SHGetSpecialFolderPathA(NULL, szPath, CSIDL_APPDATA, TRUE))
{
printf("APPDATA Path:%s\n",szPath);
if(memcmp(szPath,flag,strlen(flag))==0)
printf("[+]I'm System Privilege\n");
else
printf("[-]Not System Privilege\n");
}
return isSystemPrivilege;
}
int main(int argc, CHAR* argv[])
{
IsSystemPrivilegeCmp();
return 0;
}
如下图
注:
SHGetSpecialFolderPath 支持查询的系统路径可在 Shlobj.h 中获取
如下图
3、注册表有差异
对 HKCU 的部分注册表操作会被重定向到 HKEY_USERS.DEFAULT
如下图
0x03 从管理员权限降到普通用户权限的方法
1、runas
cmd: runas /user:a calc.exe
接着输入密码:123456
calc.exe 的权限为用户 a 的权限
如下图
缺点: 需要等待用户手动输入密码,不够自动化
但是可以借助管道实现自动输入密码,需要借助第三方工具 Sanur,方法不具体介绍
2、第三方工具:lsrunas
下载地址: http://www.verydoc.com/exeshell.html
cmd: lsrunas.exe /user:a /password:123456 /domain: /command:"calc.exe" /runpath:c:\
注: /domain:参数为空表示为本机
从管理员权限降权到普通用户权限,成功,如下图
3、第三方工具:CPAU
下载地址可参考我的 github: https://github.com/3gstudent/From-System-authority-to-Medium-authority
cmd: CPAU.exe -u a -p 123456 -ex "calc.exe" -cwd c:\windows\system32 -lwp
注: 必须添加参数-lwp 或-lwop,否则无法实现降权
从管理员权限降权到普通用户权限,成功,如下图
4、powershell
代码如下:
$uname="a"
$pwd=ConvertTo-SecureString "123456" -AsPlainText –Force
$cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)
Start-Process -FilePath "calc.exe" -Credential $cred
5、c++
使用 API:
- CreateProcessAsUser
- CreateProcess
0x04 从 system 权限降到普通用户权限的方法
注: 本次测试的 system 权限通过漏洞获取
1、runas
cmd: runas /user:a calc.exe
接着输入密码:123456
成功降权,但启动失败,如下图
2、第三方工具:lsrunas
cmd: lsrunas.exe /user:a /password:123456 /domain: /command:"calc.exe" /runpath:c:\
同上,成功降权,但启动失败
3、第三方工具:CPAU
cmd: CPAU.exe -u a -p 123456 -ex "calc.exe" -lwp
CPAU 不支持 system 权限启动,如下图
4、powershell
同 1,成功降权,但启动失败
5、c++
可以使用 Didier Stevens 的工具 SelectMyParent
注: 该代码尚未在 github 共享,所以我在我的 github 上传了该代码,并注明作者为 Didier Stevens
SelectMyParent:
用来创建具有选定父进程的 windows 进程
例如:创建新进程 calc.exe,使用 SelectMyParent 可以将新进程 calc.exe 设置为进程 winlogon.exe 的子进程
使用步骤:
1、获取进程 winlogon.exe 的 pid
在我的测试系统中,进程 winlogon.exe 的 pid 为 504
2、启动 SelectMyParent
参数如下: SelectMyParent.exe calc.exe 504
显示 calc.exe 为 winlogon.exe 的子进程,如下图
该方法主要可以用来提高进程的隐蔽性,欺骗用户
特别的地方: 由于子进程会继承父进程的权限,并且 winlogon.exe 的权限为 system,那么其子进程 calc.exe 的权限也将会成为 system
如下图
也就是说,我们可以基于 SelectMyParent 实现以下提权和降权操作:
- 提权:从管理员权限到 system 权限
- 降权:从 system 权限到 admin 权限
- 降权:从 system 权限到普通用户权限
操作步骤:
1、获取进程 pid
cmd 下获取进程 pid 的方法: tasklist /v /fo list
可获取每个进程对应的 pid 及权限(用户名的值表示),如下图
为了方便测试,可以使用过滤将特定权限的进程筛选出来,例如筛选 NT AUTHORITY\SYSTEM
命令如下: tasklist /v /fo list /fi "USERNAME eq NT AUTHORITY\SYSTEM"
如果是获取普通用户权限的进程,筛选的 USERNAME 可设置为 whoami
的返回结果
2、使用 SelectMyParent.exe
从管理员权限到 system 权限:
上文已经演示,不再重复介绍
从 system 权限到 admin 权限:
通过 tasklist 无法区分进程是否是管理员权限还是普通用户权限
于是我通过 c++写了一个小工具,作用如下:
- 遍历进程
- 判断进程权限,如果为管理员权限,进行标记
工具使用如下图
从 system 权限到普通用户权限:
选取普通用户权限进程,pid 为 3864,创建的 calc.exe 权限也会具有普通用户权限,如下图
成功实现从 system 权限到普通用户权限的降权
0x05 小结
本文对常用降权方法进行测试,结论是有些条件下降权方法会失效,通用的方式是使用 SelectMyParent 进行降权。
结合实际,开源了遍历判断进程权限的小工具,用于提高效率。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论