ssh and smtp server
This commit is contained in:
parent
b1380967a4
commit
b3cd20ca8b
@ -2,7 +2,7 @@ import os
|
||||
import sys
|
||||
|
||||
__doc__ = __doc__ or ""
|
||||
__all__ = ["util", "fileserver", "xss_handler", "rev_shell", "xp_cmdshell", "dnsserver", "sqli"]
|
||||
__all__ = ["util", "fileserver", "xss_handler", "rev_shell", "xp_cmdshell", "dnsserver", "sqli", "smtpserver"]
|
||||
|
||||
inc_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
sys.path.append(inc_dir)
|
||||
|
@ -6,4 +6,4 @@ if [ $# -lt 1 ]; then
|
||||
fi
|
||||
|
||||
HOST=$1
|
||||
gobuster dir --url="${HOST}" --wordlist="/usr/share/wordlists/SecLists/Discovery/Web-Content/raft-large-words-lowercase.txt" -b "403,404" "${@:2}"
|
||||
(set -x; gobuster dir --url="${HOST}" --wordlist="/usr/share/wordlists/SecLists/Discovery/Web-Content/raft-large-words-lowercase.txt" -b "403,404" "${@:2}")
|
||||
|
40
smtpserver.py
Normal file
40
smtpserver.py
Normal file
@ -0,0 +1,40 @@
|
||||
import smtpd
|
||||
import email
|
||||
import asyncore
|
||||
import threading
|
||||
|
||||
class SMTPServer(smtpd.SMTPServer):
|
||||
|
||||
def __init__(self, addr='0.0.0.0', port=25):
|
||||
super().__init__((addr, port), None)
|
||||
self.listen_thread = None
|
||||
self.verbose = False
|
||||
self.on_message = None
|
||||
self.is_running = True
|
||||
|
||||
def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
|
||||
if self.verbose:
|
||||
print(f"SMTP IN: {peer=} {mailfrom=} {rcpttos=} {len(data)} bytes, extra:", kwargs)
|
||||
if self.on_message and callable(self.on_message):
|
||||
mail = email.message_from_bytes(data)
|
||||
self.on_message(peer, mailfrom, rcpttos, mail)
|
||||
|
||||
def start(self):
|
||||
if self.verbose:
|
||||
print(f"SMTP server running on: {self._localaddr[0]}:{self._localaddr[1]}")
|
||||
try:
|
||||
while self.is_running:
|
||||
asyncore.loop(timeout=1, use_poll=True)
|
||||
except KeyboardInterrupt:
|
||||
self.close()
|
||||
|
||||
def start_background(self):
|
||||
self.listen_thread = threading.Thread(target=self.start)
|
||||
self.listen_thread.start()
|
||||
return self.listen_thread
|
||||
|
||||
def stop(self):
|
||||
self.is_running = False
|
||||
self.close()
|
||||
if self.listen_thread:
|
||||
self.listen_thread.join()
|
92
sshserver.py
Normal file
92
sshserver.py
Normal file
@ -0,0 +1,92 @@
|
||||
import socket
|
||||
import select
|
||||
import threading
|
||||
import paramiko
|
||||
|
||||
class ParamikoConnection(paramiko.ServerInterface):
|
||||
def __init__(self, server):
|
||||
self.event = threading.Event()
|
||||
self.server = server
|
||||
|
||||
def check_channel_request(self, kind, chanid):
|
||||
print("check_channel_request", kind, chanid)
|
||||
if kind == 'session':
|
||||
return paramiko.OPEN_SUCCEEDED
|
||||
return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
|
||||
|
||||
def check_auth_password(self, username, password):
|
||||
if self.server.on_ssh_login:
|
||||
return self.server.on_ssh_login(username, password)
|
||||
|
||||
print("check_auth_password", username, password)
|
||||
return paramiko.AUTH_SUCCESSFUL
|
||||
|
||||
class SSHServer:
|
||||
|
||||
def __init__(self, addr='0.0.0.0', port=22):
|
||||
self.server_address = addr
|
||||
self.listen_port = port
|
||||
self.listen_socket = None
|
||||
self.listen_thread = None
|
||||
self.client_sockets = []
|
||||
self.transports = []
|
||||
self.verbose = True
|
||||
self.on_message = None
|
||||
self.is_running = True
|
||||
self.private_key = None
|
||||
|
||||
# hooks
|
||||
self.on_ssh_login = None
|
||||
|
||||
|
||||
def load_private_key_from_file(self, path):
|
||||
with open(path, "r") as f:
|
||||
self.private_key = paramiko.RSAKey.from_private_key(f)
|
||||
|
||||
def start(self):
|
||||
|
||||
if self.private_key is None:
|
||||
self.private_key = paramiko.RSAKey.generate(2048)
|
||||
|
||||
self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.listen_socket.setblocking(False)
|
||||
self.listen_socket.bind((self.server_address, self.listen_port))
|
||||
self.listen_socket.listen()
|
||||
if self.verbose:
|
||||
print(f"SSH server running on: {self.server_address}:{self.listen_port}")
|
||||
try:
|
||||
while self.is_running:
|
||||
try:
|
||||
client_socket, client_address = self.listen_socket.accept()
|
||||
if self.verbose:
|
||||
print("Incoming connection:", client_address)
|
||||
self.client_sockets.append(client_socket)
|
||||
transport = paramiko.Transport(client_socket)
|
||||
transport.add_server_key(self.private_key)
|
||||
paramiko_connection = ParamikoConnection(self)
|
||||
transport.start_server(server=paramiko_connection)
|
||||
self.transports.append(transport)
|
||||
# for client_sock in self.client_sockets:
|
||||
|
||||
except BlockingIOError:
|
||||
pass
|
||||
# handle_client(client_socket, client_address)
|
||||
finally:
|
||||
self.listen_socket.close()
|
||||
|
||||
def start_background(self):
|
||||
self.listen_thread = threading.Thread(target=self.start)
|
||||
self.listen_thread.start()
|
||||
return self.listen_thread
|
||||
|
||||
def close(self):
|
||||
if self.listen_socket:
|
||||
self.listen_socket.close()
|
||||
for sock in self.client_sockets:
|
||||
sock.close()
|
||||
|
||||
def stop(self):
|
||||
self.is_running = False
|
||||
self.close()
|
||||
if self.listen_thread:
|
||||
self.listen_thread.join()
|
23
util.py
23
util.py
@ -9,6 +9,8 @@ import string
|
||||
import sys
|
||||
import os
|
||||
import io
|
||||
import json
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def isPortInUse(port):
|
||||
@ -80,6 +82,27 @@ def assert_header_present(res, header, err=None):
|
||||
err = f"[-] '{res.url}' did not return header: {header}" if err is None else err
|
||||
exit_with_error(res, err)
|
||||
|
||||
def assert_not_empty(res, err=None):
|
||||
if len(res.content) > 0:
|
||||
return
|
||||
|
||||
err = f"[-] '{res.url}' did not return any data" if err is None else err
|
||||
exit_with_error(res, err)
|
||||
|
||||
def assert_json_path(res, path, value, err=None):
|
||||
assert_content_type(res, "application/json")
|
||||
assert_not_empty(res)
|
||||
|
||||
json_data = json.loads(res.text)
|
||||
for key in filter(None, path.split(".")):
|
||||
json_data = json_data[key]
|
||||
|
||||
if json_data == value:
|
||||
return
|
||||
|
||||
err = f"[-] '{res.url}' value at path '{path}' does not match. got={json_data} expected={value}" if err is None else err
|
||||
exit_with_error(res, err)
|
||||
|
||||
def openServer(address, ports=None):
|
||||
listenPort = None
|
||||
retry = True
|
||||
|
Loading…
Reference in New Issue
Block a user