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:

  1. Scouting Ahead: Use the ancient socket technique to see if the castle gates (ports 80 and 443) are open.
  2. Capturing the Flag: Summon a headless steed (headless browser) with Selenium to visit the open gates and capture their essence (screenshots).
  3. 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.

Leave a comment

Your email address will not be published. Required fields are marked *