Added return codes + reactions to them

This commit is contained in:
Jan Stárek
2019-11-04 10:35:50 +01:00
parent bb0a30900a
commit c8d30d0425
7 changed files with 109 additions and 81 deletions

View File

@@ -1,76 +1,76 @@
import sys import sys
import json import json
from typing import Union, List from typing import Union, List
class ConfigurationManager: class ConfigurationManager:
config = None config = None
def __init__(self, config_file_pointer): def __init__(self, config_file_pointer):
ConfigurationManager.config = json.load(config_file_pointer) ConfigurationManager.config = json.load(config_file_pointer)
self._config_validation() self._config_validation()
@staticmethod @staticmethod
def get_startup_command(): def get_startup_command():
return ConfigurationManager.config["startup_command"] if "startup_command" in ConfigurationManager.config else None return ConfigurationManager.config["startup_command"] if "startup_command" in ConfigurationManager.config else None
@staticmethod @staticmethod
def get_payloads_folders_for_boolean_json_primitive() -> Union[List, None]: def get_payloads_folders_for_boolean_json_primitive() -> Union[List, None]:
return ConfigurationManager._get_payloads_folders_for_specific_json_primitive("boolean") return ConfigurationManager._get_payloads_folders_for_specific_json_primitive("boolean")
@staticmethod @staticmethod
def get_payloads_folders_for_number_json_primitive() -> Union[List, None]: def get_payloads_folders_for_number_json_primitive() -> Union[List, None]:
return ConfigurationManager._get_payloads_folders_for_specific_json_primitive("number") return ConfigurationManager._get_payloads_folders_for_specific_json_primitive("number")
@staticmethod @staticmethod
def get_payloads_folders_for_string_json_primitive() -> Union[List, None]: def get_payloads_folders_for_string_json_primitive() -> Union[List, None]:
return ConfigurationManager._get_payloads_folders_for_specific_json_primitive("string") return ConfigurationManager._get_payloads_folders_for_specific_json_primitive("string")
@staticmethod @staticmethod
def _get_payloads_folders_for_specific_json_primitive(json_type: str) -> Union[List, None]: def _get_payloads_folders_for_specific_json_primitive(json_type: str) -> Union[List, None]:
mapping = ConfigurationManager._get_payloads_to_json_primitives_mapping() mapping = ConfigurationManager._get_payloads_to_json_primitives_mapping()
if mapping: if mapping:
return mapping[json_type] if json_type in mapping else None return mapping[json_type] if json_type in mapping else None
else: else:
return None return None
@staticmethod @staticmethod
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 @staticmethod
def get_receive_timeout(): def get_receive_timeout():
return ConfigurationManager.config["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"]
@staticmethod @staticmethod
def get_keywords_for_endpoints_skipping() -> List: def get_keywords_for_endpoints_skipping() -> List:
return ConfigurationManager.config["skipping_endpoints_keywords"] return ConfigurationManager.config["skipping_endpoints_keywords"]
@staticmethod @staticmethod
def get_target(): def get_target():
return ConfigurationManager.config["target"] return ConfigurationManager.config["target"]
@staticmethod @staticmethod
def is_http_fuzzing_allowed(): def is_http_fuzzing_allowed():
return ConfigurationManager.config["http_fuzzing"] return ConfigurationManager.config["http_fuzzing"]
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"]
receive_timeout: Union[int, float] = self.config["receive_timeout"] receive_timeout: Union[int, float] = self.config["receive_timeout"]
http_fuzzing: bool = self.config["http_fuzzing"] http_fuzzing: bool = self.config["http_fuzzing"]
if reporting_interval <= 0 or reporting_interval < receive_timeout: if reporting_interval <= 0 or reporting_interval < receive_timeout:
print("Wrong reporting interval. Should be smaller than receive_timeout.") print("Wrong reporting interval. Should be smaller than receive_timeout.")
sys.exit(-1) sys.exit(2)
if "target" not in ConfigurationManager.config: if "target" not in ConfigurationManager.config:
print("Missing configuration of target.") print("Missing configuration of target.")
sys.exit(-1) sys.exit(2)
if http_fuzzing is None: if http_fuzzing is None:
print("Missing flag for enabling / disabling HTTP fuzzing.") print("Missing flag for enabling / disabling HTTP fuzzing.")
sys.exit(-1) sys.exit(2)

View File

@@ -85,3 +85,6 @@ class Fuzzer:
def fuzz(self): def fuzz(self):
report_progress(self._session, self._junit_logger) report_progress(self._session, self._junit_logger)
self._session.fuzz() self._session.fuzz()
def was_there_any_failure(self):
return self._junit_logger.was_there_any_failure

View File

@@ -31,6 +31,8 @@ class JUnitLogger(ifuzz_logger_backend.IFuzzLoggerBackend):
self._default_value = None self._default_value = None
self._mutant_value = None self._mutant_value = None
self.was_there_any_failure: bool = False
def open_test_step(self, description): def open_test_step(self, description):
skipped_count = 0 skipped_count = 0
for skipped_test_case_message_regex in self.SKIPPED_TEST_CASE_MESSAGES_REGEX: for skipped_test_case_message_regex in self.SKIPPED_TEST_CASE_MESSAGES_REGEX:
@@ -48,6 +50,7 @@ class JUnitLogger(ifuzz_logger_backend.IFuzzLoggerBackend):
def log_error(self, description): def log_error(self, description):
self._error = description self._error = description
self.was_there_any_failure = True
def log_recv(self, data): def log_recv(self, data):
self._received_bytes = helpers.hex_str(data) self._received_bytes = helpers.hex_str(data)
@@ -71,6 +74,7 @@ class JUnitLogger(ifuzz_logger_backend.IFuzzLoggerBackend):
def log_fail(self, description=""): def log_fail(self, description=""):
self._failure = description self._failure = description
self.was_there_any_failure = True
def log_pass(self, description=""): def log_pass(self, description=""):
pass pass

View File

@@ -18,7 +18,7 @@ def report_progress(session, junit_logger):
except: except:
pass pass
finally: finally:
os._exit(1) os._exit(2)
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

@@ -36,7 +36,12 @@ def main():
fuzzer = Fuzzer(endpoints, text_logger, junit_logger, protocol) fuzzer = Fuzzer(endpoints, text_logger, junit_logger, protocol)
fuzzer.fuzz() fuzzer.fuzz()
return fuzzer.was_there_any_failure()
if __name__ == '__main__': if __name__ == '__main__':
main() was_there_any_failure: bool = main()
if was_there_any_failure:
exit(1)
else:
exit(0)

10
run.ps1
View File

@@ -66,10 +66,10 @@ pip install --upgrade pip
Write-Host "Installing specific dependencies" Write-Host "Installing specific dependencies"
pip install git+https://github.com/jtpereyda/boofuzz.git pip install git+https://github.com/jtpereyda/boofuzz.git
pip install junit-xml pip install junit-xml
Write-Host "Starting fuzz testing" Write-Host "Starting fuzz testing"
python ./fuzzer/src/wapifuzz.py ${config} ${API_REQUESTS_JSON} ${JUNIT_TEST_REPORT} ${payloads} > $FUZZER_LOG python ./fuzzer/src/wapifuzz.py ${config} ${API_REQUESTS_JSON} ${JUNIT_TEST_REPORT} ${payloads} > $FUZZER_LOG
if(-Not ($?)) $FUZZER_ERROR_CODE=$LASTEXITCODE
if ($FUZZER_ERROR_CODE -eq 2)
{ {
Write-Host "Fuzzing failed. HTML report will not be produced." Write-Host "Fuzzing failed. HTML report will not be produced."
exit 1 exit 1
@@ -112,3 +112,9 @@ else
exit 1 exit 1
} }
Write-Host "--- Ending generating HTML test report ---" Write-Host "--- Ending generating HTML test report ---"
if ($FUZZER_ERROR_CODE -eq 1)
{
Write-Host "There were some failures! Returning non-zero return value."
exit 1
}

12
run.sh
View File

@@ -77,7 +77,12 @@ ${PYTHON3_BIN} -m virtualenv env
echo "Started fuzzing" echo "Started fuzzing"
. ./env/bin/activate ; \ . ./env/bin/activate ; \
pip install --upgrade pip ; pip install git+https://github.com/jtpereyda/boofuzz.git ; pip install junit-xml ; \ pip install --upgrade pip ; pip install git+https://github.com/jtpereyda/boofuzz.git ; pip install junit-xml ; \
python fuzzer/src/wapifuzz.py ${WAPIFUZZ_CONFIG} ${API_REQUESTS_JSON} ${JUNIT_TEST_REPORT} ${CUSTOM_PAYLOADS_FILE} > ${FUZZER_LOG} || { echo 'Fuzzing failed. Trying to generate HTML result of procceeded test cases.' ; } ; deactivate python fuzzer/src/wapifuzz.py ${WAPIFUZZ_CONFIG} ${API_REQUESTS_JSON} ${JUNIT_TEST_REPORT} ${CUSTOM_PAYLOADS_FILE} > ${FUZZER_LOG}
FUZZER_ERROR_CODE=$?
if [ "$FUZZER_ERROR_CODE" -eq "2" ]; then
echo "Fuzzing failed. Trying to generate HTML result of procceeded test cases.";
fi
deactivate
echo "Fuzzing finished" echo "Fuzzing finished"
echo "Starting generating HTML test report" echo "Starting generating HTML test report"
@@ -91,3 +96,8 @@ else
exit 1 exit 1
fi fi
echo "Ending generating HTML test report" echo "Ending generating HTML test report"
if [ "$FUZZER_ERROR_CODE" -eq "1" ]; then
echo "There were some failures! Returning non-zero return value.";
exit -1;
fi