Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement GetKerberoastableUsers in ldap module #4420

Merged
merged 2 commits into from
Jan 12, 2024

Conversation

5amu
Copy link
Contributor

@5amu 5amu commented Nov 26, 2023

Proposed changes

Closes #4419

With this change, a new method is exposed in the ldap module of the Javascript Protocol: GetKerberoastableUsers(). This method will return a slice of KerberoastableUser, containing important properties about the user in the context of Active Directory:

type KerberoastableUser struct {
	SAMAccountName       string
	ServicePrincipalName string
	PWDLastSet           string
	MemberOf             string
	UserAccountControl   string
	LastLogon            string
}

The filter used to make the LDAP query is almost the same as the one used in the Impacket example script GetUserSPNs.py, more precisely here:

https://github.com/fortra/impacket/blob/4b56c18a10663a62e36dfd872bcebd30aa24fb91/examples/GetUserSPNs.py#L297-L314

To test the correct implementation of this feature I set up an Active Directory (Domain: LAB.LOCAL) environment with 3 users: victim, roastme and pdtest2:

net user victim Trust_Me_Br0 /add /domain
net user roastme 123.qwe /add /domain
net user pdtest2 !Qazxsw2 /add /domain

And assigned 1 SPN to roastme and 1 SPN to pdtest2:

setspn -a DC01/ldap LAB\roastme
setspn -a DC01/cifs LAB\pdtest2

Then, I used this template:

id: ldap-list-kerberoastable-users-test

info:
  name: test
  author: 5amu
  severity: info

javascript:
  - args:
      DomainController: "{{Host}}"
    code: |
      ldap = require("nuclei/ldap");
      client = ldap.LdapClient();
      users = client.GetKerberoastableUsers(template.Domain, DomainController, template.Username, template.Password);
      to_json(users);
    extractors:
      - type: json
        json:
          - '.[]'

And executed nuclei like this:

go run cmd/nuclei/main.go -u 192.168.56.10 -var Username=victim -var Password=Trust_Me_Br0 -var Domain=LAB.LOCAL -t test.yaml

image

Checklist

  • Pull request is created against the dev branch
  • All checks passed (lint, unit/integration/regression tests etc.) with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Copy link
Member

@tarunKoyalwar tarunKoyalwar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ ./main -u 192.168.1.9 -var Username=victim -var Password=Trust_Me_Br0 -var Domain=LAB.LOCAL -var TargetUser=roastme -var SPN=DC01/cifs -t ldap.yaml -svd -v
                     __     _
   ____  __  _______/ /__  (_)
  / __ \/ / / / ___/ / _ \/ /
 / / / / /_/ / /__/ /  __/ /
/_/ /_/\__,_/\___/_/\___/_/   v3.1.0-dev
                projectdiscovery.io
[VER] Started metrics server at localhost:9092
[INF] Current nuclei version: v3.1.0-dev (outdated)
[INF] Current nuclei-templates version: v9.7.2 (latest)
[WRN] Scan results upload to cloud is disabled.
[INF] New templates added in latest release: 61
[INF] Templates loaded for current scan: 1
[WRN] Executing 1 unsigned templates. Use with caution.
[INF] Targets loaded for current scan: 1
[DBG] Javascript Protocol request variables: 
        1. DN => 1
        2. Domain => LAB.LOCAL
        3. FQDN => 192.168.1.9
        4. Host => 192.168.1.9
        5. Hostname => 192.168.1.9
        6. Password => Trust_Me_Br0
        7. Port => 
        8. RDN => 1.9
        9. SD => 192.168
        10. SPN => DC01/cifs
        11. TLD => 9
        12. TargetUser => roastme
        13. Username => victim
[VER] [ldap-list-kerberoastable-users-test] Sent Javascript request to 192.168.1.9
[DBG] Javascript Protocol response variables: 
        1. DN => 1
        2. Domain => LAB.LOCAL
        3. FQDN => 192.168.1.9
        4. Host => 192.168.1.9
        5. Hostname => 192.168.1.9
        6. Password => Trust_Me_Br0
        7. Port => 
        8. RDN => 1.9
        9. SD => 192.168
        10. SPN => DC01/cifs
        11. TLD => 9
        12. TargetUser => roastme
        13. Username => victim
        14. host => 192.168.1.9
        15. interactsh-server => 
        16. matched => 192.168.1.9
        17. request => ldap = require("nuclei/ld .... assword); to_json(users);
        18. response => [   {     "SAMAccountName ....    "LastLogon": "0"   } ]
        19. success => true
        20. template-id => ldap-list-kerberoastable-users-test
        21. template-info => {test 5amu    <nil> {info} map[] <nil> }
        22. template-path => /root/Desktop/nuclei-ldap .... oast/cmd/nuclei/ldap.yaml
        23. type => javascript
[ldap-list-kerberoastable-users-test] [javascript] [info] 192.168.1.9 [{"LastLogon":"0","MemberOf":"","PWDLastSet":"133494763976954590","SAMAccountName":"pdtest2","ServicePrincipalName":"DC01/cifs","UserAccountControl":"512"},{"LastLogon":"0","MemberOf":"","PWDLastSet":"133494763897554325","SAMAccountName":"roastme","ServicePrincipalName":"DC01/ldap","UserAccountControl":"512"}] 

thanks for pr @5amu , apologies for time it took to review and merge your pr . i don't have a windows machine so it took some time to setup and validate it .

rest assured we are in process of iterating all added modules with new and basic features which might be missing starting from smb

@ehsandeep ehsandeep merged commit edae2f4 into projectdiscovery:dev Jan 12, 2024
12 checks passed
@5amu
Copy link
Contributor Author

5amu commented Jan 14, 2024

Hi @tarunKoyalwar, you said:

rest assured we are in process of iterating all added modules with new and basic features which might be missing starting from smb

I implemented many basic (and not so basic) functionalities for LDAP (the Active Directory one) in a personal project, would you be interested in adding those to nuclei? I can help.

I implemented:

  • An authentication method that uses NTLM binding and falls back to username-password if that fails, as well as Unauthenticated binding
  • A generic method to query any object given a filter
  • Enumeration of accounts and objects that:
    • Are trusted for delegation
    • Don't require passwords
    • Are active users
    • Are users
    • Are groups
    • Are Domain Controllers
    • Have never expiring passwords
    • Are administrators
  • A method to retrieve the domain SID

Let me know if you are interested please. I'd be glad to help.

@tarunKoyalwar
Copy link
Member

@5amu , sure we are interested and appreciate your contribution and help on this . I have created new issue #4645 for that , just create a draft PR in nuclei with proposed changes and we can improve/review/add capabilities of ldap module. since i have a setup now and i will try to keep up with changes and review it quickly

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add method for ldap module to list kerberoastable users
3 participants