ctf-2011
old assets from capture-the-flag ictf 2011
git clone https://9o.is/git/ctf-2011.git
pcap-analyzer.py
(6402B)
1 #!/usr/bin/env python
2 from scapy.all import *
3 import sys
4 import re
5 import os
6 from streams import *
7 import json
8 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
9 from datetime import datetime
10 from threading import Thread
11 from SocketServer import ThreadingMixIn
12 import time
13
14 flag_regex = r'[A-Fa-f0-9]{40}'
15 #rwthctf
16 #flag_regex = r'[A-Fa-f0-9]{40}'
17 #flag_regex = r'HTTP'
18
19 class AnalyzedTraffic():
20 def __init__(self, myself=None):
21 self.myself = myself
22 self.streams = Streams(myself=myself)
23 self.seen_flags = []
24
25 def add_package(self, pkt):
26 # Let the TCP stream parser do its work...
27 s = self.streams.parse(pkt)
28 # if packet contains a flag, put a reference in seen_flags
29 mg = None
30 if hasattr(pkt, 'load'):
31 mg = re.search(flag_regex, pkt.load)
32 if mg:
33 flag = mg.group(0)
34 direction = 'unknown'
35 if pkt.haslayer(IP):
36 if pkt.getlayer(IP).src == self.myself:
37 print 'Caught OUT : ', flag
38 direction = 'out'
39 elif pkt.getlayer(IP).dst == self.myself:
40 direction = 'in'
41 print 'Caught IN : ', flag
42 if direction == 'unknown':
43 return
44
45 # either a reference to the packet or to the whole stream
46 if s:
47 s.contains_flag = True
48 self.seen_flags.append((datetime.now(), flag, direction, s))
49 else:
50 self.seen_flags.append((datetime.now(), flag, direction, pkt))
51
52 def get_latest_flags(self,foo=None):
53 r = []
54 for e in list(enumerate(self.seen_flags))[-50:]:
55 id = e[0]
56 f = e[1]
57
58 time = str(f[0].time())
59 info = f[3].summary()
60
61 if isinstance(f[3], Stream):
62 r.insert(0, (time,id,f[1],f[2],'stream', info))
63 else:
64 r.insert(0, (time,id,f[1],f[2],'packet', info))
65
66 return r
67
68 def get_stream(self, path):
69 try:
70 i = int(path.split('/')[-1])
71 packets = map(lambda x: x.__repr__(), self.seen_flags[i][3].packets)
72
73 return {'packets': packets, 'payload': self.seen_flags[i][3].content}
74 except:
75 return None
76
77 def get_packet(self, path):
78 try:
79 i = int(path.split('/')[-1])
80 return {'packets': [self.seen_flags[i][3].__repr__()],
81 'payload': None}
82 except:
83 return None
84
85 class CallbackHTTPServer(ThreadingMixIn, HTTPServer):
86 def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True, funcmap={}):
87 self.funcmap = funcmap
88 HTTPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate)
89
90 def add_callback(self, path, func):
91 self.funcmap[path] = func
92
93 class CallbackHTTPRequestHandler(BaseHTTPRequestHandler):
94 def do_GET(self):
95 #try:
96 if len(self.path):
97 if self.server.funcmap.has_key(self.path):
98 self.send_response(200)
99 self.send_header('content-type', 'application/json')
100 self.end_headers()
101
102 data = json.dumps(self.server.funcmap[self.path](self.path))
103 self.wfile.write(data)
104 return
105 else:
106 for k,v in self.server.funcmap.items():
107 if self.path.startswith(k):
108 self.send_response(200)
109 self.send_header('content-type', 'application/json')
110 self.end_headers()
111
112 data = json.dumps(v(self.path[len(k):]))
113 self.wfile.write(data)
114 return
115 #except:
116 # self.send_error(300, 'We have some problem here.')
117 req_file = os.path.abspath(os.curdir+self.path)
118 curdir = os.path.abspath(os.curdir)
119 if req_file.startswith(curdir) and os.path.isfile(req_file):
120 self.send_response(200)
121 if req_file.endswith('.js'):
122 self.send_header('content-type', 'application/javascript')
123 elif req_file.endswith('.css'):
124 self.send_header('content-type', 'text/css')
125 else:
126 self.send_header('content-type', 'text/html')
127 self.end_headers()
128
129 f = open(req_file)
130 self.wfile.write(f.read())
131 f.close()
132 return
133
134 self.send_error(404, 'File Not Found: %s' % self.path)
135
136 def serve(host="",port=80, handler=CallbackHTTPRequestHandler):
137 server = CallbackHTTPServer(('', port), CallbackHTTPRequestHandler)
138
139 server.add_callback('/get/flags', at.get_latest_flags)
140 server.add_callback('/get/stream/', at.get_stream)
141 server.add_callback('/get/packet/', at.get_packet)
142
143 #try:
144 # os.setuid(65534) # nobody
145 #except:
146 # print 'Could not drop privileges'
147
148 server.serve_forever()
149
150 #class ThreadedSniffer(Thread):
151 # def __init__(self, iface, filter, prn):
152 # Thread.__init__(self)
153 # self.iface = iface
154 # self.filter = filter
155 # self.prn = prn
156 #
157 # def run(self):
158
159 if __name__ == '__main__':
160 if len(sys.argv) < 2:
161 print 'Usage:', sys.argv[0], ' interface myself'
162 print 'Usage:', sys.argv[0], ' pcap_file'
163 sys.exit(1)
164
165 # Get HTML colors
166 conf.color_theme = scapy.themes.HTMLTheme2()
167
168 if len(sys.argv) == 2:
169 pcap_file = sys.argv[1]
170 pkts = rdpcap(pcap_file)
171
172 at = AnalyzedTraffic()
173
174 for p in pkts:
175 at.add_package(p)
176
177 try:
178 serve(port=8080)
179 except KeyboardInterrupt:
180 sys.exit(0)
181 else:
182 interface = sys.argv[1]
183 myself = sys.argv[2]
184
185 at = AnalyzedTraffic(myself)
186
187 try:
188 #ThreadedSniffer(iface=interface, prn=at.add_package, filter='host '+myself).start()
189 #time.sleep(2)
190 Thread(target=serve, args=["", 8080]).start()
191 sniff(iface=interface, prn=at.add_package)#, filter='host '+myself)
192
193 except KeyboardInterrupt:
194 sys.exit(0)
195
196