Projects STRLCPY ghauri Commits 7d0cb182
🤬
  • added threads support for boolean based blind injection only (this is just a testing phase.), fixed #24 (Add threads), updated code quality for multiple things according to threads.

  • Loading...
  • r0oth3x49 committed 1 year ago
    7d0cb182
    1 parent 7a5ac9d6
  • ■ ■ ■ ■ ■
    README.md
    1  -[![GitHub release](https://img.shields.io/badge/release-v1.1-brightgreen?style=flat-square)](https://github.com/r0oth3x49/ghauri/releases/tag/1.1)
     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)
    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 53 lines
    58 58  ## **Advanced Usage**
    59 59   
    60 60  <pre><code>
    61  -Author: Nasir khan (r0ot h3x49)
     61 +Author: Nasir khan (<a href="https://pk.linkedin.com/in/r0oth3x49">r0ot h3x49</a>)
    62 62   
    63 63  usage: ghauri -u URL [OPTIONS]
    64 64   
    skipped 29 lines
    94 94   --retries Retries when the connection related error occurs (default 3)
    95 95   --skip-urlencode Skip URL encoding of payload data
    96 96   --force-ssl Force usage of SSL/HTTPS
     97 + 
     98 +Optimization:
     99 + These options can be used to optimize the performance of ghauri
     100 + 
     101 + --threads THREADS Max number of concurrent HTTP(s) requests (default 1)
    97 102   
    98 103  Injection:
    99 104   These options can be used to specify which parameters to test for,
    skipped 57 lines
  • ■ ■ ■ ■
    ghauri/__init__.py
    skipped 23 lines
    24 24   
    25 25  """
    26 26   
    27  -__version__ = "1.1"
     27 +__version__ = "1.1.1"
    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 23 lines
    24 24   
    25 25  """
    26 26   
     27 +from ghauri.common.lib import Lock
     28 + 
    27 29   
    28 30  class GhauriConfigs:
    29 31   """
    skipped 24 lines
    54 56   batch=False,
    55 57   continue_on_http_error=False,
    56 58   follow_redirects=None,
     59 + threads=None,
    57 60   ):
    58 61   self.vectors = vectors
    59 62   self.is_string = is_string
    skipped 19 lines
    79 82   self.timesec = timesec
    80 83   self.continue_on_http_error = continue_on_http_error
    81 84   self.follow_redirects = follow_redirects
     85 + self.threads = threads
     86 + self._max_threads = 4
     87 + self._thread_chars_query = {}
     88 + self.lock = Lock()
     89 + self.thread_warning = False
     90 + self.max_threads_warning = False
    82 91   
    83 92   @property
    84 93   def session_filepath(self):
    skipped 7 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/common/lib.py
    skipped 51 lines
    52 52  from os.path import expanduser
    53 53  from io import BytesIO, StringIO
    54 54  from difflib import SequenceMatcher
     55 +import concurrent.futures as futures
     56 +from threading import Lock
    55 57  from colorama import init, Fore, Back, Style
    56 58  from urllib.error import HTTPError, URLError
    57 59  from http.server import BaseHTTPRequestHandler
    skipped 219 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/core/extract.py
    skipped 36 lines
    37 37   unquote,
    38 38   STORAGE,
    39 39   STORAGE_UPDATE,
     40 + futures,
    40 41  )
    41 42  from ghauri.common.payloads import (
    42 43   NUMBER_OF_CHARACTERS_PAYLOADS,
    skipped 278 lines
    321 322   text_only=False,
    322 323   retry=3,
    323 324   code=None,
     325 + *args,
     326 + **kwargs,
    324 327   ):
    325 328   # we will validate character indendified in case of boolean based blind sqli only for now..
    326 329   is_valid = False
    skipped 155 lines
    482 485   chars="",
    483 486   vector_type=None,
    484 487   retry=3,
     488 + *args,
     489 + **kwargs,
    485 490   ):
    486 491   if not minimum:
    487 492   minimum = 32
    skipped 4 lines
    492 497   http_firewall_code_counter = 0
    493 498   error_msg = None
    494 499   retry_on_error = 0
    495  - logger.progress(f"retrieved: {chars}")
     500 + if not conf.threads:
     501 + logger.progress(f"retrieved: {chars}")
    496 502   sleep_time = timesec
    497 503   
    498 504   def chunks(lst, n):
    skipped 97 lines
    596 602   if len(characters_list) == 1:
    597 603   character = characters_list.pop()
    598 604   character = chr(int(character))
     605 + if conf.threads:
     606 + conf._thread_chars_query.update({offset: character})
     607 + chars = "".join(
     608 + [
     609 + str(i)
     610 + for i in collections.OrderedDict(
     611 + conf._thread_chars_query.items()
     612 + ).values()
     613 + ]
     614 + )
     615 + logger.progress(f"retrieved: {chars}")
    599 616   is_found = True
    600 617   break
    601 618   else:
    skipped 75 lines
    677 694   chars="",
    678 695   vector_type=None,
    679 696   retry=3,
     697 + *args,
     698 + **kwargs,
    680 699   ):
    681 700   # need to implement retry mechanism in case of http connection related errors..
    682 701   if not minimum:
    skipped 6 lines
    689 708   http_firewall_code_counter = 0
    690 709   error_msg = None
    691 710   retry_on_error = 0
    692  - logger.progress(f"retrieved: {chars}")
     711 + if not conf.threads:
     712 + logger.progress(f"retrieved: {chars}")
    693 713   sleep_time = timesec
    694 714   while not is_found:
    695 715   if http_firewall_code_counter > 2:
    skipped 29 lines
    725 745   if (minimum == ascii_char) & (maximum == ascii_char):
    726 746   is_found = True
    727 747   character = str(chr(ascii_char))
    728  - logger.progress(f"retrieved: {chars}{character}")
     748 + if not conf.threads:
     749 + logger.progress(f"retrieved: {chars}{character}")
     750 + if conf.threads:
     751 + conf._thread_chars_query.update({offset: character})
     752 + chars = "".join(
     753 + [
     754 + str(i)
     755 + for i in collections.OrderedDict(
     756 + conf._thread_chars_query.items()
     757 + ).values()
     758 + ]
     759 + )
     760 + logger.progress(f"retrieved: {chars}")
    729 761   break
    730 762   condition = expression_payload.format(
    731 763   query=queryable, position=offset, char=ascii_char
    skipped 57 lines
    789 821   minimum = minimum
    790 822   maximum = ascii_char
    791 823   except KeyboardInterrupt as error:
     824 + if conf.threads:
     825 + raise error
    792 826   logger.warning("user aborted during data extraction phase")
    793 827   quest = logger.read_input(
    794 828   "how do you want to proceed? [(C)continue/(e)nd this phase/(q)uit] ",
    skipped 54 lines
    849 883   vector_type=None,
    850 884   retry=3,
    851 885   base=None,
     886 + *args,
     887 + **kwargs,
    852 888   ):
    853 889   # need to implement retry mechanism in case of http connection related errors..
    854 890   character = ""
    skipped 806 lines
    1661 1697   chars = start_chars
    1662 1698   pos = start_pos
    1663 1699   total_length = length + 1
    1664  - while pos < total_length:
    1665  - start_pos = pos
    1666  - if attack01 and vector_type == "boolean_vector":
    1667  - # extract characters using binary search algorithm
    1668  - try:
    1669  - if binary_search:
    1670  - retval = self._binary_search(
    1671  - url=url,
    1672  - data=data,
    1673  - vector=vector,
    1674  - parameter=parameter,
    1675  - headers=headers,
    1676  - base=base,
    1677  - injection_type=injection_type,
    1678  - delay=delay,
    1679  - timesec=timesec,
    1680  - timeout=timeout,
    1681  - proxy=proxy,
    1682  - attack01=attack01,
    1683  - code=code,
    1684  - match_string=match_string,
    1685  - not_match_string=not_match_string,
    1686  - is_multipart=is_multipart,
    1687  - suppress_output=suppress_output,
    1688  - query_check=query_check,
    1689  - minimum=32,
    1690  - maximum=127,
    1691  - offset=pos,
    1692  - expression_payload=value,
    1693  - queryable=entry,
    1694  - chars=chars,
    1695  - text_only=text_only,
    1696  - vector_type=vector_type,
     1700 + if conf.threads and not binary_search and not in_based_search:
     1701 + logger.warning(
     1702 + "ghauri will use a fallback leaner search to guess character(s), adjusting threads to 1"
     1703 + )
     1704 + conf.threads = None
     1705 + if conf.threads and vector_type == "boolean_vector":
     1706 + if not conf.thread_warning:
     1707 + logger.warning(
     1708 + "it is recommended not to use threads for data exfiltration, it could cause harm to backend DBMS or result in incorrect character(s) guessing."
     1709 + )
     1710 + conf.thread_warning = True
     1711 + [
     1712 + conf._thread_chars_query.update({offset: "_"})
     1713 + for offset in range(pos, total_length)
     1714 + ]
     1715 + if conf.threads > conf._max_threads:
     1716 + conf.threads = 4
     1717 + if not conf.max_threads_warning:
     1718 + logger.warning(
     1719 + "ghauri recommends using threads upto 4. adjusting total number of threads to 4.."
     1720 + )
     1721 + conf.max_threads_warning = True
     1722 + with futures.ThreadPoolExecutor(
     1723 + max_workers=conf.threads
     1724 + ) as ex:
     1725 + exfiltration_func = None
     1726 + # we will only use IN and > for exfitration of data using threads
     1727 + # using linear search might cause issues with backend dbms as the complexity of this technique is high
     1728 + if binary_search:
     1729 + exfiltration_func = self._binary_search
     1730 + if in_based_search:
     1731 + exfiltration_func = self._search_using_in_operator
     1732 + # if linear_search:
     1733 + # exfiltration_func = self._linear_search
     1734 + exec_map = {
     1735 + ex.submit(
     1736 + exfiltration_func,
     1737 + url=url,
     1738 + data=data,
     1739 + vector=vector,
     1740 + parameter=parameter,
     1741 + headers=headers,
     1742 + base=base,
     1743 + injection_type=injection_type,
     1744 + delay=delay,
     1745 + timesec=timesec,
     1746 + timeout=timeout,
     1747 + proxy=proxy,
     1748 + attack01=attack01,
     1749 + code=code,
     1750 + match_string=match_string,
     1751 + not_match_string=not_match_string,
     1752 + is_multipart=is_multipart,
     1753 + suppress_output=suppress_output,
     1754 + query_check=query_check,
     1755 + minimum=32,
     1756 + maximum=127,
     1757 + offset=offset,
     1758 + expression_payload=value,
     1759 + queryable=entry,
     1760 + chars=chars,
     1761 + text_only=text_only,
     1762 + vector_type=vector_type,
     1763 + ): offset
     1764 + for offset in range(pos, total_length)
     1765 + }
     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}'"
    1697 1774   )
    1698  - if retval:
    1699  - is_valid = self.validate_character(
     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}
     1785 + )
     1786 + chars = "".join(
     1787 + [
     1788 + str(i)
     1789 + for i in collections.OrderedDict(
     1790 + conf._thread_chars_query.items()
     1791 + ).values()
     1792 + ]
     1793 + )
     1794 + conf._thread_chars_query = {}
     1795 + with conf.lock:
     1796 + try:
     1797 + if dump_type and chars:
     1798 + session.dump(
     1799 + session_filepath=conf.session_filepath,
     1800 + query=STORAGE_UPDATE,
     1801 + values=(
     1802 + chars,
     1803 + last_row_id,
     1804 + dump_type,
     1805 + ),
     1806 + )
     1807 + except Exception as error:
     1808 + logger.warning(error)
     1809 + logger.debug(f"character(s) found: '{chars}'")
     1810 + else:
     1811 + while pos < total_length:
     1812 + start_pos = pos
     1813 + if attack01 and vector_type == "boolean_vector":
     1814 + # extract characters using binary search algorithm
     1815 + try:
     1816 + if binary_search:
     1817 + retval = self._binary_search(
    1700 1818   url=url,
    1701 1819   data=data,
    1702 1820   vector=vector,
    skipped 1 lines
    1704 1822   headers=headers,
    1705 1823   base=base,
    1706 1824   injection_type=injection_type,
    1707  - proxy=proxy,
    1708  - is_multipart=is_multipart,
    1709  - timeout=timeout,
    1710 1825   delay=delay,
    1711 1826   timesec=timesec,
    1712  - identified_character=retval,
    1713  - vector_type=vector_type,
     1827 + timeout=timeout,
     1828 + proxy=proxy,
     1829 + attack01=attack01,
     1830 + code=code,
     1831 + match_string=match_string,
     1832 + not_match_string=not_match_string,
     1833 + is_multipart=is_multipart,
     1834 + suppress_output=suppress_output,
     1835 + query_check=query_check,
     1836 + minimum=32,
     1837 + maximum=127,
    1714 1838   offset=pos,
    1715 1839   expression_payload=value,
    1716 1840   queryable=entry,
    1717  - code=code,
    1718  - match_string=match_string,
    1719  - not_match_string=not_match_string,
    1720  - attack01=attack01,
     1841 + chars=chars,
     1842 + text_only=text_only,
     1843 + vector_type=vector_type,
    1721 1844   )
    1722  - if not is_valid:
    1723  - logger.warning(
    1724  - "invalid character detected, retrying."
     1845 + if retval:
     1846 + is_valid = self.validate_character(
     1847 + url=url,
     1848 + data=data,
     1849 + vector=vector,
     1850 + parameter=parameter,
     1851 + headers=headers,
     1852 + base=base,
     1853 + injection_type=injection_type,
     1854 + proxy=proxy,
     1855 + is_multipart=is_multipart,
     1856 + timeout=timeout,
     1857 + delay=delay,
     1858 + timesec=timesec,
     1859 + identified_character=retval,
     1860 + vector_type=vector_type,
     1861 + offset=pos,
     1862 + expression_payload=value,
     1863 + queryable=entry,
     1864 + code=code,
     1865 + match_string=match_string,
     1866 + not_match_string=not_match_string,
     1867 + attack01=attack01,
    1725 1868   )
    1726  - bool_invalid_character_counter += 1
    1727  - binary_search = False
    1728  - in_based_search = True
    1729  - linear_search = False
    1730  - if is_valid:
    1731  - pos += 1
    1732  - chars += retval
    1733  - elif in_based_search:
    1734  - retval = self._search_using_in_operator(
    1735  - url=url,
    1736  - data=data,
    1737  - vector=vector,
    1738  - parameter=parameter,
    1739  - headers=headers,
    1740  - base=base,
    1741  - injection_type=injection_type,
    1742  - delay=delay,
    1743  - timesec=timesec,
    1744  - timeout=timeout,
    1745  - proxy=proxy,
    1746  - attack01=attack01,
    1747  - match_string=match_string,
    1748  - not_match_string=not_match_string,
    1749  - text_only=text_only,
    1750  - is_multipart=is_multipart,
    1751  - suppress_output=suppress_output,
    1752  - query_check=query_check,
    1753  - minimum=32,
    1754  - maximum=127,
    1755  - offset=pos,
    1756  - expression_payload=value,
    1757  - queryable=entry,
    1758  - chars=chars,
    1759  - vector_type=vector_type,
    1760  - )
    1761  - if retval:
    1762  - is_valid = self.validate_character(
     1869 + if not is_valid:
     1870 + logger.warning(
     1871 + "invalid character detected, retrying."
     1872 + )
     1873 + bool_invalid_character_counter += 1
     1874 + binary_search = False
     1875 + in_based_search = True
     1876 + linear_search = False
     1877 + if is_valid:
     1878 + pos += 1
     1879 + chars += retval
     1880 + elif in_based_search:
     1881 + retval = self._search_using_in_operator(
    1763 1882   url=url,
    1764 1883   data=data,
    1765 1884   vector=vector,
    skipped 1 lines
    1767 1886   headers=headers,
    1768 1887   base=base,
    1769 1888   injection_type=injection_type,
     1889 + delay=delay,
     1890 + timesec=timesec,
     1891 + timeout=timeout,
    1770 1892   proxy=proxy,
     1893 + attack01=attack01,
     1894 + match_string=match_string,
     1895 + not_match_string=not_match_string,
     1896 + text_only=text_only,
    1771 1897   is_multipart=is_multipart,
    1772  - timeout=timeout,
    1773  - delay=delay,
    1774  - timesec=timesec,
    1775  - identified_character=retval,
    1776  - vector_type=vector_type,
     1898 + suppress_output=suppress_output,
     1899 + query_check=query_check,
     1900 + minimum=32,
     1901 + maximum=127,
    1777 1902   offset=pos,
    1778 1903   expression_payload=value,
    1779 1904   queryable=entry,
    1780  - code=code,
    1781  - match_string=match_string,
    1782  - not_match_string=not_match_string,
    1783  - attack01=attack01,
     1905 + chars=chars,
     1906 + vector_type=vector_type,
    1784 1907   )
    1785  - if not is_valid:
    1786  - logger.warning(
    1787  - "invalid character detected, retrying."
     1908 + if retval:
     1909 + is_valid = self.validate_character(
     1910 + url=url,
     1911 + data=data,
     1912 + vector=vector,
     1913 + parameter=parameter,
     1914 + headers=headers,
     1915 + base=base,
     1916 + injection_type=injection_type,
     1917 + proxy=proxy,
     1918 + is_multipart=is_multipart,
     1919 + timeout=timeout,
     1920 + delay=delay,
     1921 + timesec=timesec,
     1922 + identified_character=retval,
     1923 + vector_type=vector_type,
     1924 + offset=pos,
     1925 + expression_payload=value,
     1926 + queryable=entry,
     1927 + code=code,
     1928 + match_string=match_string,
     1929 + not_match_string=not_match_string,
     1930 + attack01=attack01,
    1788 1931   )
    1789  - bool_invalid_character_counter += 1
    1790  - binary_search = False
    1791  - in_based_search = False
    1792  - linear_search = True
    1793  - if is_valid:
    1794  - pos += 1
    1795  - chars += retval
    1796  - else:
    1797  - retval = self._linear_search(
    1798  - url=url,
    1799  - data=data,
    1800  - vector=vector,
    1801  - parameter=parameter,
    1802  - headers=headers,
    1803  - injection_type=injection_type,
    1804  - proxy=proxy,
    1805  - attack01=attack01,
    1806  - is_multipart=is_multipart,
    1807  - timeout=timeout,
    1808  - match_string=match_string,
    1809  - not_match_string=not_match_string,
    1810  - text_only=text_only,
    1811  - delay=delay,
    1812  - timesec=timesec,
    1813  - suppress_output=suppress_output,
    1814  - expression_payload=value,
    1815  - queryable=entry,
    1816  - chars=chars,
    1817  - offset=pos,
    1818  - list_of_chars=list_of_chars,
    1819  - vector_type=vector_type,
    1820  - base=base,
    1821  - )
    1822  - if retval:
    1823  - is_valid = self.validate_character(
     1932 + if not is_valid:
     1933 + logger.warning(
     1934 + "invalid character detected, retrying."
     1935 + )
     1936 + bool_invalid_character_counter += 1
     1937 + binary_search = False
     1938 + in_based_search = False
     1939 + linear_search = True
     1940 + if is_valid:
     1941 + pos += 1
     1942 + chars += retval
     1943 + else:
     1944 + retval = self._linear_search(
    1824 1945   url=url,
    1825 1946   data=data,
    1826 1947   vector=vector,
    1827 1948   parameter=parameter,
    1828 1949   headers=headers,
    1829  - base=base,
    1830 1950   injection_type=injection_type,
    1831 1951   proxy=proxy,
     1952 + attack01=attack01,
    1832 1953   is_multipart=is_multipart,
    1833 1954   timeout=timeout,
     1955 + match_string=match_string,
     1956 + not_match_string=not_match_string,
     1957 + text_only=text_only,
    1834 1958   delay=delay,
    1835 1959   timesec=timesec,
    1836  - identified_character=retval,
    1837  - vector_type=vector_type,
    1838  - offset=pos,
     1960 + suppress_output=suppress_output,
    1839 1961   expression_payload=value,
    1840 1962   queryable=entry,
    1841  - code=code,
    1842  - match_string=match_string,
    1843  - not_match_string=not_match_string,
    1844  - attack01=attack01,
     1963 + chars=chars,
     1964 + offset=pos,
     1965 + list_of_chars=list_of_chars,
     1966 + vector_type=vector_type,
     1967 + base=base,
    1845 1968   )
    1846  - if not is_valid:
    1847  - logger.warning(
    1848  - "invalid character detected, retrying."
     1969 + if retval:
     1970 + is_valid = self.validate_character(
     1971 + url=url,
     1972 + data=data,
     1973 + vector=vector,
     1974 + parameter=parameter,
     1975 + headers=headers,
     1976 + base=base,
     1977 + injection_type=injection_type,
     1978 + proxy=proxy,
     1979 + is_multipart=is_multipart,
     1980 + timeout=timeout,
     1981 + delay=delay,
     1982 + timesec=timesec,
     1983 + identified_character=retval,
     1984 + vector_type=vector_type,
     1985 + offset=pos,
     1986 + expression_payload=value,
     1987 + queryable=entry,
     1988 + code=code,
     1989 + match_string=match_string,
     1990 + not_match_string=not_match_string,
     1991 + attack01=attack01,
    1849 1992   )
    1850  - bool_invalid_character_counter += 1
    1851  - binary_search = (
    1852  - retval_check.binary_search
     1993 + if not is_valid:
     1994 + logger.warning(
     1995 + "invalid character detected, retrying."
     1996 + )
     1997 + bool_invalid_character_counter += 1
     1998 + binary_search = (
     1999 + retval_check.binary_search
     2000 + )
     2001 + in_based_search = (
     2002 + retval_check.in_based_search
     2003 + )
     2004 + linear_search = (
     2005 + retval_check.linear_search
     2006 + )
     2007 + if is_valid:
     2008 + pos += 1
     2009 + chars += retval
     2010 + try:
     2011 + if bool_invalid_character_counter >= 3:
     2012 + logger.debug(
     2013 + "it seems the current payload is filtered out by some sort of WAF/IDS."
    1853 2014   )
    1854  - in_based_search = (
    1855  - retval_check.in_based_search
     2015 + break
     2016 + if dump_type and chars:
     2017 + session.dump(
     2018 + session_filepath=conf.session_filepath,
     2019 + query=STORAGE_UPDATE,
     2020 + values=(
     2021 + chars,
     2022 + last_row_id,
     2023 + dump_type,
     2024 + ),
    1856 2025   )
    1857  - linear_search = (
    1858  - retval_check.linear_search
    1859  - )
    1860  - if is_valid:
    1861  - pos += 1
    1862  - chars += retval
     2026 + except Exception as error:
     2027 + logger.warning(error)
     2028 + logger.debug(
     2029 + f"character(s) found: '{str(chars)}'"
     2030 + )
     2031 + except KeyboardInterrupt:
     2032 + is_char_found = True
     2033 + is_extracted = True
     2034 + is_done_with_vector = True
     2035 + if chars and len(chars) > 0:
     2036 + logger.info(f"retrieved: '{chars}'")
     2037 + _temp = PayloadResponse(
     2038 + ok=False,
     2039 + error="user_ended",
     2040 + result=chars,
     2041 + payload=entry,
     2042 + resumed=False,
     2043 + )
     2044 + break
     2045 + if vector_type == "time_vector":
    1863 2046   try:
    1864  - if bool_invalid_character_counter >= 3:
    1865  - logger.debug(
    1866  - "it seems the current payload is filtered out by some sort of WAF/IDS."
    1867  - )
    1868  - break
    1869  - if dump_type and chars:
    1870  - session.dump(
    1871  - session_filepath=conf.session_filepath,
    1872  - query=STORAGE_UPDATE,
    1873  - values=(
    1874  - chars,
    1875  - last_row_id,
    1876  - dump_type,
    1877  - ),
    1878  - )
    1879  - except Exception as error:
    1880  - logger.warning(error)
    1881  - logger.debug(f"character(s) found: '{str(chars)}'")
    1882  - except KeyboardInterrupt:
    1883  - is_char_found = True
    1884  - is_extracted = True
    1885  - is_done_with_vector = True
    1886  - if chars and len(chars) > 0:
    1887  - logger.info(f"retrieved: '{chars}'")
    1888  - _temp = PayloadResponse(
    1889  - ok=False,
    1890  - error="user_ended",
    1891  - result=chars,
    1892  - payload=entry,
    1893  - resumed=False,
    1894  - )
    1895  - break
    1896  - if vector_type == "time_vector":
    1897  - try:
    1898  - if binary_search:
    1899  - retval = self._binary_search(
    1900  - url=url,
    1901  - data=data,
    1902  - vector=vector,
    1903  - parameter=parameter,
    1904  - headers=headers,
    1905  - base=base,
    1906  - injection_type=injection_type,
    1907  - delay=delay,
    1908  - timesec=timesec,
    1909  - timeout=timeout,
    1910  - proxy=proxy,
    1911  - is_multipart=is_multipart,
    1912  - suppress_output=suppress_output,
    1913  - query_check=query_check,
    1914  - minimum=32,
    1915  - maximum=127,
    1916  - offset=pos,
    1917  - expression_payload=value,
    1918  - queryable=entry,
    1919  - chars=chars,
    1920  - vector_type=vector_type,
    1921  - )
    1922  - if retval:
    1923  - is_valid = self.validate_character(
     2047 + if binary_search:
     2048 + retval = self._binary_search(
    1924 2049   url=url,
    1925 2050   data=data,
    1926 2051   vector=vector,
    skipped 1 lines
    1928 2053   headers=headers,
    1929 2054   base=base,
    1930 2055   injection_type=injection_type,
     2056 + delay=delay,
     2057 + timesec=timesec,
     2058 + timeout=timeout,
    1931 2059   proxy=proxy,
    1932 2060   is_multipart=is_multipart,
    1933  - timeout=timeout,
    1934  - delay=delay,
    1935  - timesec=timesec,
    1936  - identified_character=retval,
    1937  - vector_type=vector_type,
     2061 + suppress_output=suppress_output,
     2062 + query_check=query_check,
     2063 + minimum=32,
     2064 + maximum=127,
    1938 2065   offset=pos,
    1939 2066   expression_payload=value,
    1940 2067   queryable=entry,
     2068 + chars=chars,
     2069 + vector_type=vector_type,
    1941 2070   )
    1942  - if not is_valid:
    1943  - logger.warning(
    1944  - "invalid character detected, retrying."
     2071 + if retval:
     2072 + is_valid = self.validate_character(
     2073 + url=url,
     2074 + data=data,
     2075 + vector=vector,
     2076 + parameter=parameter,
     2077 + headers=headers,
     2078 + base=base,
     2079 + injection_type=injection_type,
     2080 + proxy=proxy,
     2081 + is_multipart=is_multipart,
     2082 + timeout=timeout,
     2083 + delay=delay,
     2084 + timesec=timesec,
     2085 + identified_character=retval,
     2086 + vector_type=vector_type,
     2087 + offset=pos,
     2088 + expression_payload=value,
     2089 + queryable=entry,
    1945 2090   )
    1946  - invalid_character_detection_counter += 1
    1947  - binary_search = False
    1948  - in_based_search = True
    1949  - linear_search = False
    1950  - if is_valid:
    1951  - pos += 1
    1952  - chars += retval
    1953  - elif in_based_search:
    1954  - retval = self._search_using_in_operator(
    1955  - url=url,
    1956  - data=data,
    1957  - vector=vector,
    1958  - parameter=parameter,
    1959  - headers=headers,
    1960  - base=base,
    1961  - injection_type=injection_type,
    1962  - delay=delay,
    1963  - timesec=timesec,
    1964  - timeout=timeout,
    1965  - proxy=proxy,
    1966  - is_multipart=is_multipart,
    1967  - suppress_output=suppress_output,
    1968  - query_check=query_check,
    1969  - minimum=32,
    1970  - maximum=127,
    1971  - offset=pos,
    1972  - expression_payload=value,
    1973  - queryable=entry,
    1974  - chars=chars,
    1975  - vector_type=vector_type,
    1976  - )
    1977  - if retval:
    1978  - is_valid = self.validate_character(
     2091 + if not is_valid:
     2092 + logger.warning(
     2093 + "invalid character detected, retrying."
     2094 + )
     2095 + invalid_character_detection_counter += (
     2096 + 1
     2097 + )
     2098 + binary_search = False
     2099 + in_based_search = True
     2100 + linear_search = False
     2101 + if is_valid:
     2102 + pos += 1
     2103 + chars += retval
     2104 + elif in_based_search:
     2105 + retval = self._search_using_in_operator(
    1979 2106   url=url,
    1980 2107   data=data,
    1981 2108   vector=vector,
    skipped 1 lines
    1983 2110   headers=headers,
    1984 2111   base=base,
    1985 2112   injection_type=injection_type,
    1986  - proxy=proxy,
    1987  - is_multipart=is_multipart,
    1988  - timeout=timeout,
    1989 2113   delay=delay,
    1990 2114   timesec=timesec,
    1991  - identified_character=retval,
    1992  - vector_type=vector_type,
     2115 + timeout=timeout,
     2116 + proxy=proxy,
     2117 + is_multipart=is_multipart,
     2118 + suppress_output=suppress_output,
     2119 + query_check=query_check,
     2120 + minimum=32,
     2121 + maximum=127,
    1993 2122   offset=pos,
    1994 2123   expression_payload=value,
    1995 2124   queryable=entry,
     2125 + chars=chars,
     2126 + vector_type=vector_type,
    1996 2127   )
    1997  - if not is_valid:
    1998  - logger.warning(
    1999  - "invalid character detected, retrying.."
     2128 + if retval:
     2129 + is_valid = self.validate_character(
     2130 + url=url,
     2131 + data=data,
     2132 + vector=vector,
     2133 + parameter=parameter,
     2134 + headers=headers,
     2135 + base=base,
     2136 + injection_type=injection_type,
     2137 + proxy=proxy,
     2138 + is_multipart=is_multipart,
     2139 + timeout=timeout,
     2140 + delay=delay,
     2141 + timesec=timesec,
     2142 + identified_character=retval,
     2143 + vector_type=vector_type,
     2144 + offset=pos,
     2145 + expression_payload=value,
     2146 + queryable=entry,
    2000 2147   )
    2001  - invalid_character_detection_counter += 1
    2002  - binary_search = False
    2003  - in_based_search = False
    2004  - linear_search = True
    2005  - if is_valid:
    2006  - pos += 1
    2007  - chars += retval
    2008  - else:
    2009  - retval = self._linear_search(
    2010  - url=url,
    2011  - data=data,
    2012  - vector=vector,
    2013  - parameter=parameter,
    2014  - headers=headers,
    2015  - injection_type=injection_type,
    2016  - proxy=proxy,
    2017  - is_multipart=is_multipart,
    2018  - timeout=timeout,
    2019  - delay=delay,
    2020  - timesec=timesec,
    2021  - suppress_output=suppress_output,
    2022  - expression_payload=value,
    2023  - queryable=entry,
    2024  - chars=chars,
    2025  - offset=pos,
    2026  - list_of_chars=list_of_chars,
    2027  - vector_type=vector_type,
    2028  - )
    2029  - if retval:
    2030  - is_valid = self.validate_character(
     2148 + if not is_valid:
     2149 + logger.warning(
     2150 + "invalid character detected, retrying.."
     2151 + )
     2152 + invalid_character_detection_counter += (
     2153 + 1
     2154 + )
     2155 + binary_search = False
     2156 + in_based_search = False
     2157 + linear_search = True
     2158 + if is_valid:
     2159 + pos += 1
     2160 + chars += retval
     2161 + else:
     2162 + retval = self._linear_search(
    2031 2163   url=url,
    2032 2164   data=data,
    2033 2165   vector=vector,
    2034 2166   parameter=parameter,
    2035 2167   headers=headers,
    2036  - base=base,
    2037 2168   injection_type=injection_type,
    2038 2169   proxy=proxy,
    2039 2170   is_multipart=is_multipart,
    2040 2171   timeout=timeout,
    2041 2172   delay=delay,
    2042 2173   timesec=timesec,
    2043  - identified_character=retval,
    2044  - vector_type=vector_type,
    2045  - offset=pos,
     2174 + suppress_output=suppress_output,
    2046 2175   expression_payload=value,
    2047 2176   queryable=entry,
     2177 + chars=chars,
     2178 + offset=pos,
     2179 + list_of_chars=list_of_chars,
     2180 + vector_type=vector_type,
    2048 2181   )
    2049  - if not is_valid:
    2050  - logger.warning(
    2051  - "invalid character detected, retrying.."
     2182 + if retval:
     2183 + is_valid = self.validate_character(
     2184 + url=url,
     2185 + data=data,
     2186 + vector=vector,
     2187 + parameter=parameter,
     2188 + headers=headers,
     2189 + base=base,
     2190 + injection_type=injection_type,
     2191 + proxy=proxy,
     2192 + is_multipart=is_multipart,
     2193 + timeout=timeout,
     2194 + delay=delay,
     2195 + timesec=timesec,
     2196 + identified_character=retval,
     2197 + vector_type=vector_type,
     2198 + offset=pos,
     2199 + expression_payload=value,
     2200 + queryable=entry,
    2052 2201   )
    2053  - invalid_character_detection_counter += 1
    2054  - binary_search = (
    2055  - retval_check.binary_search
     2202 + if not is_valid:
     2203 + logger.warning(
     2204 + "invalid character detected, retrying.."
     2205 + )
     2206 + invalid_character_detection_counter += (
     2207 + 1
     2208 + )
     2209 + binary_search = (
     2210 + retval_check.binary_search
     2211 + )
     2212 + in_based_search = (
     2213 + retval_check.in_based_search
     2214 + )
     2215 + linear_search = (
     2216 + retval_check.linear_search
     2217 + )
     2218 + if is_valid:
     2219 + pos += 1
     2220 + chars += retval
     2221 + chars += retval
     2222 + pos += 1
     2223 + try:
     2224 + if invalid_character_detection_counter >= 3:
     2225 + logger.debug(
     2226 + "it seems the current payload is filtered out by some sort of WAF/IDS."
    2056 2227   )
    2057  - in_based_search = (
    2058  - retval_check.in_based_search
    2059  - )
    2060  - linear_search = (
    2061  - retval_check.linear_search
     2228 + break
     2229 + if dump_type and chars:
     2230 + session.dump(
     2231 + session_filepath=conf.session_filepath,
     2232 + query=STORAGE_UPDATE,
     2233 + values=(
     2234 + chars,
     2235 + last_row_id,
     2236 + dump_type,
     2237 + ),
    2062 2238   )
    2063  - if is_valid:
    2064  - pos += 1
    2065  - chars += retval
    2066  - chars += retval
    2067  - pos += 1
    2068  - try:
    2069  - if invalid_character_detection_counter >= 3:
    2070  - logger.debug(
    2071  - "it seems the current payload is filtered out by some sort of WAF/IDS."
    2072  - )
    2073  - break
    2074  - if dump_type and chars:
    2075  - session.dump(
    2076  - session_filepath=conf.session_filepath,
    2077  - query=STORAGE_UPDATE,
    2078  - values=(
    2079  - chars,
    2080  - last_row_id,
    2081  - dump_type,
    2082  - ),
    2083  - )
    2084  - except Exception as error:
    2085  - logger.warning(error)
    2086  - logger.debug(f"character(s) found: '{str(chars)}'")
    2087  - except KeyboardInterrupt:
    2088  - is_char_found = True
    2089  - is_extracted = True
    2090  - is_done_with_vector = True
    2091  - if chars and len(chars) > 0:
    2092  - logger.info(f"retrieved: '{chars}'")
    2093  - _temp = PayloadResponse(
    2094  - ok=False,
    2095  - error="user_ended",
    2096  - result=chars,
    2097  - payload=entry,
    2098  - resumed=is_resumed,
    2099  - )
    2100  - break
     2239 + except Exception as error:
     2240 + logger.warning(error)
     2241 + logger.debug(
     2242 + f"character(s) found: '{str(chars)}'"
     2243 + )
     2244 + except KeyboardInterrupt:
     2245 + is_char_found = True
     2246 + is_extracted = True
     2247 + is_done_with_vector = True
     2248 + if chars and len(chars) > 0:
     2249 + logger.info(f"retrieved: '{chars}'")
     2250 + _temp = PayloadResponse(
     2251 + ok=False,
     2252 + error="user_ended",
     2253 + result=chars,
     2254 + payload=entry,
     2255 + resumed=is_resumed,
     2256 + )
     2257 + break
    2101 2258   if len(chars) == length:
    2102 2259   is_char_found = True
    2103 2260   _temp = PayloadResponse(
    skipped 25 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/ghauri.py
    skipped 83 lines
    84 84   not_string=None,
    85 85   text_only=False,
    86 86   skip_urlencoding=False,
     87 + threads=None,
    87 88  ):
    88 89   verbose_levels = {
    89 90   1: logging.INFO,
    skipped 11 lines
    101 102   conf.proxy = proxy = prepare_proxy(proxy)
    102 103   verbose_level = verbose_levels.get(verbosity, logging.INFO)
    103 104   set_level(verbose_level, "")
     105 + if threads and threads > 1:
     106 + conf.threads = threads
    104 107   GhauriResponse = collections.namedtuple(
    105 108   "GhauriResponse",
    106 109   [
    skipped 691 lines
  • ■ ■ ■ ■ ■
    ghauri/logger/colored_logger.py
    skipped 34 lines
    35 35   RESET,
    36 36  )
    37 37  from ghauri.common.lib import os, sys, time, logging, collections
     38 +from ghauri.common.config import conf
    38 39   
    39 40  log = logging.getLogger("ghauri-logs")
    40 41   
    skipped 175 lines
    216 217   levelname = colorize("INFO", color="green", normal=True)
    217 218   message = f"{start}{asctime}{end} {start}{levelname}{end} {message}"
    218 219   if not done:
    219  - sys.stdout.write("\r\r\r\033[2K\033[1G\r")
    220  - sys.stdout.flush()
    221  - sys.stdout.write("\r\r\r\033[2K\033[1G\r{}\r".format(message))
    222  - sys.stdout.flush()
     220 + if not conf.threads:
     221 + sys.stdout.write("\r\r\r\033[2K\033[1G\r")
     222 + sys.stdout.flush()
     223 + sys.stdout.write("\r\r\r\033[2K\033[1G\r{}\r".format(message))
     224 + sys.stdout.flush()
     225 + if conf.threads:
     226 + with conf.lock:
     227 + print(
     228 + message,
     229 + end="\r" * len(message),
     230 + flush=True,
     231 + )
    223 232   if done:
    224 233   sys.stdout.write("\033[2K\033[1G\r\r{}\r\n".format(message))
    225 234   sys.stdout.flush()
    skipped 52 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/scripts/ghauri.py
    skipped 187 lines
    188 188   action="store_true",
    189 189   help="Force usage of SSL/HTTPS",
    190 190   )
     191 + optimization = parser.add_argument_group(
     192 + "Optimization",
     193 + description="These options can be used to optimize the performance of ghauri",
     194 + )
     195 + optimization.add_argument(
     196 + "--threads",
     197 + dest="threads",
     198 + type=int,
     199 + help="Max number of concurrent HTTP(s) requests (default 1)",
     200 + default=1,
     201 + )
    191 202   injection = parser.add_argument_group(
    192 203   "Injection",
    193 204   description="These options can be used to specify which parameters to test for, \nprovide custom injection payloads and optional tampering scripts",
    skipped 224 lines
    418 429   not_string=args.not_string,
    419 430   text_only=args.text_only,
    420 431   skip_urlencoding=args.skip_urlencoding,
     432 + threads=args.threads,
    421 433   )
    422 434   if resp.is_injected:
    423 435   target = ghauri.Ghauri(
    skipped 71 lines
  • ■ ■ ■ ■
    setup.py
    skipped 4 lines
    5 5   
    6 6  setup(
    7 7   name="ghauri",
    8  - version="1.1",
     8 + version="1.1.1",
    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