Security

Recursivly expanding ADMon groups to get members

rtadams89
Contributor

I have a search which returns a list of groups and their members from the data provided by ADMon. The members include user objects, as well as other group objects. By using a selfjoin, I can expand this sub group and link its members with the top level group. However, I have not figured out a way to traverse an arbitrary number of nested groups. Any ideas?

Tags (3)
0 Karma
1 Solution

rtadams89
Contributor

I have found a solution that will work with up to 4 levels of nesting (and can be expanded to work with up to X levels). I have setup up two lookup table generating scheduled searches.

The first search runs at *:20:00 and *:50:00.

index=activedirectory source="admon" objectClass="top|group" earliest="10/28/2012:0:0:0" | dedup objectSid | eval members=split(member, "|") | mvexpand members | eval member=replace(members, "CN=", "") | eval member=replace(member, ",OU=.*", "") | table sAMAccountName, member | outputlookup ADGroupMembership1.csv

The second search runs at *:25:00 and *:55:00 (5 minutes after search #1).

| inputlookup ADGroupMembership1.csv | eval topGroup=sAMAccountName | table topGroup, sAMAccountName, member | eval joinOn=lower(member) | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | table topGroup, member | outputlookup ADGroupMembershipExpanded.csv

After this second search runs, a lookup table is created. The table has two columns/fields: "topGroup" and "member". If you wanted to see all of the users who are members of the group "Domain Admins" (through up to 4 levels of group nesting), you simply run this search:

| inputlookup ADGroupMembershipExpanded.csv | search topGroup="Domain Admins"

If you have more than 4 levels of nesting in your environment, you can modify search #2 to include additional instances of:

join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member

View solution in original post

ahall_splunk
Splunk Employee
Splunk Employee

You can also download the SA-ldapsearch app that does this for you.

0 Karma

rtadams89
Contributor

I have found a solution that will work with up to 4 levels of nesting (and can be expanded to work with up to X levels). I have setup up two lookup table generating scheduled searches.

The first search runs at *:20:00 and *:50:00.

index=activedirectory source="admon" objectClass="top|group" earliest="10/28/2012:0:0:0" | dedup objectSid | eval members=split(member, "|") | mvexpand members | eval member=replace(members, "CN=", "") | eval member=replace(member, ",OU=.*", "") | table sAMAccountName, member | outputlookup ADGroupMembership1.csv

The second search runs at *:25:00 and *:55:00 (5 minutes after search #1).

| inputlookup ADGroupMembership1.csv | eval topGroup=sAMAccountName | table topGroup, sAMAccountName, member | eval joinOn=lower(member) | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member | table topGroup, member | outputlookup ADGroupMembershipExpanded.csv

After this second search runs, a lookup table is created. The table has two columns/fields: "topGroup" and "member". If you wanted to see all of the users who are members of the group "Domain Admins" (through up to 4 levels of group nesting), you simply run this search:

| inputlookup ADGroupMembershipExpanded.csv | search topGroup="Domain Admins"

If you have more than 4 levels of nesting in your environment, you can modify search #2 to include additional instances of:

join max=100 type=outer joinOn [| inputlookup ADGroupMembership1.csv | eval joinOn=lower(sAMAccountName)] | dedup topGroup, member

Rob
Splunk Employee
Splunk Employee

You may want to create an additional field at index time that can be used as a reference in your searches to determine the how "deep' to traverse the user groups, etc.

0 Karma

rtadams89
Contributor

It was nice meeting with you at .conf2012, and I appreciate the effort you put into this. However, after reviewing it, I'm not sure how your suggestion would be accomplished.

AD memebrships are tree like in structure. So for example I might have these events:

"Group: A; Members: Group B, Group X;"
"Group: B; Members: Group C;"
"Group: C; Members: RTAdams89, Group Y;

Because of the nesting, Groups "B", "X", "C", and "Y" and user "RTAdams89" are all members of group "A".

If I were to write a script to determine the depth, I might as well just have the script expand all the members.

0 Karma

psobisch
Path Finder

I have the same problem and I'm looking for appropriate solution.

0 Karma

rtadams89
Contributor

Anyone have ideas here?

0 Karma
Get Updates on the Splunk Community!

Introducing the 2024 SplunkTrust!

Hello, Splunk Community! We are beyond thrilled to announce our newest group of SplunkTrust members!  The ...

Introducing the 2024 Splunk MVPs!

We are excited to announce the 2024 cohort of the Splunk MVP program. Splunk MVPs are passionate members of ...

Splunk Custom Visualizations App End of Life

The Splunk Custom Visualizations apps End of Life for SimpleXML will reach end of support on Dec 21, 2024, ...