Projects STRLCPY ghauri Commits a762fabf
🤬
  • updated code quality, fixed issue with resuming data fetching in threads, updated code to terminate all the threads gracefully on user interruption, fixed issue with MSSQL post based injection urlencoding, updated code quality for auto adjusting timeout and timesec in case of read timeout warning. bumped version 1.1.2.

  • Loading...
  • r0oth3x49 committed 1 year ago
    a762fabf
    1 parent 7d0cb182
  • ■ ■ ■ ■
    README.md
    1  -[![GitHub release](https://img.shields.io/badge/release-v1.1.1-brightgreen?style=flat-square)](https://github.com/r0oth3x49/ghauri/releases/tag/1.1.1)
     1 +[![GitHub release](https://img.shields.io/badge/release-v1.1.2-brightgreen?style=flat-square)](https://github.com/r0oth3x49/ghauri/releases/tag/1.1.2)
    2 2  [![GitHub stars](https://img.shields.io/github/stars/r0oth3x49/ghauri?style=flat-square)](https://github.com/r0oth3x49/ghauri/stargazers)
    3 3  [![GitHub forks](https://img.shields.io/github/forks/r0oth3x49/ghauri?style=flat-square)](https://github.com/r0oth3x49/ghauri/network)
    4 4  [![GitHub issues](https://img.shields.io/github/issues/r0oth3x49/ghauri?style=flat-square)](https://github.com/r0oth3x49/ghauri/issues)
    skipped 157 lines
  • ■ ■ ■ ■
    ghauri/__init__.py
    skipped 23 lines
    24 24   
    25 25  """
    26 26   
    27  -__version__ = "1.1.1"
     27 +__version__ = "1.1.2"
    28 28  __author__ = "Nasir Khan (r0ot h3x49)"
    29 29  __license__ = "MIT"
    30 30  __copyright__ = "Copyright (c) 2016-2025 Nasir Khan (r0ot h3x49)"
    skipped 2 lines
  • ■ ■ ■ ■ ■
    ghauri/common/config.py
    skipped 50 lines
    51 51   attack01=None,
    52 52   delay=0,
    53 53   timesec=5,
    54  - timeout=30,
     54 + timeout=None,
    55 55   backend=None,
    56 56   batch=False,
    57 57   continue_on_http_error=False,
    skipped 30 lines
    88 88   self.lock = Lock()
    89 89   self.thread_warning = False
    90 90   self.max_threads_warning = False
     91 + self._readtimout_counter = 0
    91 92   
    92 93   @property
    93 94   def session_filepath(self):
    skipped 7 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/common/lib.py
    skipped 52 lines
    53 53  from io import BytesIO, StringIO
    54 54  from difflib import SequenceMatcher
    55 55  import concurrent.futures as futures
     56 +from concurrent.futures import thread
    56 57  from threading import Lock
    57 58  from colorama import init, Fore, Back, Style
    58 59  from urllib.error import HTTPError, URLError
    skipped 201 lines
    260 261   length integer,
    261 262   type text
    262 263  );
     264 +CREATE INDEX idx_type
     265 +ON storage (type);
    263 266  """
    264 267   
    265 268  PAYLOAD_STATEMENT = """
    skipped 13 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/common/utils.py
    skipped 1089 lines
    1090 1090   value = param.get("value")
    1091 1091   is_json = conf.is_json
    1092 1092   is_multipart = conf.is_multipart
     1093 + safe = (
     1094 + "/=*()&?%;,+\"'"
     1095 + if conf.backend == "Microsoft SQL Server" and injection_type == "POST"
     1096 + else "/=*?&:;,+"
     1097 + )
    1093 1098   if not is_json and not key == "#1*":
    1094 1099   text = urlencode(
    1095 1100   value=text,
    1096  - safe="/=*?&:;,+",
     1101 + safe=safe,
    1097 1102   decode_first=True,
    1098 1103   injection_type=injection_type,
    1099 1104   is_multipart=is_multipart,
    1100 1105   )
    1101 1106   key = urlencode(
    1102 1107   value=key,
    1103  - safe="/=*?&:;,+",
     1108 + safe=safe,
    1104 1109   decode_first=True,
    1105 1110   injection_type=injection_type,
    1106 1111   is_multipart=is_multipart,
    1107 1112   )
    1108 1113   value = urlencode(
    1109 1114   value=value,
    1110  - safe="/=*?&:;,+",
     1115 + safe=safe,
    1111 1116   decode_first=True,
    1112 1117   injection_type=injection_type,
    1113 1118   is_multipart=is_multipart,
    skipped 702 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/core/extract.py
    skipped 104 lines
    105 105   linear_search = False
    106 106   retry_on_error = 0
    107 107   http_firewall_code_counter = 0
     108 + timesec = timesec if conf.timesec <= timesec else conf.timesec
    108 109   error_msg = None
    109 110   _temp = GuessUsing(
    110 111   ok=False,
    skipped 262 lines
    373 374   expression = vector.replace("[INFERENCE]", f"{condition}").replace(
    374 375   "[SLEEPTIME]", f"{timesec}"
    375 376   )
    376  - sleep_time = timesec
     377 + sleep_time = timesec if conf.timesec <= timesec else conf.timesec
    377 378   logger.payload(f"{expression}")
    378 379   try:
    379 380   attack = inject_expression(
    skipped 119 lines
    499 500   retry_on_error = 0
    500 501   if not conf.threads:
    501 502   logger.progress(f"retrieved: {chars}")
    502  - sleep_time = timesec
     503 + if conf.threads:
     504 + chars = "".join(
     505 + [
     506 + str(i)
     507 + for i in collections.OrderedDict(
     508 + sorted(conf._thread_chars_query.items())
     509 + ).values()
     510 + ]
     511 + )
     512 + logger.progress(f"retrieved: {chars}")
     513 + sleep_time = timesec if conf.timesec <= timesec else conf.timesec
    503 514   
    504 515   def chunks(lst, n):
    505 516   """Yield successive n-sized chunks from lst."""
    skipped 204 lines
    710 721   retry_on_error = 0
    711 722   if not conf.threads:
    712 723   logger.progress(f"retrieved: {chars}")
    713  - sleep_time = timesec
     724 + if conf.threads:
     725 + chars = "".join(
     726 + [
     727 + str(i)
     728 + for i in collections.OrderedDict(
     729 + sorted(conf._thread_chars_query.items())
     730 + ).values()
     731 + ]
     732 + )
     733 + logger.progress(f"retrieved: {chars}")
     734 + sleep_time = timesec if conf.timesec <= timesec else conf.timesec
    714 735   while not is_found:
    715 736   if http_firewall_code_counter > 2:
    716 737   message = f"{error_msg} - {http_firewall_code_counter} time(s)"
    skipped 22 lines
    739 760   exit(0)
    740 761   if choice == "c":
    741 762   retry_on_error = 0
     763 + if conf._readtimout_counter >= 3:
     764 + logger.warning(
     765 + f"Ghauri detected readtimout '{conf._readtimout_counter}' time(s), increasing --timeout to 120 seconds, default was 30 seconds.."
     766 + )
     767 + conf.timeout += 90
     768 + conf._readtimout_counter = 0
    742 769   if delay > 0:
    743 770   time.sleep(delay)
    744 771   ascii_char = int((minimum + maximum) / 2)
    skipped 148 lines
    893 920   http_firewall_code_counter = 0
    894 921   error_msg = None
    895 922   retry_on_error = 0
    896  - sleep_time = timesec
     923 + sleep_time = timesec if conf.timesec <= timesec else conf.timesec
    897 924   while start < end:
    898 925   if http_firewall_code_counter > 2:
    899 926   message = f"{error_msg} - {http_firewall_code_counter} time(s)"
    skipped 150 lines
    1050 1077   for i in range(1, 10):
    1051 1078   if delay > 0:
    1052 1079   time.sleep(delay)
    1053  - sleep_time = timesec
     1080 + sleep_time = timesec if conf.timesec <= timesec else conf.timesec
    1054 1081   condition = value.format(query=entry, char=i)
    1055 1082   expression = vector.replace("[INFERENCE]", f"{condition}").replace(
    1056 1083   "[SLEEPTIME]", f"{sleep_time}"
    skipped 655 lines
    1712 1739   conf._thread_chars_query.update({offset: "_"})
    1713 1740   for offset in range(pos, total_length)
    1714 1741   ]
     1742 + # dirty hack to add characters at position so that threads won't run forever to figure out characters..
     1743 + if chars and len(chars) >= 1:
     1744 + logger.debug("appending characters found already")
     1745 + for _, ch in enumerate(chars):
     1746 + conf._thread_chars_query.update({_ + 1: ch})
     1747 + conf._thread_chars_query = collections.OrderedDict(
     1748 + sorted(conf._thread_chars_query.items())
     1749 + )
    1715 1750   if conf.threads > conf._max_threads:
    1716 1751   conf.threads = 4
    1717 1752   if not conf.max_threads_warning:
    1718 1753   logger.warning(
    1719  - "ghauri recommends using threads upto 4. adjusting total number of threads to 4.."
     1754 + "ghauri recommends using threads upto 4. adjusting total number of threads to 4."
    1720 1755   )
    1721 1756   conf.max_threads_warning = True
    1722 1757   with futures.ThreadPoolExecutor(
    skipped 40 lines
    1763 1798   ): offset
    1764 1799   for offset in range(pos, total_length)
    1765 1800   }
    1766  - for future in futures.as_completed(exec_map):
    1767  - offset = exec_map[future]
    1768  - logger.progress("retrieved: {}".format(chars))
    1769  - try:
    1770  - character = future.result()
    1771  - except Exception as exc:
    1772  - logger.error(
    1773  - f" * generated an exception: '{exc}' on offset '{offset}'"
    1774  - )
    1775  - except KeyboardInterrupt as error:
    1776  - raise error
    1777  - else:
    1778  - if (
    1779  - character
    1780  - and character != ""
    1781  - and character is not None
    1782  - ):
    1783  - conf._thread_chars_query.update(
    1784  - {offset: character}
     1801 + try:
     1802 + for future in futures.as_completed(exec_map):
     1803 + offset = exec_map[future]
     1804 + logger.progress("retrieved: {}".format(chars))
     1805 + try:
     1806 + character = future.result()
     1807 + except Exception as exc:
     1808 + logger.error(
     1809 + f" * generated an exception: '{exc}' on offset '{offset}'"
    1785 1810   )
     1811 + except KeyboardInterrupt as error:
     1812 + raise error
     1813 + else:
     1814 + if (
     1815 + character
     1816 + and character != ""
     1817 + and character is not None
     1818 + ):
     1819 + conf._thread_chars_query.update(
     1820 + {offset: character}
     1821 + )
     1822 + except KeyboardInterrupt as error:
     1823 + logger.error(
     1824 + "user aborted, terminating threads gracefully"
     1825 + )
     1826 + raise error
    1786 1827   chars = "".join(
    1787 1828   [
    1788 1829   str(i)
    1789 1830   for i in collections.OrderedDict(
    1790  - conf._thread_chars_query.items()
     1831 + sorted(conf._thread_chars_query.items())
    1791 1832   ).values()
    1792 1833   ]
    1793 1834   )
    skipped 492 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/core/inject.py
    skipped 54 lines
    55 55   # if injection_type.upper() not in ["HEADER"]
    56 56   # else expression
    57 57   # )
     58 + if conf.timeout and conf.timeout > 30:
     59 + timeout = conf.timeout
    58 60   if injection_type in ["HEADER", "COOKIE"]:
    59 61   attack_headers = prepare_attack_request(
    60 62   headers,
    skipped 48 lines
  • ■ ■ ■ ■ ■
    ghauri/core/request.py
    skipped 154 lines
    155 155   response_time = end_time - start_time
    156 156   parsed_response = parse_http_error(e)
    157 157   except (socket.timeout, requests.exceptions.ReadTimeout) as e:
    158  - logger.warning("read timeout during connection response reading..")
     158 + logger.debug("read timeout during connection response reading..")
     159 + conf._readtimout_counter += 1
     160 + conf.timeout = 25
     161 + conf.timesec = 10
    159 162   end_time = time.time()
    160 163   response_time = end_time - start_time
    161 164   parsed_response = parse_http_error(e, url=url, is_timeout=True)
    skipped 55 lines
    217 220   response_time = end_time - start_time
    218 221   parsed_response = parse_http_error(e)
    219 222   except (socket.timeout, requests.exceptions.ReadTimeout) as e:
    220  - logger.warning("read timeout during connection response reading.")
     223 + logger.debug("read timeout during connection response reading.")
     224 + conf._readtimout_counter += 1
     225 + conf.timeout = 25
     226 + conf.timesec = 10
    221 227   end_time = time.time()
    222 228   response_time = end_time - start_time
    223 229   parsed_response = parse_http_error(e, url=url, is_timeout=True)
    skipped 52 lines
  • ■ ■ ■ ■
    setup.py
    skipped 4 lines
    5 5   
    6 6  setup(
    7 7   name="ghauri",
    8  - version="1.1.1",
     8 + version="1.1.2",
    9 9   description="An advanced SQL injection detection & exploitation tool.",
    10 10   classifiers=["Programming Language :: Python3"],
    11 11   author="Nasir Khan",
    skipped 28 lines
Please wait...
Page is in error, reload to recover