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.

Challenges

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 127.0.0.1.

Then, start the LoadBalancing application.

Finally, launch the game depending on your platform:

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.

CybSec16

La Cybsec16 est maintenant terminée et toute l’équipe SCRT présente a de nouveau passé un bon moment en compagnie de différents acteurs du monde de la sécurité en suisse romande (et un peu au delà). Une excellente organisation, des conférences intéressantes et diversifiées ainsi que les divers events “networking” ont largement contribué au succès de l’événement.

Comme plusieurs personnes sont venues me demander les slides de ma présentation, les voici:

https://download.scrt.ch/cybsec16/chlam2308161-1_cybsec_swisscom.pdf

En extra, les slides de ma rump session préparée à la dernière seconde:

https://download.scrt.ch/cybsec16/chlam0311161-1_cybsec_rump.pdf

Merci aux organisateurs et à l’année prochaine!