How to attack Hacking MongoDB

Source: Internet
Author: User
Tags mongodb update

How to attack Hacking MongoDB

MongoDB is a good database engine for both commercial and personal projects, and many domestic companies have begun to use MongoDB. Compared with traditional databases, this database is relatively new and has many security problems that you are not aware of yet. These problems can usually be caught off guard.
This article mainly introduces the problems I encountered when using MongoDB and how it was used to modify Database records. Of course, the process of using SQL injection is very simple, but the SQL injection technology in various ways is the same, but many people are still prone to such errors.
Before we begin, I would like to introduce the following MongoDB features. The update mechanism provided by MongoDB is to first locate this document and then update it, as shown in the following example:
{
Name: "John ",
Info :{
Age: 65
}
}
You can use the following statement to update the above record:
Db. people. update ({"name": "John" },{ "$ set": {"info. age": 66 }})
Is it really cool? Okay, you know.

But what if the sub-key is not hard-coded? How can we pass in the content through variables? As follows:
KeyName = request. form | 'keyname' |
KeyData = request. form | 'value' |
Db. people. update ({"name": "John"}, {"$ set": {"info. {}". format (keyName): keyData }})
After the background program obtains the key and value values from the front-end request, it passes the parameters to the MongoDB update function. The problem arises. What if the front-end inputs a malicious parameter.
The following is a problem I encountered when handling an unknown user input. To illustrate this problem, let's write a section to demonstrate this vulnerability. The Code is as follows:
From flask import *
Import pymongo
Import bson
Import uuid
 
Db = pymongo. Expose client ("localhost", 27017). test
 
Form = """

"""
 
 
App = Flask (_ name __)
App. secret_key = "secret"
 
@ App. route ("/logout /")
Def logout ():
Session. pop ("_ id ")
Return redirect ("/login /")
 
@ App. route ("/")
Def index ():
If "_ id" not in session:
Return redirect ("/login /")
Name = request. args. get ("name ")
Lastname = request. args. get ("lastname ")
If not name:
Return "Search for someone"
Else:
Search_results = db. members. find_one ({"{}". format (name): lastname })
If search_results:
Search_results = name + "" + lastname + "is" + search_results ['account _ info'] ['age'] + "years old ."
Return "{}". format (search_results)
 
@ App. route ("/login/", methods = ['get', 'post'])
Def login ():
If request. method = "POST ":
Username = request. form ['username']
Password = request. form ['Password']
Check = db. members. find_one ({"username": username, "password": password })
If check:
Session ['_ id'] = str (check)
Return rediirect ("/? Name = {} ". format)
Else:
Return "Invalid Login"
Return "Login" + form
 
@ App. route ("/signup/", methods = ['get', 'post'])
Def signup ():

If request. method = "POST ":
Username = request. form ['username']
Firstname = request. form ['firstname']
Lastname = request. form ['lastname']
Password = request. form ['Password']
Age = request. form ['age']
Session ['_ id'] = str (db. members. insert ({"username": username, "password": password, firstname: lastname, "account_info": {"age": age, "age": age, "isAdmin ": false, "secret_key": uuid. uuid4 (). hex }}))
Return redirect ("/")
Return "Signup" + form
 
@ App. route ("/settings/", methods = ['get', "POST"])
Def settings ():
If request. method = "POST ":
Username = request. form ['username']
Firstname = request. form ['firstname']
Lastname = request. form ['lastname']
Password = request. form ['Password']
Age = request. form ['age']
Db. members. update ({"_ id": bson. objectId (session ['_ id']) },{ "$ set ":{"{}". format (firstname): lastname, "account_info.age": age, "username": username }})
Return "Values have been updated! "
Return "Settings" + form
 
@ App. route ("/admin/", methods = ['get', 'post'])
Def admin ():
If "_ id" not in session:
Return redirect ("/login /")
TheUser = db. members. find_one ({"_ id": bson. ObjectId (session ['_ id'])})
If not theUser ['account _ info'] ['isadmin']:
Return "You do not have access to this page ."
If request. method = "POST ":
Secret = request. form ['secret _ key']
Return str (db. members. find_one ({"account_info.secret_key": secret }))
Return "" Search user by secret key

"""
 
App. run (debug = True)
This website is very simple. It is a login page, a registration page, a setting page, and an index page. Users can enter their/their names on these pages, and then return the age, such.


Note that this code is vulnerable to injection attacks. Next, let's take a look at how to inject it.
Our goal is to obtain the permission to access the admin page. We can find from the website code that the background verifies user permissions based on the isAdmin field, as shown in figure

Check whether the background database is like this:

Among them, Firstname: Lastname is directly inserted into the name, it looks strange.
Create a user first, and then access the/admin/page. The returned result is as follows:

Good ...... No access permission. In retrospect, isAdmin can be used to control the page, that is, the user may be in the database like this:

Among them, firstname: lastname is controllable and entered on the settings page, "username", "password", "firstname ", and "lastname" are actually all input. firstname: lastname can be used for query. It seems that some articles can be written.
Change fistname to account_info.isAdmin and lastname to "1". 1 indicates True in python.

 


Click Submint and the modification is successful.

Access the/admin/Page:

You can access the admin page: D
Similarly, if you want to use the secret key to query the entire content, you can do this:

Input query:

Successful:

At this point, we can actually do a lot more. We can use it to modify the account and password of other users and view other users. I will not introduce it here.
Obviously, all the security measures for this website are useless, and sensitive data is also becoming dangerous. Of course, when your website is attacked and you look back at the code, you may think your code is very funny, but this is absolutely not to be ignored. Well, in fact, I have made such a mistake and I am glad to find it in time.
Like SQL Injection in relational databases, what we need to do is filter input parameters.
 

 

 

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.