Detection rules › Splunk

Rubeus Password Change (Windows Event Log)

Group by
_time, host
Source
github.com/anvilogic-forge/armory

The changepw module will take a user's TGT .kirbi blog and execute a MS kpasswd password change with the specified /new:PASSWORD value. If a /dc is not specified, the computer's current domain controller is extracted and used as the destination for the password reset traffic. This is the Aorato Kerberos password reset disclosed in 2014, and is equivalent to Kekeo's misc::changepw function.

MITRE ATT&CK coverage

TacticTechniques
Initial AccessT1078 Valid Accounts
PersistenceT1078 Valid Accounts
Privilege EscalationT1078 Valid Accounts
StealthT1078 Valid Accounts
Credential AccessT1558 Steal or Forge Kerberos Tickets

References

Event coverage

Rule body yaml

id: '5471.5637'
title: Rubeus Password Change
description: The changepw module will take a user's TGT .kirbi blog and execute a
  MS kpasswd password change with the specified /new:PASSWORD value. If a /dc is not
  specified, the computer's current domain controller is extracted and used as the
  destination for the password reset traffic. This is the Aorato Kerberos password
  reset disclosed in 2014, and is equivalent to Kekeo's misc::changepw function.
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_winevent` ((TERM(EventCode=4738) OR
  "<EventID>4738<") TERM(ANONYMOUS) TERM(LOGON) ) OR (TERM(EventCode=4723) OR "<EventID>4723<")
  | eval user=mvappend(coi_user, user) | table _time, host, user, signature_id, session_id,
  signature | bin span=5s | stats values(*) as * by _time, host | where match(signature_id,
  "4738") AND match(signature_id, "4723") '
techniques:
- persistence:valid accounts
- privilege-escalation:valid accounts
- defense-evasion:valid accounts
- credential-access:steal or forge kerberos tickets
technique_id: 
- T1078
- T1558
data_category:
- Windows event logs
references:
- https://github.com/GhostPack/Rubeus/blob/master/Rubeus/Commands/Changepw.cs

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_winevent` ((TERM(EventCode=4738) OR "<EventID>4738<") TERM(ANONYMOUS) TERM(LOGON) ) OR (TERM(EventCode=4723) OR "<EventID>4723<")

Stage 2: eval

| eval user=mvappend(coi_user, user)

Stage 3: table

| table _time, host, user, signature_id, session_id, signature

Stage 4: bucket

| bin span=5s

Stage 5: stats

| stats values(*) as * by _time, host

Stage 6: where

| where match(signature_id, "4738") AND match(signature_id, "4723")

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
EventCodeeq
  • 4723 corpus 2 (splunk 1, kusto 1)
  • 4738 corpus 6 (splunk 4, elastic 1, kusto 1)
signature_idmatch
  • "4723"
  • "4738"

Search terms

Bare-string tokens in the SPL search body. Splunk matches each token against _raw (the untyped raw event text) anywhere it appears, not against a specific field. These don't surface in the Indicators table because they aren't predicates on a known field.

StageTerm
1TERM
1"<EventID>4738<"
1TERM
1ANONYMOUS
1TERM
1LOGON
1TERM
1"<EventID>4723<"