diff --git a/README.md b/README.md index 0f9ceb1..f0375d2 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Please note: ``` usage: python3 hashtopolis.zip [-h] [--de-register] [--version] [--number-only] [--disable-update] [--debug] [--voucher VOUCHER] [--url URL] [--cert CERT] [--files-path FILES_PATH] [--crackers-path CRACKERS_PATH] [--hashlists-path HASHLISTS_PATH] - [--preprocessors-path PREPROCESSORS_PATH] [--zaps-path ZAPS_PATH] [--cpu-only] + [--preprocessors-path PREPROCESSORS_PATH] [--zaps-path ZAPS_PATH] [--cpu-only] [--http-headers HTTP_HEADERS] Hashtopolis Client v0.7.5 @@ -58,6 +58,8 @@ options: --zaps-path ZAPS_PATH Use given folder path as zaps location --cpu-only Force client to register as CPU only and also only reading out CPU information + --http-headers HTTP_HEADERS + Use given http headers in all HTTP requests, format: "Header1: Value1, Header2: Value2" ``` diff --git a/__main__.py b/__main__.py index d45ffee..257d3d8 100644 --- a/__main__.py +++ b/__main__.py @@ -16,7 +16,7 @@ from htpclient.generic_cracker import GenericCracker from htpclient.hashcat_cracker import HashcatCracker from htpclient.hashlist import Hashlist -from htpclient.helpers import start_uftpd, file_get_contents +from htpclient.helpers import start_uftpd, file_get_contents, parse_http_headers from htpclient.initialize import Initialize from htpclient.jsonRequest import * from htpclient.dicts import * @@ -141,6 +141,8 @@ def init(args): CONFIG.set_value('zaps-path', os.path.abspath(args.zaps_path)) if args.preprocessors_path and len(args.preprocessors_path): CONFIG.set_value('preprocessors-path', os.path.abspath(args.preprocessors_path)) + if args.http_headers and len(args.http_headers): + CONFIG.set_value('http-headers', parse_http_headers(args.http_headers)) logging.info("Starting client '" + Initialize.get_version() + "'...") @@ -154,6 +156,7 @@ def init(args): session = Session(requests.Session()).s session.headers.update({'User-Agent': Initialize.get_version()}) + session.headers.update(CONFIG.get_value('http-headers')) if CONFIG.get_value('proxies'): session.proxies = CONFIG.get_value('proxies') @@ -335,6 +338,7 @@ def de_register(): parser.add_argument('--preprocessors-path', type=str, required=False, help='Use given folder path as preprocessors location') parser.add_argument('--zaps-path', type=str, required=False, help='Use given folder path as zaps location') parser.add_argument('--cpu-only', action='store_true', help='Force client to register as CPU only and also only reading out CPU information') + parser.add_argument('--http-headers', type=str, required=False, help='Use given http headers in all HTTP requests, format: "Header1: Value1, Header2: Value2"') args = parser.parse_args() if args.version: diff --git a/build.sh b/build.sh index 59ea817..3bb8ce0 100755 --- a/build.sh +++ b/build.sh @@ -4,14 +4,25 @@ if [ -f hashtopolis.zip ]; then rm hashtopolis.zip fi +# Make sure tags are available locally (some CI/PR checkouts or forks only +# have a single branch without tags), so git describe can actually find the +# latest release tag instead of silently failing. +git fetch --tags --quiet 2>/dev/null || true + # write commit count since release into version number when compiling into zip -count=$(git log $(git describe --tags --abbrev=0)..HEAD --oneline | wc -l) -if [ ${count} \> 0 ]; -then - sed -i -E 's/return "([0-9]+)\.([0-9]+)\.([0-9]+)"/return "\1.\2.\3.'$count'"/g' htpclient/initialize.py -fi; +latest_tag=$(git describe --tags --abbrev=0 2>/dev/null) +if [ -n "$latest_tag" ]; then + count=$(git log "${latest_tag}"..HEAD --oneline | wc -l) +else + count=0 +fi + +if [ "$count" -gt 0 ]; then + sed -i -E 's/return "([0-9]+)\.([0-9]+)\.([0-9]+)"/return "\1.\2.\3.'$count'"/g' htpclient/initialize.py +fi + zip -r hashtopolis.zip __main__.py htpclient -x "*__pycache__*" -if [ ${count} \> 0 ]; -then - sed -i -E 's/return "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)"/return "\1.\2.\3"/g' htpclient/initialize.py -fi; \ No newline at end of file + +if [ "$count" -gt 0 ]; then + sed -i -E 's/return "([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)"/return "\1.\2.\3"/g' htpclient/initialize.py +fi diff --git a/htpclient/helpers.py b/htpclient/helpers.py index 2698cbe..d6db047 100644 --- a/htpclient/helpers.py +++ b/htpclient/helpers.py @@ -64,7 +64,8 @@ def file_get_contents(filename): def start_uftpd(os_extension, config): try: - subprocess.check_output("killall -s 9 uftpd", shell=True) # stop running service to make sure we can start it again + # stop running service to make sure we can start it again + subprocess.check_output("killall -s 9 uftpd", shell=True) except subprocess.CalledProcessError: pass # ignore in case uftpd was not running path = retrieve_binary('uftpd' + os_extension) @@ -137,6 +138,18 @@ def escape_ansi(line): ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]') return ansi_escape.sub('', line) + +def parse_http_headers(header_str): + headers = {} + if header_str: + pairs = header_str.split(',') + for pair in pairs: + if ':' in pair: + key, value = pair.split(':', 1) + headers[key.strip()] = value.strip() + return headers + + # function to retrieve a system or local binary. def retrieve_binary(binary): cwd = Path.cwd() @@ -152,4 +165,4 @@ def retrieve_binary(binary): if system_binary: return system_binary - return None \ No newline at end of file + return None diff --git a/htpclient/jsonRequest.py b/htpclient/jsonRequest.py index 1d68e45..7c8636c 100644 --- a/htpclient/jsonRequest.py +++ b/htpclient/jsonRequest.py @@ -13,7 +13,8 @@ def __init__(self, data): def execute(self): try: logging.debug(self.data) - r = self.session.post(self.config.get_value('url'), json=self.data, timeout=30) + headers = self.config.get_value('http-headers') or {} + r = self.session.post(self.config.get_value('url'), json=self.data, timeout=30, headers=headers) if r.status_code != 200: logging.error("Status code from server: " + str(r.status_code)) return None