Vulnérabilités dans Fckeditor <= 2.6.4

Le SANS ISC (SANS Internet Storm Center) a lancé une alerte sur l’éditeur HTML FCKeditor après que de nombreuses attaques 0day aient été détectées. Ces attaques vise particulièrement les sites web utilisant Adobe ColdFusion 8 (FCKeditor est module livré avec ce logiciel).

L’éditeur Adobe a aussi émit une alerte “potentielle” (sic) sur la vulnérabilité de son produit, et une mise à jour sera livrée, peut-être, semaine prochaine …. Une semaine complète, au minimum, durant laquelle de nombreux sites web utilisant ColdFusion 8 pourront servir de relais à des attaques. De plus, Adobe a eu l’idée ingénieuse d’activer par défaut le module FCKeditor ColdFusion depuis la version 8.0.1 de son logiciel.

Mais ce qui est le plus inquiétant c’est que toutes les versions antérieures ou égales à FCKeditor 2.6.4 sont vulnérables, et cela peut importe si on utilise ColdFusion ou non. L’exploitation de la vulnérabilité est possible dès qu’un connecteur est déclaré comme actif dans le fichier de configuration “config.php”. Les entrées envoyées au paramètre “CurrentFolder“, de différents modules de connexion (voir liste ci-dessous), ne sont pas traitées correctement permettant ainsi d’afficher le contenu de répertoire arbitraires ou de télécharger des fichiers sur le serveur. D’autres vulnérabilités, du type Cross Site Scripting (XSS) sont aussi présentes et celles-ci fonctionne aussi peut importe le langage supporté.

L’éditeur a fournis une mise à jour de sécurité 2.6.4.1 corrigeant les vulnérabilités. Si la version de FCKeditor n’est pas à jour, et qu’un seul des connecteurs soit actif dans le fichier de configuration, l’on peut dire bye bye a son serveur.

L’on peut même se demander, si finalement l’éditeur de FCKeditor n’a pas mis trop de temps à réagir –> regardez cela http://www.milw0rm.org/exploits/8060 –> oula c’est sorti le 2009-02-16, hum hum un tas de foin pour rien ???

Les fichiers mis à jour entre la version 2.6.4 et la version 2.6.4.1, et qui traite le XSS, sont :

_samples/asp/sample02.asp, la variable "Lang" a été protégée contre les attaques du type XSS
_samples/asp/sample03.asp, la variable "Toolbar" a été protégée contre les attaques du type XSS
_samples/asp/sample04.asp, la variable "Skin" a été protégée contre les attaques du type XSS

 

_samples/cfm/sample02.cfm, la variable "Lang" a été protégée contre les attaques du type XSS
_samples/cfm/sample02_mx.cfm, la variable "Lang" a été protégée contre les attaques du type XSS
_samples/cfm/sample03.cfm, la variable "Toolbar" a été protégée contre les attaques du type XSS
_samples/cfm/sample03_mx.cfm, la variable "Toolbar" a été protégée contre les attaques du type XSS
_samples/cfm/sample04.cfm, la variable "Skin" a été protégée contre les attaques du type XSS
_samples/cfm/sample04_mx.cfm, la variable "Skin" a été protégée contre les attaques du type XSS
Le XSS permet de s'exécuter lors du traitement des variables retournées par le script _samples/cfm/sampleposteddata.cfm

_samples/lasso/sample02.lasso, la variable "Lang" a été protégée contre les attaques du type XSS
_samples/lasso/sample03.lasso, la variable "Toolbar" a été protégée contre les attaques du type XSS
_samples/lasso/sample04.lasso, la variable "Skin" a été protégée contre les attaques du type XSS
Le XSS permet de s'exécuter lors du traitement des variables retournées par le script /_samples/lasso/sampleposteddata.lasso

_samples/perl/sample02.cgi, la variable “Lang” a été protégée contre les attaques du type XSS
_samples/perl/sample03.cgi, la variable “Toolbar” a été protégée contre les attaques du type XSS
_samples/perl/sample04.cgi, la variable “Skin” a été protégée contre les attaques du type XSS
Le XSS permet de s’exécuter lors du traitement des variables retournées par le script _samples/perl/sampleposteddata.cgi

_samples/php/sample02.php, la variable “Lang” a été protégée contre les attaques du type XSS
_samples/php/sample03.php, la variable “Toolbar” a été protégée contre les attaques du type XSS
_samples/php/sample04.php, la variable “Skin” a été protégée contre les attaques du type XSS
Le XSS permet de s’exécuter lors du traitement des variables retournées par le script _samples/php/sampleposteddata.php

 

Le XSS permet de s’exécuter lors du traitement des variables retournées par le script sampleposteddata.py

Les fichiers mis à jour entre la version 2.6.4 et la version 2.6.4.1, et qui traite l’upload de fichier arbitraire, sont :

editor/filemanager/connectors/asp/io.asp
editor/filemanager/connectors/asp/upload.asp

editor/filemanager/connectors/cfm/cf_io.cfm
editor/filemanager/connectors/cfm/cf_upload.cfm

editor/filemanager/connectors/lasso/upload.lasso

editor/filemanager/connectors/perl/connector.cgi
editor/filemanager/connectors/perl/io.pl
editor/filemanager/connectors/perl/upload.cgi

editor/filemanager/connectors/php/commands.php
editor/filemanager/connectors/php/io.php
editor/filemanager/connectors/php/upload.php

 

editor/filemanager/connectors/py/upload.py

Fping à la découverte d’hôtes

Quoi de mieux que la bonne commande “ping” pour découvrir si des hôtes répondent présents ou non dans un réseau. Mais si nous avons plusieurs centaines de machines à vérifier, et/ou si un Firewall détecte les comportements de ping d’une adresse IP les unes après les autres, la mission de reconnaissance devient longue et fastidieuse.

Afin de palier au manque de la commande “ping” classique, l’outil fping permet de fournir en entrée une liste de plusieurs hôtes, ou réseaux, à analyser. Et à la place d’attendre la réponse d’un hôte pour commencer le test suivant, fping passera à un hôte suivant sélectionné dans la liste fournie en entrée et cela de façon aléatoire.

  • Ping sur un hôte

xxxx@xxxx $ sudo fping xxx.xxx.xxx.xxx
xxx.xxx.xxx.xxx is unreachable

  • Ping sur plusieurs hôtes

xxxxx@xxxxx $ sudo fping xxx.xxx.xxxx.xxx yyy.yyy.yyy.yyy
yyy.yyy.yyy.yyy is alive
xxx.xxx.xxx.xxx is unreachable

  • Ping sur plusieurs hôtes fournis dans un fichier

xxxx@xxxxx $ cat hosts.txt
xxx.xxx.xxx.xxx
yyy.yyy.yyy.yyy

xxxxx@xxxx $ sudo fping -f hosts.txt
yyy.yyy.yyy.yyy is alive
xxx.xxx.xxx.xxx is unreachable

  • Ping sur un réseau ou un nombre déterminé de hôtes

xxxxx@xxxxxx $ sudo fping -g xxx.xxx.xxx.0/24

xxxxx@xxxxxx $ sudo fping -g xxx.xxx.xxx.8 xxx.xxx.xxx.15

Il n’est pas possible de spécifier plusieurs réseaux les uns à la suite des autres, ni même de les appeler par l’option “-f

  • Afficher le temps de réponse au ping

xxxxx@xxxx $ sudo fping -e yyy.yyy.yyy.yyy
yyy.yyy.yyy.yyy is alive (128 ms)

  • Afficher la résolution de l’adresse IP

xxxx@xxxx $ sudo fping -n yyy.yyy.yyy.yyy
toto.toto.com is alive

  • Afficher l’IP et la résolution de l’adresse IP

xxxx@xxxx $ sudo fping -n -A yyy.yyy.yyy.yyy
toto.toto.com (yyy.yyy.yyy.yyy) is alive

  • Afficher les statistiques finale

xxxxx@xxxxx $ sudo fping -s xxx.xxx.xxx.xxx yyy.yyy.yyy.yyy
yyy.yyy.yyy.yyy is alive
xxx.xxx.xxx.xxx is unreachable

2 targets
1 alive
1 unreachable
0 unknown addresses

4 timeouts (waiting for response)
5 ICMP Echos sent
1 ICMP Echo Replies received
0 other ICMP received

23.3 ms (min round trip time)
23.3 ms (avg round trip time)
23.3 ms (max round trip time)
4.087 sec (elapsed real time)

  • N’afficher que les hôtes qui répondent

xxxx@xxxx $ sudo fping -a xxx.xxx.xxx.xxx yyy.yyy.yyy.yyy
yyy.yyy.yyy.yyy

  • N’afficher que les hôtes qui ne répondent pas

xxxx@xxxxx $ sudo fping -u xxx.xxx.xxx.xxx yyy.yyy.yyy.yyy
xxx.xxx.xxx.xxx

  • Ping fping versus ping nmap

Nmap propose aussi une option ping pour vérifier si un hôte est accessible ou pas (-sP). A la différence de fping (qui effectue uniquement une demande “ICMP echo request“, nmap va lancer une connexion ACK sur le port 80 de l’adresse IP, et demandera aussi un “ICMP echo request“. L’option “-sP” de nmap n’est pas un véritable ping, mais permet éventuellement d’aller un peu plus loin dans l’étude de disponibilité d’un hôte ou pas.

Prenons, par exemple, notre machine xxx.xxx.xxx.xxx qui ne répond pas avec fping, et lançons l’analyse avec nmap.

xxxxx@xxxxxx $ sudo nmap -v -sP xxx.xxx.xxx.xxx

Starting Nmap 4.76 ( http://nmap.org ) at 2009-06-28 11:09 CEST
Initiating Ping Scan at 11:09
Scanning xxx.xxx.xxx.xxx [2 ports]
Completed Ping Scan at 11:09, 0.08s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 11:09
Completed Parallel DNS resolution of 1 host. at 11:09, 0.00s elapsed
Host toto.titi.com (xxx.xxx.xxx.xxx) appears to be up.
Read data files from: /usr/local/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.59 seconds
Raw packets sent: 2 (68B) | Rcvd: 1 (40B)

Un tcpdump nous permet de voir ce qui se passe lorsque nmap -sP est lancé.

10:17:19.259833 IP 192.168.aaa.aaa.50409 > xxx.xxx.xxx.xxx.80: . ack 2315653060 win 3072
10:17:19.260143 IP 192.168.aaa.aaa > xxx.xxx.xxx.xxx: ICMP echo request, id 21709, seq 0, length 8
10:17:19.283920 IP xxx.xxx.xxx.xxx.80 > 192.168.aaa.aaa.50409: R 2315653060:2315653060(0) win 0

Le hôte ne répond pas à la connexion “ICMP echo request”, mais par contre répond sur le port 80. Ce fait peut être vérifié par un simple telnet.

xxxxx@xxxxxx $ telnet xxx.xxx.xxx.xxx 80
Trying xxx.xxx.xxx.xxx...
telnet: connect to address xxx.xxx.xxx.xxx: Connection refused
telnet: Unable to connect to remote host

L’on peut remarquer que le port 80 est ouvert, mais filtré par des règles quelconques.

  • Détection de filtrage par le biais de fping, versus nmap

Fping pourra permettre par les réponses données, de voir que certains hôtes sont inaccessible à cause de règles quelconques, petits exemples :

Exemple 1 :

xxxxxx@xxxxx $ sudo fping zzz.zzz.zzz.zzz
ICMP Unreachable (Communication Administratively Prohibited) from zzz.zzz.zzz.zzz for ICMP Echo sent to zzz.zzz.zzz.zzz
ICMP Unreachable (Communication Administratively Prohibited) from zzz.zzz.zzz.zzz for ICMP Echo sent to zzz.zzz.zzz.zzz
ICMP Unreachable (Communication Administratively Prohibited) from zzz.zzz.zzz.zzz for ICMP Echo sent to zzz.zzz.zzz.zzz
ICMP Unreachable (Communication Administratively Prohibited) from zzz.zzz.zzz.zzz for ICMP Echo sent to zzz.zzz.zzz.zzz
zzz.zzz.zzz.zzz is unreachable

L’hôte sera déclaré comme “unreachable”, par contre les messages de retour montre qu’un élément filtrant empêche la communication.

Comparons maintenant ces résultats avec l’option “-sP” de nmap.

xxxx@xxxxx $ sudo nmap -v -sP zzz.zzz.zzz.zzz

Starting Nmap 4.76 ( http://nmap.org ) at 2009-06-28 11:20 CEST
Initiating Ping Scan at 11:20
Scanning zzz.zzz.zzz.zzz [2 ports]
Completed Ping Scan at 11:20, 0.08s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 11:20
Completed Parallel DNS resolution of 1 host. at 11:20, 0.02s elapsed
Host yaya.gougou.com (zzz.zzz.zzz.zzz) appears to be up.
Read data files from: /usr/local/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.74 seconds
Raw packets sent: 2 (68B) | Rcvd: 1 (56B)

Nmap a déclaré que l’hôte était accessible, car le port 80 de cette machine est accessible, mais par contre ne nous a pas donner autant d’information sur fping sur la présence d’un élément filtrant. Il faudra rajouter l’option “-d” ou “–packet-trace” pour avoir le même résultat que fping.

Exemple 2 :

xxxxx@xxxxx $ sudo fping rrr.rrr.rrr.rrr
ICMP Host Unreachable from sss.sss.sss.sss for ICMP Echo sent to rrr.rrr.rrr.rrr
ICMP Host Unreachable from sss.sss.sss.sss for ICMP Echo sent to rrr.rrr.rrr.rrr
ICMP Host Unreachable from sss.sss.sss.sss for ICMP Echo sent to rrr.rrr.rrr.rrr
rrr.rrr.rrr.rrr is unreachable

L’on peut voir grâce à fping que l’hôte sss.sss.sss.sss répond lorsque l’on effectue un ping sur l’hôte rrr.rrr.rrr.rrr

Comparons maintenant ces résultats avec l’option “-sP” de nmap.

xxxxx@xxxxx $ sudo nmap -v -sP rrr.rrr.rrr.rrr

Starting Nmap 4.76 ( http://nmap.org ) at 2009-06-28 11:29 CEST
Initiating Ping Scan at 11:29
Scanning rrr.rrr.rrr.rrr [2 ports]
Completed Ping Scan at 11:29, 3.03s elapsed (1 total hosts)
Host rrr.rrr.rrr.rrr appears to be down.
Read data files from: /usr/local/share/nmap
Note: Host seems down. If it is really up, but blocking our ping probes, try -PN
Nmap done: 1 IP address (0 hosts up) scanned in 3.57 seconds
Raw packets sent: 4 (136B) | Rcvd: 0 (0B)

L’on peut voir ici que nmap ne nous signifie pas que l’hôte sss.sss.sss.sss répond lorsque l’on effectue un ping sur l’hôte rrr.rrr.rrr.rrr

L’option “-PN” pourra détecter que l’hôte rrr.rrr.rrr.rrr est up, mais sans pour autant nous signifier que sss.sss.sss.sss est un élément intermédiaire de filtrage.

Fping est un outil de base, qui en complément avec d’autres outils, tels que nmap, pourrait permettre d’avoir une vue complète sur un réseau et effectuer une phase d’approche intéressante.

Wafw00f – Web Application Firewall Detection Tool

Un WAF (Web Application Firewall) est une “appliance”, ou un “plug-in” serveur, ou un filtre qui appliquera certaines règles lors de requêtes HTTP. Les règles mises en place permettent surtout de contrecarrer les attaques du type XSS et injection SQL, même si l’application, que le WAF est censé protégé, possède de nombreuses vulnérabilités. En customisant les règles à son application Web que l’on désire protéger la plupart des attaques seront alors bloquées. Les efforts à fournir pour la customisation des règles, ainsi que leurs maintenances peuvent être important, car dès que l’application web sera modifiée, il faudra ajouter de nouvelles règles, ou adapter des règles déjà existantes.

WAFW00F est un logiciel développé en Python, qui permettra de détecter si un WAF est présent et surtout quel type WAF est utiliser pour protéger l’application web. Afin de détecter si un WAF est présent, différents scénarios seront joués, comme par exemple :

– Analyse des cookies (certains WAF génère leurs propres cookies).
– Modifications des en-têtes HTTP et des URL appelées, en y injectant par exemple des chaînes XSS.
– Codes réponses qui ne devraient pas être ceux présentés.

WAFW00F est capable de détecter près de 20 WAF différents (Profense, ModSecurity, NetContinuum, HyperGuard, Barracuda, Airlock, BinarySec, F5 Trafficshield, F5 ASM, Teros, DenyALL, BIG-IP, Citrix NetScaler, webApp.secure, WebKnight, URLScan, SecureIIS, dotDefender ).

Ci-dessous une détection du “plug-in” Apache mod_security.

[xxxxx@xxxxx waffit-read-only]$ python wafw00f.py http://www.xxxxxx.com

^     ^
_   __  _   ____ _   __  _    _   ____
///7/ /.' \ / __////7/ /,' \ ,' \ / __/
| V V // o // _/ | V V // 0 // 0 // _/
|_n_,'/_n_//_/   |_n_,' \_,' \_,'/_/
<
...'

WAFW00F - Web Application Firewall Detection Tool

By Sandro Gauci && Wendel G. Henrique

Checking http://www.xxxxxx.com
The site http://www.xxxxxx.com is behind a ModSecurity (positive model)
Number of requests: 9

Cette détection peut être confirmée par l’exemple manuel suivant, et le code de retour HTTP 404 qui n’est pas cohérent.

xxxxx@xxxx waffit-read-only]$ telnet www.xxxxx.com 80
Trying xxx.xxx.xxx.xxx...
Connected to www.xxxxxx.com (xxx.xxx.xxx.xxx).
Escape character is '^]'.
GET /index.php?action=<script>alert(document.cookie)</script> HTTP/1.0

[b]HTTP/1.1 404 Not Found[/b]
Date: Sat, 27 Jun 2009 11:15:56 GMT
Server: Apache
Content-Length: 207
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /index.php was not found on this server.</p>
</body></html>
Connection closed by foreign host.

Ci-dessous la détection d’un WAF sans que le modèle puisse être spécifié.

xxxxx@xxxxx waffit-read-only]$ python wafw00f.py http://www.yyyyyy.com

^     ^
_   __  _   ____ _   __  _    _   ____
///7/ /.' \ / __////7/ /,' \ ,' \ / __/
| V V // o // _/ | V V // 0 // 0 // _/
|_n_,'/_n_//_/   |_n_,' \_,' \_,'/_/
<
...'

WAFW00F - Web Application Firewall Detection Tool

By Sandro Gauci && Wendel G. Henrique

Checking http://www.yyyyyy.com
Generic Detection results:
The site http://www.yyyyyy.com seems to be behind a WAF
Reason: The server returned a different response code when a string trigged the blacklist.
Normal response code is "404", while the response code to an attack is "403"
Number of requests: 11

Cette détection peut être aussi confirmer en effectuant une détection manuelle, et par le code retour HTTP 403.

xxxxxx@xxxx waffit-read-only]$ telnet www.yyyy.com 80
Trying yyy.yyy.yyy.yyy...
Connected to www.yyyyy.com (yyy.yyy.yyy.yyy).
Escape character is '^]'.
GET /index.php?action=<script>alert(document.cookie)</script> HTTP/1.0

[b]HTTP/1.1 403 Forbidden[/b]
Date: Sat, 27 Jun 2009 11:12:26 GMT
Server: Apache
Content-Length: 211
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /index.php
on this server.</p>
</body></html>
Connection closed by foreign host.

Exemple d’un maillage simple de réseau RFI

j’avais abordé dans un billet précédent une étude sur un RFI et le principe des attaques par intermédiaire. Cette étude se limitait sur une attaque avec simplement trois adresses IP impliquées (celle de l’attaquant, celle de la cible et celle de l’intermédiaire).

Ce qui est plus intéressant à faire est d’essayer de modéliser les réseaux RFI en place et leurs maillages. Ce billet traitera d’un exemple simple de maillage RFI.

82.194.87.219 situé à Bilbao en Espagne, tente, en tant qu’attaquant à inclure sur la cible ZATAZ, situé en France, un payload localisé sur l’intermédiaire 195.114.18.99 (aka www.laubrotel.com) lui aussi situé en France.

Events source de 82.194.87.219 en relation avec le payload localisé sur l’intermédiaire 195.114.18.99 durant le dernier mois.

82.194.87.219, l’attaquant, a été vu la première fois le 2009-04-22 à 06:07:02 et la dernière fois le 2009-06-27 à 01:03:33, et à générer une totalité de 520 events. Celui-ci est en fait un serveur d’hébergement mutualisé (voir les sites référencés sur cette adresses IP) qui est aussi sûrement compromis de puis plus de 2 mois.

195.114.18.99, l’intermédiaire, a été vu la première fois le 2009-02-20 à 21:51:43 et la dernière fois le 2009-06-27 à 01:03:33, et à été impliqué dans près de 559 events. Le payload, toujours actif (http://www.laubrotel.com/letter/id?), est du à une mise à jour non effectué sur un Joomla. Ce site web est maintenant compromis depuis plus de 4 mois.

Nous voyons donc que l’intermédiaire, aka 195.114.18.99, a une durée de vie beaucoup plus grande que l’attaquant, ce qui sous-entend donc, que le payload a été utilisé au préalable par d’autres attaquant.

Vous pourrez trouvez donc ci-dessous, après un petit développement et une petite analyse tous les attaquants ayant été en relation avec l’intermédiaire 195.114.18.99.

Ce qui donne la représentation GoogleMap, de tous le cycle de vie de l’intermédiaire suivant.

L’on peut voir ici que cet intermédiaire a été utilisé par différents attaquants qui sont sûrement liés au même réseau.

Le prochaine billet portera sur une étude plus complexe du maillage des réseaux RFI.