Merge pull request #10 from ysoftdevs/remove_timeout_workarounds

Remove timeout workarounds
This commit is contained in:
Jan Stárek
2019-10-31 23:05:25 +01:00
committed by GitHub
7 changed files with 24 additions and 55 deletions

View File

@@ -42,8 +42,7 @@ The only thing you need to do is create config file. You can find template in ro
In config file you are able to specify following options: In config file you are able to specify following options:
- **fixed_url_attributes** -> if you want to set some attributes to static values - **fixed_url_attributes** -> if you want to set some attributes to static values
- **headers** -> headers which are sent by each request (useful for AUTH token insertion) - **headers** -> headers which are sent by each request (useful for AUTH token insertion)
- **polling_interval** -> interval between checks for response (in seconds) - **receive_timeout** -> maximum amount of time waiting for response (in seconds)
- **response_timeout** -> maximum amount of time waiting for response (in seconds)
- **reporting_interval** -> progress reporting interval (in seconds) - **reporting_interval** -> progress reporting interval (in seconds)
- **http_fuzzing** -> boolean value for enabling / disabling fuzzing of HTTP protocol - **http_fuzzing** -> boolean value for enabling / disabling fuzzing of HTTP protocol
- **skipping_endpoints_keywords** [list of string keywords] -> endpoints containing any keyword in it from this list will be skipped (can be used for skipping auth/logout endpoints) - **skipping_endpoints_keywords** [list of string keywords] -> endpoints containing any keyword in it from this list will be skipped (can be used for skipping auth/logout endpoints)

View File

@@ -10,8 +10,7 @@
"reporting_interval": 60, "reporting_interval": 60,
"http_fuzzing": true, "http_fuzzing": true,
"skipping_endpoints_keywords": ["logout", "auth"], "skipping_endpoints_keywords": ["logout", "auth"],
"polling_interval": 0.005, "receive_timeout": 2,
"response_timeout": 2,
"startup_command": ["python", "C:\\server\\httpd.py"], "startup_command": ["python", "C:\\server\\httpd.py"],
"target": { "target": {
"hostname": "target_hostname", "hostname": "target_hostname",

View File

@@ -38,6 +38,10 @@ class ConfigurationManager:
def _get_payloads_to_json_primitives_mapping(): def _get_payloads_to_json_primitives_mapping():
return ConfigurationManager.config["payloads_to_json_primitives_mapping"] if "payloads_to_json_primitives_mapping" in ConfigurationManager.config else None return ConfigurationManager.config["payloads_to_json_primitives_mapping"] if "payloads_to_json_primitives_mapping" in ConfigurationManager.config else None
@staticmethod
def get_receive_timeout():
return ConfigurationManager.config["receive_timeout"]
@staticmethod @staticmethod
def get_reporting_interval(): def get_reporting_interval():
return ConfigurationManager.config["reporting_interval"] return ConfigurationManager.config["reporting_interval"]
@@ -56,16 +60,10 @@ class ConfigurationManager:
def _config_validation(self): def _config_validation(self):
reporting_interval: Union[int, float] = self.config["reporting_interval"] reporting_interval: Union[int, float] = self.config["reporting_interval"]
response_timeout: Union[int, float] = self.config["response_timeout"] receive_timeout: Union[int, float] = self.config["receive_timeout"]
polling_interval: Union[int, float] = self.config["polling_interval"]
http_fuzzing: bool = self.config["http_fuzzing"] http_fuzzing: bool = self.config["http_fuzzing"]
if response_timeout <= polling_interval or polling_interval <= 0: if reporting_interval <= 0 or reporting_interval < receive_timeout:
print("Wrong timeout and polling interval. Timeout has to be greater than polling interval" +
" and polling interval has to be greater than zero.")
sys.exit(-1)
if reporting_interval <= 0 or reporting_interval < response_timeout:
print("Wrong reporting interval. Should be smaller than response_timeout.") print("Wrong reporting interval. Should be smaller than response_timeout.")
sys.exit(-1) sys.exit(-1)

View File

@@ -1,6 +1,5 @@
import sys import sys
import ssl import ssl
import os
from typing import List from typing import List
from boofuzz import Session, Target, SocketConnection, s_get, pedrpc from boofuzz import Session, Target, SocketConnection, s_get, pedrpc
from progress_reporter import report_progress from progress_reporter import report_progress
@@ -38,19 +37,14 @@ class Fuzzer:
ssl_context.check_hostname = False ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE ssl_context.verify_mode = ssl.CERT_NONE
# Workaround for issue with TLS with Boofuzz on Windows recv_timeout = ConfigurationManager.get_receive_timeout()
# https://github.com/jtpereyda/boofuzz/pull/300#issuecomment-548108378
send_and_rcv_timeout = 5.0
if os.name == 'nt':
send_and_rcv_timeout = 5000.0
remote_connection = SocketConnection( remote_connection = SocketConnection(
target_config["hostname"], target_config["hostname"],
target_config["port"], target_config["port"],
proto=self._protocol, proto=self._protocol,
sslcontext=ssl_context, sslcontext=ssl_context,
send_timeout=send_and_rcv_timeout, recv_timeout=recv_timeout
recv_timeout=send_and_rcv_timeout
) )
if startup_command: if startup_command:
process_monitor = pedrpc.Client(target_config["hostname"], 26002) process_monitor = pedrpc.Client(target_config["hostname"], 26002)

View File

@@ -1,43 +1,25 @@
import time
import threading
import json import json
from http.client import HTTPResponse from http.client import HTTPResponse
from boofuzz import exception from boofuzz import exception
from configuration_manager import ConfigurationManager
from fake_socket import get_response_object from fake_socket import get_response_object
class PostTestCaseCallback(object): class PostTestCaseCallback(object):
timeout_flag: bool = False timeout_message = "Timeout or closed connection"
@staticmethod
def set_timeout():
PostTestCaseCallback.timeout_flag = True
@staticmethod @staticmethod
def post_test_callback(target, fuzz_data_logger, session, sock, *args, **kwargs): def post_test_callback(target, fuzz_data_logger, session, sock, *args, **kwargs):
fuzz_data_logger.log_info("Mutation: " + session.fuzz_node.mutant._rendered.decode('utf-8', errors='ignore')) fuzz_data_logger.log_info("Mutation: " + session.fuzz_node.mutant._rendered.decode('utf-8', errors='ignore'))
fuzz_data_logger.log_info("Original value: " + session.fuzz_node.mutant.original_value.decode('utf-8', errors='ignore')) fuzz_data_logger.log_info("Original value: " + session.fuzz_node.mutant.original_value.decode('utf-8', errors='ignore'))
response_timeout = ConfigurationManager.config["response_timeout"] try:
polling_interval = ConfigurationManager.config["polling_interval"] response_string = target.recv()
except exception.BoofuzzTargetConnectionReset:
timer = threading.Timer(response_timeout, PostTestCaseCallback.set_timeout) fuzz_data_logger.log_fail(PostTestCaseCallback.timeout_message)
return
response_string = None
PostTestCaseCallback.timeout_flag = False
timer.start()
while not PostTestCaseCallback.timeout_flag:
try:
response_string = target.recv()
timer.cancel()
break
except exception.BoofuzzTargetConnectionReset:
time.sleep(polling_interval)
continue
if not response_string: if not response_string:
fuzz_data_logger.log_fail("Timeout or closed connection") fuzz_data_logger.log_fail(PostTestCaseCallback.timeout_message)
return return
response = get_response_object(response_string) response = get_response_object(response_string)

View File

@@ -5,13 +5,6 @@ import datetime
from configuration_manager import ConfigurationManager from configuration_manager import ConfigurationManager
DID_FUZZING_STARTED_CHECKS_TIME_INTERVAL_IN_SECONDS = 5 DID_FUZZING_STARTED_CHECKS_TIME_INTERVAL_IN_SECONDS = 5
HANGED_TIMEOUT = 120
def close_testing_and_kill_fuzzer(junit_logger, session):
if is_fuzzing_hanged(session):
junit_logger.close_test()
os._exit(1)
def report_progress(session, junit_logger): def report_progress(session, junit_logger):
@@ -20,7 +13,12 @@ def report_progress(session, junit_logger):
if is_fuzzing_hanged(session): if is_fuzzing_hanged(session):
message = create_hanged_message(session) message = create_hanged_message(session)
print(message, file=sys.stderr) print(message, file=sys.stderr)
threading.Timer(HANGED_TIMEOUT, close_testing_and_kill_fuzzer, [junit_logger, session]).start() try:
junit_logger.close_test()
except:
pass
finally:
os._exit(1)
if is_fuzzing_still_in_progress(session): if is_fuzzing_still_in_progress(session):
plan_another_report(session, junit_logger, ConfigurationManager.get_reporting_interval()) plan_another_report(session, junit_logger, ConfigurationManager.get_reporting_interval())

View File

@@ -1,8 +1,7 @@
{ {
"fixed_url_attributes": {}, "fixed_url_attributes": {},
"headers": {}, "headers": {},
"polling_interval": 0.05, "receive_timeout": 1,
"response_timeout": 1,
"reporting_interval": 10, "reporting_interval": 10,
"skipping_endpoints_keywords": [], "skipping_endpoints_keywords": [],
"http_fuzzing": false, "http_fuzzing": false,