Skip to content

Commit 1305195

Browse files
committed
Handling client disconnections and adding static filter for sorted fuzzer
This commit includes fixes for better handling disconnected clients, by trying to reconnect them. For the sorted fuzzer, a static filter for methods containing "close" was implemented, because these methods likely close the context handle and cause the rest of the procedure calls to fail that take the context handle as input parameter. Finally, a bug was fixed that the endpoint for ncacn_tcp was not included when a interface supports both ncalrpc and ncacn_tcp, GetRpcData.
1 parent f000fb7 commit 1305195

3 files changed

Lines changed: 148 additions & 23 deletions

File tree

source/DefaultFuzzer.ps1

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,8 @@ function Invoke-DefaultFuzzer {
143143
# Loop over all stringbindings for the RPC interface
144144
foreach ($stringbinding in $stringBindings) {
145145
# Connect the RPC client
146-
try {
147-
Connect-RpcClient -client $client -stringBinding $stringbinding -AuthenticationLevel PacketPrivacy -AuthenticationType WinNT
148-
} catch {
149-
try {
150-
Connect-RpcClient -client $client -stringBinding $stringbinding
151-
} catch {
152-
Write-Verbose "[!] Could not connect client to $stringbinding : $_"
153-
}
154-
}
146+
Connect-Client -client $client -stringbinding $stringbinding
147+
155148
# Get methods for the RPC interface
156149
if ($Procedure) {
157150
# User only wants to fuzz one specific procedure
@@ -280,6 +273,43 @@ function Invoke-DefaultFuzzer {
280273
-Service $service `
281274
-FuzzInput $inputResult `
282275
-OutPath $OutPath `
276+
} elseif ($_ -match "not connected") {
277+
# Try to reconnect the RPC client
278+
Connect-Client -client $client -stringbinding $stringbinding
279+
280+
# Also write error message to results
281+
$Errormessage = $_ -replace '"', ''
282+
$Endpoint = $Client.Endpoint.ToString()
283+
$Endpoint = $Endpoint.replace("\u", "*u")
284+
Export-ErrorFuzzedInput -MethodName $methodName `
285+
-RpcServerName $rpcServerName `
286+
-RpcInterface $Client.InterfaceId.Uuid `
287+
-Endpoint $Endpoint `
288+
-ProcedureName $procedureName `
289+
-MethodDefinition $methodDefinition `
290+
-Service $service `
291+
-FuzzInput $inputResult `
292+
-Errormessage $Errormessage `
293+
-OutPath $OutPath `
294+
} elseif ($_ -match "pipe is in the disconnected state") {
295+
# Disconnect client and reconnect
296+
Disconnect-RpcClient $client
297+
Connect-Client -client $client -stringbinding $stringbinding
298+
299+
# Also write error message to results
300+
$Errormessage = $_ -replace '"', ''
301+
$Endpoint = $Client.Endpoint.ToString()
302+
$Endpoint = $Endpoint.replace("\u", "*u")
303+
Export-ErrorFuzzedInput -MethodName $methodName `
304+
-RpcServerName $rpcServerName `
305+
-RpcInterface $Client.InterfaceId.Uuid `
306+
-Endpoint $Endpoint `
307+
-ProcedureName $procedureName `
308+
-MethodDefinition $methodDefinition `
309+
-Service $service `
310+
-FuzzInput $inputResult `
311+
-Errormessage $Errormessage `
312+
-OutPath $OutPath `
283313
} else {
284314
# Error is not access denied, so we assume our input caused the server to send a error
285315
$Errormessage = $_ -replace '"', ''
@@ -302,10 +332,40 @@ function Invoke-DefaultFuzzer {
302332
Write-Verbose "[!] Failed to invoke method $($Method.Name) on client $($Client.Endpoint)"
303333
}
304334
}
305-
Disconnect-RpcClient $client
335+
try {
336+
Disconnect-RpcClient $client
337+
} catch {
338+
Write-Verbose "[!] RPC client already disconnected for $($Client.Endpoint)"
339+
}
306340
}
307341
}
308342
}
309343
Write-Host "[+] Completed fuzzing" -ForegroundColor Green
310344
Write-Host "[+] To load data into Neo4j use: '.\output\Allowed.json' | Import-DatatoNeo4j -Neo4jHost '127.0.0.1:7474' -Neo4jUsername 'neo4j'" -ForegroundColor Green
311345
}
346+
347+
<#
348+
.SYNOPSIS
349+
Connect the RPC client with a string binding
350+
.DESCRIPTION
351+
This function connects a RPC client to a string binding
352+
.PARAMETER Client
353+
The RPC client to connect
354+
.PARAMETER stringBinding
355+
The string binding to connect the RPC client to
356+
#>
357+
function Connect-Client {
358+
param (
359+
$client,
360+
$stringBinding
361+
)
362+
try {
363+
Connect-RpcClient -client $client -stringBinding $stringbinding -AuthenticationLevel PacketPrivacy -AuthenticationType WinNT
364+
} catch {
365+
try {
366+
Connect-RpcClient -client $client -stringBinding $stringbinding
367+
} catch {
368+
Write-Verbose "[!] Could not connect client to $stringbinding : $_"
369+
}
370+
}
371+
}

source/GetRpcData.ps1

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,12 @@ function Get-RpcServerData {
167167
foreach ($endpoint in $endpoints) {
168168
try {
169169
$client = Get-RpcClient $rpcInt
170-
170+
171+
# Check if it's a 'ncacn_ip_tcp' endpoint and try to connect
172+
if ($endpoint -match 'ncacn_ip_tcp') {
173+
$stringBindings += $endpoint
174+
}
175+
171176
# Check if it's a 'ncacn_np' endpoint and try to connect
172177
if ($endpoint -match 'ncacn_np') {
173178
try {
@@ -182,7 +187,7 @@ function Get-RpcServerData {
182187
# Still no endpoint found but the mode is remote? Then just see if we can connect to it using random named pipes (works for example with PetitPotam)
183188
$pipeNames = (Get-ChildItem \\.\pipe\) | Where-Object { $_.Name -match '^[a-zA-Z0-9_]+$' } | Select-Object -ExpandProperty Name
184189

185-
foreach ($name in $pipeNames) {
190+
foreach ($name in $pipeNames | Where-Object { $_ -ne "MGMTAPI" }) {
186191
try {
187192
$StringBinding = "ncacn_np:127.0.0.1[\\pipe\\$name]"
188193
Connect-RpcClient $client `

source/SortedFuzzer.ps1

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,8 @@ function Invoke-SortedFuzzer {
150150
# Loop over all stringbindings for the RPC interface
151151
foreach ($stringbinding in $stringBindings) {
152152
# Connect the RPC client
153-
try {
154-
Connect-RpcClient -client $client -stringBinding $stringbinding -AuthenticationLevel PacketPrivacy -AuthenticationType WinNT
155-
} catch {
156-
try {
157-
Connect-RpcClient -client $client -stringBinding $stringbinding
158-
} catch {
159-
Write-Verbose "[!] Could not connect client to $stringbinding : $_"
160-
}
161-
}
153+
Connect-Client -client $client -stringbinding $stringbinding
154+
162155
# Get methods for the RPC interface
163156
if ($Procedure) {
164157
# User only wants to fuzz one specific procedure
@@ -224,7 +217,7 @@ function Invoke-SortedFuzzer {
224217
$invokeParams = $params | ForEach-Object { $_.Value }
225218

226219
# Check if procedure in blacklist, if so do not execute
227-
if ($Blacklist -notcontains $ProcedureName) {
220+
if ($Blacklist -notcontains $ProcedureName -and $ProcedureName -notmatch "close") {
228221
# Log before making the RPC call
229222
$logEntry = "RPCserver: $rpcServerName `nInterface: $RpcInterface `nProcedure: $procedureName`nParams: $inputResult`n------------------------`n"
230223
$logFilePath = "$OutPath\log.txt"
@@ -310,6 +303,43 @@ function Invoke-SortedFuzzer {
310303
-Service $service `
311304
-FuzzInput $inputResult `
312305
-OutPath $OutPath `
306+
} elseif ($_ -match "not connected") {
307+
# Try to reconnect the RPC client
308+
Connect-Client -client $client -stringbinding $stringbinding
309+
310+
# Also write error message to results
311+
$Errormessage = $_ -replace '"', ''
312+
$Endpoint = $Client.Endpoint.ToString()
313+
$Endpoint = $Endpoint.replace("\u", "*u")
314+
Export-ErrorFuzzedInput -MethodName $methodName `
315+
-RpcServerName $rpcServerName `
316+
-RpcInterface $Client.InterfaceId.Uuid `
317+
-Endpoint $Endpoint `
318+
-ProcedureName $procedureName `
319+
-MethodDefinition $methodDefinition `
320+
-Service $service `
321+
-FuzzInput $inputResult `
322+
-Errormessage $Errormessage `
323+
-OutPath $OutPath `
324+
} elseif ($_ -match "pipe is in the disconnected state") {
325+
# Disconnect client and reconnect
326+
Disconnect-RpcClient $client
327+
Connect-Client -client $client -stringbinding $stringbinding
328+
329+
# Also write error message to results
330+
$Errormessage = $_ -replace '"', ''
331+
$Endpoint = $Client.Endpoint.ToString()
332+
$Endpoint = $Endpoint.replace("\u", "*u")
333+
Export-ErrorFuzzedInput -MethodName $methodName `
334+
-RpcServerName $rpcServerName `
335+
-RpcInterface $Client.InterfaceId.Uuid `
336+
-Endpoint $Endpoint `
337+
-ProcedureName $procedureName `
338+
-MethodDefinition $methodDefinition `
339+
-Service $service `
340+
-FuzzInput $inputResult `
341+
-Errormessage $Errormessage `
342+
-OutPath $OutPath `
313343
} else {
314344
# Error is not access denied, so we assume our input caused the server to send a error
315345
$Errormessage = $_ -replace '"', ''
@@ -332,7 +362,11 @@ function Invoke-SortedFuzzer {
332362
Write-Verbose "[!] Failed to invoke method $($Method.Name) on client $($Client.Endpoint)"
333363
}
334364
}
335-
Disconnect-RpcClient $client
365+
try {
366+
Disconnect-RpcClient $client
367+
} catch {
368+
Write-Verbose "[!] RPC client already disconnected for $($Client.Endpoint)"
369+
}
336370
}
337371
# Clear the list of stored parameters for the current interface after all stringbindings are fuzzed
338372
# This ensures that complex parameters are specific to each interface.
@@ -342,3 +376,29 @@ function Invoke-SortedFuzzer {
342376
Write-Host "[+] Completed fuzzing" -ForegroundColor Green
343377
Write-Host "[+] To load data into Neo4j use: '.\output\Allowed.json' | Import-DatatoNeo4j -Neo4jHost '127.0.0.1:7474' -Neo4jUsername 'neo4j'" -ForegroundColor Green
344378
}
379+
380+
<#
381+
.SYNOPSIS
382+
Connect the RPC client with a string binding
383+
.DESCRIPTION
384+
This function connects a RPC client to a string binding
385+
.PARAMETER Client
386+
The RPC client to connect
387+
.PARAMETER stringBinding
388+
The string binding to connect the RPC client to
389+
#>
390+
function Connect-Client {
391+
param (
392+
$client,
393+
$stringBinding
394+
)
395+
try {
396+
Connect-RpcClient -client $client -stringBinding $stringbinding -AuthenticationLevel PacketPrivacy -AuthenticationType WinNT
397+
} catch {
398+
try {
399+
Connect-RpcClient -client $client -stringBinding $stringbinding
400+
} catch {
401+
Write-Verbose "[!] Could not connect client to $stringbinding : $_"
402+
}
403+
}
404+
}

0 commit comments

Comments
 (0)