Welcome to the second part of Python for penetration testing. Today, we embark on a noble quest: to check if the digital gates (ports, for the uninitiated) of our fortresses (servers, in tech-speak) are up or inviting trouble.
Gathering Your Tools
Before our adventure begins, ensure your satchel is equipped with Selenium and python-docx, potent Python spells that automate browsers and conjure Word documents from thin air. Installing these is as simple as whispering to your terminal:
pip install selenium python-docx webdriver-manager
Beware, young apprentice, for you also need the socket
library, but fear not – it comes pre-packed with your Python installation, ready to reveal the open ports in your quest.
The Plan of Attack
Our journey has three pivotal steps:
- Scouting Ahead: Use the ancient
socket
technique to see if the castle gates (ports 80 and 443) are open. - Capturing the Flag: Summon a headless steed (headless browser) with Selenium to visit the open gates and capture their essence (screenshots).
- Telling the Tale: Employ python-docx to scribe your findings into a magical tome (Word document), detailing the exploits of your journey.
Casting the Spells
1. Scouting Ahead with socket
Our first spell determines if the ports are open, a task most crucial. The socket
library, with its mystical powers, allows us to peer into the abyss and see if the gates stand unguarded:
import socket
def is_port_open(host, port, timeout=10):
try:
# Whispering to the gates to see if they respond
with socket.create_connection((host, port), timeout=timeout):
return True
except socket.error:
return False # Alas, the gates are closed
2. Capturing the Essence with Selenium
With the gates open, we summon our headless steed, Firefox, through the enchanted forests of the web:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from webdriver_manager.firefox import GeckoDriverManager
options = Options()
options.headless = True # Our steed shall remain unseen
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install(), options=options)
We approach each gate, capturing its essence if it stands ajar:
if is_port_open(host, 80):
# HTTP - The old, less secure gate
capture_screenshot('http', host)
if is_port_open(host, 443):
# HTTPS - The new, fortified gate
capture_screenshot('https', host)
3. Telling the Tale with python-docx
Finally, we document our journey, inscribing each screenshot next to its corresponding port in a tome for the ages:
import docx
from docx.shared import Inches
doc = docx.Document()
table = doc.add_table(rows=1, cols=2)
# And so, we add our captured essences and tales to the table
The Full Incantation
Behold, the full spell woven together, ready to reveal the openness of digital fortresses and document the findings for posterity:
#Capture screens and place them in a word document (docx)
#Usage example: python script.py hosts.txt web_screenshots.docx
#Note the hosts.txt file should contain IPs or URLs without schemes (http or https)
#Author: Atom / hacking.cool
import os
import socket
import sys
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from webdriver_manager.firefox import GeckoDriverManager
import docx
from docx.shared import Inches
import argparse
def parse_arguments():
parser = argparse.ArgumentParser(description='Take screenshots of webpages listed in a file and add them to a Word document.')
parser.add_argument('hosts_file', help='The path to the file containing hosts (one per line)')
parser.add_argument('output_file', help='The path where the Word document will be saved')
return parser.parse_args()
def print_green(text):
print(f"\033[92m{text}\033[0m")
def is_port_open(host, port, timeout=10):
try:
with socket.create_connection((host, port), timeout=timeout):
return True
except socket.error:
return False
def take_screenshots_for_host(driver, host, schemes, doc):
for scheme in schemes:
url = f"{scheme}://{host}"
try:
driver.get(url)
screenshot_path = f'temp_screenshot_{scheme}.png'
driver.save_screenshot(screenshot_path)
row_cells = doc.add_row().cells
row_cells[0].text = url
paragraph = row_cells[1].paragraphs[0]
run = paragraph.add_run()
run.add_picture(screenshot_path, width=Inches(3.5))
os.remove(screenshot_path)
print_green(f"Successfully captured {url}")
except Exception as e:
print(f"Failed to capture {url}: {e}")
def main(hosts_file, output_file):
doc = docx.Document()
table = doc.add_table(rows=1, cols=2)
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'Web Request Info'
hdr_cells[1].text = 'Web Screenshot'
options = Options()
options.headless = True
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install(), options=options)
driver.set_page_load_timeout(20)
with open(hosts_file, 'r') as file:
for host in file:
host = host.strip()
if not host:
continue
schemes_to_try = []
if is_port_open(host, 443):
schemes_to_try.append('https')
if is_port_open(host, 80):
schemes_to_try.append('http')
if not schemes_to_try:
print(f"Both ports 80 and 443 are closed for {host}")
continue
take_screenshots_for_host(driver, host, schemes_to_try, table)
driver.quit()
doc.save(output_file)
if __name__ == "__main__":
args = parse_arguments()
main(args.hosts_file, args.output_file)
In Conclusion
Armed with Python, your journey through the realms of penetration testing is both noble and necessary. Remember, with great power comes great responsibility. Use these spells wisely, and may your path be clear, your findings true, and your documentation ever helpful.
Embarking on this scripting journey wasn’t just a whim; it was born out of necessity. EyeWitness, a tool often praised in our realm for its keen ability to observe and report, somehow didn’t align with what I envisioned, especially in how the results were presented. My quest was not only to tailor the reconnaissance to my specific needs but also to capture the essence of these digital expeditions in a format that resonates with the old-school charm and structure – a Word document. This concoction of code isn’t just a workaround; it’s a testament to the power of creating bespoke tools when off-the-shelf solutions fall short.
And thus concludes our tale.