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. Commercial Alternative to JupyterHub.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/dev/update_user_agent_strings.rb
Views: 15959
1
#!/usr/bin/env ruby
2
# -*- coding: binary -*-
3
4
require 'optparse'
5
require 'net/http'
6
require 'uri'
7
optparse = OptionParser.new do |opts|
8
opts.banner = 'Usage: ruby tools/dev/update_user_agent_strings.rb [options]'
9
opts.separator "This program updates lib/rex/user_agent.rb so Metasploit uses the most up-to-date User Agent strings across the framework."
10
opts.separator ""
11
opts.on('-h', '--help', 'Display this screen.') do
12
puts opts
13
exit
14
end
15
end
16
optparse.parse!
17
18
# colors and puts templates from msftidy.rb
19
20
class String
21
def red
22
"\e[1;31;40m#{self}\e[0m"
23
end
24
25
def yellow
26
"\e[1;33;40m#{self}\e[0m"
27
end
28
29
def green
30
"\e[1;32;40m#{self}\e[0m"
31
end
32
33
def cyan
34
"\e[1;36;40m#{self}\e[0m"
35
end
36
end
37
38
#
39
# Display an error message, given some text
40
#
41
def error(txt)
42
puts "[#{'ERROR'.red}] #{cleanup_text(txt)}"
43
end
44
45
#
46
# Display a warning message, given some text
47
#
48
def warning(txt)
49
puts "[#{'WARNING'.yellow}] #{cleanup_text(txt)}"
50
end
51
52
#
53
# Display a info message, given some text
54
#
55
def info(txt)
56
puts "[#{'INFO'.cyan}] #{cleanup_text(txt)}"
57
end
58
59
def cleanup_text(txt)
60
# remove line breaks
61
txt = txt.gsub(/[\r\n]/, ' ')
62
# replace multiple spaces by one space
63
txt.gsub(/\s{2,}/, ' ')
64
end
65
66
def replace_agent_string(lines, replace_marker, url, regex)
67
valid_chars = 'a-zA-Z0-9\(\);:\.,/_ '
68
regex = regex.gsub('{VALID_CHARS}', valid_chars)
69
info "Checking: #{replace_marker}"
70
71
index = lines.index { |line| line.include?(replace_marker) }
72
raise "Couldn't find marker #{replace_marker}" if index.nil?
73
74
uri = URI(url)
75
response = Net::HTTP.get_response(uri)
76
raise "Can't retrieve #{url}" unless response.is_a?(Net::HTTPSuccess)
77
78
match = response.body.match(/#{regex}/)
79
raise "Couldn't match regex #{regex}" if match.nil?
80
81
new_string = match[1]
82
83
old_line = lines[index]
84
if old_line.include?("'#{new_string}'")
85
puts " (Unchanged): #{new_string}"
86
else
87
new_line = old_line.gsub(/'(.*)'/, "'#{new_string}'")
88
if old_line == new_line
89
raise " Line didn't change: #{old_line}"
90
end
91
puts " New value is: #{new_string}"
92
lines[index] = new_line
93
end
94
end
95
96
chrome_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome"
97
edge_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/edge"
98
safari_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/safari"
99
firefox_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/firefox"
100
101
user_agent_filename = 'lib/rex/user_agent.rb'
102
lines = File.read(user_agent_filename).split("\n")
103
104
replace_agent_string(lines, 'Chrome Windows', chrome_url, '<td>Chrome \\(Standard\\)</td>\s*<td>\s*<ul>\s*<li><span class="code">([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)</span>')
105
replace_agent_string(lines, 'Chrome MacOS', chrome_url, '<td>Chrome \\(Standard\\)</td>\s*<td>\s*<ul>\s*<li><span class="code">([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)</span>')
106
replace_agent_string(lines, 'Edge Windows', edge_url, '<td>Edge \\(Standard\\)</td>\s*<td>\s*<ul>\s*<li><span class="code">([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)</span>')
107
replace_agent_string(lines, 'Safari iPad', safari_url, '<td>\s*Safari on <b>Ipad</b>\s*</td>\s*<td>\s*<ul>\s*<li><span class="code">([{VALID_CHARS}]*iPad[{VALID_CHARS}]*)</span>')
108
replace_agent_string(lines, 'Safari MacOS', safari_url, '<td>Safari \\(Standard\\)</td>\s*<td>\s*<ul>\s*<li><span class="code">([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)</span>')
109
replace_agent_string(lines, 'Firefox Windows', firefox_url, '<td>\s*Firefox on <b>Windows</b>\s*</td>\s*<td>\s*<ul>\s*<li><span class="code">([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)</span>')
110
replace_agent_string(lines, 'Firefox MacOS', firefox_url, '<td>\s*Firefox on <b>Macos</b>\s*</td>\s*<td>\s*<ul>\s*<li><span class="code">([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)</span>')
111
112
File.write(user_agent_filename, lines.join("\n") + "\n")
113
114