-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreassembler.py
More file actions
136 lines (112 loc) · 4.87 KB
/
reassembler.py
File metadata and controls
136 lines (112 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/python
# The following code will reassemble fragmented packets using the BSD, BSD-Right, First, Last and Linux so that an analyst gets a better understanding of how an attack would affect each of his different hosts.
# This program was written by @MarkBaggett and is available for download at http://baggett-scripts.googlecode.com/svn/trunk/reassembler/
# If you have questions about the script you can read the associated SANS Gold paper called "IP Fragment Reassembly with Scapy" by Mark Baggett
from scapy.all import *
import StringIO
from optparse import OptionParser
import os
import sys
def rfc791(fragmentsin):
buffer = StringIO.StringIO()
for pkt in fragmentsin:
buffer.seek(pkt[IP].frag * 8)
buffer.write(pkt[IP].payload)
return buffer.getvalue()
def first(fragmentsin):
buffer = StringIO.StringIO()
for pkt in fragmentsin[::-1]:
buffer.seek(pkt[IP].frag * 8)
buffer.write(pkt[IP].payload)
return buffer.getvalue()
def bsdright(fragmentsin):
buffer = StringIO.StringIO()
for pkt in sorted(fragmentsin, key=lambda x:x[IP].frag):
buffer.seek(pkt[IP].frag * 8)
buffer.write(pkt[IP].payload)
return buffer.getvalue()
def bsd(fragmentsin):
buffer = StringIO.StringIO()
for pkt in sorted(fragmentsin, key=lambda x:x[IP].frag)[::-1]:
buffer.seek(pkt[IP].frag * 8)
buffer.write(pkt[IP].payload)
return buffer.getvalue()
def linux(fragmentsin):
buffer = StringIO.StringIO()
for pkt in sorted(fragmentsin, key=lambda x:x[IP].frag, reverse=True):
buffer.seek(pkt[IP].frag * 8)
buffer.write(pkt[IP].payload)
return buffer.getvalue()
def genjudyfrags():
pkts = scapy.plist.PacketList()
pkts.append(IP(flags="MF", frag=0) / ("1"*24))
pkts.append(IP(flags="MF", frag=4) / ("2"*16))
pkts.append(IP(flags="MF", frag=6) / ("3"*24))
pkts.append(IP(flags="MF", frag=1) / ("4"*32))
pkts.append(IP(flags="MF", frag=6) / ("5"*24))
pkts.append(IP(frag=9) / ("6"*24))
return pkts
def processfrags(fragmenttrain):
print "Reassembled using policy: First (Windows, SUN, MacOS, HPUX)"
print first(fragmenttrain)
print "Reassembled using policy: Last/RFC791 (Cisco)"
print rfc791(fragmenttrain)
print "Reassembled using policy: Linux (Umm.. Linux)"
print linux(fragmenttrain)
print "Reassembled using policy: BSD (AIX, FreeBSD, HPUX, VMS)"
print bsd(fragmenttrain)
print "Reassembled using policy: BSD-Right (HP Jet Direct)"
print bsdright(fragmenttrain)
def writefrags(fragmenttrain):
fileobj = open(options.prefix + "-first", "w")
fileobj.write(first(fragmenttrain))
fileobj.close()
fileobj = open(options.prefix + "-rfc791", "w")
fileobj.write(rfc791(fragmenttrain))
fileobj.close()
fileobj = open(options.prefix + "-bsd", "w")
fileobj.write(bsd(fragmenttrain))
fileobj.close()
fileobj = open(options.prefix + "-bsdright", "w")
fileobj.write(bsdright(fragmenttrain))
fileobj.close()
fileobj = open(options.prefix + "-linux", "w")
fileobj.write(linux(fragmenttrain))
fileobj.close()
def main():
parser = OptionParser(usage='%prog [OPTIONS]')
parser.add_option('-r', '--read', default="", help='Read the specified packet capture', dest='pcap')
parser.add_option('-d', '--demo', action='store_true', help='Generate classic fragment test pattern and reassemble it.')
parser.add_option('-w', '--write', action='store_true', help='Write 5 files to disk with the payloads.')
parser.add_option('-p', '--prefix', default='reassembled', help='Specify the prefix for file names')
if (len(sys.argv) == 1):
parser.print_help()
sys.exit()
global options, args
(options, args) = parser.parse_args()
if options.demo:
processfrags(genjudyfrags())
if not os.path.exists(options.pcap):
print "Packet capture file not found."
sys.exit(2)
print "Reading fragmented packets from disk."
packets = rdpcap(options.pcap)
ippackets = [a for a in packets if a.haslayer("IP")]
fragmentedpackets = [a for a in ippackets if a[IP].flags == 1 or a[IP].frag > 0]
if len(fragmentedpackets) == 0:
print "No fragments in packet capture."
sys.exit(2)
uniqipids = {}
for a in fragmentedpackets:
uniqipids[a[IP].id] = 'we are here'
for ipid in uniqipids.keys():
print "Packet fragments found. Collecting fragments now."
fragmenttrain = [ a for a in fragmentedpackets if a[IP].id == ipid ]
processit = raw_input("Reassemble packets between hosts " + str(fragmenttrain[0][IP].src) + " and " + str(fragmenttrain[0][IP].dst) + "? [Y/N]")
if str(processit).lower() == "y":
if options.write:
writefrags(fragmenttrain)
else:
processfrags(fragmenttrain)
if __name__ == '__main__':
main()