Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# $Id: sip.py 48 2008-05-27 17:31:15Z yardley $
"""Session Initiation Protocol."""
from . import http
class Request(http.Request):
"""SIP request."""
__hdr_defaults__ = {
'method':'INVITE',
'uri':'sip:user@example.com',
'version':'2.0',
'headers':{ 'To':'', 'From':'', 'Call-ID':'', 'CSeq':'', 'Contact':'' }
}
__methods = dict.fromkeys((
'ACK', 'BYE', 'CANCEL', 'INFO', 'INVITE', 'MESSAGE', 'NOTIFY',
'OPTIONS', 'PRACK', 'PUBLISH', 'REFER', 'REGISTER', 'SUBSCRIBE',
'UPDATE'
))
__proto = 'SIP'
class Response(http.Response):
"""SIP response."""
def test_invalid_header():
# valid header.
s = b'POST /main/redirect/ab/1,295,,00.html HTTP/1.0\r\n' \
b'Referer: http://www.email.com/login/snap/login.jhtml\r\n' \
b'Connection: Keep-Alive\r\n' \
b'User-Agent: Mozilla/4.75 [en] (X11; U; OpenBSD 2.8 i386; Nav)\r\n' \
b'Host: ltd.snap.com\r\n' \
b'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n' \
b'Accept-Encoding: gzip\r\n' \
b'Accept-Language: en\r\n' \
b'Accept-Charset: iso-8859-1,*,utf-8\r\n' \
b'Content-type: application/x-www-form-urlencoded\r\n' \
b'Content-length: 61\r\n\r\n' \
b'sn=em&mn=dtest4&pw=this+is+atest&fr=true&login=Sign+in&od=www'
r = Request(s)
assert r.method == 'POST'
assert r.uri == '/main/redirect/ab/1,295,,00.html'
assert r.body == b'sn=em&mn=dtest4&pw=this+is+atest&fr=true&login=Sign+in&od=www'
assert r.headers['content-type'] == 'application/x-www-form-urlencoded'
# invalid header.
s_weird_end = b'POST /main/redirect/ab/1,295,,00.html HTTP/1.0\r\n' \
b'Referer: http://www.email.com/login/snap/login.jhtml\r\n' \
b'Connection: Keep-Alive\r\n' \
b'User-Agent: Mozilla/4.75 [en] (X11; U; OpenBSD 2.8 i386; Nav)\r\n' \
b'Host: ltd.snap.com\r\n' \
b'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n' \
b'Accept-Encoding: gzip\r\n' \
b'Accept-Language: en\r\n' \
b'Accept-Charset: iso-8859-1,*,utf-8\r\n' \
b'Content-type: application/x-www-form-urlencoded\r\n' \
def findDownload(pcap):
for (ts, buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
src = socket.inet_ntoa(ip.src)
tcp = ip.data
http = dpkt.http.Request(tcp.data)
if http.method == http_method:
uri = http.uri.lower()
if file_ext in uri and loic in uri:
print '[!] ' + src + ' Downloaded LOIC.'
except:
pass
def get_packet_metadata(pkt, ts):
eth = dpkt.ethernet.Ethernet(pkt)
metadata = {}
metadata['timestamp'] = ts
metadata['src'] = mac_addr(eth.src)
metadata['dst'] = mac_addr(eth.dst)
try:
ip = eth.data
tcp = ip.data
try:
metadata['ip'] = {}
metadata['ip']['src'] = socket.inet_ntoa(ip.src)
metadata['ip']['dst'] = socket.inet_ntoa(ip.dst)
if tcp.dport == 80 and len(tcp.data) > 0:
try:
http = dpkt.http.Request(tcp.data)
metadata['http'] = {}
metadata['http']['headers'] = http.headers
except TypeError as e:
pass
except:
pass
except:
pass
return metadata
def parse_request(self, ts, sent):
try:
res = dpkt.http.Request(sent)
res.raw = sent
return res
except dpkt.UnpackError as e:
if str(e).startswith("invalid http method"):
log.warning("This is not a HTTP request (timestamp %f).", ts)
else:
log.warning(
"Unknown HTTP request error (timestamp %f): %s", ts, e
)
if tupl in self.conn:
self.conn[tupl].append(l7.data)
else:
self.conn[tupl] = Connection(l7.data)
try:
response = None
stream = self.conn[tupl].data
if stream[:4] == 'HTTP':
http = dpkt.http.Response(stream)
k = (ip2, dport, ip1, sport)
if k in self.rere:
self.rere[k].response = http
self.rere[k].delta = (ts - self.rere[k].start) * 1000
response = self.rere[k]
else:
http = dpkt.http.Request(stream)
self.rere[(ip1, sport, ip2, dport)] = RequestResponse(http, ts)
stream = stream[len(http):]
if len(stream) == 0:
del self.conn[tupl]
else:
self.conn[tupl] = Connection(stream)
if response is not None:
return response
except dpkt.UnpackError:
pass
def _add_http(self, tcpdata, dport):
"""Add an HTTP flow.
@param tcpdata: TCP data flow.
@param dport: destination port.
"""
if tcpdata in self.http_requests:
self.http_requests[tcpdata]["count"] += 1
return True
try:
http = dpkt.http.Request()
http.unpack(tcpdata)
except dpkt.dpkt.UnpackError:
pass
try:
entry = {"count": 1}
if "host" in http.headers:
entry["host"] = convert_to_printable(http.headers["host"])
else:
entry["host"] = ""
entry["port"] = dport
# Manually deal with cases when destination port is not the
# default one and it is not included in host header.
# We can not handle HTTPS
if 443 in [sport, dport]:
logging.warning("Ignoring HTTPS/SSL stream (%s:%s -> %s:%s)" % (src, sport, dst, dport))
return
# data to server
server_data = tcp.server.data[:tcp.server.count]
# data to client
client_data = tcp.client.data[:tcp.client.count]
# extract *all* the requests in this stream
req = ""
while len(req) < len(server_data):
req_parsed = False
try:
req = dpkt.http.Request(server_data)
req_parsed = True
host_hdr = req.headers['host']
full_uri = req.uri if req.uri.startswith("http://") else \
"http://%s:%d%s" % (host_hdr, dport, req.uri) if dport != 80 else \
"http://%s%s" % (host_hdr, req.uri)
logging.info("Processing tcp stream for %s", full_uri)
res = dpkt.http.Response(client_data)
logging.debug(res)
if "content-length" in res.headers:
body_len = int(res.headers["content-length"])
hdr_len = client_data.find('\r\n\r\n')
client_data = client_data[body_len + hdr_len + 4:]
else:
hdr_len = client_data.find('\r\n\r\n')
body_len = client_data[hdr_len:].find("HTTP/1")
client_data = client_data[hdr_len + body_len:]
if not isinstance(eth.data, dpkt.ip.IP):
print('Non IP Packet type not supported %s\n' % eth.data.__class__.__name__)
continue
# Now grab the data within the Ethernet frame (the IP packet)
ip = eth.data
# Check for TCP in the transport layer
if isinstance(ip.data, dpkt.tcp.TCP):
# Set the TCP data
tcp = ip.data
# Now see if we can parse the contents as a HTTP request
try:
request = dpkt.http.Request(tcp.data)
except (dpkt.dpkt.NeedData, dpkt.dpkt.UnpackError):
continue
# Pull out fragment information (flags and offset all packed into off field, so use bitmasks)
do_not_fragment = bool(ip.off & dpkt.ip.IP_DF)
more_fragments = bool(ip.off & dpkt.ip.IP_MF)
fragment_offset = ip.off & dpkt.ip.IP_OFFMASK
# Print out the info
print('Timestamp: ', str(datetime.datetime.utcfromtimestamp(timestamp)))
print('Ethernet Frame: ', mac_addr(eth.src), mac_addr(eth.dst), eth.type)
print('IP: %s -> %s (len=%d ttl=%d DF=%d MF=%d offset=%d)' %
(inet_to_str(ip.src), inet_to_str(ip.dst), ip.len, ip.ttl, do_not_fragment, more_fragments, fragment_offset))
print('HTTP request: %s\n' % repr(request))
# Check for Header spanning acrossed TCP segments
b'Host: ltd.snap.com\r\n' \
b'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\r\n' \
b'Accept-Encoding: gzip\r\n' \
b'Accept-Language: en\r\n' \
b'Accept-Charset: iso-8859-1,*,utf-8\r\n' \
b'Content-type: application/x-www-form-urlencoded\r\n' \
b'Cookie: TrackID=1PWdcr3MO_C611BGW'
r = Request(s_weird_end)
assert r.method == 'POST'
assert r.uri == '/main/redirect/ab/1,295,,00.html'
assert r.headers['content-type'] == 'application/x-www-form-urlencoded'
# messy header.
s_messy_header = b'aaaaaaaaa\r\nbbbbbbbbb'
try:
r = Request(s_messy_header)
except dpkt.UnpackError:
assert True
# If the http request is built successfully or raised exceptions
# other than UnpackError, then return a false assertion.
except:
assert False
else:
assert False