| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
import os,time,socket |
|---|
| 7 |
from data import * |
|---|
| 8 |
import base_classes |
|---|
| 9 |
import themes |
|---|
| 10 |
from error import log_scapy |
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
class ConfClass(object): |
|---|
| 17 |
def configure(self, cnf): |
|---|
| 18 |
self.__dict__ = cnf.__dict__.copy() |
|---|
| 19 |
def __repr__(self): |
|---|
| 20 |
return str(self) |
|---|
| 21 |
def __str__(self): |
|---|
| 22 |
s="" |
|---|
| 23 |
keys = self.__class__.__dict__.copy() |
|---|
| 24 |
keys.update(self.__dict__) |
|---|
| 25 |
keys = keys.keys() |
|---|
| 26 |
keys.sort() |
|---|
| 27 |
for i in keys: |
|---|
| 28 |
if i[0] != "_": |
|---|
| 29 |
r = repr(getattr(self, i)) |
|---|
| 30 |
r = " ".join(r.split()) |
|---|
| 31 |
wlen = 76-max(len(i),10) |
|---|
| 32 |
if len(r) > wlen: |
|---|
| 33 |
r = r[:wlen-3]+"..." |
|---|
| 34 |
s += "%-10s = %s\n" % (i, r) |
|---|
| 35 |
return s[:-1] |
|---|
| 36 |
|
|---|
| 37 |
class ProgPath(ConfClass): |
|---|
| 38 |
pdfreader = "acroread" |
|---|
| 39 |
psreader = "gv" |
|---|
| 40 |
dot = "dot" |
|---|
| 41 |
display = "display" |
|---|
| 42 |
tcpdump = "tcpdump" |
|---|
| 43 |
tcpreplay = "tcpreplay" |
|---|
| 44 |
hexedit = "hexer" |
|---|
| 45 |
wireshark = "wireshark" |
|---|
| 46 |
|
|---|
| 47 |
class Resolve: |
|---|
| 48 |
def __init__(self): |
|---|
| 49 |
self.fields = {} |
|---|
| 50 |
def add(self, *flds): |
|---|
| 51 |
for fld in flds: |
|---|
| 52 |
self.fields[fld]=None |
|---|
| 53 |
def remove(self, *flds): |
|---|
| 54 |
for fld in flds: |
|---|
| 55 |
if fld in self.fields: |
|---|
| 56 |
del(self.fields[fld]) |
|---|
| 57 |
def __contains__(self, elt): |
|---|
| 58 |
return elt in self.fields |
|---|
| 59 |
def __repr__(self): |
|---|
| 60 |
return "<Resolve [%s]>" % " ".join(str(x) for x in self.fields) |
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
class Num2Layer: |
|---|
| 64 |
def __init__(self): |
|---|
| 65 |
self.num2layer = {} |
|---|
| 66 |
self.layer2num = {} |
|---|
| 67 |
|
|---|
| 68 |
def register(self, num, layer): |
|---|
| 69 |
self.register_num2layer(num, layer) |
|---|
| 70 |
self.register_layer2num(num, layer) |
|---|
| 71 |
|
|---|
| 72 |
def register_num2layer(self, num, layer): |
|---|
| 73 |
self.num2layer[num] = layer |
|---|
| 74 |
def register_layer2num(self, num, layer): |
|---|
| 75 |
self.layer2num[layer] = num |
|---|
| 76 |
|
|---|
| 77 |
def __getitem__(self, item): |
|---|
| 78 |
if isinstance(item, base_classes.Packet_metaclass): |
|---|
| 79 |
return self.layer2num[item] |
|---|
| 80 |
return self.num2layer[item] |
|---|
| 81 |
def __contains__(self, item): |
|---|
| 82 |
if isinstance(item, base_classes.Packet_metaclass): |
|---|
| 83 |
return item in self.layer2num |
|---|
| 84 |
return item in self.num2layer |
|---|
| 85 |
def get(self, item, default=None): |
|---|
| 86 |
if item in self: |
|---|
| 87 |
return self[item] |
|---|
| 88 |
return default |
|---|
| 89 |
|
|---|
| 90 |
def __repr__(self): |
|---|
| 91 |
lst = [] |
|---|
| 92 |
for num,layer in self.num2layer.iteritems(): |
|---|
| 93 |
if layer in self.layer2num and self.layer2num[layer] == num: |
|---|
| 94 |
dir = "<->" |
|---|
| 95 |
else: |
|---|
| 96 |
dir = " ->" |
|---|
| 97 |
lst.append((num,"%#6x %s %-20s (%s)" % (num,dir,layer.__name__,layer.name))) |
|---|
| 98 |
for layer,num in self.layer2num.iteritems(): |
|---|
| 99 |
if num not in self.num2layer or self.num2layer[num] != layer: |
|---|
| 100 |
lst.append((num,"%#6x <- %-20s (%s)" % (num,layer.__name__,layer.name))) |
|---|
| 101 |
lst.sort() |
|---|
| 102 |
return "\n".join(y for x,y in lst) |
|---|
| 103 |
|
|---|
| 104 |
|
|---|
| 105 |
class LayersList(list): |
|---|
| 106 |
def __repr__(self): |
|---|
| 107 |
s=[] |
|---|
| 108 |
for l in self: |
|---|
| 109 |
s.append("%-20s: %s" % (l.__name__,l.name)) |
|---|
| 110 |
return "\n".join(s) |
|---|
| 111 |
def register(self, layer): |
|---|
| 112 |
self.append(layer) |
|---|
| 113 |
|
|---|
| 114 |
class CommandsList(list): |
|---|
| 115 |
def __repr__(self): |
|---|
| 116 |
s=[] |
|---|
| 117 |
for l in sorted(self,key=lambda x:x.__name__): |
|---|
| 118 |
if l.__doc__: |
|---|
| 119 |
doc = l.__doc__.split("\n")[0] |
|---|
| 120 |
else: |
|---|
| 121 |
doc = "--" |
|---|
| 122 |
s.append("%-20s: %s" % (l.__name__,doc)) |
|---|
| 123 |
return "\n".join(s) |
|---|
| 124 |
def register(self, cmd): |
|---|
| 125 |
self.append(cmd) |
|---|
| 126 |
return cmd |
|---|
| 127 |
|
|---|
| 128 |
def lsc(): |
|---|
| 129 |
print repr(conf.commands) |
|---|
| 130 |
|
|---|
| 131 |
class CacheInstance(dict): |
|---|
| 132 |
def __init__(self, name="noname", timeout=None): |
|---|
| 133 |
self.timeout = timeout |
|---|
| 134 |
self.name = name |
|---|
| 135 |
self._timetable = {} |
|---|
| 136 |
def __getitem__(self, item): |
|---|
| 137 |
val = dict.__getitem__(self,item) |
|---|
| 138 |
if self.timeout is not None: |
|---|
| 139 |
t = self._timetable[item] |
|---|
| 140 |
if time.time()-t > self.timeout: |
|---|
| 141 |
raise KeyError(item) |
|---|
| 142 |
return val |
|---|
| 143 |
def get(self, item, default=None): |
|---|
| 144 |
|
|---|
| 145 |
|
|---|
| 146 |
try: |
|---|
| 147 |
return self[item] |
|---|
| 148 |
except KeyError: |
|---|
| 149 |
return default |
|---|
| 150 |
def __setitem__(self, item, v): |
|---|
| 151 |
self._timetable[item] = time.time() |
|---|
| 152 |
dict.__setitem__(self, item,v) |
|---|
| 153 |
def update(self, other): |
|---|
| 154 |
dict.update(self, other) |
|---|
| 155 |
self._timetable.update(other._timetable) |
|---|
| 156 |
def iteritems(self): |
|---|
| 157 |
if self.timeout is None: |
|---|
| 158 |
return dict.iteritems(self) |
|---|
| 159 |
t0=time.time() |
|---|
| 160 |
return ((k,v) for (k,v) in dict.iteritems(self) if t0-self._timetable[k] < self.timeout) |
|---|
| 161 |
def iterkeys(self): |
|---|
| 162 |
if self.timeout is None: |
|---|
| 163 |
return dict.iterkeys(self) |
|---|
| 164 |
t0=time.time() |
|---|
| 165 |
return (k for k in dict.iterkeys(self) if t0-self._timetable[k] < self.timeout) |
|---|
| 166 |
def __iter__(self): |
|---|
| 167 |
return self.iterkeys() |
|---|
| 168 |
def itervalues(self): |
|---|
| 169 |
if self.timeout is None: |
|---|
| 170 |
return dict.itervalues(self) |
|---|
| 171 |
t0=time.time() |
|---|
| 172 |
return (v for (k,v) in dict.iteritems(self) if t0-self._timetable[k] < self.timeout) |
|---|
| 173 |
def items(self): |
|---|
| 174 |
if self.timeout is None: |
|---|
| 175 |
return dict.items(self) |
|---|
| 176 |
t0=time.time() |
|---|
| 177 |
return [(k,v) for (k,v) in dict.iteritems(self) if t0-self._timetable[k] < self.timeout] |
|---|
| 178 |
def keys(self): |
|---|
| 179 |
if self.timeout is None: |
|---|
| 180 |
return dict.keys(self) |
|---|
| 181 |
t0=time.time() |
|---|
| 182 |
return [k for k in dict.iterkeys(self) if t0-self._timetable[k] < self.timeout] |
|---|
| 183 |
def values(self): |
|---|
| 184 |
if self.timeout is None: |
|---|
| 185 |
return dict.values(self) |
|---|
| 186 |
t0=time.time() |
|---|
| 187 |
return [v for (k,v) in dict.iteritems(self) if t0-self._timetable[k] < self.timeout] |
|---|
| 188 |
def __len__(self): |
|---|
| 189 |
if self.timeout is None: |
|---|
| 190 |
return dict.__len__(self) |
|---|
| 191 |
return len(self.keys()) |
|---|
| 192 |
def summary(self): |
|---|
| 193 |
return "%s: %i valid items. Timeout=%rs" % (self.name, len(self), self.timeout) |
|---|
| 194 |
def __repr__(self): |
|---|
| 195 |
s = [] |
|---|
| 196 |
if self: |
|---|
| 197 |
mk = max(len(k) for k in self.iterkeys()) |
|---|
| 198 |
fmt = "%%-%is %%s" % (mk+1) |
|---|
| 199 |
for item in self.iteritems(): |
|---|
| 200 |
s.append(fmt % item) |
|---|
| 201 |
return "\n".join(s) |
|---|
| 202 |
|
|---|
| 203 |
|
|---|
| 204 |
|
|---|
| 205 |
|
|---|
| 206 |
class NetCache: |
|---|
| 207 |
def __init__(self): |
|---|
| 208 |
self._caches_list = [] |
|---|
| 209 |
|
|---|
| 210 |
|
|---|
| 211 |
def add_cache(self, cache): |
|---|
| 212 |
self._caches_list.append(cache) |
|---|
| 213 |
setattr(self,cache.name,cache) |
|---|
| 214 |
def new_cache(self, name, timeout=None): |
|---|
| 215 |
c = CacheInstance(name=name, timeout=timeout) |
|---|
| 216 |
self.add_cache(c) |
|---|
| 217 |
def __delattr__(self, attr): |
|---|
| 218 |
raise AttributeError("Cannot delete attributes") |
|---|
| 219 |
def update(self, other): |
|---|
| 220 |
for co in other._caches_list: |
|---|
| 221 |
if hasattr(self, co.name): |
|---|
| 222 |
getattr(self,co.name).update(co) |
|---|
| 223 |
else: |
|---|
| 224 |
self.add_cache(co.copy()) |
|---|
| 225 |
def flush(self): |
|---|
| 226 |
for c in self._caches_list: |
|---|
| 227 |
c.flush() |
|---|
| 228 |
def __repr__(self): |
|---|
| 229 |
return "\n".join(c.summary() for c in self._caches_list) |
|---|
| 230 |
|
|---|
| 231 |
|
|---|
| 232 |
class LogLevel(object): |
|---|
| 233 |
def __get__(self, obj, otype): |
|---|
| 234 |
return obj._logLevel |
|---|
| 235 |
def __set__(self,obj,val): |
|---|
| 236 |
log_scapy.setLevel(val) |
|---|
| 237 |
obj._logLevel = val |
|---|
| 238 |
|
|---|
| 239 |
|
|---|
| 240 |
class Conf(ConfClass): |
|---|
| 241 |
"""This object contains the configuration of scapy. |
|---|
| 242 |
session : filename where the session will be saved |
|---|
| 243 |
stealth : if 1, prevents any unwanted packet to go out (ARP, DNS, ...) |
|---|
| 244 |
checkIPID: if 0, doesn't check that IPID matches between IP sent and ICMP IP citation received |
|---|
| 245 |
if 1, checks that they either are equal or byte swapped equals (bug in some IP stacks) |
|---|
| 246 |
if 2, strictly checks that they are equals |
|---|
| 247 |
checkIPsrc: if 1, checks IP src in IP and ICMP IP citation match (bug in some NAT stacks) |
|---|
| 248 |
check_TCPerror_seqack: if 1, also check that TCP seq and ack match the ones in ICMP citation |
|---|
| 249 |
iff : selects the default output interface for srp() and sendp(). default:"eth0") |
|---|
| 250 |
verb : level of verbosity, from 0 (almost mute) to 3 (verbose) |
|---|
| 251 |
promisc : default mode for listening socket (to get answers if you spoof on a lan) |
|---|
| 252 |
sniff_promisc : default mode for sniff() |
|---|
| 253 |
filter : bpf filter added to every sniffing socket to exclude traffic from analysis |
|---|
| 254 |
histfile : history file |
|---|
| 255 |
padding : includes padding in desassembled packets |
|---|
| 256 |
except_filter : BPF filter for packets to ignore |
|---|
| 257 |
debug_match : when 1, store received packet that are not matched into debug.recv |
|---|
| 258 |
route : holds the Scapy routing table and provides methods to manipulate it |
|---|
| 259 |
warning_threshold : how much time between warnings from the same place |
|---|
| 260 |
ASN1_default_codec: Codec used by default for ASN1 objects |
|---|
| 261 |
mib : holds MIB direct access dictionnary |
|---|
| 262 |
resolve : holds list of fields for which resolution should be done |
|---|
| 263 |
noenum : holds list of enum fields for which conversion to string should NOT be done |
|---|
| 264 |
AS_resolver: choose the AS resolver class to use |
|---|
| 265 |
extensions_paths: path or list of paths where extensions are to be looked for |
|---|
| 266 |
""" |
|---|
| 267 |
version = "2.0.0.11 beta" |
|---|
| 268 |
session = "" |
|---|
| 269 |
interactive = False |
|---|
| 270 |
stealth = "not implemented" |
|---|
| 271 |
iface = None |
|---|
| 272 |
layers = LayersList() |
|---|
| 273 |
commands = CommandsList() |
|---|
| 274 |
logLevel = LogLevel() |
|---|
| 275 |
checkIPID = 0 |
|---|
| 276 |
checkIPsrc = 1 |
|---|
| 277 |
checkIPaddr = 1 |
|---|
| 278 |
check_TCPerror_seqack = 0 |
|---|
| 279 |
verb = 2 |
|---|
| 280 |
prompt = ">>> " |
|---|
| 281 |
promisc = 1 |
|---|
| 282 |
sniff_promisc = 1 |
|---|
| 283 |
raw_layer = None |
|---|
| 284 |
default_l2 = None |
|---|
| 285 |
l2types = Num2Layer() |
|---|
| 286 |
l3types = Num2Layer() |
|---|
| 287 |
L3socket = None |
|---|
| 288 |
L2socket = None |
|---|
| 289 |
L2listen = None |
|---|
| 290 |
histfile = os.path.join(os.environ.get("HOME",""), ".scapy_history") |
|---|
| 291 |
padding = 1 |
|---|
| 292 |
except_filter = "" |
|---|
| 293 |
debug_match = 0 |
|---|
| 294 |
wepkey = "" |
|---|
| 295 |
route = None |
|---|
| 296 |
route6 = None |
|---|
| 297 |
auto_fragment = 1 |
|---|
| 298 |
debug_dissector = 0 |
|---|
| 299 |
color_theme = themes.DefaultTheme() |
|---|
| 300 |
warning_threshold = 5 |
|---|
| 301 |
prog = ProgPath() |
|---|
| 302 |
resolve = Resolve() |
|---|
| 303 |
noenum = Resolve() |
|---|
| 304 |
use_pcap = False |
|---|
| 305 |
use_dnet = False |
|---|
| 306 |
ipv6_enabled = socket.has_ipv6 |
|---|
| 307 |
ethertypes = ETHER_TYPES |
|---|
| 308 |
protocols = IP_PROTOS |
|---|
| 309 |
services_tcp = TCP_SERVICES |
|---|
| 310 |
services_udp = UDP_SERVICES |
|---|
| 311 |
extensions_paths = "." |
|---|
| 312 |
manufdb = load_manuf("/usr/share/wireshark/manuf") |
|---|
| 313 |
stats_classic_protocols = [] |
|---|
| 314 |
stats_dot11_protocols = [] |
|---|
| 315 |
temp_files = [] |
|---|
| 316 |
netcache = NetCache() |
|---|
| 317 |
load_layers = ["l2", "inet", "dhcp", "dns", "dot11", "gprs", "hsrp", "inet6", "ir", "isakmp", "l2tp", |
|---|
| 318 |
"mgcp", "mobileip", "netbios", "netflow", "ntp", "ppp", "radius", "rip", "rtp", |
|---|
| 319 |
"sebek", "skinny", "smb", "snmp", "tftp", "x509", "bluetooth", "dhcp6", "llmnr" ] |
|---|
| 320 |
|
|---|
| 321 |
|
|---|
| 322 |
if not Conf.ipv6_enabled: |
|---|
| 323 |
log_scapy.warning("IPv6 support disabled in Python. Cannot load scapy IPv6 layers.") |
|---|
| 324 |
for m in ["inet6","dhcp6"]: |
|---|
| 325 |
if m in Conf.load_layers: |
|---|
| 326 |
Conf.load_layers.remove(m) |
|---|
| 327 |
|
|---|
| 328 |
|
|---|
| 329 |
conf=Conf() |
|---|
| 330 |
conf.logLevel=30 |
|---|
| 331 |
|
|---|
| 332 |
|
|---|