-
Kkevsterrr committed 4 years ago1 parent 88cfcf45
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
-
1 + """ 2 + Client 3 + Run by the evaluator, tests a forbidden string from client to server 4 + """ 5 + 6 + import argparse 7 + import logging 8 + import os 9 + import random 10 + import socket 11 + import sys 12 + import time 13 + import traceback 14 + import urllib.request 15 + 16 + import requests 17 + 18 + socket.setdefaulttimeout(1) 19 + 20 + import external_sites 21 + import actions.utils 22 + 23 + from plugins.plugin_client import ClientPlugin 24 + 25 + BASEPATH = os.path.dirname(os.path.abspath(__file__)) 26 + 27 + 28 + class SMTPClient(ClientPlugin): 29 + """ 30 + Defines the SMTP client. 31 + """ 32 + name = "smtp" 33 + 34 + def __init__(self, args): 35 + """ 36 + Initializes the SMTP client. 37 + """ 38 + ClientPlugin.__init__(self) 39 + self.args = args 40 + 41 + @staticmethod 42 + def get_args(command): 43 + """ 44 + Defines required args for this plugin 45 + """ 46 + super_args = ClientPlugin.get_args(command) 47 + parser = argparse.ArgumentParser(description='SMTP Client') 48 + 49 + parser.add_argument('--server', action='store', help="server to connect to") 50 + parser.add_argument('--smtp-request', action='store_true', help='Send an SMTP byte string that triggers censorship') 51 + 52 + args, _ = parser.parse_known_args(command) 53 + args = vars(args) 54 + 55 + super_args.update(args) 56 + return super_args 57 + 58 + def run(self, args, logger, engine=None): 59 + """ 60 + Try to send a forbidden string 61 + """ 62 + fitness = 0 63 + port = int(args["port"]) 64 + server = args["server"] 65 + bad_word = args["bad_word"] 66 + msg = bad_word 67 + 68 + if args.get('smtp_request'): 69 + msg = b'MAIL FROM: [email protected] \r\n' 70 + 71 + if type(msg) == str: 72 + msg = msg.encode() 73 + 74 + try: 75 + client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 76 + client.settimeout(10) 77 + client.connect((server, port)) 78 + 79 + tries = args.get("tries", 1) 80 + for idx in range(0, int(tries)): 81 + client.sendall(msg) 82 + server_data = client.recv(1024) 83 + logger.debug("Data recieved: %s", server_data.decode('utf-8', 'ignore')) 84 + if server_data == b'k': 85 + fitness += 100 86 + else: 87 + fitness -= 90 88 + break 89 + 90 + time.sleep(1) 91 + client.close() 92 + # If the fitness is 0, the strategy did something to corrupt/interfere with the socket 93 + # sending/receiving, usually by just artificially closing the connection. This behavior 94 + # should not be rewarded with a higher fitness 95 + if fitness == 0: 96 + fitness -= 100 97 + except socket.timeout: 98 + logger.debug("Client: Timeout") 99 + fitness -= 100 100 + except socket.error as exc: 101 + # If the censor we're running against tears down connects via RSTs, we can punish RSTs as 102 + # if the strategy did not harm the underlying connection. However, if the censor only injects 103 + # traffic, not resets, we should punish RSTs harshly, as the strategy likely caused it. 104 + 105 + if exc.errno == 104: 106 + if args.get("injection_censor"): 107 + fitness -= 110 108 + else: 109 + fitness -= 90 110 + logger.debug("Client: Connection RST.") 111 + else: 112 + fitness -= 100 113 + logger.exception("Socket error caught in client smtp test.") 114 + except Exception: 115 + logger.exception("Exception caught in client smtp test.") 116 + fitness = -120 117 + finally: 118 + logger.debug("Client finished smtp test.") 119 + return fitness * 4 120 + -
1 + import argparse 2 + import os 3 + import socket 4 + import subprocess 5 + import time 6 + 7 + from plugins.plugin_server import ServerPlugin 8 + 9 + BASEPATH = os.path.dirname(os.path.abspath(__file__)) 10 + 11 + 12 + class SMTPServer(ServerPlugin): 13 + """ 14 + Defines the SMTP client. 15 + """ 16 + name = "smtp" 17 + def __init__(self, args): 18 + """ 19 + Initializes the SMTP client. 20 + """ 21 + ServerPlugin.__init__(self) 22 + self.args = args 23 + if args: 24 + self.port = args["port"] 25 + 26 + @staticmethod 27 + def get_args(command): 28 + """ 29 + Defines arguments for this plugin 30 + """ 31 + super_args = ServerPlugin.get_args(command) 32 + 33 + parser = argparse.ArgumentParser(description='SMTP Server') 34 + 35 + parser.add_argument('--smtp-request', action='store_true', help='Send an SMTP byte string that triggers censorship') 36 + 37 + args, _ = parser.parse_known_args(command) 38 + args = vars(args) 39 + super_args.update(args) 40 + return super_args 41 + 42 + def run(self, args, logger): 43 + """ 44 + Initializes the SMTP server. 45 + """ 46 + logger.debug("SMTP server initializing") 47 + try: 48 + port = int(args["port"]) 49 + control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 50 + # Allow socket re-use 51 + control_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 52 + server_address = ('0.0.0.0', port) 53 + logger.debug("Binding to server address 0.0.0.0:%d" % port) 54 + control_socket.bind(server_address) 55 + control_socket.settimeout(5) 56 + control_socket.listen(1) 57 + except: 58 + logger.exception("Caught exception in smtp run") 59 + return 60 + 61 + try: 62 + connection, client_address = self.get_request(control_socket) 63 + if not connection: 64 + logger.error("Failed to get connection") 65 + return 66 + 67 + bad_word = args["bad_word"] 68 + expected_msg = bad_word 69 + 70 + if args.get('smtp_request'): 71 + expected_msg = b'MAIL FROM: [email protected] \r\n' 72 + 73 + if type(expected_msg) == str: 74 + expected_msg = expected_msg.encode() 75 + 76 + # SMTP data back and forth 77 + tries = args.get("tries", 1) 78 + for i in range(0, int(tries)): 79 + msg = b'' 80 + while msg != expected_msg: 81 + msg += connection.recv(1024) 82 + time.sleep(1) 83 + connection.sendall(b'k') 84 + 85 + time.sleep(1) 86 + connection.close() 87 + except socket.error as e: 88 + if e.errno == 104: 89 + logger.debug("Server: Connection RST.") 90 + else: 91 + logger.debug("Server: Client quit.") 92 + except socket.ConnectionResetError: 93 + logger.debug("Server: Connection RST.") 94 + except Exception: 95 + logger.exception("Failed during server communication.") 96 + finally: 97 + logger.debug("Server exiting") 98 + 99 + def get_request(self, control_socket): 100 + """ 101 + Get a request from the socket. 102 + """ 103 + while True: 104 + try: 105 + sock, addr = control_socket.accept() 106 + sock.settimeout(5) 107 + return (sock, addr) 108 + except socket.timeout: 109 + pass 110 + return (None, None) 111 + 112 + def stop(self): 113 + """ 114 + Stops this server. 115 + """ 116 + ServerPlugin.stop(self) 117 +