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 (https://papers.mathyvanhoef.com/ccs2017.pdf) 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: https://papers.mathyvanhoef.com/ccs2017.pdf)

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 https://github.com/julesduvivier/PasswordFilterService/releases 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 https://github.com/julesduvivier/PasswordFilter

Jules Duvivier

Numerous Swiss domain names temporarily hijacked

Last Friday at around 14:05 we noticed that our website (www.scrt.ch) 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 nic.ch 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 www.scrt.ch, 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 www.scrt.ch. 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 nic.ch (Switch).
  3. Then the resolver will query the name server at nic.ch which will in turn provide the resolver with the IP address of the name servers responsible for scrt.ch.
  4. Finally, the resolver will query the name server authoritative for scrt.ch and will get the IP address matching the record www.scrt.ch.

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 scrt.ch is registered at Gandi where we configure the IP addresses of our name servers. Gandi is responsible for propagating this information to nic.ch, enabling the resolution for our domain scrt.ch 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 nic.ch, 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 nic.ch 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 www.scrt.ch 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 scrt.ch 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 nic.ch 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.

Insomni’Hack 2017 – FPS Write-Ups

For the 10th Insomni’Hack anniversary, new hacking challenge categories were available during the CTF. They consisted of social engineering, hacking room, and a multiplayer FPS game.

This article will cover several write-ups for this last category. It is a great occasion to understand quickly some basis of modern game hacking.

The game was compiled with Unity Engine, methods demonstrated here could work on other games compiled by the same engine. The binaries and installation instructions will be available at the end of the article.


The following mention was written into every challenge description: “You will find almost all of the logic code into Data\Managed\Assembly-CSharp.dll.“

A .NET assembly editor and decompiler are needed as CSharp uses .NET platform. The decompiler has to feature a decent search method (a game .dll to analyze is likely to have a large number of classes). For this write-up, the dnSpy tool was used. It is available on Github.

Escape Room

The game developers are implementing a tutorial level called “Basement”. They tried to block players from accessing the level by setting obstacles. Show them you are still able to reach the main room.

This is the first and only challenge to do on the “Basement” map.

Once connected, we spawn into a small room. There seems to be only one way out :

Our jump power is way too low to go there. So we could try to implement a fly hack but it may be too overkill for this first challenge. A smarter way would be to find a variable that increases our jump enough to go through this way.

We launch dnSpy and decompile the earlier mentioned .dll.

We should start by searching for the “Jump” string into DnSpy. At this point, we already note that a lot of our search results are located in the vp_FPController class and see some interesting names containing the JumpForce string which sounds like an interesting name. We refine our search:

(On dnSpy, a string being referenced several times in the same file will only be shown once into the search assemblies (bottom window) results. You must then use the other search bar in the editor window at the upper right corner to navigate through the several references from the same file.)

The MotorJumpForce is the only candidate for a jump variable that is located in this vp_FPController class that we see so often in the results. Let’s start from there and if it doesn’t work we will check the ones in the other classes.

This variable is only referenced into the OnStart_Jump callback whose code is below:

(Note the usage of the class member MotorFreeFly on the second line whose name is interesting. In this method, this class member would cancel the jump if set to true and if the player isn’t grounded, this will be useful for the next challenge).

Now that we found this function, let’s multiply by 10 our jump force. Edit Method (Ctrl+Shift+E) and replace the next to last line for this one:

Now press the Compile button at the bottom-right of the window to close the method edition and Save All (Ctrl+Shift+S) to overwrite the existing .dll.

We’ve succeeded to through this way, but at some point, there are mines blocking the way. If we listen carefully we hear a trigger sound before the explosion occurs. If the explosion occurs after a delay, and that we succeed to trigger it running fast enough, we can avoid damage.

Now that we patched the jump force, we should try to patch the player’s acceleration or movement speed by searching some related words like “speed” or “acceleration” in the same vp_FPController class.

We fall in two methods coming from the same caller UpdateMotor() :

If we suppose the MotorFreeFly variable is not set, we have to edit the last line of the UpdateThrottleWalk() method, where m_MotorThrottle.z get reassigned. Z-axis corresponds to the W and S controller keys.

Once we increased this variable, we are able to pass this obstruction, we get the flag and can finally move on the next map.

Reach the Top

Positioning is the key to any tactical operation, especially if you are alone. Prove you are the best player by reaching the top of the building:

(Using the previous jump hack doesn’t directly help to solve this challenge because you need to be alive for several seconds to get the flag).

The first idea is to remove gravity from our player. m_GravityMultiplier and PhysicsGravityModifier look good candidates especially the second one since he’s located in vp_Controller.

Once again we find some references in the vp_Controller class, in a method called UpdateForces that is not taking any parameter.

This method is called every frame and calculates the falling speed the player.

We can replace the 0.002f coefficient to 0f, and recompile. The plan is to jump and see if we could go above the building.

In this demo, the player is getting stuck after his first jump. The player cannot jump a second time because the controller checks whether you are grounded or not before allowing your next jump.

Remember the MotorFreeFly variable we found several times earlier? Let’s inspect it a little more, and find references to it. Right-click on it and choose “Analyze” (Ctrl + Shift + R).

Again, we see that the functions come from the same vp_FPController class we edited earlier. The MotorFreeFly variable is used 4 times in it. In the CanStart_Jump and OnStart_Jump functions, this variable is used to check if the player should perform a jump, but the UpdateJump and UpdateMotor functions, that are called every frame, reveal something more interesting:

As we saw earlier, we understand that the controller will handle walk and jump functions differently depending on whether the MotorFreeFly variable is set to “True” or not.

A lot of FPS games have an advanced “free fly” mode implemented (called “no clipping” and prevents the first person camera from being obstructed by other objects and also permits the camera to move in any direction). The code implemented for this feature could be triggered by a player to cheat without having to understand the game physics.

To solve this part, we should find all references to MotorFreeFly in any conditional expression, remove the ‘!’ negation operator when prefixed, and conversely append it when not present.

Re-toast it!

A bug was reported to the developers about an unstable toasting feature. They patched the toaster to restrict players from triggering it by adding a keypad. Once the toaster is activated, you don’t have much time to enter the password. Could you show them that you can still make a toast?

Let’s search for the “Toast” keyword:

We find an interesting function name, it takes a string in an argument called “code”.

This function seems to be a wrapper for a RPC call destined to the Master (second argument) that checks if the submitted code matches. The RPC function code is the following one, it’s executed server-side:

No anti-brute force mechanism is implemented, then, surrounding the RPC call with a basic loop will brute-force the PIN:

Finally, trying any combination in-game results in defusing the toaster and receiving the flag.

Install instructions

The game was not designed to be publicly released. It is still far away from a real game and this is why won’t find it on any game platform. Nevertheless, it has a great educational value and we want to share it for these purposes.

To play the game, first, register (free) on PhotonEngine and download the Server SDK.

Run the PhotonControl application, and set the Server IP to

Then, start the LoadBalancing application.

Finally, launch the game depending on your platform: