<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8913849285886833150</id><updated>2011-04-21T21:10:27.835-07:00</updated><category term='linux'/><category term='tools'/><title type='text'>c1de0x</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://c1de0x.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8913849285886833150/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://c1de0x.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>c1de0x</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8913849285886833150.post-7763006625117652908</id><published>2007-06-25T01:36:00.000-07:00</published><updated>2007-06-25T01:44:23.639-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>If only there were a windows variant</title><content type='html'>&lt;a href="http://syscalltrack.sourceforge.net/"&gt;syscalltrack&lt;/a&gt; tracks and allows for 'hijacking' of practically all kernel syscalls.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8913849285886833150-7763006625117652908?l=c1de0x.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://c1de0x.blogspot.com/feeds/7763006625117652908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8913849285886833150&amp;postID=7763006625117652908' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8913849285886833150/posts/default/7763006625117652908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8913849285886833150/posts/default/7763006625117652908'/><link rel='alternate' type='text/html' href='http://c1de0x.blogspot.com/2007/06/if-only-there-were-windows-variant.html' title='If only there were a windows variant'/><author><name>c1de0x</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8913849285886833150.post-2945600464040462169</id><published>2007-06-24T01:52:00.000-07:00</published><updated>2007-06-24T01:59:20.157-07:00</updated><title type='text'>TCP Replay</title><content type='html'>&lt;span style="font-family:verdana;"&gt;I put together a python script based on &lt;a href="http://www.secdev.org/projects/scapy/"&gt;Scapy&lt;/a&gt; which allows for easy replay of Layer3 network traffic, more specifically, TCP traffic.&lt;br /&gt;&lt;br /&gt;The script uses a pcap file as a 'script' and simulates one of the parties in the file, listening for live packets and responding with the 'answers' that match from the pcap file.&lt;br /&gt;&lt;br /&gt;The script:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;&lt;br /&gt;##&lt;br /&gt;## replay by c1de0x &lt;c1de0x[at]gmail&gt;&lt;br /&gt;## ----------------------------------&lt;br /&gt;## v0.1&lt;br /&gt;##&lt;br /&gt;## Scapy extension to allow pcap-captured network traffic to be used as&lt;br /&gt;## a 'script' or 'template' for responses to live requests.&lt;br /&gt;##&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;import scapy&lt;br /&gt;from util.matches import get_match&lt;br /&gt;from socket import gethostname,gethostbyname&lt;br /&gt;import sys&lt;br /&gt;import getopt&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class TCPReplayer(scapy.AnsweringMachine):&lt;br /&gt;   """&lt;br /&gt;   Replays TCP traffic by matching incoming live packets to packets in a given&lt;br /&gt;   list, and then transmitting the answering packets from the list on the wire.&lt;br /&gt;   """&lt;br /&gt;   filter="tcp"&lt;br /&gt;   function_name="replay_tcp"&lt;br /&gt;   send_function = staticmethod(scapy.sendp)&lt;br /&gt;&lt;br /&gt;   def parse_options(self,list,resequence=0,port=80):&lt;br /&gt;       self.list = list&lt;br /&gt;       self.serverip = gethostbyname(gethostname())&lt;br /&gt;       self.resequence = resequence&lt;br /&gt;       self.port = port&lt;br /&gt;       if self.resequence: self.seq = 1L&lt;br /&gt;  &lt;br /&gt;   def get_answers(self, packet):&lt;br /&gt;       answers = []&lt;br /&gt;       for other in self.list:&lt;br /&gt;           if other.answers(packet):&lt;br /&gt;              answers.append(other)&lt;br /&gt;  &lt;br /&gt;       return answers&lt;br /&gt;  &lt;br /&gt;   def fixup_response(self,resp,req):&lt;br /&gt;       if resp.haslayer(scapy.Ether):&lt;br /&gt;           resp[scapy.Ether].dst = req[scapy.Ether].src&lt;br /&gt;           resp[scapy.Ether].src = req[scapy.Ether].dst&lt;br /&gt;       if resp.haslayer(scapy.IP):&lt;br /&gt;           resp[scapy.IP].src = self.serverip&lt;br /&gt;           del resp[scapy.IP].chksum&lt;br /&gt;       if resp.haslayer(scapy.TCP):&lt;br /&gt;           resp[scapy.TCP].dport = req[scapy.TCP].sport&lt;br /&gt;          &lt;br /&gt;          &lt;br /&gt;           if not isinstance(req[scapy.TCP].payload,scapy.NoPayload) \&lt;br /&gt;               and not isinstance(req[scapy.TCP].payload,scapy.Padding): #have real payload&lt;br /&gt;                   resp[scapy.TCP].ack = req[scapy.TCP].seq + len(req[scapy.TCP].payload)&lt;br /&gt;           else:&lt;br /&gt;               resp[scapy.TCP].ack = req[scapy.TCP].seq + 1L&lt;br /&gt;&lt;br /&gt;           if self.resequence:&lt;br /&gt;               resp[scapy.TCP].seq = self.seq&lt;br /&gt;               if not isinstance(resp[scapy.TCP].payload,scapy.NoPayload) \&lt;br /&gt;                   and not isinstance(resp[scapy.TCP].payload,scapy.Padding): #have real payload&lt;br /&gt;                   #load bearing packets increment seq for following packets&lt;br /&gt;                   self.seq += len(req[scapy.TCP].payload)&lt;br /&gt;          &lt;br /&gt;           del resp[scapy.TCP].chksum&lt;br /&gt;       return resp&lt;br /&gt;          &lt;br /&gt;   def is_request(self, req):&lt;br /&gt;       if not len(self.list):&lt;br /&gt;           print "Playback list is empty - exiting."&lt;br /&gt;           sys.exit(0)&lt;br /&gt;       if not req.haslayer(scapy.TCP):&lt;br /&gt;           return 0&lt;br /&gt;       tcp = req.getlayer(scapy.TCP)&lt;br /&gt;       if req.getlayer(scapy.IP).dst != self.serverip or tcp.dport != self.port:&lt;br /&gt;           return 0&lt;br /&gt;      &lt;br /&gt;       if scapy.TCPflags2str(tcp.flags) == 'A': #packet is an ack, do nothing.&lt;br /&gt;            if verbose: print "a-&gt; ", repr(req)&lt;br /&gt;            match = get_match(self.list,req)&lt;br /&gt;            if match:&lt;br /&gt;                self.list.remove(match)&lt;br /&gt;            else:&lt;br /&gt;                if verbose: print "Couldn't match ack"&lt;br /&gt;            return 0&lt;br /&gt;&lt;br /&gt;       self.currentmatch = get_match(self.list,req)&lt;br /&gt;       if not self.currentmatch:&lt;br /&gt;           if verbose: print "Couldn't find match for: ", repr(req)&lt;br /&gt;           return 0&lt;br /&gt;       self.list.remove(self.currentmatch)&lt;br /&gt;&lt;br /&gt;       answers = self.get_answers(self.currentmatch)&lt;br /&gt;       if not len(answers):&lt;br /&gt;           if verbose: print "Couldn't find answer for: ", repr(req)&lt;br /&gt;           return 0&lt;br /&gt;      &lt;br /&gt;       resp = []&lt;br /&gt;       for answer in answers:&lt;br /&gt;           self.list.remove(answer)&lt;br /&gt;           answer = self.fixup_response(answer,req)&lt;br /&gt;           resp.append(answer)&lt;br /&gt;&lt;br /&gt;       if self.resequence: self.seq += 1L # Increment sequence every 'response set'&lt;br /&gt;       self.currentanswer = resp&lt;br /&gt;       return 1&lt;br /&gt;&lt;br /&gt;   def print_reply(self,req,reply):&lt;br /&gt;       if verbose:&lt;br /&gt;           print "i-&gt; ", repr(req)&lt;br /&gt;           print "o-&gt; ", reply&lt;br /&gt;  &lt;br /&gt;   def make_reply(self, req):&lt;br /&gt;       if not self.currentmatch or not self.currentanswer:&lt;br /&gt;           raise Error("ASSERT: should never get here!")&lt;br /&gt;       resp = self.currentanswer&lt;br /&gt;       return resp&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def Usage():&lt;br /&gt;       print """Usage: replay --recording=file.pcap [--port=80] [--resequence] [-v]&lt;br /&gt;       --recording     The pcap file to replay.&lt;br /&gt;       --port          The port to 'listen' on. If no port is specified, 80 is assumed.&lt;br /&gt;       --resequence    If specified, new sequence numbers will be assigned to outgoing packets,&lt;br /&gt;                       otherwise the original sequence values will be used.&lt;br /&gt;       -v, --verbose   Turn on verbose logging.&lt;br /&gt;       -h, --help      This help message.&lt;br /&gt;       """&lt;br /&gt;       sys.exit(1)&lt;br /&gt;&lt;br /&gt;port = 80&lt;br /&gt;verbose = recording = resequence = 0&lt;br /&gt;try:&lt;br /&gt;   opts=getopt.getopt(sys.argv[1:], "hv",["help","verbose","recording=","resequence","port="])&lt;br /&gt;   for opt, parm in opts[0]:&lt;br /&gt;       if opt in ["-h","--help"]:&lt;br /&gt;           Usage()&lt;br /&gt;       elif opt == "--recording":&lt;br /&gt;           recording = parm&lt;br /&gt;       elif opt == "--resequence":&lt;br /&gt;           resequence = 1&lt;br /&gt;       elif opt == "--port":&lt;br /&gt;           port = int(parm)&lt;br /&gt;       elif opt in ["-v","--verbose"]:&lt;br /&gt;           verbose = 1&lt;br /&gt;          &lt;br /&gt;except getopt.GetoptError:&lt;br /&gt;   Usage()&lt;br /&gt;      &lt;br /&gt;if not recording:&lt;br /&gt;   print "--recording must be specified."&lt;br /&gt;   Usage()&lt;br /&gt;&lt;br /&gt;file = scapy.rdpcap(recording)&lt;br /&gt;&lt;br /&gt;from scapy import replay_tcp&lt;br /&gt;print "Replayer active, waiting for incoming traffic...\n"&lt;br /&gt;replay_tcp(list=file,port=port,resequence=resequence)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It also makes use of the following utility script:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import scapy&lt;br /&gt;&lt;br /&gt;def matches(packet,other):&lt;br /&gt;   if not isinstance(other,packet.__class__):&lt;br /&gt;       return 0&lt;br /&gt;&lt;br /&gt;   if isinstance(packet,scapy.IP):&lt;br /&gt;       #print packet.src, other.src&lt;br /&gt;       if packet.src != other.src:&lt;br /&gt;           return 0&lt;br /&gt;   elif isinstance(packet,scapy.TCP):&lt;br /&gt;       #print packet.dport, other.dport&lt;br /&gt;       #print packet.flags, other.flags&lt;br /&gt;       if packet.dport != other.dport or packet.flags != other.flags:&lt;br /&gt;           return 0&lt;br /&gt;   elif isinstance(packet,scapy.Raw) or isinstance(packet,scapy.Padding):&lt;br /&gt;       #print repr(packet),repr(other)&lt;br /&gt;       if packet.load != other.load:&lt;br /&gt;           return 0&lt;br /&gt;&lt;br /&gt;   if not isinstance(packet.payload,scapy.NoPayload) and \&lt;br /&gt;           not isinstance(other.payload,scapy.NoPayload): # if both packets have got payloads, recurse&lt;br /&gt;       return matches(packet.payload,other.payload)&lt;br /&gt;   elif (isinstance(packet.payload,scapy.NoPayload) and isinstance(other.payload,scapy.Padding)) \&lt;br /&gt;       or (isinstance(packet.payload,scapy.Padding) and isinstance(other.payload,scapy.NoPayload)):&lt;br /&gt;           # special case, if one has padding and the other has no payload, still consider it a match.&lt;br /&gt;           return 1&lt;br /&gt;   elif packet.payload.__class__ != other.payload.__class__:&lt;br /&gt;       print packet.payload.__class__ , other.payload.__class__&lt;br /&gt;       return 0&lt;br /&gt;   else:&lt;br /&gt;       return 1&lt;br /&gt;&lt;br /&gt;def get_match(list, packet):&lt;br /&gt;   for other in list:&lt;br /&gt;       #print "|||", repr(other)&lt;br /&gt;       if matches(packet,other):&lt;br /&gt;           return other&lt;br /&gt;   return 0&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#=============================== Tests =========================================&lt;br /&gt;class AssertionError(Exception):&lt;br /&gt;   pass&lt;br /&gt;&lt;br /&gt;def test_MatchSelf():&lt;br /&gt;   print "test_matchSelf... \t\t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57",dst="10.0.1.60")/scapy.TCP(dport=80,sport=11111,flags='S')/scapy.Raw(load="test")&lt;br /&gt;   if not matches(packet,packet):&lt;br /&gt;       raise AssertionError('packet should match itself')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_MatchEtherNoPayload():&lt;br /&gt;   print "test_MatchEtherNoPayload... \t\t",&lt;br /&gt;   packet = scapy.Ether()&lt;br /&gt;   if not matches(packet,packet):&lt;br /&gt;       raise AssertionError('packet should match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_MatchIPNoPayload():&lt;br /&gt;   print "test_MatchIPNoPayload... \t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57",dst="10.0.1.60")&lt;br /&gt;   if not matches(packet,packet):&lt;br /&gt;       raise AssertionError('packet should match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_MatchIPMissingSrc():&lt;br /&gt;   print "test_MatchIPMissingSrc... \t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP()&lt;br /&gt;   if not matches(packet,packet):&lt;br /&gt;       raise AssertionError('packet should match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_NoMatchIP():&lt;br /&gt;   print "test_NoMatchIP... \t\t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57")&lt;br /&gt;   packet2 = scapy.Ether()/scapy.IP(src="10.0.1.67")&lt;br /&gt;   if matches(packet,packet2):&lt;br /&gt;       raise AssertionError('packet should not match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_NoMatchTCP():&lt;br /&gt;   print "test_NoMatchTCP... \t\t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118)&lt;br /&gt;   packet2 = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8117)&lt;br /&gt;   if matches(packet,packet2):&lt;br /&gt;       raise AssertionError('packet should not match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_NoMatchTCP2():&lt;br /&gt;   print "test_NoMatchTCP2... \t\t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118)&lt;br /&gt;   packet2 = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP()&lt;br /&gt;   if matches(packet,packet2):&lt;br /&gt;       raise AssertionError('packet should not match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_PartialMatchTCP():&lt;br /&gt;   print "test_PartialMatchTCP... \t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118, flags='SA')&lt;br /&gt;   packet2 = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118, flags='A')&lt;br /&gt;   if matches(packet,packet2):&lt;br /&gt;       raise AssertionError('packet should not match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_PartialMatchTCP2():&lt;br /&gt;   print "test_PartialMatchTCP2... \t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118, flags='SA')&lt;br /&gt;   packet2 = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118)&lt;br /&gt;   if matches(packet,packet2):&lt;br /&gt;       raise AssertionError('packet should not match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def test_NoMatchRaw():&lt;br /&gt;   print "test_NoMatchRaw... \t\t\t",&lt;br /&gt;   packet = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118)/"Test"&lt;br /&gt;   packet2 = scapy.Ether()/scapy.IP(src="10.0.1.57")/scapy.TCP(dport=8118)/"Test2"&lt;br /&gt;   if matches(packet,packet2):&lt;br /&gt;       raise AssertionError('packet should not match')&lt;br /&gt;   print "pass"&lt;br /&gt;&lt;br /&gt;def run_tests():&lt;br /&gt;   test_MatchSelf()&lt;br /&gt;   test_MatchEtherNoPayload()&lt;br /&gt;   test_MatchIPNoPayload()&lt;br /&gt;   test_MatchIPMissingSrc()&lt;br /&gt;   test_NoMatchIP()&lt;br /&gt;   test_NoMatchTCP()&lt;br /&gt;   test_NoMatchTCP2()&lt;br /&gt;   test_NoMatchRaw()&lt;br /&gt;   test_PartialMatchTCP()&lt;br /&gt;   test_PartialMatchTCP2()&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8913849285886833150-2945600464040462169?l=c1de0x.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://c1de0x.blogspot.com/feeds/2945600464040462169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8913849285886833150&amp;postID=2945600464040462169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8913849285886833150/posts/default/2945600464040462169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8913849285886833150/posts/default/2945600464040462169'/><link rel='alternate' type='text/html' href='http://c1de0x.blogspot.com/2007/06/tcp-replay.html' title='TCP Replay'/><author><name>c1de0x</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
