|
@@ -1,6 +1,17 @@
|
|
|
-#!/usr/bin/python2
|
|
|
+#!/usr/bin/env python
|
|
|
|
|
|
-# (c) 2017 by Siegrist(SystemLoesungen) <PSS@ZweierNet.ch>
|
|
|
+# (c) 2017-2019 by Siegrist(SystemLoesungen) <PSS@ZweierNet.ch>
|
|
|
+#
|
|
|
+# All Rights reserved.
|
|
|
+# 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.
|
|
|
+#
|
|
|
+# 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.
|
|
|
+#
|
|
|
|
|
|
from scapy.all import *
|
|
|
import pwd
|
|
@@ -11,10 +22,20 @@ import sys
|
|
|
import string
|
|
|
import fcntl
|
|
|
import struct
|
|
|
-import commands
|
|
|
import argparse
|
|
|
+if sys.version_info.major == 2:
|
|
|
+ import commands as subprocess
|
|
|
+elif sys.version_info.major == 3:
|
|
|
+ import subprocess
|
|
|
|
|
|
-VERSION = "0.81"
|
|
|
+def _to_str(inp):
|
|
|
+ if sys.version_info.major == 2:
|
|
|
+ return inp
|
|
|
+ else:
|
|
|
+ return "".join( chr(x) for x in inp)
|
|
|
+
|
|
|
+
|
|
|
+VERSION = "0.90"
|
|
|
|
|
|
PROC_TCP4 = "/proc/net/tcp"
|
|
|
PROC_UDP4 = "/proc/net/udp"
|
|
@@ -63,7 +84,7 @@ def get_conn_info(proto,hosts,ports):
|
|
|
|
|
|
|
|
|
if pid == "NoPid":
|
|
|
- #print ">>>>>>>>>>>NoPID:" + str(hosts) +" "+ str(ports) + "//" + str(line_array)
|
|
|
+ #print(">>>>>>>>>>>NoPID:" + str(hosts) +" "+ str(ports) + "//" + str(line_array))
|
|
|
return ['-', '-', uid]
|
|
|
|
|
|
try: # try read the process name.
|
|
@@ -71,7 +92,7 @@ def get_conn_info(proto,hosts,ports):
|
|
|
except:
|
|
|
exe = None
|
|
|
|
|
|
- #print str(lhost) +" "+ str(lport) +" "+ inode +" "+ pid
|
|
|
+ #print(str(lhost) +" "+ str(lport) +" "+ inode +" "+ pid)
|
|
|
return [pid, exe, uid]
|
|
|
|
|
|
|
|
@@ -115,7 +136,7 @@ def _proc4load(proto,hosts,ports):
|
|
|
|
|
|
return 0
|
|
|
except:
|
|
|
- print "open proc_udp4 error"
|
|
|
+ print("open proc_udp4 error")
|
|
|
return 0
|
|
|
elif proto == IPPROTO_TCP:
|
|
|
try:
|
|
@@ -133,7 +154,7 @@ def _proc4load(proto,hosts,ports):
|
|
|
|
|
|
return 0
|
|
|
except:
|
|
|
- print "open proc_tcp error"
|
|
|
+ print("open proc_tcp error")
|
|
|
return 0
|
|
|
|
|
|
elif proto == IPPROTO_ICMP:
|
|
@@ -150,7 +171,7 @@ def _proc4load(proto,hosts,ports):
|
|
|
|
|
|
return 0
|
|
|
except:
|
|
|
- print "open proc_icmp4 error"
|
|
|
+ print("open proc_icmp4 error")
|
|
|
return 0
|
|
|
|
|
|
return 0
|
|
@@ -171,7 +192,6 @@ def _ip(s):
|
|
|
|
|
|
def _ip6(s):
|
|
|
ip = [s[6:8],s[4:6],s[2:4],s[0:2],s[12:14],s[14:16],s[10:12],s[8:10],s[22:24],s[20:22],s[18:20],s[16:18],s[30:32],s[28:30],s[26:28],s[24:26]]
|
|
|
- #print '66666:', ':'.join(ip), s
|
|
|
return ':'.join(ip)
|
|
|
|
|
|
def _ip_hexrev(ip):
|
|
@@ -253,7 +273,6 @@ def doPackets(packet):
|
|
|
if len(conn_cache) >= cc_maxlen:
|
|
|
conn_cache.pop(0)
|
|
|
conn_cache.append([c_hash,program,pid])
|
|
|
- #print conn_cache
|
|
|
else:
|
|
|
program = sexe
|
|
|
pid = spid
|
|
@@ -273,11 +292,16 @@ def doPackets(packet):
|
|
|
except:
|
|
|
pass
|
|
|
else:
|
|
|
- if program != filter_prog:
|
|
|
- return
|
|
|
+ if filter_prog.startswith('not-'):
|
|
|
+ if program == filter_prog[4:]:
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ if program != filter_prog:
|
|
|
+ return
|
|
|
|
|
|
|
|
|
o_payload = ""
|
|
|
+
|
|
|
if packet.haslayer(UDP):
|
|
|
o_proto = "UDP"
|
|
|
try:
|
|
@@ -289,7 +313,7 @@ def doPackets(packet):
|
|
|
except:
|
|
|
o_sport = str(packet[0][2].sport)
|
|
|
flags = ""
|
|
|
- #o_payload = packet[0].sprintf('%10s,UDP.payload%')
|
|
|
+ #o_payload = _to_str(packet[0].sprintf('%10s,UDP.payload%'))
|
|
|
elif packet.haslayer(TCP):
|
|
|
o_proto = "TCP"
|
|
|
try:
|
|
@@ -304,8 +328,10 @@ def doPackets(packet):
|
|
|
if payloadH == True:
|
|
|
if packet.haslayer(Raw):
|
|
|
#tpld = packet[0].sprintf('%TCP.payload%')
|
|
|
- tpld = packet[0][TCP].load
|
|
|
- if re.match("^GET|POST|HTTP|HEAD|PUT|PATCH|DELETE|TRACE|OPTIONS|CONNECT.*", tpld[0:8]):
|
|
|
+ tpld = _to_str(packet[0][TCP].load)
|
|
|
+ tpldhead = tpld[0:8]
|
|
|
+ #print("tpld:" + tpldhead)
|
|
|
+ if re.match(r'GET|POST|HTTP|HEAD|PUT|PATCH|DELETE|TRACE|OPTIONS|CONNECT.*', tpldhead):
|
|
|
if payloadHl == True:
|
|
|
o_payload = str(tpld)
|
|
|
else:
|
|
@@ -328,11 +354,19 @@ def doPackets(packet):
|
|
|
o_sport = str(packet[0][2].dport)
|
|
|
flags = "["+packet[0].sprintf('%ICMP.type%') + "/" + packet[0].sprintf('%ICMP.code%')+"]"
|
|
|
else:
|
|
|
- o_proto = "UNKNOWN"
|
|
|
+ layerukn = packet[0][IP].getlayer(1)
|
|
|
+ if layerukn is None:
|
|
|
+ o_proto = "UNKNOWN"
|
|
|
+ else:
|
|
|
+ #print("Layer:", xxl1.name)
|
|
|
+ o_proto = layerukn.name
|
|
|
+
|
|
|
+ #o_proto = "UNKNOWN"
|
|
|
|
|
|
if o_dir == 1:
|
|
|
if numeric == False:
|
|
|
- if res_cache.has_key(packet[0][1].dst):
|
|
|
+ #if res_cache.has_key(packet[0][1].dst):
|
|
|
+ if packet[0][1].dst in res_cache:
|
|
|
rem_name = res_cache[packet[0][1].dst]
|
|
|
else:
|
|
|
rem_name = _resolve_ip(packet[0][1].dst)
|
|
@@ -343,7 +377,8 @@ def doPackets(packet):
|
|
|
return "\033[1m"+str(program)+"\033[0m" +"/"+ str(pid) + " - " + o_proto + ": " + packet[0][1].src + ":" + o_sport + "\033[1m\033[31m ->>> \033[0m" + rem_name + ":" + o_dport + " " + flags + " Len:" + str(packet[0][1].len) + " : " + o_payload
|
|
|
else:
|
|
|
if numeric == False:
|
|
|
- if res_cache.has_key(packet[0][1].src):
|
|
|
+ #if res_cache.has_key(packet[0][1].src):
|
|
|
+ if packet[0][1].src in res_cache:
|
|
|
rem_name = res_cache[packet[0][1].src]
|
|
|
else:
|
|
|
rem_name = _resolve_ip(packet[0][1].src)
|
|
@@ -361,19 +396,18 @@ if not check_root():
|
|
|
print("This program needs root privileges !\nThats because of reading the /proc filesystem and using libpcap functions.\nSo I give up\n")
|
|
|
conf.sniff_promisc=0
|
|
|
conf.sniff_promisc=0
|
|
|
- #print conf
|
|
|
sys.exit()
|
|
|
|
|
|
# get the interfaces
|
|
|
-ifaces = commands.getoutput("ls /sys/class/net")
|
|
|
+ifaces = subprocess.getoutput("ls /sys/class/net")
|
|
|
iface_list = ifaces.split('\n')
|
|
|
|
|
|
-print
|
|
|
+print("")
|
|
|
# commandline params
|
|
|
parser = argparse.ArgumentParser(description='sisniff V'+VERSION)
|
|
|
parser.add_argument('-i', help="Interface (required)", choices=iface_list, required=True)
|
|
|
parser.add_argument('-n', help="Do not resolve IP-Addresses", action="store_true")
|
|
|
-parser.add_argument('-p', help="Filter by program name", type=str, metavar='program')
|
|
|
+parser.add_argument('-p', help='Filter by program name ([not-] negates)', type=str, metavar='program|not-program')
|
|
|
parser.add_argument('-pH', help="Show HTTP Payload", action="store_true")
|
|
|
parser.add_argument('-pHl', help="Show HTTP Payload, long output", action="store_true")
|
|
|
parser.add_argument('filter', nargs='?', help="Filter (BPF syntax) on top of IP (in dbl-quotes \"...\")", type=str)
|
|
@@ -388,7 +422,7 @@ if args.pHl:
|
|
|
payloadHl = True
|
|
|
if args.filter:
|
|
|
fillter = " and (" + args.filter + ")"
|
|
|
- print "> Applying Filter: \"ip" + fillter + "\""
|
|
|
+ print("> Applying Filter: \"ip" + fillter + "\"")
|
|
|
if args.p:
|
|
|
filter_prog = args.p
|
|
|
|
|
@@ -398,7 +432,7 @@ MYADDRS = _remove_empty([os.popen('ip addr show '+iface).read().split("inet ")[1
|
|
|
MYADDRS.append('0.0.0.0')
|
|
|
MYADDRS.append('127.0.0.1')
|
|
|
xMYADDRS = [_ip_hexrev(x) for x in MYADDRS]
|
|
|
-print "> My IP-Addresses: " + str(MYADDRS)
|
|
|
+print("> My IP-Addresses: " + str(MYADDRS))
|
|
|
|
|
|
# confirmed connections cache (ringboffer)
|
|
|
conn_cache = []
|
|
@@ -407,11 +441,11 @@ cc_maxlen = 20
|
|
|
# resolver cache
|
|
|
res_cache = {}
|
|
|
n_try = 3
|
|
|
-print
|
|
|
-print "Prog/PID mavericks: ?/? = No entry in /proc/net/xxx; -/- = No PID for Inode found; ./. = Inode=0;"
|
|
|
-print
|
|
|
-print "Program/PID: Local addr:port <<->> Remote addr:port [Flags] Len:length : [Payload]"
|
|
|
-print "-------------------------------------------------------------------------------"
|
|
|
+print("")
|
|
|
+print("Prog/PID mavericks: ?/? = No entry in /proc/net/xxx; -/- = No PID for Inode found; ./. = Inode=0;")
|
|
|
+print("")
|
|
|
+print("Program/PID: Local addr:port <<->> Remote addr:port [Flags] Len:length : [Payload]")
|
|
|
+print("-------------------------------------------------------------------------------")
|
|
|
|
|
|
# sniff, filtering for IP traffic
|
|
|
sniff(filter="ip"+fillter,iface=iface,prn=doPackets, store=0)
|