Projects STRLCPY ghauri Commits 2ea2d789
🤬
  • updated code quality, added support for testing multiple parameter(s) on user demand, bumped version 1.1.4.

  • Loading...
  • r0oth3x49 committed 1 year ago
    2ea2d789
    1 parent af76a158
  • ■ ■ ■ ■
    ghauri/__init__.py
    skipped 23 lines
    24 24   
    25 25  """
    26 26   
    27  -__version__ = "1.1.3"
     27 +__version__ = "1.1.4"
    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 91 lines
    92 92   self._json_post_data = []
    93 93   self.request_counter = 1
    94 94   self.req_counter_injected = 0
     95 + self.params_count = 0
    95 96   
    96 97   @property
    97 98   def session_filepath(self):
    skipped 7 lines
  • ■ ■ ■ ■ ■
    ghauri/common/session.py
    skipped 35 lines
    36 36   SESSION_STATEMENETS,
    37 37  )
    38 38  from ghauri.logger.colored_logger import logger
     39 +from ghauri.common.utils import Struct
    39 40   
    40 41   
    41 42  class SessionFactory:
    skipped 6 lines
    48 49   _temp[col[0]] = row[idx]
    49 50   return _temp
    50 51   
    51  - def fetchall(self, session_filepath="", query="", values=None):
     52 + def fetchall(self, session_filepath="", query="", values=None, to_object=False):
    52 53   conn = sqlite3.connect(session_filepath)
    53 54   conn.row_factory = self._dict_factory
    54 55   if values:
    55 56   cursor = conn.execute(query, values)
    56 57   else:
    57 58   cursor = conn.execute(query)
    58  - return cursor.fetchall()
     59 + if to_object:
     60 + cursor_response = [Struct(**resp) for resp in cursor.fetchall()]
     61 + else:
     62 + cursor_response = cursor.fetchall()
     63 + return cursor_response
    59 64   
    60 65   def fetch_cursor(self, session_filepath="", query=""):
    61 66   conn = sqlite3.connect(session_filepath)
    skipped 203 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/common/utils.py
    skipped 55 lines
    56 56  from ghauri.logger.colored_logger import logger
    57 57  from ghauri.common.prettytable import PrettyTable, from_db_cursor
    58 58   
     59 + 
     60 +class Struct:
     61 + def __init__(self, **entries):
     62 + self.__dict__.update(entries)
     63 + 
     64 + 
    59 65  # source: https://stackoverflow.com/questions/4685217/parse-raw-http-headers
    60 66  class HTTPRequest(BaseHTTPRequestHandler):
    61 67   def __init__(self, request_text):
    skipped 1760 lines
    1822 1828   _temp.append(_r)
    1823 1829   return _temp
    1824 1830   
     1831 + 
     1832 +def payloads_to_objects(records):
     1833 + ParameterResult = collections.namedtuple(
     1834 + "ParameterResult",
     1835 + ["parameter", "backend", "injection_type", "result"],
     1836 + )
     1837 + seen = set()
     1838 + _temp = []
     1839 + for entry in records:
     1840 + parameter = json.loads(entry.parameter)
     1841 + parameter = Struct(**parameter)
     1842 + if parameter.key not in seen:
     1843 + seen.add(parameter.key)
     1844 + out = []
     1845 + for entry in records:
     1846 + ok = Struct(**json.loads(entry.parameter))
     1847 + title = entry.title
     1848 + vector = entry.vector
     1849 + payload = entry.payload
     1850 + backend = entry.backend
     1851 + attempts = entry.attempts
     1852 + endpoint = entry.endpoint
     1853 + payload_type = entry.payload_type
     1854 + injection_type = entry.injection_type
     1855 + if ok.key == parameter.key:
     1856 + if payload_type.startswith("boolean-based"):
     1857 + res = {
     1858 + "title": title,
     1859 + "backend": backend,
     1860 + "payload": payload,
     1861 + "vector": vector,
     1862 + "attempts": attempts,
     1863 + "endpoint": endpoint,
     1864 + "payload_type": payload_type,
     1865 + "injection_type": injection_type,
     1866 + "parameter": ok,
     1867 + }
     1868 + res = Struct(**res)
     1869 + out.append(res)
     1870 + if payload_type.startswith("error-based"):
     1871 + res = {
     1872 + "title": title,
     1873 + "backend": backend,
     1874 + "payload": payload,
     1875 + "vector": vector,
     1876 + "attempts": attempts,
     1877 + "endpoint": endpoint,
     1878 + "payload_type": payload_type,
     1879 + "injection_type": injection_type,
     1880 + "parameter": ok,
     1881 + }
     1882 + res = Struct(**res)
     1883 + out.append(res)
     1884 + if payload_type.startswith("time-based"):
     1885 + res = {
     1886 + "title": title,
     1887 + "backend": backend,
     1888 + "payload": payload,
     1889 + "vector": vector,
     1890 + "attempts": attempts,
     1891 + "endpoint": endpoint,
     1892 + "payload_type": payload_type,
     1893 + "injection_type": injection_type,
     1894 + "parameter": ok,
     1895 + }
     1896 + res = Struct(**res)
     1897 + out.append(res)
     1898 + if payload_type.startswith("stacked"):
     1899 + res = {
     1900 + "title": title,
     1901 + "backend": backend,
     1902 + "payload": payload,
     1903 + "vector": vector,
     1904 + "attempts": attempts,
     1905 + "endpoint": endpoint,
     1906 + "payload_type": payload_type,
     1907 + "injection_type": injection_type,
     1908 + "parameter": ok,
     1909 + }
     1910 + res = Struct(**res)
     1911 + out.append(res)
     1912 + if payload_type.startswith("inline"):
     1913 + res = {
     1914 + "title": title,
     1915 + "backend": backend,
     1916 + "payload": payload,
     1917 + "vector": vector,
     1918 + "attempts": attempts,
     1919 + "endpoint": endpoint,
     1920 + "payload_type": payload_type,
     1921 + "injection_type": injection_type,
     1922 + "parameter": ok,
     1923 + }
     1924 + res = Struct(**res)
     1925 + out.append(res)
     1926 + if out:
     1927 + _temp.append(
     1928 + ParameterResult(
     1929 + parameter=parameter,
     1930 + backend=entry.backend,
     1931 + injection_type=entry.injection_type,
     1932 + result=out,
     1933 + )
     1934 + )
     1935 + return _temp
     1936 + 
  • ■ ■ ■ ■ ■ ■
    ghauri/core/tests.py
    skipped 58 lines
    59 59   search_possible_dbms_errors,
    60 60   fetch_payloads_by_suffix_prefix,
    61 61   get_payloads_with_functions,
     62 + payloads_to_objects,
    62 63  )
    63 64   
    64 65   
    skipped 48 lines
    113 114   session_filepath=conf.session_filepath,
    114 115   query="SELECT * FROM tbl_payload WHERE `endpoint`=?",
    115 116   values=(base.path,),
     117 + to_object=True,
    116 118   )
    117 119   if retval:
    118  - json_data_parameters = [
    119  - json.loads(i.get("parameter", "{}")) for i in retval
    120  - ]
     120 + json_data_parameters = [json.loads(i.parameter) for i in retval]
    121 121   params_tested_already = list(
    122 122   set(
    123 123   [
    skipped 897 lines
    1021 1021   timebased_only=bool("T" in techniques),
    1022 1022   stack_queries_only=False,
    1023 1023   )
    1024  - payloads_response_delay = [stack_queries_payloads, time_based_payloads]
     1024 + payloads_list = []
     1025 + [
     1026 + payloads_list.extend([s, t])
     1027 + for t in time_based_payloads
     1028 + for s in stack_queries_payloads
     1029 + ]
    1025 1030   param_key = parameter.get("key")
    1026 1031   param_value = parameter.get("value")
    1027 1032   # in case of very slow internet users we will consider timesec value for testing and it should be >= 10 otherwise with good internet we are good to consider random sleep value
    skipped 6 lines
    1034 1039   terminate_on_web_firewall = False
    1035 1040   http_firewall_code_counter = 0
    1036 1041   error_msg = None
    1037  - _out = []
    1038  - for payloads_delay in payloads_response_delay:
    1039  - for entry in payloads_delay:
    1040  - backend = entry.dbms
    1041  - index_of_payload = 0
    1042  - retry_on_error = 0
    1043  - if terminate_on_web_firewall:
    1044  - break
    1045  - if terminate_on_errors:
    1046  - break
    1047  - payloads = fetch_payloads_by_suffix_prefix(
    1048  - payloads=entry.payloads, prefix=prefix, suffix=suffix
    1049  - )
    1050  - total_payloads = len(payloads)
    1051  - if possible_dbms or dbms:
    1052  - if entry.dbms and entry.dbms not in [possible_dbms, dbms]:
    1053  - logger.debug(f"skipping '{entry.title}'")
    1054  - continue
    1055  - logger.info(f"testing '{entry.title}'")
    1056  - while index_of_payload < total_payloads:
    1057  - if http_firewall_code_counter > 2 and not conf.continue_on_http_error:
    1058  - message = f"{error_msg} - {http_firewall_code_counter} time(s)"
    1059  - logger.warning(f"HTTP error code detected during run:")
    1060  - choice = logger.read_input(
    1061  - f"{message}. Do you want to keep testing the others (if any) [y/N]? ",
    1062  - batch=False,
    1063  - user_input="N",
     1042 + for entry in payloads_list:
     1043 + backend = entry.dbms
     1044 + index_of_payload = 0
     1045 + retry_on_error = 0
     1046 + if terminate_on_web_firewall:
     1047 + break
     1048 + if terminate_on_errors:
     1049 + break
     1050 + if "stacked" in entry.title:
     1051 + prefix = None
     1052 + suffix = None
     1053 + payloads = fetch_payloads_by_suffix_prefix(
     1054 + payloads=entry.payloads, prefix=prefix, suffix=suffix
     1055 + )
     1056 + total_payloads = len(payloads)
     1057 + if possible_dbms or dbms:
     1058 + if entry.dbms and entry.dbms not in [possible_dbms, dbms]:
     1059 + logger.debug(f"skipping '{entry.title}'")
     1060 + continue
     1061 + logger.info(f"testing '{entry.title}'")
     1062 + while index_of_payload < total_payloads:
     1063 + if http_firewall_code_counter > 2 and not conf.continue_on_http_error:
     1064 + message = f"{error_msg} - {http_firewall_code_counter} time(s)"
     1065 + logger.warning(f"HTTP error code detected during run:")
     1066 + choice = logger.read_input(
     1067 + f"{message}. Do you want to keep testing the others (if any) [y/N]? ",
     1068 + batch=False,
     1069 + user_input="N",
     1070 + )
     1071 + if choice == "n":
     1072 + terminate_on_web_firewall = True
     1073 + break
     1074 + if choice == "y":
     1075 + conf.continue_on_http_error = True
     1076 + http_firewall_code_counter = 0
     1077 + if retry_on_error >= retry:
     1078 + logger.warning(f"Ghauri detected connection errors multiple times")
     1079 + choice = logger.read_input(
     1080 + f"Do you want to keep testing the others (if any) [y/N]? ",
     1081 + batch=False,
     1082 + user_input="N",
     1083 + )
     1084 + if choice == "n":
     1085 + terminate_on_errors = True
     1086 + break
     1087 + if choice == "y":
     1088 + retry_on_error = 0
     1089 + if delay > 0:
     1090 + time.sleep(delay)
     1091 + _payload = payloads[index_of_payload]
     1092 + string = _payload.string
     1093 + expression = string.replace("[SLEEPTIME]", "%s" % (sleep_time))
     1094 + decoded_expression = urldecode(expression)
     1095 + logger.payload(f"{decoded_expression}")
     1096 + try:
     1097 + attack = inject_expression(
     1098 + url=url,
     1099 + data=data,
     1100 + proxy=proxy,
     1101 + delay=delay,
     1102 + timesec=timesec,
     1103 + timeout=timeout,
     1104 + headers=headers,
     1105 + parameter=parameter,
     1106 + expression=expression,
     1107 + is_multipart=is_multipart,
     1108 + injection_type=injection_type,
     1109 + )
     1110 + index_of_payload += 1
     1111 + retry_on_error = 0
     1112 + except KeyboardInterrupt:
     1113 + logger.warning("user aborted during detection phase")
     1114 + quest = logger.read_input(
     1115 + "how do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit] ",
     1116 + batch=False,
     1117 + user_input="S",
     1118 + )
     1119 + if quest and quest == "n":
     1120 + # later on will handle this nicely..
     1121 + return "next parameter"
     1122 + if quest and quest == "q":
     1123 + logger.error("user quit")
     1124 + logger.end("ending")
     1125 + exit(0)
     1126 + if quest and quest == "e":
     1127 + end_detection_phase = True
     1128 + if quest and quest == "s":
     1129 + break
     1130 + except ConnectionAbortedError as e:
     1131 + logger.critical(
     1132 + f"connection attempt to the target URL was aborted by the peer, Ghauri is going to retry"
     1133 + )
     1134 + retry_on_error += 1
     1135 + except ConnectionRefusedError as e:
     1136 + logger.critical(
     1137 + f"connection attempt to the target URL was refused by the peer. Ghauri is going to retry"
     1138 + )
     1139 + retry_on_error += 1
     1140 + except ConnectionResetError as e:
     1141 + logger.critical(
     1142 + f"connection attempt to the target URL was reset by the peer. Ghauri is going to retry"
     1143 + )
     1144 + retry_on_error += 1
     1145 + except Exception as error:
     1146 + logger.critical(
     1147 + f"error {error}, during detection phase. Ghauri is going to retry"
     1148 + )
     1149 + retry_on_error += 1
     1150 + response_time = attack.response_time
     1151 + if response_time < sleep_time and end_detection_phase:
     1152 + return None
     1153 + with_status_code_msg = ""
     1154 + with_status_code = attack.status_code
     1155 + if attack.status_code != base.status_code:
     1156 + is_different_status_code_injectable = True
     1157 + if with_status_code == 4001:
     1158 + with_status_code_msg = (
     1159 + f" (with error ReadTimeout on --timeout={timeout})"
    1064 1160   )
    1065  - if choice == "n":
    1066  - terminate_on_web_firewall = True
    1067  - break
    1068  - if choice == "y":
    1069  - conf.continue_on_http_error = True
    1070  - http_firewall_code_counter = 0
    1071  - if retry_on_error >= retry:
    1072  - logger.warning(f"Ghauri detected connection errors multiple times")
    1073  - choice = logger.read_input(
    1074  - f"Do you want to keep testing the others (if any) [y/N]? ",
    1075  - batch=False,
    1076  - user_input="N",
     1161 + else:
     1162 + with_status_code_msg = f" (with --code={with_status_code})"
     1163 + if attack.status_code in [403, 406] and code and code not in [403, 406]:
     1164 + logger.debug(
     1165 + f"{attack.error_msg} HTTP error code detected. ghauri is going to retry."
     1166 + )
     1167 + time.sleep(0.5)
     1168 + error_msg = attack.error_msg
     1169 + http_firewall_code_counter += 1
     1170 + continue
     1171 + logger.debug(f"sleep time: {sleep_time}, response time: {response_time}")
     1172 + if response_time >= sleep_time:
     1173 + is_injected = True
     1174 + _it = injection_type
     1175 + if param_key == "#1*":
     1176 + _it = "URI"
     1177 + if is_multipart:
     1178 + message = f"(custom) {injection_type} parameter '{mc}MULTIPART {param_key}{nc}' appears to be '{mc}{entry.title}{nc}' injectable{with_status_code_msg}"
     1179 + elif is_json:
     1180 + message = f"(custom) {injection_type} parameter '{mc}JSON {param_key}{nc}' appears to be '{mc}{entry.title}{nc}' injectable{with_status_code_msg}"
     1181 + else:
     1182 + message = f"{_it} parameter '{mc}{param_key}{nc}' appears to be '{mc}{entry.title}{nc}' injectable{with_status_code_msg}"
     1183 + if with_status_code_msg and "ReadTimeout" in with_status_code_msg:
     1184 + logger.warning(
     1185 + "in case of read timeout performing further tests to confirm if the detected payload is working.."
    1077 1186   )
    1078  - if choice == "n":
    1079  - terminate_on_errors = True
    1080  - break
    1081  - if choice == "y":
    1082  - retry_on_error = 0
    1083  - if delay > 0:
    1084  - time.sleep(delay)
    1085  - _payload = payloads[index_of_payload]
    1086  - string = _payload.string
    1087  - expression = string.replace("[SLEEPTIME]", "%s" % (sleep_time))
    1088  - decoded_expression = urldecode(expression)
    1089  - logger.payload(f"{decoded_expression}")
    1090  - try:
    1091  - attack = inject_expression(
     1187 + ok = confirm_timebased_sqli(
     1188 + base,
     1189 + parameter,
     1190 + _payload,
     1191 + sleep_time,
     1192 + response_time,
    1092 1193   url=url,
    1093 1194   data=data,
     1195 + headers=headers,
     1196 + injection_type=injection_type,
    1094 1197   proxy=proxy,
     1198 + is_multipart=is_multipart,
     1199 + timeout=timeout,
    1095 1200   delay=delay,
    1096 1201   timesec=timesec,
    1097  - timeout=timeout,
    1098  - headers=headers,
    1099  - parameter=parameter,
    1100  - expression=expression,
    1101  - is_multipart=is_multipart,
    1102  - injection_type=injection_type,
    1103  - )
    1104  - index_of_payload += 1
    1105  - retry_on_error = 0
    1106  - except KeyboardInterrupt:
    1107  - logger.warning("user aborted during detection phase")
    1108  - quest = logger.read_input(
    1109  - "how do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit] ",
    1110  - batch=False,
    1111  - user_input="S",
    1112  - )
    1113  - if quest and quest == "n":
    1114  - # later on will handle this nicely..
    1115  - return "next parameter"
    1116  - if quest and quest == "q":
    1117  - logger.error("user quit")
    1118  - logger.end("ending")
    1119  - exit(0)
    1120  - if quest and quest == "e":
    1121  - end_detection_phase = True
    1122  - if quest and quest == "s":
    1123  - break
    1124  - except ConnectionAbortedError as e:
    1125  - logger.critical(
    1126  - f"connection attempt to the target URL was aborted by the peer, Ghauri is going to retry"
    1127  - )
    1128  - retry_on_error += 1
    1129  - except ConnectionRefusedError as e:
    1130  - logger.critical(
    1131  - f"connection attempt to the target URL was refused by the peer. Ghauri is going to retry"
    1132  - )
    1133  - retry_on_error += 1
    1134  - except ConnectionResetError as e:
    1135  - logger.critical(
    1136  - f"connection attempt to the target URL was reset by the peer. Ghauri is going to retry"
    1137  - )
    1138  - retry_on_error += 1
    1139  - except Exception as error:
    1140  - logger.critical(
    1141  - f"error {error}, during detection phase. Ghauri is going to retry"
     1202 + is_read_timedout=True,
     1203 + vector=f"{_payload.prefix}{entry.vector}{_payload.suffix}",
    1142 1204   )
    1143  - retry_on_error += 1
    1144  - response_time = attack.response_time
    1145  - if response_time < sleep_time and end_detection_phase:
    1146  - return None
    1147  - with_status_code_msg = ""
    1148  - with_status_code = attack.status_code
    1149  - if attack.status_code != base.status_code:
    1150  - is_different_status_code_injectable = True
    1151  - if with_status_code == 4001:
    1152  - with_status_code_msg = (
    1153  - f" (with error ReadTimeout on --timeout={timeout})"
     1205 + if not ok.vulnerable:
     1206 + logger.warning(
     1207 + "false positive payload detected with read timeout continue testing.."
    1154 1208   )
    1155  - else:
    1156  - with_status_code_msg = f" (with --code={with_status_code})"
    1157  - if attack.status_code in [403, 406] and code and code not in [403, 406]:
    1158  - logger.critical(
    1159  - f"{attack.error_msg} HTTP error code detected. ghauri is going to retry."
    1160  - )
    1161  - time.sleep(0.5)
    1162  - error_msg = attack.error_msg
    1163  - http_firewall_code_counter += 1
    1164  - continue
    1165  - logger.debug(
    1166  - f"sleep time: {sleep_time}, response time: {response_time}"
     1209 + continue
     1210 + logger.notice(message)
     1211 + _url = attack.request_url if injection_type == "GET" else attack.url
     1212 + payload_type = f"{entry.type}"
     1213 + if payload_type == "time-based":
     1214 + payload_type += " blind"
     1215 + if conf.req_counter_injected < 1:
     1216 + conf.req_counter_injected = conf.request_counter - 1
     1217 + _temp = Response(
     1218 + url=_url,
     1219 + data=attack.data,
     1220 + path=attack.path,
     1221 + title=entry.title,
     1222 + param=parameter,
     1223 + payload=expression,
     1224 + base=base._asdict(),
     1225 + prefix=_payload.prefix,
     1226 + suffix=_payload.suffix,
     1227 + vector=entry.vector,
     1228 + attacks=attack._asdict(),
     1229 + injection_type=injection_type,
     1230 + sleep_time=sleep_time,
     1231 + response_time=response_time,
     1232 + injected=is_injected,
     1233 + prepared_vector=f"{_payload.prefix}{entry.vector}{_payload.suffix}",
     1234 + number_of_requests=conf.request_counter,
     1235 + backend=backend,
     1236 + payload_type=payload_type,
     1237 + payload_raw=_payload,
     1238 + with_status_code=with_status_code,
     1239 + is_different_status_code_injectable=is_different_status_code_injectable,
    1167 1240   )
    1168  - if response_time >= sleep_time:
    1169  - is_injected = True
    1170  - _it = injection_type
    1171  - if param_key == "#1*":
    1172  - _it = "URI"
    1173  - if is_multipart:
    1174  - message = f"(custom) {injection_type} parameter '{mc}MULTIPART {param_key}{nc}' appears to be '{mc}{entry.title}{nc}' injectable{with_status_code_msg}"
    1175  - elif is_json:
    1176  - message = f"(custom) {injection_type} parameter '{mc}JSON {param_key}{nc}' appears to be '{mc}{entry.title}{nc}' injectable{with_status_code_msg}"
    1177  - else:
    1178  - message = f"{_it} parameter '{mc}{param_key}{nc}' appears to be '{mc}{entry.title}{nc}' injectable{with_status_code_msg}"
    1179  - if with_status_code_msg and "ReadTimeout" in with_status_code_msg:
    1180  - logger.warning(
    1181  - "in case of read timeout performing further tests to confirm if the detected payload is working.."
    1182  - )
    1183  - ok = confirm_timebased_sqli(
    1184  - base,
    1185  - parameter,
    1186  - _payload,
    1187  - sleep_time,
    1188  - response_time,
    1189  - url=url,
    1190  - data=data,
    1191  - headers=headers,
    1192  - injection_type=injection_type,
    1193  - proxy=proxy,
    1194  - is_multipart=is_multipart,
    1195  - timeout=timeout,
    1196  - delay=delay,
    1197  - timesec=timesec,
    1198  - is_read_timedout=True,
    1199  - vector=f"{_payload.prefix}{entry.vector}{_payload.suffix}",
    1200  - )
    1201  - if not ok.vulnerable:
    1202  - logger.warning(
    1203  - "false positive payload detected with read timeout continue testing.."
    1204  - )
    1205  - continue
    1206  - logger.notice(message)
    1207  - _url = attack.request_url if injection_type == "GET" else attack.url
    1208  - payload_type = f"{entry.type}"
    1209  - if payload_type == "time-based":
    1210  - payload_type += " blind"
    1211  - if conf.req_counter_injected < 1:
    1212  - conf.req_counter_injected = conf.request_counter - 1
    1213  - _temp = Response(
    1214  - url=_url,
    1215  - data=attack.data,
    1216  - path=attack.path,
    1217  - title=entry.title,
    1218  - param=parameter,
    1219  - payload=expression,
    1220  - base=base._asdict(),
    1221  - prefix=_payload.prefix,
    1222  - suffix=_payload.suffix,
    1223  - vector=entry.vector,
    1224  - attacks=attack._asdict(),
    1225  - injection_type=injection_type,
    1226  - sleep_time=sleep_time,
    1227  - response_time=response_time,
    1228  - injected=is_injected,
    1229  - prepared_vector=f"{_payload.prefix}{entry.vector}{_payload.suffix}",
    1230  - number_of_requests=conf.request_counter,
    1231  - backend=backend,
    1232  - payload_type=payload_type,
    1233  - payload_raw=_payload,
    1234  - with_status_code=with_status_code,
    1235  - is_different_status_code_injectable=is_different_status_code_injectable,
    1236  - )
    1237  - return _temp
     1241 + return _temp
    1238 1242   return None
    1239 1243   
    1240 1244   
    skipped 59 lines
    1300 1304   error_based_payloads = get_payloads_with_functions(
    1301 1305   error_based_payloads, backend=dbms, possible_dbms=possible_dbms
    1302 1306   )
     1307 + error_based_payloads.reverse()
    1303 1308   for entry in error_based_payloads:
    1304 1309   backend = entry.dbms
    1305 1310   index_of_payload = 0
    skipped 217 lines
    1523 1528   return None
    1524 1529   
    1525 1530   
     1531 +def get_injectable_payloads(
     1532 + url="",
     1533 + data="",
     1534 + base="",
     1535 + injection_type="",
     1536 + session_filepath="",
     1537 + is_json=False,
     1538 + is_multipart=False,
     1539 + injected_and_vulnerable=False,
     1540 +):
     1541 + Injections = collections.namedtuple(
     1542 + "Injections",
     1543 + [
     1544 + "retval",
     1545 + "template_msg",
     1546 + "tested_parameters",
     1547 + ],
     1548 + )
     1549 + retval = session.fetchall(
     1550 + session_filepath=session_filepath,
     1551 + query="SELECT * FROM tbl_payload WHERE `endpoint`=?",
     1552 + values=(base.path,),
     1553 + to_object=True,
     1554 + )
     1555 + retval = payloads_to_objects(retval)
     1556 + if not injected_and_vulnerable:
     1557 + message = (
     1558 + "Ghauri resumed the following injection point(s) from stored session:\n"
     1559 + )
     1560 + else:
     1561 + message = "Ghauri identified the following injection point(s) with a total of {nor} HTTP(s) requests:\n".format(
     1562 + nor=conf.req_counter_injected
     1563 + )
     1564 + message += "---\n"
     1565 + param_set = set()
     1566 + message_list = []
     1567 + for entry in retval:
     1568 + param_name = entry.parameter.key
     1569 + param_value = entry.parameter.value
     1570 + results = entry.result
     1571 + if param_name not in param_set:
     1572 + _p = f"{param_name}"
     1573 + _it = injection_type if param_name != "#1*" else "URI"
     1574 + if is_json:
     1575 + _p = f"JSON {param_name}"
     1576 + _it = f"(custom) {injection_type}"
     1577 + if is_multipart:
     1578 + _p = f"MULTIPART {param_name}"
     1579 + _it = f"(custom) {injection_type}"
     1580 + message_ok = "Parameter: {} ({})".format(_p, _it)
     1581 + param_set.add(param_name)
     1582 + __ = []
     1583 + for res in results:
     1584 + _url = url
     1585 + _data = data
     1586 + if entry.parameter.key != res.parameter.key:
     1587 + continue
     1588 + payload = res.payload
     1589 + payload_type = res.payload_type
     1590 + title = res.title
     1591 + vector = res.vector
     1592 + backend = res.backend
     1593 + if injection_type == "POST":
     1594 + _data = prepare_attack_request(
     1595 + text=data,
     1596 + payload=payload,
     1597 + param=vars(res.parameter),
     1598 + is_multipart=is_multipart,
     1599 + injection_type=injection_type,
     1600 + encode=False,
     1601 + )
     1602 + if injection_type == "GET":
     1603 + _url = prepare_attack_request(
     1604 + text=url,
     1605 + payload=payload,
     1606 + param=vars(res.parameter),
     1607 + injection_type=injection_type,
     1608 + encode=False,
     1609 + )
     1610 + if injection_type == "GET":
     1611 + payload = parse_payload(
     1612 + _url, injection_type=injection_type, param_name=param_name
     1613 + )
     1614 + elif injection_type == "POST":
     1615 + payload = parse_payload(
     1616 + url,
     1617 + data=_data,
     1618 + injection_type=injection_type,
     1619 + is_multipart=is_multipart,
     1620 + )
     1621 + elif injection_type == "HEADER":
     1622 + payload = f"{param_name}: {param_value}{payload}"
     1623 + payload = parse_payload(
     1624 + payload=payload,
     1625 + injection_type=injection_type,
     1626 + )
     1627 + elif injection_type == "COOKIE":
     1628 + payload = f"{param_name}={param_value}{payload}"
     1629 + payload = parse_payload(
     1630 + payload=payload,
     1631 + injection_type=injection_type,
     1632 + )
     1633 + _msg = TEMPLATE_INJECTED_MESSAGE.format(
     1634 + PAYLOAD_TYPE=payload_type,
     1635 + TITLE=title,
     1636 + PAYLOAD=payload,
     1637 + )
     1638 + __.append(_msg)
     1639 + message_ok += "\n".join(__)
     1640 + message_list.append(message_ok)
     1641 + message += "\n\n".join(message_list)
     1642 + message += "\n---"
     1643 + return Injections(
     1644 + retval=retval, template_msg=message, tested_parameters=list(param_set)
     1645 + )
     1646 + 
     1647 + 
    1526 1648  def check_session(
    1527 1649   url="",
    1528 1650   data="",
    skipped 14 lines
    1543 1665   text_only=False,
    1544 1666   possible_dbms=None,
    1545 1667   dbms=None,
     1668 + injected_and_vulnerable=False,
    1546 1669  ):
    1547  - retval = session.fetchall(
     1670 + ok = get_injectable_payloads(
     1671 + url=url,
     1672 + data=data,
     1673 + base=base,
     1674 + injection_type=injection_type,
    1548 1675   session_filepath=session_filepath,
    1549  - query="SELECT * FROM tbl_payload WHERE `endpoint`=?",
    1550  - values=(base.path,),
     1676 + is_json=is_json,
     1677 + is_multipart=is_multipart,
     1678 + injected_and_vulnerable=injected_and_vulnerable,
    1551 1679   )
     1680 + retval = ok.retval
    1552 1681   if retval:
    1553  - param = json.loads(retval[-1].get("parameter", "{}"))
    1554  - _k = parameter.get("key")
    1555  - __k = param.get("key")
    1556  - if _k != __k:
    1557  - logger.debug(f"parameter '{_k}' is not tested..")
     1682 + if parameter.get("key") not in ok.tested_parameters:
     1683 + logger.debug(f"parameter '{parameter.get('key')}' is not tested..")
    1558 1684   return None
    1559 1685   Response = collections.namedtuple(
    1560 1686   "Session",
    skipped 9 lines
    1570 1696   "is_string",
    1571 1697   ],
    1572 1698   )
    1573  - vulnerable = False
    1574  - vectors = {}
    1575  - match_string = None
    1576  - attack_false = None
    1577  - __injecton_type = None
    1578  - param = None
    1579  - backend = None
    1580  - is_string = False
    1581  - is_boolean_vuln = False
    1582  - is_error_vuln = False
    1583  - to_str = False
    1584  - to_char = False
     1699 + _temp = []
     1700 + response = None
    1585 1701   if retval:
    1586  - message = (
    1587  - "Ghauri resumed the following injection point(s) from stored session:\n"
    1588  - )
    1589  - message += "---\n"
    1590  - parameter = json.loads(retval[-1].get("parameter", "{}"))
    1591  - param = parameter
    1592  - injection_type = retval[-1].get("injection_type")
    1593  - backend = retval[-1].get("backend")
    1594  - param_name = parameter.get("key")
    1595  - _p = f"{param_name}"
    1596  - _it = injection_type if param_name != "#1*" else "URI"
    1597  - if is_json:
    1598  - _p = f"JSON {param_name}"
    1599  - _it = f"(custom) {injection_type}"
    1600  - if is_multipart:
    1601  - _p = f"MULTIPART {param_name}"
    1602  - _it = f"(custom) {injection_type}"
    1603  - message += "Parameter: {} ({})".format(_p, _it)
    1604  - __ = []
    1605 1702   for entry in retval:
    1606  - _url = url
    1607  - _data = data
    1608  - injection_type = entry.get("injection_type")
    1609  - __injecton_type = injection_type
    1610  - param_name = parameter.get("key")
    1611  - param_value = parameter.get("value").replace("*", "")
    1612  - payload = entry.get("payload")
    1613  - payload_type = entry.get("payload_type")
    1614  - title = entry.get("title")
    1615  - vector = entry.get("vector")
    1616  - backend = entry.get("backend")
    1617  - # if not possible_dbms:
    1618  - # possible_dbms = backend
    1619  - if payload_type == "boolean-based blind":
    1620  - vectors.update({"boolean_vector": vector})
    1621  - logger.debug(
    1622  - f"confirming if {injection_type} parameter '{param_name}' is '{title}' vulnerable.."
    1623  - )
    1624  - random_boolean = random.randint(1234, 9999)
    1625  - random_boolean01 = random_boolean - 68
    1626  - expression = vector.replace(
    1627  - "[INFERENCE]",
    1628  - "{:05}={:05}".format(random_boolean, random_boolean),
    1629  - )
    1630  - expression = expression.replace(
    1631  - "[ORIGVALUE]", param_value.replace("*", "")
    1632  - )
    1633  - expression01 = vector.replace(
    1634  - "[INFERENCE]",
    1635  - "{:05}={:05}".format(random_boolean, random_boolean01),
    1636  - )
    1637  - expression01 = expression01.replace(
    1638  - "[ORIGVALUE]", param_value.replace("*", "")
    1639  - )
    1640  - try:
    1641  - attack = inject_expression(
    1642  - url=url,
    1643  - data=data,
    1644  - proxy=proxy,
    1645  - delay=delay,
    1646  - timesec=timesec,
    1647  - timeout=timeout,
    1648  - headers=headers,
    1649  - parameter=parameter,
    1650  - expression=expression,
    1651  - is_multipart=is_multipart,
    1652  - injection_type=injection_type,
     1703 + param_info = entry.parameter
     1704 + results = entry.result
     1705 + vectors = {}
     1706 + boolean_or_error_in_vectors = False
     1707 + attack_false = None
     1708 + match_string = None
     1709 + backend = None
     1710 + is_string = False
     1711 + to_str = False
     1712 + to_char = False
     1713 + for res in results:
     1714 + injection_type = res.injection_type
     1715 + payload = res.payload
     1716 + payload_type = res.payload_type
     1717 + title = res.title
     1718 + vector = res.vector
     1719 + backend = res.backend
     1720 + param_json = vars(res.parameter)
     1721 + param_name = res.parameter.key
     1722 + param_value = res.parameter.value.replace("*", "")
     1723 + if payload_type == "boolean-based blind":
     1724 + logger.debug(
     1725 + f"confirming if {injection_type} parameter '{param_name}' is '{title}'"
    1653 1726   )
    1654  - attack01 = inject_expression(
    1655  - url=url,
    1656  - data=data,
    1657  - proxy=proxy,
    1658  - delay=delay,
    1659  - timesec=timesec,
    1660  - timeout=timeout,
    1661  - headers=headers,
    1662  - parameter=parameter,
    1663  - expression=expression01,
    1664  - is_multipart=is_multipart,
    1665  - injection_type=injection_type,
     1727 + random_boolean = random.randint(1234, 9999)
     1728 + random_boolean01 = random_boolean - 68
     1729 + expression = vector.replace(
     1730 + "[INFERENCE]",
     1731 + "{:05}={:05}".format(random_boolean, random_boolean),
    1666 1732   )
    1667  - attack_false = attack01
    1668  - boolean_retval = check_boolean_responses(
    1669  - base,
    1670  - attack,
    1671  - attack01,
    1672  - code=code,
    1673  - match_string=match_string,
    1674  - not_match_string=not_match_string,
    1675  - text_only=text_only,
     1733 + expression = expression.replace(
     1734 + "[ORIGVALUE]", param_value.replace("*", "")
    1676 1735   )
    1677  - retval = boolean_retval.vulnerable
    1678  - case = boolean_retval.case
    1679  - match_string = (
    1680  - boolean_retval.string if not match_string else match_string
     1736 + expression01 = vector.replace(
     1737 + "[INFERENCE]",
     1738 + "{:05}={:05}".format(random_boolean, random_boolean01),
    1681 1739   )
    1682  - not_match_string = (
    1683  - boolean_retval.not_string
    1684  - if not not_match_string
    1685  - else not_match_string
     1740 + expression01 = expression01.replace(
     1741 + "[ORIGVALUE]", param_value.replace("*", "")
    1686 1742   )
    1687  - if retval:
    1688  - vulnerable = True
    1689  - is_boolean_vuln = True
    1690  - logger.debug(
    1691  - f"{injection_type} parameter '{param_name}' is '{title}' vulnerable."
     1743 + try:
     1744 + attack = inject_expression(
     1745 + url=url,
     1746 + data=data,
     1747 + proxy=proxy,
     1748 + delay=delay,
     1749 + timesec=timesec,
     1750 + timeout=timeout,
     1751 + headers=headers,
     1752 + parameter=param_json,
     1753 + expression=expression,
     1754 + is_multipart=is_multipart,
     1755 + injection_type=injection_type,
    1692 1756   )
    1693  - else:
    1694  - logger.debug(
    1695  - f"{injection_type} parameter '{param_name}' is '{title}' not vulnerable."
     1757 + attack01 = inject_expression(
     1758 + url=url,
     1759 + data=data,
     1760 + proxy=proxy,
     1761 + delay=delay,
     1762 + timesec=timesec,
     1763 + timeout=timeout,
     1764 + headers=headers,
     1765 + parameter=param_json,
     1766 + expression=expression01,
     1767 + is_multipart=is_multipart,
     1768 + injection_type=injection_type,
    1696 1769   )
    1697  - except Exception as e:
    1698  - logger.critical(f"error {e}, during injection confirmation..")
    1699  - if payload_type == "error-based":
    1700  - vectors.update({"error_vector": vector})
    1701  - logger.debug(
    1702  - f"confirming if {injection_type} parameter '{param_name}' is '{title}' vulnerable.."
    1703  - )
    1704  - string = "r0oth3x49"
    1705  - regex = r"(?is)(?:r0oth3x49)"
    1706  - if backend == "Microsoft SQL Server":
    1707  - if "string error-based" in title:
    1708  - to_str = is_string = True
    1709  - if is_string:
    1710  - string = "r0ot"
    1711  - regex = r"(?is)(?:r0ot)"
    1712  - else:
    1713  - to_char = not is_string
    1714  - if backend == "MySQL":
    1715  - if "string error-based" in title:
    1716  - to_str = is_string = True
    1717  - if is_string:
    1718  - string = "r0ot"
    1719  - regex = r"(?is)(?:r0ot)"
    1720  - else:
    1721  - to_char = not is_string
    1722  - expression = vector.replace(
    1723  - "[INFERENCE]",
    1724  - to_dbms_encoding(
    1725  - string, backend=backend, to_str=to_str, to_char=to_char
    1726  - ),
    1727  - )
    1728  - try:
    1729  - attack = inject_expression(
    1730  - url=url,
    1731  - data=data,
    1732  - proxy=proxy,
    1733  - delay=delay,
    1734  - timesec=timesec,
    1735  - timeout=timeout,
    1736  - headers=headers,
    1737  - parameter=parameter,
    1738  - expression=expression,
    1739  - is_multipart=is_multipart,
    1740  - injection_type=injection_type,
     1770 + attack_false = attack01
     1771 + boolean_retval = check_boolean_responses(
     1772 + base,
     1773 + attack,
     1774 + attack01,
     1775 + code=code,
     1776 + match_string=match_string,
     1777 + not_match_string=not_match_string,
     1778 + text_only=text_only,
     1779 + )
     1780 + retval = boolean_retval.vulnerable
     1781 + case = boolean_retval.case
     1782 + match_string = (
     1783 + boolean_retval.string if not match_string else match_string
     1784 + )
     1785 + not_match_string = (
     1786 + boolean_retval.not_string
     1787 + if not not_match_string
     1788 + else not_match_string
     1789 + )
     1790 + if retval:
     1791 + boolean_or_error_in_vectors = True
     1792 + vectors.update({"boolean_vector": vector})
     1793 + logger.debug(
     1794 + f"{injection_type} parameter '{param_name}' is '{title}' vulnerable."
     1795 + )
     1796 + else:
     1797 + logger.debug(
     1798 + f"{injection_type} parameter '{param_name}' is '{title}' not vulnerable."
     1799 + )
     1800 + except Exception as e:
     1801 + logger.critical(f"error {e}, during injection confirmation..")
     1802 + if payload_type == "error-based":
     1803 + logger.debug(
     1804 + f"confirming if {injection_type} parameter '{param_name}' is '{title}'"
    1741 1805   )
    1742  - mobj = re.search(regex, attack.text)
    1743  - if mobj:
    1744  - vulnerable = True
    1745  - is_error_vuln = True
    1746  - logger.debug(
    1747  - f"{injection_type} parameter '{param_name}' is '{title}' vulnerable."
     1806 + string = "r0oth3x49"
     1807 + regex = r"(?is)(?:r0oth3x49)"
     1808 + if backend == "Microsoft SQL Server":
     1809 + if "string error-based" in title:
     1810 + to_str = is_string = True
     1811 + if is_string:
     1812 + string = "r0ot"
     1813 + regex = r"(?is)(?:r0ot)"
     1814 + else:
     1815 + to_char = not is_string
     1816 + if backend == "MySQL":
     1817 + if "string error-based" in title:
     1818 + to_str = is_string = True
     1819 + if is_string:
     1820 + string = "r0ot"
     1821 + regex = r"(?is)(?:r0ot)"
     1822 + else:
     1823 + to_char = not is_string
     1824 + expression = vector.replace(
     1825 + "[INFERENCE]",
     1826 + to_dbms_encoding(
     1827 + string, backend=backend, to_str=to_str, to_char=to_char
     1828 + ),
     1829 + )
     1830 + try:
     1831 + attack = inject_expression(
     1832 + url=url,
     1833 + data=data,
     1834 + proxy=proxy,
     1835 + delay=delay,
     1836 + timesec=timesec,
     1837 + timeout=timeout,
     1838 + headers=headers,
     1839 + parameter=param_json,
     1840 + expression=expression,
     1841 + is_multipart=is_multipart,
     1842 + injection_type=injection_type,
    1748 1843   )
    1749  - else:
    1750  - logger.debug(
    1751  - f"{injection_type} parameter '{param_name}' is '{title}' not vulnerable."
     1844 + mobj = re.search(regex, attack.text)
     1845 + if mobj:
     1846 + boolean_or_error_in_vectors = True
     1847 + vectors.update({"error_vector": vector})
     1848 + logger.debug(
     1849 + f"{injection_type} parameter '{param_name}' is '{title}' vulnerable."
     1850 + )
     1851 + else:
     1852 + logger.debug(
     1853 + f"{injection_type} parameter '{param_name}' is '{title}' not vulnerable."
     1854 + )
     1855 + except Exception as e:
     1856 + logger.critical(f"error {e}, during injection confirmation..")
     1857 + if payload_type == "time-based blind":
     1858 + if boolean_or_error_in_vectors:
     1859 + vectors.update({"time_vector": vector})
     1860 + continue
     1861 + logger.debug(
     1862 + f"confirming if {injection_type} parameter '{param_name}' is '{title}'"
     1863 + )
     1864 + sleep_time = random.randint(5, 8)
     1865 + if injected_and_vulnerable:
     1866 + sleep_time = 1
     1867 + expression = vector.replace("[INFERENCE]", "03567=3567").replace(
     1868 + "[SLEEPTIME]", f"{sleep_time}"
     1869 + )
     1870 + try:
     1871 + attack = inject_expression(
     1872 + url=url,
     1873 + data=data,
     1874 + proxy=proxy,
     1875 + delay=delay,
     1876 + timesec=timesec,
     1877 + timeout=timeout,
     1878 + headers=headers,
     1879 + parameter=param_json,
     1880 + expression=expression,
     1881 + is_multipart=is_multipart,
     1882 + injection_type=injection_type,
    1752 1883   )
    1753  - except Exception as e:
    1754  - logger.critical(f"error {e}, during injection confirmation..")
    1755  - if payload_type == "time-based blind":
    1756  - vectors.update({"time_vector": vector})
    1757  - if not is_boolean_vuln and not is_error_vuln:
     1884 + if attack.status_code in [403, 406]:
     1885 + mobj = re.search(
     1886 + r"(?is)(?:(?:(?:SLEEP\(|RECEIVE_MESSAGE\([\w',]*)|0\:0\:)(?P<sleep_time>\d+)(?:(?:\)|\')))",
     1887 + payload,
     1888 + )
     1889 + sleep_time = (
     1890 + int(mobj.group("sleep_time")) if mobj else timesec
     1891 + )
     1892 + expression = payload
     1893 + attack = inject_expression(
     1894 + url=url,
     1895 + data=data,
     1896 + proxy=proxy,
     1897 + delay=delay,
     1898 + timesec=timesec,
     1899 + timeout=timeout,
     1900 + headers=headers,
     1901 + parameter=param_json,
     1902 + expression=expression,
     1903 + is_multipart=is_multipart,
     1904 + injection_type=injection_type,
     1905 + )
     1906 + response_time = attack.response_time
     1907 + if response_time >= sleep_time:
     1908 + vectors.update({"time_vector": vector})
     1909 + logger.debug(
     1910 + f"{injection_type} parameter '{param_name}' is '{title}' vulnerable."
     1911 + )
     1912 + else:
     1913 + logger.debug(
     1914 + f"{injection_type} parameter '{param_name}' is '{title}' not vulnerable."
     1915 + )
     1916 + except Exception as e:
     1917 + logger.critical(f"error {e}, during injection confirmation..")
     1918 + if payload_type == "stacked-queries":
     1919 + if boolean_or_error_in_vectors:
     1920 + vectors.update({"time_vector": vector})
     1921 + continue
    1758 1922   logger.debug(
    1759  - f"confirming if {injection_type} parameter '{param_name}' is '{title}' vulnerable.."
     1923 + f"confirming if {injection_type} parameter '{param_name}' is '{title}'"
    1760 1924   )
    1761 1925   sleep_time = random.randint(5, 8)
     1926 + if injected_and_vulnerable:
     1927 + sleep_time = 1
    1762 1928   expression = vector.replace("[INFERENCE]", "03567=3567").replace(
    1763 1929   "[SLEEPTIME]", f"{sleep_time}"
    1764 1930   )
    skipped 6 lines
    1771 1937   timesec=timesec,
    1772 1938   timeout=timeout,
    1773 1939   headers=headers,
    1774  - parameter=parameter,
     1940 + parameter=param_json,
    1775 1941   expression=expression,
    1776 1942   is_multipart=is_multipart,
    1777 1943   injection_type=injection_type,
    1778 1944   )
    1779 1945   if attack.status_code in [403, 406]:
    1780  - # retry with original payload..
    1781 1946   mobj = re.search(
    1782 1947   r"(?is)(?:(?:(?:SLEEP\(|RECEIVE_MESSAGE\([\w',]*)|0\:0\:)(?P<sleep_time>\d+)(?:(?:\)|\')))",
    1783 1948   payload,
    skipped 10 lines
    1794 1959   timesec=timesec,
    1795 1960   timeout=timeout,
    1796 1961   headers=headers,
    1797  - parameter=parameter,
     1962 + parameter=param_json,
    1798 1963   expression=expression,
    1799 1964   is_multipart=is_multipart,
    1800 1965   injection_type=injection_type,
    1801 1966   )
    1802 1967   response_time = attack.response_time
    1803 1968   if response_time >= sleep_time:
    1804  - vulnerable = True
     1969 + vectors.update({"time_vector": vector})
    1805 1970   logger.debug(
    1806 1971   f"{injection_type} parameter '{param_name}' is '{title}' vulnerable."
    1807 1972   )
    skipped 3 lines
    1811 1976   )
    1812 1977   except Exception as e:
    1813 1978   logger.critical(f"error {e}, during injection confirmation..")
    1814  - if injection_type == "POST":
    1815  - _data = prepare_attack_request(
    1816  - text=data,
    1817  - payload=payload,
    1818  - param=parameter,
    1819  - is_multipart=is_multipart,
    1820  - injection_type=injection_type,
    1821  - encode=False,
    1822  - )
    1823  - if injection_type == "GET":
    1824  - _url = prepare_attack_request(
    1825  - text=url,
    1826  - payload=payload,
    1827  - param=parameter,
    1828  - injection_type=injection_type,
    1829  - encode=False,
     1979 + vectors_detected = bool(vectors)
     1980 + if vectors_detected:
     1981 + _temp.append(
     1982 + Response(
     1983 + vulnerable=vectors_detected,
     1984 + attack01=attack_false,
     1985 + match_string=match_string,
     1986 + not_match_string=not_match_string,
     1987 + vectors=vectors,
     1988 + injection_type=entry.injection_type,
     1989 + param=vars(param_info),
     1990 + backend=entry.backend,
     1991 + is_string=is_string,
     1992 + )
    1830 1993   )
    1831  - if injection_type == "GET":
    1832  - payload = parse_payload(
    1833  - _url, injection_type=injection_type, param_name=param_name
    1834  - )
    1835  - elif injection_type == "POST":
    1836  - payload = parse_payload(
    1837  - url,
    1838  - data=_data,
    1839  - injection_type=injection_type,
    1840  - is_multipart=is_multipart,
    1841  - )
    1842  - elif injection_type == "HEADER":
    1843  - payload = f"{param_name}: {param_value}{payload}"
    1844  - payload = parse_payload(
    1845  - payload=payload,
    1846  - injection_type=injection_type,
    1847  - )
    1848  - elif injection_type == "COOKIE":
    1849  - payload = f"{param_name}={param_value}{payload}"
    1850  - payload = parse_payload(
    1851  - payload=payload,
    1852  - injection_type=injection_type,
    1853  - )
    1854  - _msg = TEMPLATE_INJECTED_MESSAGE.format(
    1855  - PAYLOAD_TYPE=payload_type,
    1856  - TITLE=title,
    1857  - PAYLOAD=payload,
    1858  - )
    1859  - __.append(_msg)
    1860  - message += "\n".join(__)
    1861  - message += "\n---"
    1862  - if not vulnerable:
    1863  - if is_multipart:
    1864  - param_name = f"MULTIPART {param_name}"
    1865  - if is_json:
    1866  - param_name = f"JSON {param_name}"
     1994 + if not vectors_detected:
     1995 + name = f"{param_info.key}"
     1996 + msg = ""
     1997 + if is_multipart or is_json:
     1998 + msg += "(custom) "
     1999 + msg += f"{entry.injection_type} parameter "
     2000 + if is_multipart:
     2001 + name = f"MULTIPART {param_info.key}"
     2002 + if is_json:
     2003 + name = f"JSON {param_info.key}"
     2004 + msg += f"'{name}' does not seem to be injectable"
     2005 + logger.debug(msg)
     2006 + if not bool(_temp):
    1867 2007   logger.critical(
    1868  - f"it seems the parameter '{nc}{param_name}{mc}' is not vulnerable, please rerun the program with --flush-session switch.."
     2008 + f"all tested parameters do not appear to be injectable., please rerun Ghauri with '--flush-session'."
    1869 2009   )
    1870 2010   logger.end("ending")
    1871 2011   exit(0)
    1872  - logger.success(message)
    1873  - _temp = Response(
    1874  - vulnerable=vulnerable,
    1875  - attack01=attack_false,
    1876  - match_string=match_string,
    1877  - not_match_string=not_match_string,
    1878  - vectors=vectors,
    1879  - injection_type=__injecton_type,
    1880  - param=param,
    1881  - backend=backend,
    1882  - is_string=is_string,
    1883  - )
    1884  - boolean_vector = vectors.get("boolean_vector")
    1885  - error_based_in_vectors = bool("error_vector" in vectors)
    1886  - if boolean_vector and not error_based_in_vectors:
    1887  - attack = attack_false
    1888  - conf.attack01 = attack_false
    1889  - match_string = match_string
    1890  - backend = extended_dbms_check(
    1891  - base,
    1892  - parameter,
    1893  - url=url,
    1894  - data=data,
    1895  - headers=headers,
    1896  - injection_type=injection_type,
    1897  - proxy=proxy,
    1898  - is_multipart=is_multipart,
    1899  - timeout=timeout,
    1900  - delay=delay,
    1901  - timesec=timesec,
    1902  - vector=boolean_vector,
    1903  - backend=backend,
    1904  - attack=attack,
    1905  - code=code,
    1906  - match_string=match_string,
    1907  - not_match_string=not_match_string,
    1908  - text_only=text_only,
    1909  - possible_dbms=possible_dbms,
    1910  - dbms=dbms,
    1911  - )
    1912  - if not backend:
    1913  - session.execute_query(
    1914  - session_filepath=session_filepath,
    1915  - query="DELETE FROM tbl_payload; DELETE FROM storage;",
    1916  - )
    1917  - logger.warning("ghauri could not determine the backend DBMS")
    1918  - logger.warning(
    1919  - "false positive or unexploitable injection point detected"
     2012 + logger.success(ok.template_msg)
     2013 + if len(_temp) == 1:
     2014 + response = _temp[-1]
     2015 + if len(_temp) > 1:
     2016 + ses = "there were multiple injection points, please select the one to use for following injections:\n"
     2017 + for index, i in enumerate(_temp):
     2018 + ses += f"[{index}] place: {i.injection_type}, parameter: {i.param.get('key')}"
     2019 + if index == 0:
     2020 + ses += " (default)"
     2021 + ses += "\n"
     2022 + ses += "[q] Quit\n"
     2023 + ses += "> "
     2024 + choice = logger.read_input(ses, user_input="0")
     2025 + if isinstance(choice, str):
     2026 + if choice == "q":
     2027 + logger.error("user quit")
     2028 + logger.end("ending")
     2029 + exit(0)
     2030 + else:
     2031 + choice = int(choice)
     2032 + response = _temp[choice]
     2033 + if response:
     2034 + vects = response.vectors
     2035 + boolean_vector = vects.get("boolean_vector")
     2036 + error_based_in_vectors = bool("error_vector" in vects)
     2037 + if boolean_vector and not error_based_in_vectors:
     2038 + conf.attack01 = response.attack01
     2039 + backend = extended_dbms_check(
     2040 + base,
     2041 + response.param,
     2042 + url=url,
     2043 + data=data,
     2044 + headers=headers,
     2045 + injection_type=injection_type,
     2046 + proxy=proxy,
     2047 + is_multipart=is_multipart,
     2048 + timeout=timeout,
     2049 + delay=delay,
     2050 + timesec=timesec,
     2051 + vector=boolean_vector,
     2052 + backend=response.backend,
     2053 + attack=response.attack01,
     2054 + code=code,
     2055 + match_string=response.match_string,
     2056 + not_match_string=not_match_string,
     2057 + text_only=text_only,
     2058 + possible_dbms=possible_dbms,
     2059 + dbms=dbms,
    1920 2060   )
    1921  - return None
    1922  - else:
    1923  - logger.info(f"testing {backend}")
    1924  - logger.info(f"confirming {backend}")
    1925  - logger.notice(f"the back-end DBMS is {backend}")
    1926  - return _temp
     2061 + if not backend:
     2062 + session.execute_query(
     2063 + session_filepath=session_filepath,
     2064 + query="DELETE FROM tbl_payload; DELETE FROM storage;",
     2065 + )
     2066 + logger.warning("Ghauri could not determine the backend DBMS")
     2067 + logger.warning(
     2068 + "false positive or unexploitable injection point detected"
     2069 + )
     2070 + return None
     2071 + else:
     2072 + logger.info(f"testing {backend}")
     2073 + logger.info(f"confirming {backend}")
     2074 + logger.notice(f"the back-end DBMS is {backend}")
     2075 + return response
    1927 2076   return None
    1928 2077   
    1929 2078   
    skipped 89 lines
    2019 2168   headers=headers,
    2020 2169   base=base,
    2021 2170   injection_type=retval_session.injection_type,
    2022  - vulnerable=True,
     2171 + vulnerable=retval_session.vulnerable,
    2023 2172   is_multipart=is_multipart,
    2024 2173   boolean_false_attack=retval_session.attack01,
    2025 2174   match_string=retval_session.match_string,
    skipped 224 lines
    2250 2399   else:
    2251 2400   message = f"\n{_it} parameter '{param_name}' is vulnerable. Do you want to keep testing the others (if any)? [y/N] "
    2252 2401   question = logger.read_input(message, batch=batch, user_input="N")
    2253  - if question == "y":
    2254  - logger.debug("dumping current status of injected paramter to session..")
     2402 + if sqlis:
    2255 2403   for entry in sqlis:
    2256 2404   session.dump(
    2257 2405   session_filepath=session_filepath,
    skipped 10 lines
    2268 2416   base.path,
    2269 2417   ),
    2270 2418   )
    2271  - if question == "n":
    2272  - message = "Ghauri identified the following injection point(s) with a total of {nor} HTTP(s) requests:\n".format(
    2273  - nor=conf.req_counter_injected
     2419 + if question and question == "y":
     2420 + if conf.params_count == 0:
     2421 + question = "n"
     2422 + if question and question == "n":
     2423 + retval_session = check_session(
     2424 + url=url,
     2425 + data=data,
     2426 + base=base,
     2427 + proxy=proxy,
     2428 + delay=delay,
     2429 + timesec=timesec,
     2430 + timeout=timeout,
     2431 + headers=headers,
     2432 + parameter=parameter,
     2433 + is_multipart=is_multipart,
     2434 + injection_type=injection_type,
     2435 + session_filepath=session_filepath,
     2436 + is_json=is_json,
     2437 + code=code,
     2438 + match_string=string,
     2439 + not_match_string=not_string,
     2440 + text_only=text_only,
     2441 + possible_dbms=possible_dbms,
     2442 + dbms=dbms,
     2443 + injected_and_vulnerable=True,
    2274 2444   )
    2275  - message += "---\n"
    2276  - _p = param_name
    2277  - _it = injection_type if param_name != "#1*" else "URI"
    2278  - if is_json:
    2279  - _p = f"JSON {param_name}"
    2280  - _it = f"(custom) {injection_type}"
    2281  - if is_multipart:
    2282  - _p = f"MULTIPART {param_name}"
    2283  - _it = f"(custom) {injection_type}"
    2284  - message += "Parameter: {} ({})".format(_p, _it)
    2285  - payload_lists = []
    2286  - backend = esqli.backend if error_based_in_priority else None
    2287  - attack01 = None
    2288  - match_string = None
    2289  - if dbms and not backend:
    2290  - backend = dbms
    2291  - for entry in sqlis:
    2292  - param_value = entry.param.get("value").replace("*", "")
    2293  - injection_type = entry.injection_type
    2294  - _payload = urldecode(entry.payload)
    2295  - if entry.backend == "Microsoft SQL Server":
    2296  - _payload = _payload.replace("%2b", "+")
    2297  - session.dump(
    2298  - session_filepath=session_filepath,
    2299  - query=PAYLOAD_STATEMENT,
    2300  - values=(
    2301  - entry.title,
    2302  - entry.number_of_requests,
    2303  - entry.payload,
    2304  - entry.prepared_vector,
    2305  - entry.backend,
    2306  - json.dumps(entry.param),
    2307  - entry.injection_type,
    2308  - entry.payload_type,
    2309  - base.path,
    2310  - ),
    2311  - )
    2312  - if injection_type == "GET":
    2313  - payload = parse_payload(
    2314  - entry.url,
    2315  - injection_type=injection_type,
    2316  - param_name=param_name,
    2317  - )
    2318  - elif injection_type == "POST":
    2319  - payload = parse_payload(
    2320  - url,
    2321  - data=entry.data,
    2322  - injection_type=injection_type,
    2323  - is_multipart=is_multipart,
    2324  - )
    2325  - elif injection_type == "HEADER":
    2326  - payload = f"{param_name}: {param_value}{_payload}"
    2327  - payload = parse_payload(
    2328  - payload=payload,
    2329  - injection_type=injection_type,
    2330  - )
    2331  - elif injection_type == "COOKIE":
    2332  - payload = f"{param_name}={param_value}{_payload}"
    2333  - payload = parse_payload(
    2334  - payload=payload,
    2335  - injection_type=injection_type,
    2336  - )
    2337  - _msg = TEMPLATE_INJECTED_MESSAGE.format(
    2338  - PAYLOAD_TYPE=entry.payload_type,
    2339  - TITLE=entry.title,
    2340  - PAYLOAD=payload,
    2341  - )
    2342  - payload_lists.append(_msg)
    2343  - message += "\n".join(payload_lists)
    2344  - message += "\n---"
    2345  - logger.success(message)
    2346  - boolean = priorities.get("boolean-based")
    2347  - if boolean:
    2348  - attack01 = boolean.attacks[-1]
    2349  - match_string = boolean.string
    2350  - if boolean and "error-based" not in priority_keys:
    2351  - attack = boolean.attacks[-1]
    2352  - conf.attack01 = attack
    2353  - boolean_vector = boolean.prepared_vector
    2354  - backend = extended_dbms_check(
    2355  - base,
    2356  - parameter,
     2445 + if retval_session and retval_session.vulnerable:
     2446 + return Ghauri(
    2357 2447   url=url,
    2358 2448   data=data,
     2449 + vectors=retval_session.vectors,
     2450 + backend=retval_session.backend,
     2451 + parameter=retval_session.param,
    2359 2452   headers=headers,
    2360  - injection_type=injection_type,
    2361  - proxy=proxy,
     2453 + base=base,
     2454 + injection_type=retval_session.injection_type,
     2455 + vulnerable=retval_session.vulnerable,
    2362 2456   is_multipart=is_multipart,
    2363  - timeout=timeout,
    2364  - delay=delay,
    2365  - timesec=timesec,
    2366  - vector=boolean_vector,
    2367  - backend=backend,
    2368  - attack=attack,
    2369  - code=code,
    2370  - match_string=string,
    2371  - not_match_string=not_string,
    2372  - text_only=text_only,
    2373  - possible_dbms=possible_dbms,
    2374  - dbms=dbms,
     2457 + boolean_false_attack=retval_session.attack01,
     2458 + match_string=retval_session.match_string,
     2459 + is_string=retval_session.is_string,
    2375 2460   )
    2376  - if not backend:
    2377  - session.execute_query(
    2378  - session_filepath=session_filepath,
    2379  - query="DELETE FROM tbl_payload; DELETE FROM storage;",
    2380  - )
    2381  - logger.warning("ghauri could not determine the backend DBMS")
    2382  - logger.warning(
    2383  - "false positive or unexploitable injection point detected"
    2384  - )
    2385  - return None
    2386  - else:
    2387  - logger.info(f"testing {backend}")
    2388  - logger.info(f"confirming {backend}")
    2389  - logger.notice(f"the back-end DBMS is {backend}")
    2390  - return Ghauri(
    2391  - url=url,
    2392  - data=data,
    2393  - vectors=vectors,
    2394  - backend=backend,
    2395  - parameter=parameter,
    2396  - headers=headers,
    2397  - base=base,
    2398  - injection_type=injection_type,
    2399  - vulnerable=True,
    2400  - is_multipart=is_multipart,
    2401  - boolean_false_attack=attack01,
    2402  - match_string=match_string,
    2403  - is_string=is_string,
    2404  - )
    2405 2461   else:
    2406 2462   logger.warning("false positive or unexploitable injection point detected")
    2407 2463   _it = injection_type
    skipped 24 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/ghauri.py
    skipped 250 lines
    251 251   parameters = injection_points.get(injection_type)
    252 252   if testparameter:
    253 253   parameters = [i for i in parameters if i.get("key") in testparameter]
     254 + conf.params_count = len(parameters)
    254 255   for parameter in parameters:
    255 256   param_name = parameter.get("key")
    256 257   param_value = parameter.get("value")
    skipped 13 lines
    270 271   # msg = f"ignoring {injection_type} parameter '{param_name}'"
    271 272   # logger.info(msg)
    272 273   # continue
     274 + conf.params_count -= 1
    273 275   if not is_connection_tested:
    274 276   retval_check = basic_check(
    275 277   url=url,
    skipped 527 lines
  • ■ ■ ■ ■
    setup.py
    skipped 4 lines
    5 5   
    6 6  setup(
    7 7   name="ghauri",
    8  - version="1.1.3",
     8 + version="1.1.4",
    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