Skip to content

Commit 5ac5f18

Browse files
author
Domwhewell
authored
Added the source and compiled version
0 parents  commit 5ac5f18

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

enum4linux_parse.exe

2.43 MB
Binary file not shown.

main.go

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"io/ioutil"
7+
"regexp"
8+
"strings"
9+
)
10+
11+
var recurse bool
12+
var file_name string
13+
var username string
14+
var group_name string
15+
16+
var help = fmt.Sprint("This script will recursively lookup groups or users in an active directory environment from the enum4linux groups output.\n- For example 'user1' is a member of \x1b[31m'IT Support'\x1b[0m which is itself a member of \x1b[31m'Domain Admins'\x1b[0m making 'user1' effectively a domain admin.\nThis script will colour code the output so \x1b[31m'Groups'\x1b[0m are always highlighted as \x1b[31mred\x1b[0m to make them easier to make out.\n")
17+
18+
func groups(groupsRaw, username, groupName string, recurse bool) {
19+
fmt.Println(help)
20+
21+
// Obtain a list of group names
22+
group_lines := regexp.MustCompile(`\x1b?(?:\^\[)?(?:\[[0-9;]*m)?group:\[(.+?)\] rid:\[.+?\]`).FindAllStringSubmatch(groupsRaw, -1)
23+
groups := []string{}
24+
for _, match := range group_lines {
25+
groups = append(groups, match[1])
26+
}
27+
28+
if groupName != "" {
29+
// If the domain is included in the group name, remove it.
30+
if strings.Contains(groupName, "\\") {
31+
groupName = strings.Split(groupName, "\\")[1]
32+
}
33+
34+
groupMembers(groupName, groups, groupsRaw)
35+
} else if username != "" {
36+
// If the domain is included in the username, remove it.
37+
if strings.Contains(username, "\\") {
38+
username = strings.Split(username, "\\")[1]
39+
}
40+
41+
membersOfGroup(username, groupsRaw, groups)
42+
} else {
43+
fmt.Println("\x1b[31m[!]\x1b[0m Error you did not specify a group_name or username")
44+
}
45+
}
46+
47+
func groupMembers(groupName string, groups []string, groupsRaw string) {
48+
fmt.Println("\x1b[32m[!]\x1b[0m Members of group: \x1b[31m" + groupName + "\x1b[0m")
49+
var name string
50+
var group_names []string
51+
members_of_group := regexp.MustCompile(`\x1b?(?:\^\[)?(?:\[[0-9;]*m)?Group: \x1b?(?:\^\[)?(?:\[[0-9;]*m)?\'?`+groupName+`\'? \(RID\: \d+\) has member\: (.+)`).FindAllStringSubmatch(groupsRaw, -1)
52+
for _, member := range members_of_group {
53+
if strings.Contains(member[1], "\\") {
54+
name = strings.Split(member[1], "\\")[1]
55+
} else {
56+
name = member[1]
57+
}
58+
if contains(groups, name) {
59+
if !contains(group_names, name) {
60+
group_names = append(group_names, name)
61+
}
62+
} else {
63+
fmt.Println(name)
64+
}
65+
if recurse {
66+
for _, group := range group_names {
67+
fmt.Println("\x1b[32m[!]\x1b[0m\x1b[31m " + group + "\x1b[0m is a member of \x1b[31m" + group_name + "\x1b[0m")
68+
groupMembers(group, groups, groupsRaw)
69+
}
70+
}
71+
}
72+
}
73+
74+
func membersOfGroup(username, groupsRaw string, groups []string) {
75+
groupsUserIsAMemberOf := regexp.MustCompile(`(?m)\x1b?(?:\^\[)?(?:\[[0-9;]*m)?Group\:? \x1b?(?:\^\[)?(?:\[[0-9;]*m)?\'?(.+?)\'? \(RID\: \d+\) has member\: .+\\`+username+`$`).FindAllStringSubmatch(groupsRaw, -1)
76+
for _, member_group := range groupsUserIsAMemberOf {
77+
// Check if this variable is a group name or a username so we can colour code them differently
78+
var member_of string
79+
if contains(groups, member_group[1]) {
80+
member_of = fmt.Sprint("\x1b[31m" + member_group[1] + "\x1b[0m")
81+
} else {
82+
member_of = member_group[1]
83+
}
84+
85+
// Check if this variable is a group name or a username so we can colour code them differently
86+
var member string
87+
if contains(groups, username) {
88+
member = fmt.Sprint("\x1b[31m" + username + "\x1b[0m")
89+
} else {
90+
member = username
91+
}
92+
fmt.Println(member + " is a member of " + member_of)
93+
if recurse {
94+
membersOfGroup(member_group[1], groupsRaw, groups)
95+
}
96+
}
97+
}
98+
99+
func contains(x []string, s string) bool {
100+
for _, v := range x {
101+
if v == s {
102+
return true
103+
}
104+
}
105+
return false
106+
}
107+
108+
func main() {
109+
// grab some arguments from the command line
110+
flag.BoolVar(&recurse, "recurse", true, "Disable recursive search")
111+
flag.StringVar(&file_name, "file", "", "Set the `enum4linux -G` file to read from")
112+
flag.StringVar(&username, "username", "", "Set the username to search for")
113+
flag.StringVar(&group_name, "group_name", "", "Set the groupname to search for")
114+
flag.Parse()
115+
116+
if file_name != "" {
117+
data, err := ioutil.ReadFile(file_name)
118+
if err != nil {
119+
fmt.Println(err)
120+
return
121+
}
122+
// Convert the buffer to a string.
123+
groups_raw := string(data)
124+
125+
groups(groups_raw, username, group_name, recurse)
126+
} else {
127+
fmt.Println(help)
128+
flag.Usage()
129+
fmt.Println()
130+
fmt.Println("\x1b[31m[!]\x1b[0m Error you must specify the 'enum4linux -G' output file to load.")
131+
}
132+
}

0 commit comments

Comments
 (0)