#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
# example: sudo tcpdump -i ppp0 -x -nn src host `ifconfig ppp0 | head -n 2 | tail -n 1 | cut -d":" -f2 | cut -d" " -f1` | python rtmpsniff.py
import binascii
import sys
import string
BUFSIZE = 1024 # arbitrary buffer size - increase as needed
def extractParameter(text):
# extracts param-value pairs from RTMP packets:
#
params = ["app","flashVer","swfUrl","pageUrl","tcUrl","play"]
for param in params:
pos = text.find(param)
parmSize = None
if not pos == -1:
# if pos == 0:
# print "parameter %s might not fit in buffer, consider increasing it's size"%(param)
if param == "play":
padding = 10
else:
padding = 0
if len(text) > (pos+len(param)+padding+2):
if not ord(text[pos+len(param)+padding]) == 2:
# print "dumped \"%s\" as it does not seem to belong to an RTMP string packet"%text
return None
parmSize = ord(text[pos+len(param)+padding+1])*256+ord(text[pos+len(param)+padding+2])
if parmSize:
# if param == "play":
# paramSize = 15
if parmSize > BUFSIZE:
print "parameter %s does not fit in buffer, increase buffer size to at least %d"%(param,parmSize)
return None
elif len(text) > (pos+len(param)+padding+2+parmSize):
# print "param %s value size %d"%(param,parmSize)
return (param,text[pos+len(param)+padding+3:]+'\0')
return None
text = ""
haveConnect = False
lastBytes = []
lastPort = None
for line in sys.stdin:
if line.startswith("\t"):
line = line.strip().split(" ")
line.pop(0)
line.pop(0)
for word in line:
bytes = [word[x:x+2] for x in xrange(0,len(word),2)]
for byte in bytes:
lastBytes.append(byte)
if len(lastBytes) > 8:
lastBytes.pop(0)
if lastBytes[0] == "06" and lastBytes[1] == "00" and lastBytes[6]=="00" and lastBytes[7]=="07":
print "found encrypted RTMP header, can't decode. try rtmpsuck at port %d"%lastPort
char = binascii.unhexlify(byte)
# if lastPort == 53:
# if char in string.printable:
# sys.stdout.write(char)
# continue
if ord(char) == 195:
continue
text += char
if not haveConnect:
if text.startswith("connect"):
haveConnect = True
text = ""
elif len(text) > 7:
text = text[1:]
else:
param = extractParameter(text)
if not param == None:
cmd = param[0]
value = param[1].strip()
if cmd == "tcUrl":
cmd = "rtmp" # this may not always be correct
elif cmd == "swfUrl":
cmd = "swfVfy" # for signature checking
elif cmd == "play":
cmd = "playpath"
print "--"+cmd+" \""+value+"\" \\"
text = "" # flush buffer as it should only contain garbage, parameter, padding and value (in this order)
if param[0] == "play":
haveConnect = False # abort after first play found - probably annoying with ads
if len(text) > BUFSIZE:
text = text[1:]
else:
line = line.strip().split(" ")
lastPort = int(line[4].split(".")[4][:-1])