Heap Overflow Vulnerability in Citrix NetScaler Gateway (CVE-2017-7219)

After presenting my findings on the Swisscom router at the CybSecConference last year, I started looking for a new product to analyze. I quickly found that it’s possible to download virtual “demo” appliances of Citrix products, so I went on to download a Netscaler VPX, which at the time was at version 11.10 (b50.10). The goal as always was to discover a way to compromise the device remotely, which is what led me to discover a heap overflow vulnerability which allows an authenticated user to compromise the device with root privileges. During the research, I (un)fortunately wasn’t able to find a way to exploit the flaw without credentials.


A heap overflow in the “ping” functionality allows an authenticated VPN user to trigger a use-after-free condition in order to execute arbitrary commands on the appliance. (CVE-2017-7219)

The following Metasploit module can be used to exploit the vulnerability (use at your own risk…), though it will probably only function against the version that was analyzed.


As mentioned above, I began by downloading the virtual appliance and started it up on my machine. Since I’ve never used or configured a Netscaler appliance in the past, it took a while to get things going and configuring it in some kind of standard mode.

Once the appliance is started, it is possible to log into the console with the standard nsroot account. This gives access to a “limited” shell, but Citrix were nice enough to add a shell command which gives root access to the box, so I used this to extract the filesystem and analyze what was going on.

Going through the various files on the system, I found one that seemed promising which was named /netscaler/nsvpnd. As it’s name hints at, it is used to handle requests sent to the VPN web interface. Though only authenticated requests seem to get here, as authentication itself is performed by another binary on the system.

One of the requests that is performed by the nsvpnd binary is the ping request.

This results in the following HTTP request:

POST /cvpn/aHR0cDovLzEyNy4wLjAuMQ/fs/ping HTTP/1.1
Cookie: NSC_AAAC=b2f85f0b72ef21c82eac5ac4d314a4170af182cd945525d5f4f58455e445a4a42; NSC_FSSO=0
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 41


Apparently the /cvpn/aHR0cDovLzEyNy4wLjAuMQ part of the URL is not actually required, so it can safely be removed. In any case, this request is eventually handled by one of two vulnerable functions that contain an unbounded strcpy with our host parameter, as shown below.

This is where the overflow happens, though we are not overwriting a stack variable, but one of the members of a struct, which is expected to be at most 256 bytes long. Our parameter on the other hand can go up to 512 bytes, which is what allows us to overflow this buffer.

So it is possible to write up to 256 bytes after the host member of the structure, therefore overwriting any other members of the structure after the host, which is where things get interesting. One of the following members is actually a pointer to another structure (a parameter list) on the heap which was previously allocated and eventually gets free‘d by the application when the request has completely been processed.  This means we can essentially free an arbitrary memory location.

Before going any further, a quick analysis of the system and binary show that FreeBSD uses jemalloc instead of dlmalloc, the heap is not executable, but the stack is, and ASLR is not enabled (this was 2016 after all). Another thing that was helpful in exploiting this particular issue is that all requests to the web interface are handled by one single process, which means we can actually interact many times with the process by sending multiple HTTP requests if required.

At this point, my idea to gain code execution was the following:

  1. Find a function pointer somewhere in the application, as well as the size that was used to allocate that memory
  2. Free the memory address of this function pointer
  3. On the next malloc of the appropriate size, the same address should be returned
  4. Overwrite the function pointer with user-controlled data (a pointer to my shellcode) when it is copied to this memory address
  5. Trigger the function pointer to call my shellcode

The only remaining problem is getting a shellcode to some predictable location. Thankfully, as mentioned earlier, ASLR is disabled, the stack is executable and the value we send in our host parameter is actually stored on the stack! All we need is to get this address and plug it into the function pointer to get the shellcode to execute. Obviously, despite ASLR being disabled, the stack will not always be exactly at the same place, so I used a super-l33t technique consisting of pre-pending my shellcode with lots of NOPs (because 2016).

So we can now break down each step and look at how we can achieve them:

  1. With some reverse engineering and debugging, I found one function pointer that was always allocated at address 0x2840a0c0. This function seems to be used to decode parameters sent in the HTTP requests. The memory address is initially allocated at 0x08097fb9 with a call to malloc(32).
  2. Use the overflow to overwrite the pointer to the parameter list with 0x2840a0c0. The address is then free‘d when the request has finished being processed. Here, we also need to take a note of where our host parameter is located on the stack, as this is where we will store our shellcode.
  3. While searching through the binary’s code, I found one place where a malloc is called with a length which can be specified by the VPN user directly. This is when providing the username and password to log into a SMB server. There may be other parts of the code that could be exploited in a more reliable manner, but this is the first I found and decided to go with it. The only problem is that it means we need to initiate a SMB login to a server that is accessible to the Netscaler appliance.
  4. As long as our password is between 16 and 32 characters, the previously free‘d address is returned and we can therefore overwrite the function pointer with the value of our password. It must therefore be the address of our shellcode, which we discovered was placed on the stack when performing the ping.
  5. The function pointer is actually called at regular intervals by the application while processing data, so we can just wait until it is called to get our code executed.

As you’ve probably deduced by now, in order to exploit the vulnerability, we are going to use two separate HTTP requests. The first one is used to put the shellcode on the stack and trigger the overflow, while the second is used to overwrite the function pointer with the address of our shellcode and actually execute our payload. This is summarised here:

Request 1 (ping host)

→ Start of host value contains shellcode which is conveniently placed on the stack

→ Use overflow to overwrite pointer to parameter list with 0x2840a0c0

→ When the request has been entirely processed, the program frees the address 0x2840a0c0

Request 2 (smb login)

→ Specify a password parameter of length between 16 and 32, this forces malloc to return the address that was previously freed.

→ Password value (shellcode location) overwrites function pointer that was previously located there

→ While processing the request, the overwritten function pointer is called, executing the shellcode

So that’s pretty much it. The following MSF module, should be able to exploit the flaw, but use it at your own risk. I’ve only tested it on a controlled lab environment.

For those of you who participated in our Insomni’hack teaser this year, you’ll notice many similarities with “The Great Escape – part 2” challenge, as it was very much inspired by this flaw.


  • 08.12.2016: Initial report sent to Citrix
  • 09.12.2016: Case opened by Citrix to investigate the issue
  • 14.12.2016: Vulnerability acknowledged and reproduced by Citrix team
  • February-March 2017: Rollout of fixed Netscaler versions
  • 12.04.2017: Release of security bulletin: https://support.citrix.com/article/CTX222657


SCRT is proud to announce the opening of its new office in Bern

To sustain its growth and continue to maintain relations of proximity with its customers and partners, SCRT is glad to announce the opening of its new office in Bern.

SCRT is one of the leaders in Information Security in Switzerland, with headquarters in Préverenges (Vaud) and a branch office in Bordeaux (France). This new SCRT location will facilitate the provision of professional IT Security Services to new and existing clients in the German speaking part of Switzerland.

Ideally located in the Monbijou district, close to the train station, this office offers a dynamic, welcoming and optimal setting for our customers and staff. SCRT will continue to offer the same services at our new address in Bern and ensure our well known proximity and reactivity all over Switzerland.

We look forward to welcoming you!

SecureIT Valais – Workshop Buffer Overflow

La première édition de SecureIT s’est déroulée vendredi le 17 février à Sierre. L’événement organisé par l’AVPC (Association Valaisanne pour la Promotion de la Cybersécurité) en collaboration avec la HES-SO Valais-Wallis, Parti Pirate et le groupe de hackers étiques Fourchette Bombe, a rassemblé près de 300 participants.

J’y ai présenté un workshop sur l’exploitation d’un Buffer Overflow, vulnérabilité très ancienne et pourtant largement exploitée même de nos jours. Le but du workshop était de faire une introduction à l’exploitation de cette vulnérabilité, sans toutefois avoir la prétention d’un cours complet sur le sujet.

Voici les slides ainsi que l’exercice complet de mon workshop.

Mot de passe pour l’archive: scrt

SecureIT – Valais

Voici les slides de ma présentation de Vendredi dernier pour Secure-IT. J’y ai présenté quelques-unes des techniques les plus communément exploitées en test d’intrusion pour compromettre un domaine Windows ainsi que les différentes remédiations possibles.

Pour ceux qui n’auraient pas le temps de parcourir la totalité des slides, voici un bref résumé des recommendations:

  • Désactiver WPAD et les protocoles de résolutions de noms LLMNR et NetBios
  • Utiliser un système come LAPS pour gérer les mots de passe des administrateurs locaux
  • Limiter l’utilisation des comptes privilégiés (surtout les “admins du domaine”)
  • Utiliser AppLocker pour empêcher l’exécution de programmes non autorisés
  • Améliorer le filtrage réseau entre les VLANs internes et même au sein du même VLAN (Firewall local)
  • Limiter les privilèges utilisés par les applications (notamment Tomcat et serveurs SQL)
  • Utiliser un système de corrélation de logs pour pouvoir détecter les anomalies sur le réseau

L’utilisation de tests d’intrusion de type “Red Team” ou “Purple Team” permet ensuite de valider la pertinence des logs et des alertes remontées, ceci dans le but d’accélérer la réponse à incident pour pouvoir palier à une réelle attaque.

recon Bruxelles 2017

Première édition de recon en Belgique en ce début d’année! Le logo de l’évènement change, mais le programme reste le même: Reverse engineering et exploitation. Du coup, pas une seule conférence n’a oublié son screenshot d’IDA Pro (qui est d’ailleurs le sponsor de l’évenement). Comme pour l’édition 2016 de Montréal, les conférences ont duré trois jours avec une seule track, donc pas de remords ni de regrets. 🙂

Je vous propose un aperçu de quelques conférences de cette première édition Européene:

Hackable Security Modules Reversing and Exploiting FIPS-140-2 lvl3 HSM firmware

Cette présentation traitait de l’analyse d’un firmware de HSM dans le but d’y déceler des vulnérabilités. Un HSM (Hardware Security Module) permet de stocker et gérer des clés cryptographiques de manière sécurisée. Ils sont typiquement utilisés par les autorités de certification afin de protéger l’accès à leurs clés privées.

Le HSM testé est produit par la société Ultimaco et est certifié FIPS-140-2 level 3. Cette certification implique que le boitier dispose d’un mécanisme de détection des intrusions physiques en plus d’un système bloquant l’accès aux clés contenues dans le module. L’appliance est un système Linux doté d’un module HSM connecté en PCIe. Lors du premier démarrage, une clé de chiffrement et une clé de backup sont générées afin de protéger toutes les autres clés stockées sur le système.

La première étape a consisté à décompresser le firmware qui utilisait un format propriétaire (MPKG) et qui contenait différents firmwares pour chaque module de l’appareil au format MTC. Ce format MTC est une version modifiée du standard COFF. Après l’avoir reversé, le code binaire a pu être extrait. Sauf que le HSM utilise un processeur de signal (DSP) TMS320C64x produit par Texas Instrument qui n’est pas pris en charge par les logiciels de désassemblage classiques. Ainsi il était nécessaire de créer un module de désassemblage pour ajouter cette architecture dans Capstone. La complexité de l’architecture a rendu la tâche très ardue mais finalement le code a pu être désassemblé.

L’analyse du code a permis de mettre en évidence au moins une vulnérabilité. En effet, un contrôle est effectué au moment d’ouvrir une base de données afin d’empêcher l’accès aux clés. La routine de vérification contrôle que la base de données ne soit pas la chaine de caractères VMBK1 (nom de la base contenant la clé de backup). Sauf que le nom de base peut être préfixé par la localisation de cette dernière, ainsi FLASH\VMBK1.db permet de récupérer les clés.. 🙂

L’entreprise qui développe le produit à mis près d’une année pour corriger la faille… Cependant il ne lui a fallu que quelques jours après la présentation pour demander à l’auteur de retirer ses outils hébergés sur Github.

Breaking Code Read Protection on the NXP LPC-family Microcontrôlers

L’auteur présente le contournement de la protection Code Read Protection (CRP) implémentée dans les microcontrôlers de la famille NXP LPC. Cette protection permet normalement d’éviter que le code du microcontrôleur puisse être extrait de la flash. Chris Gerlinsky nous montre comment mettre en place une attaque par glitching afin de neutraliser le CRP.

Le contournement débute par l’acquisition d’un microcontrôleur de cette famille. Le chip est programmé avec un code simple qui consite en une boucle infinie dans laquelle deux variables sont incrémentées de manière identique puis comparées. Le but étant de détecter si l’une des deux variables n’a pas été incrémentée correctement à cause d’un glitch.

Un circuit particulier (Xmega-A1 MAX4619) est utilisé pour générer les glitchs (impulsions de tension basses) en switchant entre deux sources d’alimentation: Une source à la tension nominale (1.9v) et une autre plus basse qui va permettre de générer les erreurs (~0.7v). Ce circuit est directement utilisé pour alimenter le microcontrôleur. Des glitchs sont ensuite générés en variant la tension basse afin de trouver une valeur qui génère un maximum d’erreurs dans la comparaison des deux variables incrémentées sans interrompre l’alimentation du microcontrôleur. L’étape suivante consiste à faire varier la longueur des impulsions et finalement de décaler l’impulsion dans le temps afin qu’elle affecte la vérification du flag CRP.

Lorsque l’impulsion arrive au bon moment, le résultat de la comparaison du flag CRP est modifiée et l’accès au bootloader est autorisé permettant ainsi de lire la flash.

Le code du module de glitch est disponible sur github.

Transforming Open Source to Open Access in Closed Applications

Un grand nombre de logiciels propriétaires intègrent du code Open Source afin de réduire le temps de développement et par conséquent les coûts. Cette démarche à cependant un certain nombre de désavantages en termes de sécurité qui ne sont pas forcément pris en compte par l’éditeur du logiciel. D’une part, les mises à jour du logiciel Open Source doivent être intégrées dans le projet ce qui retarde la correction effective des vulnérabilités dans la solution propriétaire. D’autre part, l’abandon d’un projet Open Source utilisé expose fortement le logiciel dont le/les composants ne seraient plus mis à jour.

Ce cas de figure est illustré dans la présentation par le logiciel Acrobat Reader. En effet, le moteur de traitement XSLT d’Acrobat est basé sur le projet Open Source Sablotron, qui a cessé d’être maintenu en mai 2015. Les auteurs utilisent une technique de matching de code binaire pour trouver des correspondances entre le code propriétaire et le logiciel Open Source.

L’analyse du code source des fonctions/parties reprisent a permis de mettre en évidence plusieurs vulnérabilités critiques (exécution de code) dans le lecteur de PDF.


Kevin Larson a apporté sa pierre à l’édifice du cracking NFC contre les cartes Mifare Classic et Mifare Plus. Il a présenté son outil miLazyCracker qui, faute d’améliorer l’attaque, rend l’exploitation extrêmement simple. En effet, l’outil développé n’attend aucun argument et se met en attente d’une carte Mifare. De plus il exploite un hardware bon marché, le SCL3711.

Vous trouverez son outil directement sur Github miLazyCracker.

Teaching Old Shellcode New Tricks

Le framework Metasploit utilise une technique baptisée Stephen Fewer’s Hash API (SFHA) qui permet de simplifier l’appel d’une fonction particulière de l’API Windows en utilisant un hash. Les solutions antivirus ont fini par utiliser ce pattern afin de détecter Meterpreter (la partie cliente de Metasploit). De plus, l’outil EMET de Microsoft détecte et bloque l’exécution de shellcode qui emploie cette technique.

Ce talk présente une technique basée sur IAT / LLAGBA qui permet de remplacer le SFHA. L’outil développé traite un payload généré à l’aide de msfvenom et remplace le stub SFHA afin de bypasser EMET. En plus de cela, il permet de supprimer les hashs originaux afin de limiter la détection du payload par les anti-virus.

Pour son outil, c’est par ici: fido.

Harnessing Intel Processor Trace on Windows for fuzzing and dynamic analysis

Cette présentation décrit la nouvelle fonctionnalité intégrée dans les processeurs Intel de génération Skylake, à savoir Intel Processor Trace. Cette fonctionnalité permet de tracer l’exécution d’un programme directement en hardware, ce qui réduit largement la charge CPU nécessaire au suivi.

Les deux présentateurs travaillent sur le développement d’un driver Open Source pour Windows qui supporte le multiprocesseur. Un plugin permettant de visualiser la trace directement dans IDA Pro est également disponible. Le code du driver et du plugin sont disponible dans ce repository WindowsIntelPT.

Le driver active la fonctionnalité dans le processeur. Ce dernier commence alors à enregistrer les instructions dans plusieurs fichiers de log (un par processeur logique). En parallèle le driver collecte certaines informations sur la mémoire. Les différentes informations récupérées sont croisées avec le binaire lui-même afin de retracer l’exécution. Finalement le plugin IDA permet de charger la trace et de visualiser graphiquement le chemin d’exécution. D’après les conférenciers, un overhead de l’ordre des 10% serait constaté.