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