30 days of CTF: lessons learned

30 days in a row! It’s cool so far. Here are some thoughts.

7 thoughts for attackers

1. Stealing capabilities

A pretty bad server configuration allows escalating root privileges by manually setting permissions for common binaries such as Python.

In the last CTF I’ve played, I did not need to run a sudo command. A simple local user was enough:

setcap cap_setuid+ep python
./python -c 'import os; os.setuid(0); os.system("/bin/sh")'

Indeed, sudo is often out of reach because the password is too strong to be brute-forced.

2. PwnKit the destroyer

Just grab any public POC and you’ll be able to root many [unpatched] machines. This memory corruption is really handy, especially if you’re stucked.

Note that it does fail sometimes, but it’s pretty rare, though.

3. Let the tools handle SQL injections

Manual SQL injections can be tedious. Fortunately, sqlmap automates and chains many operations, for example, with the --batch option. The --level and --risk options are useful for blind SQLI and the --dump option allows getting the results a bit faster.

4. gtrace protection is disabled

Something I already knew but never experimented: you can reuse sudo tokens under specific conditions:

  • a local user’ shell session
  • the user has executed a sudo command within the last 15 minutes
  • gtrace protection is disabled (very bad configuration)
  • you can access to a package called gdb (or upload a static binary)

These requirements allow performing a sudo injection. It’s not exactly the easiest hack to achieve, though, even in the context of a CTF, so imagine in real-world conditions.

However, it’s good to know.

5. Swapping binaries on Windows

Proprietary and open-source solutions for Windows systems use small executables (.exe) to manage internal services and processes. It’s possible to generate “evil” versions (e.g. with Metasploit) to replace these binaries and escalate privileges.

Such post-exploitation is quite common on Windows and can even lead to a reverse shell as root.

6. Time-consuming approaches to avoid

Methodology is the key. Speed is a great indicator to assess your level.

It’s best if you can avoid the following approaches, IMHO:

  • lucky guesses: you’d better use automated scripts and scanning tools instead, even if you think you can be the next Mentalist
  • using default wordlists only: do not hesitate to use alternative wordlists when rockyou.txt does not work
  • falling into obvious traps: next-level CTFs will likely attempt to mislead you
  • betting everything on Brute-Force: this approach often leads to a rabbit hole

7. Take notes

This way, you don’t have to repeat the same researches and operations again and again and again. Besides you can resume interrupted sessions and skip steps you have already unlocked.

I use a collection of folders and custom README.md files for now, but there are existing boilerplates and software available on Internet for your inspiration.

7 thoughts for defenders

1. Take notes

Just like attackers, defenders need to keep things organized.

2. Patch it!

Most machines provided in CTFs are unpatched, making the hack way easier. Indeed, CTFs are made for educational purposes and sometimes even give you the particular CVE or technique to use.

Nevertheless, it’s amazing how a fully-patched system can block an attacker, at least, for a while, which is pretty efficient to mitigate post-exploitation.

In contrast, the more you wait to apply security patches, the more it extends the attack surface.

It’s true that some updates introduce nasty regressions and new vulnerabilities, but keeping the system up-to-date is still the best strategy.

3. Strong passwords can save the day

Most free tools like John can retrieve weak passwords in seconds.

Sometimes CTFs use identical or very similar pairs of usernames / passwords (e.g., admin:admin, admin:admin123). It’s quite frequent with quick and dirty Basic authentications, as developers may add them to “protect” dev and staging environments.

In another perspective, platforms like to implement password Strength Indicators, but many approve passwords like Maria_2022 just because it has a capital letter, several numbers, and an underscore…

Users should not even be able to set weak passwords, to me. Full stop.

4. Default configs are the worst

Default credentials for admins and standard configurations are quite often used in production. You’d be surprised how many installations rely on default settings or default accounts for administration.

It’s a huge security risk, as such information is publicly available and the attackers will likely automate some tests or use frameworks that already include them.

It’s best if you don’t use default ports as well for your services when it’s possible.

5. Don’t neglect social engineering (SE)

Some CTFs try to highlight this very powerful approach, even if it’s hard to emulate it technically. Some pen-testers use SE to get credentials or remote access with minimal efforts like “open the gate please.”

It can be achieved with a simple email or a phone call. Some employees can be less vigilant, for example, when under time pressure, so it’s easy to make them click on a tricked link or even disable their protection.

6. Attack and see, don’t wait

You can download public POCs that demonstrate known CVEs to attack and see how quick you can root the machine.

It’s part of the hacker’s routine to use existing resources, especially when a critical vulnerability is disclosed (e.g. log4j).

7. Disable unused services and ports

In my experience, many hacks aren’t possible if you shut down unused resources. It’s pretty efficient to reduce the attack surface.

If your machine is not a router, then there’s no reason to keep port 80 open. Likewise, disable port 22 if you don’t need SSH connections.

Wrap up

CTFs won’t make you a God, but it’s a great way to determine what’s technically feasible and what’s [probably] not.