Description
This is a simple python script to replay a tcp session with a server. It also has a function to add code for fuzzing the replay session.Download
simpleSessionReplay_1.py
Code
#! /usr/bin/python
#
# Export the packet data from wireshark in the following text format and this script will replay
# the session to a specified target IP and port.
#
# No. Time Source Destination Protocol Info
# 6 0.001176 192.168.186.173 192.168.186.132 LDAP bindRequest(1) "<ROOT>" simple
#
# 0000 00 0c 29 83 0c d1 00 0c 29 c1 a1 6e 08 00 45 00 ..).....)..n..E.
# 0010 00 42 43 40 40 00 40 06 00 f3 c0 a8 ba ad c0 a8 .BC@@.@.........
# 0020 ba 84 cf c7 01 85 38 93 b5 86 89 70 43 47 80 18 ......8....pCG..
# 0030 00 e5 b9 b9 00 00 01 01 08 0a 0b b3 f6 bb 05 7e ...............~
# 0040 72 07 30 0c 02 01 01 60 07 02 01 03 04 00 80 00 r.0....`........
#
import socket
import string
import struct
import getopt
import sys
class packet(object):
def __init__(self,srcIP,dstIP,payload,payloadLength):
self.srcIP = srcIP
self.dstIP = dstIP
self.payload = payload
self.payloadLength = payloadLength
def printUsage():
print '\nExport the packet data from wireshark in the following text format and this script will replay'
print 'the session to a specified target IP and port.'
print ''
print ' No. Time Source Destination Protocol Info'
print '6 0.001176 192.168.186.173 192.168.186.132 LDAP bindRequest(1) "<ROOT>" simple'
print '0000 00 0c 29 83 0c d1 00 0c 29 c1 a1 6e 08 00 45 00 ..).....)..n..E.'
print '0010 00 42 43 40 40 00 40 06 00 f3 c0 a8 ba ad c0 a8 .BC@@.@.........'
print '0020 ba 84 cf c7 01 85 38 93 b5 86 89 70 43 47 80 18 ......8....pCG..'
print '0030 00 e5 b9 b9 00 00 01 01 08 0a 0b b3 f6 bb 05 7e ...............~'
print '0040 72 07 30 0c 02 01 01 60 07 02 01 03 04 00 80 00 r.0....`........'
print ''
print 'An empty line must follow each packets data in the text file.'
print ''
print 'USAGE:'
print '\tsimpleSessionReplay.py -f <file> -d <ip address> -p <port> -s <seed value>'
print ''
print '-s Set this flag to fuzz a message based on a seed value you provide. (Not supported on this version)'
def readPacketsFromFIle(fileName):
nextLineType = 'header'
byteList = []
sourceIP = ''
destIP = ''
packetList = []
print 'Opening packet file ' + fileName
fileHandle = open(fileName,'r')
while 1:
# Read one line from the file
line = fileHandle.readline()
if not line:
#Only keep the layer 5 message so that means we don't need tcp/ip headers
print 'Payload :'
payloadList = byteList[0x42:]
print payloadList
#convert binary data list to binary string
buf = struct.pack('%sB' % len(payloadList),*payloadList)
packetList.append(packet(sourceIP,destIP,buf,len(payloadList)))
# Rest byteList for next packet info we loop through
byteList = []
print 'Finished reading packet info'
break
# The line will be 1 of 3 types of info in order (header, frame description data or a binary frame)
if nextLineType == 'header':
print '\nStarting to read packet info...'
# Verify that this line is the header line
tokens = line.split();
if tokens and tokens[0] != 'No.':
print 'FAILURE: Could not parse line \n\t' + line
exit()
else:
# We can expect the next line to be packet description info
nextLineType = 'description'
elif nextLineType == 'description':
tokens = line.split()
# If not set yet, capture the source and destination IPs
#if sourceIP == '' and destIP == '':
sourceIP = tokens[2]
destIP = tokens[3]
print 'src : ' + sourceIP
print 'dst : ' + destIP
nextLineType = 'emptyLineThenData'
elif nextLineType == 'emptyLineThenData':
# Verify it is an empty line
if line == '':
print 'FAILURE: Expect an empty line before the data'
exit()
nextLineType = 'data'
elif nextLineType == 'data':
# If the line is empty then the next line will be the header info for the next packet
tokens = line.split()
if tokens and tokens[0] != 'No.' :
# Convert the ascii represented binary data to binary data.
# Drop the first and last token. Those tokens are not binary data
for index in range( 1 , len(tokens)-1 ):
byteList.append(int(tokens[index],16))
else:
#Only keep the layer 5 message so that means we don't need tcp/ip headers
print 'Payload :'
payloadList = byteList[0x42:]
print payloadList
#convert binary data list to binary string
buf = struct.pack('%sB' % len(payloadList),*payloadList)
packetList.append(packet(sourceIP,destIP,buf,len(payloadList)))
# Rest byteList for next packet info we loop through
byteList = []
print 'Finished reading packet info'
# The end of the data has been reached. We should have collected the full payload
#print '\nStarting to read packet info...'
# Verify that this line is the header line
tokens = line.split();
if tokens and tokens[0] != 'No.':
print 'FAILURE: Could not parse line \n\t' + line
exit()
else:
# We can expect the next line to be packet description info
nextLineType = 'header'
fileHandle.close()
return packetList
def fuzz(packetList,seedValue):
fuzzFileName = 'fuzzFile.txt'
packetToFuzzIndex = 0
# Determine how many packets need to be sent to get a range
count = 0
src = packetList[0].srcIP
for packet in packetList:
if packet.srcIP == src:
count += 1
print 'packets to send: ' + str(count)
# Pick a packet to fuzz based on seed (0 - (n-1) ).
packetToFuzzIndex = seedValue % count
packetToFuzz = packetList[ packetToFuzzIndex ]
# Write the packet to a file.
print 'Writing bytes to file'
handle = open(fuzzFileName,'wb')
handle.write(packetToFuzz.payload)
handle.close()
# Call fuzzing method here on the file.
# < Place fuzzing code here >
print 'Fuzzing client->server packet ' + str(packetToFuzzIndex) + ' of packets 0 - ' + str(count-1) + '.'
print 'Fuzzing not supported!!!'
# Read in file
handle = open(fuzzFileName,'rb')
fuzzedPacket = handle.read()
handle.close()
# Place fuzzed packet in packet list
packetList[packetToFuzzIndex].payload = fuzzedPacket
# Return packet list
return packetList
fileName = ''
destinationIP = ''
destinationPort = -1
seed = -1
# Read in the command line arguments
try:
opts, args = getopt.getopt(sys.argv[1:],'f:d:p:s:')
except getopt.GetoptError, err:
printUsage()
sys.exit(2)
for o, a in opts:
if o == '-f':
fileName = a
elif o == '-d':
destinationIP = a
elif o == '-p':
destinationPort = int(a)
elif o == '-s':
seed = int(a)
else:
printUsage()
sys.exit(2)
#check that args were set
if fileName == '' or destinationIP == '' or destinationPort == -1:
printUsage()
sys.exit(2)
# Puts packet info from a file into a list of packet objects
packetList = readPacketsFromFIle(fileName)
# Check if packetList is returned
if packetList:
print 'Successfully read packets in from file!'
else:
print 'Failed to read packets from file'
#If the user choose to fuzz a packet, complete the fuzzing job (optional argument)
#Not suppoted in this version
if seed != -1:
print 'FUZZING NOT SUPPORTED!'
# packetList = fuzz(packetList,seed)
# Open a socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((destinationIP,destinationPort))
#Look at the first packet and record src and dest to determine when to send and receive
firstPacket = packetList[0]
client = firstPacket.srcIP
server = firstPacket.dstIP
print '\nReplaying session to ' + destinationIP + ' at port ' + str(destinationPort) + ' ...'
for index in range( len(packetList) ):
if packetList[index].srcIP == client:
msg = packetList[index].payload
msgLength = packetList[index].payloadLength
totalsent = 0
while totalsent < msgLength:
sent = sock.send(msg[totalsent:])
print 'Message sent ' + str(sent) + ' bytes'
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
else:
msg = ''
msgLength = packetList[index].payloadLength
while len(msg) < msgLength:
chunk = sock.recv(msgLength-len(msg))
print 'Message received: ' + str(msgLength-len(msg)) + ' bytes'
if chunk == '':
raise RuntimeError("socket connection broken")
msg = msg + chunk
print 'Done replaying session,closing connection'
sock.close()
No comments:
Post a Comment