Alright so i have two scripts that i'd like to combine. First off we have my python replacement tool for Netcat called PyCat. Now this is useful for interacting with hosts on the local network. Here's muh code.
# PyCat is a python replacement for Netcat
import sys
import socket
import getopt
import threading
import subprocess
# Define global variables
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0
# Usage/Help function
def usage():
# ASCII Logo
print '8888888b. .d8888b. 888 '
print '888 Y88b d88P Y88b 888_ '
print '888 888 888 888 888 '
print '888 d88P888 888888 8888b. 888888 '
print '8888888P" 888 888888 "88b8 88 '
print '888 888 888888 888. d888888 888 '
print '888 Y88b 888Y88b d88P 888 888 Y88b. '
print '888 "Y88888 "Y8888P" "Y888888 "Y888 '
print ' 888 '
print ' Y8b d88P '
print ' "Y88P" '
# ASCII Logo
# Help text
print
print
print "PyCat Net Tool"
print
print "Usage: PyCat.py -t target_host -p port"
print
print "-l --listen"
print "listen on [host]:[port] for incoming connections"
print
print "-c --command"
print "Initialize a command shell"
print
print "-e --execute=file_to_run"
print "Execute file upon connection"
print
print "-u --upload=destination"
print "Upon connection upload file and write to [destination]"
print
print "Examples: "
print "PyCat.py -t 192.168.0.1 -p 5555 -l -c"
print "PyCat.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe"
print "Pycat.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\""
print "echo 'ABCDEFGHI' | ./PyCat.py -t 192.168.11.12 -p 135"
sys.exit(0)
def client_sender(buffer):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Connect to target host
client.connect((target,port))
# Check for input from stdin, if input is present send to remote target
if len(buffer):
client.send(buffer)
# Recieve data back until there is no more data to recieve
while True:
# Wait for data response
recv_len = 1
response = ""
while recv_len:
data = client.recv(4096)
recv_len = len(data)
response+= data
if recv_len < 4096:
break
print response,
# Wait for more input
buffer = raw_input("")
buffer += "\n"
# Send it off (Loop)
client.send(buffer)
except:
print "
[*] Exception! Exiting."
# Close connection
client.close()
# Primary server loop and stub function to handle command execution and command shell
def server_loop():
global target
# If no target is specified, we listen on all interfaces
if not len(target):
target = "0.0.0.0"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((target,port))
server.listen(5)
while True:
client_socket, addr = server.accept()
# Spin off a thread to handle new client
client_thread = threading.Thread(target=client_handler, args=(client_socket,))
client_thread.start()
def run_command(command):
# Trim the new line
command = command.rstrip()
# Run command and retrieve output
try:
output = subprocess.check_output(command,stderr=subprocess.STDOUT, shell=True)
except:
output = "Failed to execute command. \r\n"
# Send output back to the client
return output
def client_handler(client_socket):
global upload
global execute
global command
# Check for upload
if len(upload_destination):
# Read in all of the bytes and write to out destination
file_buffer = ""
# Keep reading data until none is available
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
# Now we take these bytes and try to write them out
try:
file_descriptor = open(upload_destination,"wb")
file_descriptor.write(file_buffer)
file_descriptor.close()
# Acknowledge that we wrote the file out
client_socket.send("Succesfully saved file to %s\r\n" % upload_destination)
except:
client_socket.send("Failed to save file to %s\r\n" % upload_destination)
if len(execute):
# Run the command
output = run_command(execute)
client_socket.send(output)
# Start another loop if command shell was requested
if command:
while True:
# Show prompt
client_socket.send("<BHP:#> ")
# Now we recieve until we see a linefeed (enter key)
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket.recv(1024)
# Send back the command output
response = run_command(cmd_buffer)
# Send the response back
client_socket.send(response)
# Main funtion
def main():
global listen
global port
global execute
global command
global upload_destination
global target
# Check if proper arguments are passed
if not len(sys.argv[1:]):
usage()
# Read commandline options
try:
opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:cu",["help","listen","execute","target","port","command","upload"])
except getopt.GetoptError as err:
print str(err)
usage()
for o,a in opts:
if o in ("-h","--help"):
usage()
elif o in ("-1", "--listen"):
listen = True
elif o in ("-e", "--execute"):
execute = a
elif o in ("-c", "--commandshell"):
command = True
elif o in ("-u", "--upload"):
upload_destination = a
elif o in ("-p", "--port"):
port = int(a)
else:
assert False,"Unhandled Option"
# Are we going to listen or just send data from stdin?
if not listen and len(target) and port > 0:
# Read in the buffer from the commandline, this will block, so send CTRL-D if not sending input to stdin
buffer = sys.stdin.read()
# Send data off
client_sender(buffer)
# We are going to listen and potentially upload things, execute commands and drop a shell back -
# depending on the above commandline options
if listen:
server_loop
main()
Now i have another program that scans the local network for hosts that are up and i'd like to combine the two, so you scan for hosts that are up and then when you have an idea of which one's are up you can have the rest of PyCat functionality to interact with these hosts so you can execute remote commands and such. Here's the code for my network scanner.
import socket
import os
import struct
import threading
from netaddr import IPNetwork,IPAddress
from ctypes import *
# Host to listen on
host = "192.168.0.187"
# Subnet to target
subnet = "192.168.0.0/24"
# Message we'll check ICMP responses for
magic_message = "FIREBALL!"
def udp_sender(subnet,magic_message):
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for ip in IPNetwork(subnet):
try:
sender.sendto(magic_message,("%s" % ip,65212))
except:
pass
class IP(Structure):
_fields_ = [
("ihl", c_ubyte, 4),
("version", c_ubyte, 4),
("tos", c_ubyte),
("len", c_ushort),
("id", c_ushort),
("offset", c_ushort),
("ttl", c_ubyte),
("protocol_num", c_ubyte),
("sum", c_ushort),
("src", c_ulong),
("dst", c_ulong)
]
def __new__(self, socket_buffer=None):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer=None):
# map protocol constants to their names
self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"}
# human readable IP addresses
self.src_address = socket.inet_ntoa(struct.pack("<L",self.src))
self.dst_address = socket.inet_ntoa(struct.pack("<L",self.dst))
# human readable protocol
try:
self.protocol = self.protocol_map[self.protocol_num]
except:
self.protocol = str(self.protocol_num)
class ICMP(Structure):
_fields_ = [
("type", c_ubyte),
("code", c_ubyte),
("checksum", c_ushort),
("unused", c_ushort),
("next_hop_mtu", c_ushort)
]
def __new__(self, socket_buffer):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer):
pass
# Create a raw socket and bind it to the public interface
if os.name == "nt":
socket_protocol = socket.IPPROTO_IP
else:
socket_protocol = socket.IPPROTO_ICMP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
# We want the IP headers included in the capture
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# If we're on Windows we need to send some ioctls
# to setup promiscuous mode
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
# Start sending packets
t = threading.Thread(target=udp_sender,args=(subnet,magic_message))
t.start()
try:
while True:
# Read in a single packet
raw_buffer = sniffer.recvfrom(65565)[0]
# Create an IP header from the first 20 bytes of the buffer
ip_header = IP(raw_buffer[0:20])
#print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)
# If it's ICMP we want it
if ip_header.protocol == "ICMP":
# Calculate where our ICMP packet starts
offset = ip_header.ihl * 4
buf = raw_buffer[offset:offset + sizeof(ICMP)]
# Create our ICMP structure
icmp_header = ICMP(buf)
#print "ICMP -> Type: %d Code: %d" % (icmp_header.type, icmp_header.code)
# Now check for the TYPE 3 and CODE 3 which indicates
# a host is up but no port available to talk to
if icmp_header.code == 3 and icmp_header.type == 3:
# Check to make sure we are receiving the response
# that lands in our subnet
if IPAddress(ip_header.src_address) in IPNetwork(subnet):
# Test for our magic message
if raw_buffer[len(raw_buffer)-len(magic_message):] == magic_message:
print "Host Up: %s" % ip_header.src_address
# Handle CTRL-C
except KeyboardInterrupt:
# if we're on Windows turn off promiscuous mode
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
Now how would i go about combining the two?