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\configsystemprofile\AppDataRoaming 管理员权限下,查询到的环境变量APPDATA为C:\Usersa\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:%sn",szPath); if(memcmp(szPath,flag,strlen(flag))==0) printf("[+]I'm System Privilegen"); else printf("[-]Not System Privilegen"); } 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 [url=]http://www.verydoc.com/exeshell.html[/url] cmd: lsrunas.exe /user:a /password:123456 /domain: /command:"calc.exe" /runpath:c: 注: /domain:参数为空表示为本机 从管理员权限降权到普通用户权限,成功,如下图 3、第三方工具:CPAU
下载地址可参考我的github: [url=]https://github.com/3gstudent/From-System-authority-to-Medium-authority[/url] cmd: CPAU.exe -u a -p 123456 -ex "calc.exe" -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 代码地址: [url=]https://github.com/3gstudent/From-System-authority-to-Medium-authority/blob/master/SelectMyParent.cpp[/url] 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 AUTHORITYSYSTEM 命令如下: tasklist /v /fo list /fi "USERNAME eq NT AUTHORITYSYSTEM" 如果是获取普通用户权限的进程,筛选的USERNAME可设置为whoami的返回结果 2、使用SelectMyParent.exe 从管理员权限到system权限: 上文已经演示,不再重复介绍 从system权限到admin权限: 通过tasklist无法区分进程是否是管理员权限还是普通用户权限 于是我通过c++写了一个小工具,作用如下: 遍历进程 判断进程权限,如果为管理员权限,进行标记 代码下载地址: [url=]https://github.com/3gstudent/From-System-authority-to-Medium-authority/blob/master/Processauthority.cpp[/url] 工具使用如下图 从system权限到普通用户权限:
选取普通用户权限进程,pid为3864,创建的calc.exe权限也会具有普通用户权限,如下图 成功实现从system权限到普通用户权限的降权
0x05 小结 本文对常用降权方法进行测试,结论是有些条件下降权方法会失效,通用的方式是使用SelectMyParent进行降权。 结合实际,开源了遍历判断进程权限的小工具,用于提高效率。
|