diff --git a/.github/workflows/weekly-data-and-external-tool-updater.yml b/.github/workflows/weekly-data-and-external-tool-updater.yml
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tools/dev/update_joomla_components.py b/tools/dev/update_joomla_components.py
deleted file mode 100755
index 3aa0ae1be278..000000000000
--- a/tools/dev/update_joomla_components.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/python3
-import requests
-
-new_com = requests.get("https://raw.githubusercontent.com/rezasp/joomscan/master/exploit/db/componentslist.txt").text
-with open('data/wordlists/joomla.txt', 'r') as j:
- old = j.read().splitlines()
-
-for com in new_com.splitlines():
- if not 'components/%s/'%(com) in old:
- old.append('components/%s/'%(com))
- print('[+] Adding: components/%s/'%(com))
-
-old.sort()
-with open('data/wordlists/joomla.txt', 'w') as j:
- j.write('\n'.join(old))
- j.write('\n')
diff --git a/tools/dev/update_joomla_components.rb b/tools/dev/update_joomla_components.rb
new file mode 100644
index 000000000000..f19c0cc06920
--- /dev/null
+++ b/tools/dev/update_joomla_components.rb
@@ -0,0 +1,78 @@
+#!/usr/bin/env ruby
+# -*- coding: binary -*-
+
+#
+# by h00die
+#
+
+require 'optparse'
+require 'net/http'
+require 'uri'
+optparse = OptionParser.new do |opts|
+ opts.banner = 'Usage: ruby tools/dev/update_joomla_components.rb [options]'
+ opts.separator "This program updates data/wordlists/joomla.txt which is used by modules/auxiliary/scanner/http/joomla_scanner.rb to have the most up-to-date list of vuln components"
+ opts.separator ""
+ opts.on('-h', '--help', 'Display this screen.') do
+ puts opts
+ exit
+ end
+end
+optparse.parse!
+
+# colors and puts templates from msftidy.rb
+
+class String
+ def red
+ "\e[1;31;40m#{self}\e[0m"
+ end
+
+ def yellow
+ "\e[1;33;40m#{self}\e[0m"
+ end
+
+ def green
+ "\e[1;32;40m#{self}\e[0m"
+ end
+
+ def cyan
+ "\e[1;36;40m#{self}\e[0m"
+ end
+end
+
+#
+# Display an error message, given some text
+#
+def error(txt)
+ puts "[#{'ERROR'.red}] #{cleanup_text(txt)}"
+end
+
+#
+# Display a warning message, given some text
+#
+def warning(txt)
+ puts "[#{'WARNING'.yellow}] #{cleanup_text(txt)}"
+end
+
+#
+# Display a info message, given some text
+#
+def info(txt)
+ puts "[#{'INFO'.cyan}] #{cleanup_text(txt)}"
+end
+
+uri = URI.parse('https://raw.githubusercontent.com/rezasp/joomscan/master/exploit/db/componentslist.txt')
+new_com = Net::HTTP.get(uri)
+
+old = File.read('data/wordlists/joomla.txt').split("\n")
+
+new_com.each_line do |com|
+ unless old.include?("components/#{com.strip}/")
+ old << "components/#{com.strip}/"
+ info "Adding: components/#{com.strip}/"
+ end
+end
+
+old.sort!
+File.open('data/wordlists/joomla.txt', 'w') do |file|
+ file.puts old
+end
\ No newline at end of file
diff --git a/tools/dev/update_user_agent_strings.py b/tools/dev/update_user_agent_strings.py
deleted file mode 100644
index bac548d78fd0..000000000000
--- a/tools/dev/update_user_agent_strings.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/python3
-import requests
-import re
-
-def replace_agent_string(lines, replace_marker, url, regex):
- VALID_CHARS = 'a-zA-Z0-9\\(\\);:\\.,/_ '
- regex = regex.replace('{VALID_CHARS}', VALID_CHARS)
- print(f'Updating {replace_marker}')
- for x in range(0, len(lines)):
- if replace_marker in lines[x]:
- break
- else:
- raise RuntimeError(f"Couldn't find marker {replace_marker}")
-
- response = requests.get(url)
- if response.status_code != 200:
- raise RuntimeError(f"Can't retrieve {url}")
-
- match = re.search(regex, response.text)
- if match is None:
- raise RuntimeError(f"Couldn't match regex {regex}")
-
- new_string = match.groups()[0]
- print(f'New value is: {new_string}')
- old_line = lines[x]
- if f"'{new_string}'" in old_line:
- print('(This is unchanged from the previous value)')
- else:
- new_line = re.sub("'(.*)'", f"'{new_string}'", old_line)
- if old_line == new_line:
- raise RuntimeError(f"Line didn't change: {old_line}")
-
- lines[x] = new_line
-
-
-chrome_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome"
-edge_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/edge"
-safari_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/safari"
-firefox_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/firefox"
-
-user_agent_filename = 'lib/rex/user_agent.rb'
-with open(user_agent_filename,'r') as f:
- lines = f.read().splitlines()
-
-replace_agent_string(lines, 'Chrome Windows', chrome_url, '
Chrome \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)')
-replace_agent_string(lines, 'Chrome MacOS', chrome_url, '
Chrome \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)')
-replace_agent_string(lines, 'Edge Windows', edge_url, '
Edge \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)')
-replace_agent_string(lines, 'Safari iPad', safari_url, '
\s*Safari on Ipad\s* | \s*\s*\s*- ([{VALID_CHARS}]*iPad[{VALID_CHARS}]*)')
-replace_agent_string(lines, 'Safari MacOS', safari_url, '
Safari \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)')
-replace_agent_string(lines, 'Firefox Windows', firefox_url, '
\s*Firefox on Windows\s* | \s*\s*\s*- ([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)')
-replace_agent_string(lines, 'Firefox MacOS', firefox_url, '
\s*Firefox on Macos\s* | \s*\s*\s*- ([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)')
-
-with open(user_agent_filename, 'w') as f:
- f.write('\n'.join(lines) + '\n')
-
-print('Done')
diff --git a/tools/dev/update_user_agent_strings.rb b/tools/dev/update_user_agent_strings.rb
new file mode 100644
index 000000000000..929cc65925ba
--- /dev/null
+++ b/tools/dev/update_user_agent_strings.rb
@@ -0,0 +1,112 @@
+#!/usr/bin/env ruby
+# -*- coding: binary -*-
+
+require 'optparse'
+require 'net/http'
+require 'uri'
+optparse = OptionParser.new do |opts|
+ opts.banner = 'Usage: ruby tools/dev/update_user_agent_strings.rb [options]'
+ opts.separator "This program updates lib/rex/user_agent.rb so Metasploit uses the most up-to-date User Agent strings across the framework."
+ opts.separator ""
+ opts.on('-h', '--help', 'Display this screen.') do
+ puts opts
+ exit
+ end
+end
+optparse.parse!
+
+# colors and puts templates from msftidy.rb
+
+class String
+ def red
+ "\e[1;31;40m#{self}\e[0m"
+ end
+
+ def yellow
+ "\e[1;33;40m#{self}\e[0m"
+ end
+
+ def green
+ "\e[1;32;40m#{self}\e[0m"
+ end
+
+ def cyan
+ "\e[1;36;40m#{self}\e[0m"
+ end
+end
+
+#
+# Display an error message, given some text
+#
+def error(txt)
+ puts "[#{'ERROR'.red}] #{cleanup_text(txt)}"
+end
+
+#
+# Display a warning message, given some text
+#
+def warning(txt)
+ puts "[#{'WARNING'.yellow}] #{cleanup_text(txt)}"
+end
+
+#
+# Display a info message, given some text
+#
+def info(txt)
+ puts "[#{'INFO'.cyan}] #{cleanup_text(txt)}"
+end
+
+def cleanup_text(txt)
+ # remove line breaks
+ txt = txt.gsub(/[\r\n]/, ' ')
+ # replace multiple spaces by one space
+ txt.gsub(/\s{2,}/, ' ')
+end
+
+def replace_agent_string(lines, replace_marker, url, regex)
+ valid_chars = 'a-zA-Z0-9\(\);:\.,/_ '
+ regex = regex.gsub('{VALID_CHARS}', valid_chars)
+ info "Checking: #{replace_marker}"
+
+ index = lines.index { |line| line.include?(replace_marker) }
+ raise "Couldn't find marker #{replace_marker}" if index.nil?
+
+ uri = URI(url)
+ response = Net::HTTP.get_response(uri)
+ raise "Can't retrieve #{url}" unless response.is_a?(Net::HTTPSuccess)
+
+ match = response.body.match(/#{regex}/)
+ raise "Couldn't match regex #{regex}" if match.nil?
+
+ new_string = match[1]
+
+ old_line = lines[index]
+ if old_line.include?("'#{new_string}'")
+ puts " (Unchanged): #{new_string}"
+ else
+ new_line = old_line.gsub(/'(.*)'/, "'#{new_string}'")
+ if old_line == new_line
+ raise " Line didn't change: #{old_line}"
+ end
+ puts " New value is: #{new_string}"
+ lines[index] = new_line
+ end
+end
+
+chrome_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome"
+edge_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/edge"
+safari_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/safari"
+firefox_url = "https://www.whatismybrowser.com/guides/the-latest-user-agent/firefox"
+
+user_agent_filename = 'lib/rex/user_agent.rb'
+lines = File.read(user_agent_filename).split("\n")
+
+replace_agent_string(lines, 'Chrome Windows', chrome_url, '
Chrome \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)')
+replace_agent_string(lines, 'Chrome MacOS', chrome_url, '
Chrome \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)')
+replace_agent_string(lines, 'Edge Windows', edge_url, '
Edge \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)')
+replace_agent_string(lines, 'Safari iPad', safari_url, '
\s*Safari on Ipad\s* | \s*\s*\s*- ([{VALID_CHARS}]*iPad[{VALID_CHARS}]*)')
+replace_agent_string(lines, 'Safari MacOS', safari_url, '
Safari \\(Standard\\) | \s*\s*\s*- ([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)')
+replace_agent_string(lines, 'Firefox Windows', firefox_url, '
\s*Firefox on Windows\s* | \s*\s*\s*- ([{VALID_CHARS}]*Windows NT[{VALID_CHARS}]*)')
+replace_agent_string(lines, 'Firefox MacOS', firefox_url, '
\s*Firefox on Macos\s* | \s*\s*\s*- ([{VALID_CHARS}]*Macintosh[{VALID_CHARS}]*)')
+
+File.write(user_agent_filename, lines.join("\n") + "\n")
diff --git a/tools/dev/update_wordpress_vulnerabilities.rb b/tools/dev/update_wordpress_vulnerabilities.rb
index 6217518ccc63..680ac4e5ea9e 100755
--- a/tools/dev/update_wordpress_vulnerabilities.rb
+++ b/tools/dev/update_wordpress_vulnerabilities.rb
@@ -1,9 +1,6 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
-#
-# Update modules/auxiliary/scanner/http/wordpress_scanner.rb to have the most
-# up to date list of vuln components based on exploits/scanners in the framework
#
# by h00die
#
@@ -12,7 +9,9 @@
options = {}
optparse = OptionParser.new do |opts|
- opts.banner = 'Usage: update_wordpress_vulnerabilities.rb [options]'
+ opts.banner = 'Usage: ruby tools/dev/update_wordpress_vulnerabilities.rb [options]'
+ opts.separator "This program updates data/wordlists/wp-exploitable-themes.txt and wp-exploitable-plugins.txt which are used by modules/auxiliary/scanner/http/wordpress_scanner.rb to have the most up-to-date list of vuln components"
+ opts.separator ""
opts.on('-h', '--help', 'Display this screen.') do
puts opts
exit
| | | | | | | | | | | | | |