Fixed issues #1 & #2
1 parent 2e6a41c commit 5e71e8f467eca0fd056bb5528906270ae1dfab25
root authored on 21 Feb 2022
Showing 7 changed files
View
LdapUsrEnum-linux-386
Not supported
View
LdapUsrEnum-linux-amd64
Not supported
View
LdapUsrEnum-windows-386.exe
Not supported
View
LdapUsrEnum-windows-amd64.exe
Not supported
View
49
LdapUsrEnum.go
 
 
// SEARCH FOR USERNAME'S "sAMAccountName" (basic test)
// Filters must start and finish with ()!
fmt.Print("[+] query to get account username... ")
fmt.Print("[+] query shortname to get account username... ")
DCQueryName := baseDN
var mainUser string = ""
filter := fmt.Sprintf("(CN=%s)", ldap.EscapeFilter(*username))
searchReq := ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName","distinguishedName", "primaryGroupID"}, []ldap.Control{})
searchReq := ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName","distinguishedName", "primaryGroupID"}, []ldap.Control{})
result, err := l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
fmt.Print("[+] query full domain to get account username... ")
DCQueryName = *domain
filter = fmt.Sprintf("(CN=%s)", ldap.EscapeFilter(*username))
searchReq = ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName","distinguishedName", "primaryGroupID"}, []ldap.Control{})
result, err = l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
}
}
if len(result.Entries) == 0{
fmt.Println("[-] user can't query LDAP")
os.Exit(1)
mainUser = entry.GetAttributeValue("sAMAccountName")
}
fmt.Println( mainUser )
//result.PrettyPrint(2)
//os.Exit(1)
 
// SEARCH FOR ALL UERNAME'S
fmt.Print("[+] ALL usernames... ")
filter = fmt.Sprintf("(&(objectCategory=person)(objectClass=user)(SamAccountName=*))")
searchReq = ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName", "whenCreated", "whenChanged", "lastLogon",}, []ldap.Control{})
searchReq = ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName", "whenCreated", "whenChanged", "lastLogon","description"}, []ldap.Control{})
result, err = l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
var foundUsers []string
var foundUCreated []string
var foundUChanged []string
var foundULogon []string
var foundUDesc []string
for _, entry := range result.Entries {
//fmt.Printf("%s: %v\n", entry.GetAttributeValues("memberOf"), entry.GetAttributeValue("sAMAccountName"))
foundUsers = append(foundUsers, entry.GetAttributeValue("sAMAccountName") )
foundUCreated = append(foundUCreated, entry.GetAttributeValue("whenCreated") )
foundUChanged = append(foundUChanged, entry.GetAttributeValue("whenChanged") )
foundULogon = append(foundULogon, entry.GetAttributeValue("lastLogon") )
foundUDesc = append(foundUDesc, entry.GetAttributeValue("description") )
}
 
// SEARCH FOR ALL LOCKED OUT ACCOUNTS
fmt.Print("[+] locked accounts... ")
filter = fmt.Sprintf("(&(sAMAccountType=805306368)(lockoutTime>=1))")
searchReq = ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
searchReq = ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
result, err = l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
 
// SEARCH FOR ALL DISABLED ACCOUNTS
fmt.Print("[+] disabled accounts... ")
filter = fmt.Sprintf("(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=2))")
searchReq = ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
searchReq = ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
result, err = l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
 
// SEARCH FOR ALL PASSWORD NEVER EXPIRE
fmt.Print("[+] non-expire passwords... ")
filter = fmt.Sprintf("(&(samAccountType=805306368)(|(UserAccountControl:1.2.840.113556.1.4.803:=65536)(msDS-UserDontExpirePassword=TRUE)))")
searchReq = ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
searchReq = ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
result, err = l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
// SEARCH FOR ALL groups NOT "Default users" (rid 513)
fmt.Print("[+] groups... ")
filter = fmt.Sprintf("(&(objectCategory=group)(objectClass=group))")
//filter = fmt.Sprintf("(&(CN=\"Administrator\"))")
searchReq = ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"objectCategory", "sAMAccountName", "distinguishedName"}, []ldap.Control{})
searchReq = ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"objectCategory", "sAMAccountName", "distinguishedName"}, []ldap.Control{})
result, err = l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
for _, entry := range result.Entries {
 
// Search for all users of that group
filter = fmt.Sprintf("(&(objectCategory=person)(objectClass=user)(SamAccountName=*)(memberOf:1.2.840.113556.1.4.1941:=%v))", strings.Trim(entry.GetAttributeValue("distinguishedName"), "\t \n" ))
searchReq2 := ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
searchReq2 := ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
result2, err := l.Search(searchReq2)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
}
 
// All users of Default Group (RID 513)
filter = fmt.Sprintf("(&(objectCategory=person)(objectClass=user)(primaryGroupID=513))")
searchReq2 := ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
searchReq2 := ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"sAMAccountName"}, []ldap.Control{})
result2, err := l.Search(searchReq2)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
 
// SEARCH FOR PASSWORD POLICY
fmt.Println("[+] password policy ")
filter = fmt.Sprintf("(objectClass=domainDNS)")
searchReq = ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"minPwdLength","minPwdAge","maxPwdAge","pwdHistoryLength","lockoutThreshold","lockoutDuration","lockOutObservationWindow"}, []ldap.Control{})
searchReq = ldap.NewSearchRequest(DCQueryName, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{"minPwdLength","minPwdAge","maxPwdAge","pwdHistoryLength","lockoutThreshold","lockoutDuration","lockOutObservationWindow"}, []ldap.Control{})
result, err = l.Search(searchReq)
if err != nil {
fmt.Println("[-] failed to query LDAP: %w", err)
os.Exit(1)
fmt.Printf(" (%v)\n", ldapDiff(lasLog) )
}else{
fmt.Println(" Never Logged In")
}
lasDesc := foundUDesc[i]
if lasDesc != "" {
fmt.Printf(" (Desc: %v)\n", lasDesc )
}
}
fmt.Println("--- to try (ALL) ---")
toTry := ""
for i := 0; i < len(foundUsers); i++ {
View
108
README.md
-g will display a list of the groups with users in the corresponding group.
 
comma seperated list of all users except one used to scan with at end, or list of all users in groups that user used is not a member of.. for easy pasting into brute-force tools.
![LdapUsrEnum Screenshot](https://rossmarks.uk/git/0xRoM/LdapUsrEnum/raw/master/LdapUsrEnum_Screenshot.png)
```
╰» ./LdapUsrEnum-linux-amd64 -d 192.168.69.13 -w -redacted- -u Reno -p -redacted-
[i] DC/AD: 192.168.69.13
[i] domain: -redacted-
[!] trying plaintext auth
[+] using: CN=Reno,DC=-redacted-,DC=-redacted-
[!] trying to connect with supplied password
[+] query shortname to get account username... Reno
[+] ALL usernames... 10
[+] locked accounts... 0
[+] disabled accounts... 3
[+] non-expire passwords... 9
[+] groups... 51
[+] Matching users to groups.. this could take a while!
[+] password policy
--- pwd pol ---
minPwdLength: 7
minPwdAge: -864000000000
maxPwdAge: 42
pwdHistoryLength: 24
lockoutThreshold: 0
lockoutDuration: 30
lockOutObservationWindow: 30
--- results ---
Administrator PassNevExp
2022-02-21 09:52:35 (0 day(s) 00:22:24)
(Desc: Built-in account for administering the computer/domain)
Guest Disabled PassNevExp
Never Logged In
(Desc: Built-in account for guest access to the computer/domain)
krbtgt Disabled
Never Logged In
(Desc: Key Distribution Center Service Account)
Reno PassNevExp
2022-02-17 09:05:41 (4 day(s) 01:09:18)
T.Holt Disabled PassNevExp
Never Logged In
pfSense PassNevExp
2021-08-17 12:00:17 (188 day(s) 23:14:42)
r.marks PassNevExp
2022-02-21 05:23:05 (0 day(s) 04:51:54)
Rude PassNevExp
2021-08-17 15:35:04 (188 day(s) 19:39:55)
Cissnei PassNevExp
2021-08-17 15:56:36 (188 day(s) 19:18:23)
(Desc: -redacted-)
Elena PassNevExp
2021-08-17 15:56:36 (188 day(s) 19:18:23)
--- to try (ALL) ---
Administrator, pfSense, r.marks, Rude, Cissnei, Elena
--- to try (Diff Group) ---
Administrator, pfSense, r.marks
 
```
View
2
■■■
go.mod 100755 → 100644
go 1.16
 
require (
github.com/akamensky/argparse v1.3.1
github.com/go-ldap/ldap/v3 v3.3.0 // indirect
github.com/go-ldap/ldap/v3 v3.3.0
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/ldap.v2 v2.5.1 // indirect
)
Buy Me A Coffee