├── .gitignore ├── HTTP.py ├── README.md ├── cmds.search.txt ├── cmds.searchreplace.txt ├── cmds.settcp.txt ├── cmds.setudp.txt ├── http.cap ├── pcapedit.py ├── requirements.txt └── todo /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | 29 | # Translations 30 | *.mo 31 | 32 | # Mr Developer 33 | .mr.developer.cfg 34 | .project 35 | .pydevproject 36 | 37 | # Vim swp files 38 | *.swp 39 | 40 | # mod pcaps generated by pcapedit 41 | *.mod.* 42 | 43 | -------------------------------------------------------------------------------- /HTTP.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | # http://tools.ietf.org/html/rfc2616 4 | # Author : Steeve Barbeau 5 | # Twitter : @steevebarbeau 6 | # Blog : steeve-barbeau.blogspot.com 7 | 8 | import logging,re 9 | logging.getLogger("scapy").setLevel(1) 10 | 11 | from scapy.all import bind_layers, interact, Packet, StrField, TCP 12 | 13 | 14 | class HTTPrequest(Packet): 15 | name = "HTTP Request" 16 | http_methods = "^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT)" 17 | fields_desc=[StrField("Method", None, fmt="H"), 18 | StrField("Host", None, fmt="H"), 19 | StrField("UserAgent", None, fmt="H"), 20 | StrField("Accept", None, fmt="H"), 21 | StrField("AcceptLanguage", None, fmt="H"), 22 | StrField("AcceptEncoding", None, fmt="H"), 23 | StrField("AcceptCharset", None, fmt="H"), 24 | StrField("Referer", None, fmt="H"), 25 | StrField("Authorization", None, fmt="H"), 26 | StrField("Expect", None, fmt="H"), 27 | StrField("From", None, fmt="H"), 28 | StrField("IfMatch", None, fmt="H"), 29 | StrField("IfModifiedSince", None, fmt="H"), 30 | StrField("IfNoneMatch", None, fmt="H"), 31 | StrField("IfRange", None, fmt="H"), 32 | StrField("IfUnmodifiedSince", None, fmt="H"), 33 | StrField("MaxForwards", None, fmt="H"), 34 | StrField("ProxyAuthorization", None, fmt="H"), 35 | StrField("Range", None, fmt="H"), 36 | StrField("TE", None, fmt="H")] 37 | 38 | 39 | def do_dissect(self, s): 40 | fields_rfc = ["Method", "Host", "User-Agent", "Accept", "Accept-Language", "Accept-Encoding", "Accept-Charset", "Referer", "Authorization", "Expect", "From", "If-Match", "If-Modified-Since", "If-None-Match", "If-Range", "If-Unmodified-Since", "Max-Forwards", "Proxy-Authorization", "Range", "TE"] 41 | 42 | a=s.split("\r\n") 43 | obj = self.fields_desc[:] 44 | obj.reverse() 45 | fields_rfc.reverse() 46 | while obj: 47 | f = obj.pop() 48 | g = fields_rfc.pop() 49 | for x in a: 50 | if(g=="Method"): 51 | prog=re.compile(self.http_methods) 52 | else: 53 | prog=re.compile(g+":", re.IGNORECASE) 54 | result=prog.search(x) 55 | if result: 56 | self.setfieldval(f.name, x+'\r\n') 57 | a.remove(x) 58 | return '\r\n'+"".join(a) 59 | 60 | 61 | class HTTPresponse(Packet): 62 | name = "HTTP Response" 63 | fields_desc=[StrField("StatusLine", None, fmt="H"), 64 | StrField("AcceptRanges", None, fmt="H"), 65 | StrField("Age", None, fmt="H"), 66 | StrField("ETag", None, fmt="H"), 67 | StrField("Location", None, fmt="H"), 68 | StrField("ProxyAuthenticate", None, fmt="H"), 69 | StrField("RetryAfter", None, fmt="H"), 70 | StrField("Server", None, fmt="H"), 71 | StrField("Vary", None, fmt="H"), 72 | StrField("WWWAuthenticate", None, fmt="H")] 73 | 74 | def do_dissect(self, s): 75 | fields_rfc = ["Status-Line","Accept-Ranges","Age","ETag","Location","Proxy-Authenticate", "Retry-After", "Server", "Vary", "WWW-Authenticate"] 76 | 77 | a=s.split("\r\n") 78 | obj = self.fields_desc[:] 79 | obj.reverse() 80 | fields_rfc.reverse() 81 | while obj: 82 | f = obj.pop() 83 | g = fields_rfc.pop() 84 | for x in a: 85 | if(g=="Status-Line"): 86 | prog=re.compile("^HTTP/((0\.9)|(1\.0)|(1\.1))\ [0-9]{3}.*") 87 | else: 88 | prog=re.compile(g+":", re.IGNORECASE) 89 | result=prog.search(x) 90 | if result: 91 | self.setfieldval(f.name, x+'\r\n') 92 | a.remove(x) 93 | return '\r\n'+"".join(a) 94 | 95 | 96 | class HTTP(Packet): 97 | name="HTTP" 98 | fields_desc = [StrField("CacheControl", None, fmt="H"), 99 | StrField("Connection", None, fmt="H"), 100 | StrField("Date", None, fmt="H"), 101 | StrField("Pragma", None, fmt="H"), 102 | StrField("Trailer", None, fmt="H"), 103 | StrField("TransferEncoding", None, fmt="H"), 104 | StrField("Upgrade", None, fmt="H"), 105 | StrField("Via", None, fmt="H"), 106 | StrField("Warning", None, fmt="H"), 107 | StrField("KeepAlive", None, fmt="H"), 108 | StrField("Allow", None, fmt="H"), 109 | StrField("ContentEncoding", None, fmt="H"), 110 | StrField("ContentLanguage", None, fmt="H"), 111 | StrField("ContentLength", None, fmt="H"), 112 | StrField("ContentLocation", None, fmt="H"), 113 | StrField("ContentMD5", None, fmt="H"), 114 | StrField("ContentRange", None, fmt="H"), 115 | StrField("ContentType", None, fmt="H"), 116 | StrField("Expires", None, fmt="H"), 117 | StrField("LastModified", None, fmt="H")] 118 | 119 | def do_dissect(self, s): 120 | fields_rfc = ["Cache-Control", "Connection", "Date", "Pragma", "Trailer", "Transfer-Encoding", "Upgrade", "Via", "Warning", "Keep-Alive", "Allow", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Expires", "Last-Modified"] 121 | 122 | a=s.split("\r\n") 123 | obj = self.fields_desc[:] 124 | obj.reverse() 125 | fields_rfc.reverse() 126 | while obj: 127 | f = obj.pop() 128 | g = fields_rfc.pop() 129 | for x in a: 130 | prog=re.compile(g+":", re.IGNORECASE) 131 | result=prog.search(x) 132 | if result: 133 | self.setfieldval(f.name, x+'\r\n') 134 | a.remove(x) 135 | return "\r\n".join(a) 136 | 137 | def guess_payload_class(self, payload): 138 | prog=re.compile("^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT)") 139 | result=prog.search(payload) 140 | if result: 141 | return HTTPrequest 142 | else: 143 | prog=re.compile("^HTTP/((0\.9)|(1\.0)|(1\.1))\ [0-9]{3}.*") 144 | result=prog.search(payload) 145 | if result: 146 | return HTTPresponse 147 | return Packet.guess_payload_class(self, payload) 148 | 149 | 150 | bind_layers(TCP, HTTP) 151 | 152 | 153 | if __name__ == "__main__": 154 | interact(mydict=globals(), mybanner="HTTP Scapy extension") 155 | 156 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pcapedit 2 | 3 | This script will help you interactively search within and edit a pcap file. Check following sample output from included command files for more details. 4 | 5 | ## Usage: 6 | 7 | ```bash 8 | $ python pcapedit.py 26 | 27 | search for raw string 28 | Found 19 matches for search query '.* in pay.load': 4, 6, 8, 10, 11, 14, 16, 18, 20, 21, 23, 26, 27, 29, 31, 32, 34, 36, 38 29 | 30 | search within ether packets 31 | Found 20 matches for search query '00:00:01:00:00:00 in ether.src': 1, 3, 4, 7, 9, 12, 13, 15, 18, 19, 22, 25, 28, 30, 33, 35, 37, 39, 41, 42 32 | $ 33 | $ python pcapedit.py 1.1.1.1 (coz IP.src is 145.254.160.237) 40 | 2: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 41 | 3: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 42 | 6: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 43 | 8: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 44 | 11: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 45 | 12: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 46 | 14: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 47 | 17: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 48 | 18: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 49 | 21: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 50 | 24: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 51 | 27: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 52 | 29: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 53 | 32: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 54 | 34: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 55 | 36: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 56 | 38: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 57 | 40: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 58 | 41: IP.src: 145.254.160.237 -> 1.1.1.1 (coz IP.src is 145.254.160.237) 59 | Replacing IP.dst to '1.1.1.1' where IP.dst is '145.254.160.237' 60 | 1: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 61 | 4: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 62 | 5: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 63 | 7: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 64 | 9: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 65 | 10: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 66 | 13: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 67 | 15: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 68 | 16: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 69 | 19: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 70 | 20: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 71 | 22: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 72 | 23: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 73 | 25: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 74 | 26: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 75 | 28: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 76 | 30: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 77 | 31: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 78 | 33: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 79 | 35: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 80 | 37: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 81 | 39: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 82 | 42: IP.dst: 145.254.160.237 -> 1.1.1.1 (coz IP.dst is 145.254.160.237) 83 | 84 | Replacing IP.src to '2.2.2.2' where IP.src is '65.208.228.223' 85 | 1: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 86 | 4: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 87 | 5: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 88 | 7: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 89 | 9: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 90 | 10: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 91 | 13: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 92 | 15: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 93 | 19: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 94 | 20: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 95 | 22: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 96 | 28: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 97 | 30: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 98 | 31: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 99 | 33: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 100 | 37: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 101 | 39: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 102 | 42: IP.src: 65.208.228.223 -> 2.2.2.2 (coz IP.src is 65.208.228.223) 103 | Replacing IP.dst to '2.2.2.2' where IP.dst is '65.208.228.223' 104 | 0: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 105 | 2: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 106 | 3: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 107 | 6: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 108 | 8: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 109 | 11: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 110 | 14: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 111 | 18: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 112 | 21: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 113 | 24: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 114 | 29: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 115 | 32: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 116 | 34: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 117 | 38: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 118 | 40: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 119 | 41: IP.dst: 65.208.228.223 -> 2.2.2.2 (coz IP.dst is 65.208.228.223) 120 | 121 | 0: 2004/05/13 03:17:07 1.1.1.1:3372 -> 2.2.2.2:80 TCP S 122 | 1: 2004/05/13 03:17:08 2.2.2.2:80 -> 1.1.1.1:3372 TCP SA 123 | 2: 2004/05/13 03:17:08 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 124 | 3: 2004/05/13 03:17:08 1.1.1.1:3372 -> 2.2.2.2:80 TCP PA (479 bytes) 125 | 4: 2004/05/13 03:17:08 2.2.2.2:80 -> 1.1.1.1:3372 TCP A 126 | 5: 2004/05/13 03:17:08 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 127 | 6: 2004/05/13 03:17:09 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 128 | 7: 2004/05/13 03:17:09 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 129 | 8: 2004/05/13 03:17:09 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 130 | 9: 2004/05/13 03:17:09 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 131 | 10: 2004/05/13 03:17:09 2.2.2.2:80 -> 1.1.1.1:3372 TCP PA (1380 bytes) 132 | 11: 2004/05/13 03:17:09 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 133 | 12: 2004/05/13 03:17:09 1.1.1.1:3009 -> 145.253.2.203:53 UDP (47 bytes) 134 | 13: 2004/05/13 03:17:09 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 135 | 14: 2004/05/13 03:17:10 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 136 | 15: 2004/05/13 03:17:10 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 137 | 16: 2004/05/13 03:17:10 145.253.2.203:53 -> 1.1.1.1:3009 UDP (146 bytes) 138 | 17: 2004/05/13 03:17:10 1.1.1.1:3371 -> 216.239.59.99:80 TCP PA (721 bytes) 139 | 18: 2004/05/13 03:17:10 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 140 | 19: 2004/05/13 03:17:10 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 141 | 20: 2004/05/13 03:17:10 2.2.2.2:80 -> 1.1.1.1:3372 TCP PA (1380 bytes) 142 | 21: 2004/05/13 03:17:10 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 143 | 22: 2004/05/13 03:17:10 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 144 | 23: 2004/05/13 03:17:10 216.239.59.99:80 -> 1.1.1.1:3371 TCP A 145 | 24: 2004/05/13 03:17:11 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 146 | 25: 2004/05/13 03:17:11 216.239.59.99:80 -> 1.1.1.1:3371 TCP PA (1430 bytes) 147 | 26: 2004/05/13 03:17:11 216.239.59.99:80 -> 1.1.1.1:3371 TCP PA (160 bytes) 148 | 27: 2004/05/13 03:17:11 1.1.1.1:3371 -> 216.239.59.99:80 TCP A 149 | 28: 2004/05/13 03:17:11 2.2.2.2:80 -> 1.1.1.1:3372 TCP PA (1380 bytes) 150 | 29: 2004/05/13 03:17:11 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 151 | 30: 2004/05/13 03:17:11 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 152 | 31: 2004/05/13 03:17:11 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 153 | 32: 2004/05/13 03:17:11 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 154 | 33: 2004/05/13 03:17:11 2.2.2.2:80 -> 1.1.1.1:3372 TCP A (1380 bytes) 155 | 34: 2004/05/13 03:17:11 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 156 | 35: 2004/05/13 03:17:12 216.239.59.99:80 -> 1.1.1.1:3371 TCP PA (1430 bytes) 157 | 36: 2004/05/13 03:17:12 1.1.1.1:3371 -> 216.239.59.99:80 TCP A 158 | 37: 2004/05/13 03:17:12 2.2.2.2:80 -> 1.1.1.1:3372 TCP PA (424 bytes) 159 | 38: 2004/05/13 03:17:12 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 160 | 39: 2004/05/13 03:17:25 2.2.2.2:80 -> 1.1.1.1:3372 TCP FA 161 | 40: 2004/05/13 03:17:25 1.1.1.1:3372 -> 2.2.2.2:80 TCP A 162 | 41: 2004/05/13 03:17:37 1.1.1.1:3372 -> 2.2.2.2:80 TCP FA 163 | 42: 2004/05/13 03:17:37 2.2.2.2:80 -> 1.1.1.1:3372 TCP A 164 | 165 | Wrote 43 packet(s) to http.mod.cap 166 | $ 167 | ``` 168 | 169 | ## Credits: 170 | 171 | * [Scapy](https://github.com/secdev/scapy) 172 | -------------------------------------------------------------------------------- /cmds.search.txt: -------------------------------------------------------------------------------- 1 | search 2 | !echo 3 | 4 | analyze http.cap 5 | !echo 6 | 7 | !echo search for tcp packets 8 | search --key ip.proto --value 6 9 | !echo 10 | 11 | !echo search for udp packets 12 | search --key ip.proto --value 17 13 | !echo 14 | 15 | !echo search for raw string 16 | search --key pay.load --value "(?i)Google" 17 | !echo 18 | 19 | !echo search for raw string 20 | search --key dns.ns --value "test" 21 | !echo 22 | 23 | !echo search for raw string 24 | search --key pay.load --value ".*" 25 | !echo 26 | 27 | !echo search within ether packets 28 | search --key ether.src --value 00:00:01:00:00:00 29 | !echo 30 | -------------------------------------------------------------------------------- /cmds.searchreplace.txt: -------------------------------------------------------------------------------- 1 | analyze http.cap 2 | !echo 3 | 4 | set ip.src 1.1.1.1 ip.src 145.254.160.237 5 | set ip.dst 1.1.1.1 ip.dst 145.254.160.237 6 | !echo 7 | 8 | set ip.src 2.2.2.2 ip.src 65.208.228.223 9 | set ip.dst 2.2.2.2 ip.dst 65.208.228.223 10 | !echo 11 | 12 | summary 13 | !echo 14 | 15 | save 16 | !echo 17 | -------------------------------------------------------------------------------- /cmds.settcp.txt: -------------------------------------------------------------------------------- 1 | analyze http.cap 2 | !echo 3 | 4 | edit 6 5 | !echo 6 | 7 | set ether.src 11:22:33:44:55 8 | set ether.dst 55:44:33:22:11 9 | set ether.type 2048 10 | !echo 11 | 12 | set ip.version 88 13 | set ip.ihl 56 14 | set ip.tos 33 15 | set ip.len 36 16 | set ip.id 12 17 | set ip.flags 81 18 | set ip.frag 22 19 | set ip.ttl 27 20 | set ip.proto 15 21 | set ip.chksum 78 22 | set ip.src 12 23 | set ip.dst 21 24 | set ip.options 99 25 | !echo 26 | 27 | set tcp.sport 1234 28 | set tcp.dport 4321 29 | set tcp.seq 11 30 | set tcp.ack 12 31 | set tcp.dataofs 1 32 | set tcp.reserved 9 33 | set tcp.flags 90 34 | set tcp.window 36 35 | set tcp.chksum 88 36 | set tcp.urgptr 67 37 | set tcp.options 98 38 | !echo 39 | 40 | summary 41 | !echo 42 | 43 | save 1-11 44 | -------------------------------------------------------------------------------- /cmds.setudp.txt: -------------------------------------------------------------------------------- 1 | analyze http.cap 2 | !echo 3 | 4 | edit 12 5 | !echo 6 | 7 | set ether.src 11:22:33:44:55 8 | set ether.dst 55:44:33:22:11 9 | !echo 10 | 11 | set ip.version 88 12 | set ip.ihl 56 13 | set ip.tos 33 14 | set ip.len 36 15 | set ip.id 12 16 | set ip.flags 81 17 | set ip.frag 22 18 | set ip.ttl 27 19 | set ip.proto 15 20 | set ip.chksum 78 21 | set ip.src 12 22 | set ip.dst 21 23 | set ip.options 99 24 | !echo 25 | 26 | set udp.sport 4321 27 | set udp.dport 1234 28 | set udp.len 99 29 | set udp.chksum 81 30 | !echo 31 | 32 | set dns.id 1 33 | set dns.qr 2 34 | set dns.opcode 3 35 | set dns.aa 4 36 | set dns.tc 5 37 | set dns.rd 6 38 | set dns.ra 7 39 | set dns.z 8 40 | set dns.rcode 9 41 | set dns.qdcount 10 42 | set dns.ancount 11 43 | set dns.nscount 12 44 | set dns.arcount 13 45 | set dns.qd 14 46 | set dns.an 15 47 | set dns.ns 16 48 | set dns.ar 17 49 | !echo 50 | 51 | summary 52 | !echo 53 | 54 | save 55 | !echo 56 | -------------------------------------------------------------------------------- /http.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/7h3rAm/pcapedit/356975d38f9b3cce318b824e6d6905aa50850ea3/http.cap -------------------------------------------------------------------------------- /pcapedit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import re 5 | import sys 6 | import binascii 7 | import argparse 8 | import readline 9 | import atexit 10 | from cmd2 import with_argparser 11 | 12 | from cmd2 import Cmd 13 | from datetime import datetime 14 | 15 | import logging 16 | logging.getLogger('scapy.runtime').setLevel(logging.ERROR) 17 | 18 | from scapy.all import * 19 | from scapy.utils import * 20 | 21 | history_file = os.path.expanduser('~/.pcapedit_history') 22 | if not os.path.exists(history_file): 23 | with open(history_file, "w") as fobj: 24 | fobj.write("") 25 | 26 | readline.read_history_file(history_file) 27 | atexit.register(readline.write_history_file, history_file) 28 | 29 | class editor(Cmd): 30 | intro = 'PcapEdit - An Interactive Pcap Editor\n' 31 | prompt = '>>> ' 32 | quit_on_sigint = True 33 | 34 | packets = [] 35 | editid = -1 36 | inpcap = None 37 | outpcap = None 38 | 39 | protodict = { 40 | "ether": { 41 | "scapyproto": "Ether", 42 | "src": str, 43 | "dst": str, 44 | "type": int 45 | }, 46 | "ip": { 47 | "scapyproto": "IP", 48 | "version": int, 49 | "ihl": int, 50 | "tos": int, 51 | "len": int, 52 | "id": int, 53 | "flags": int, 54 | "frag": int, 55 | "ttl": int, 56 | "proto": int, 57 | "chksum": int, 58 | "src": str, 59 | "dst": str, 60 | "options": int 61 | }, 62 | "tcp": { 63 | "scapyproto": "TCP", 64 | "sport": int, 65 | "dport": int, 66 | "seq": int, 67 | "ack": int, 68 | "dataofs": int, 69 | "reserved": int, 70 | "ttl": int, 71 | "flags": int, 72 | "window": int, 73 | "chksum": int, 74 | "urgptr": int, 75 | "options": int 76 | }, 77 | "udp": { 78 | "scapyproto": "UDP", 79 | "sport": int, 80 | "dport": int, 81 | "len": int, 82 | "chksum": int 83 | }, 84 | "dns": { 85 | "scapyproto": "DNS", 86 | "id": int, 87 | "qr": int, 88 | "opcode": int, 89 | "aa": int, 90 | "tc": int, 91 | "rd": int, 92 | "ra": int, 93 | "z": int, 94 | "rcode": int, 95 | "qdcount": int, 96 | "ancount": int, 97 | "nscount": int, 98 | "arcount": int, 99 | "qd": int, 100 | "an": int, 101 | "ns": int, 102 | "ar": int 103 | }, 104 | "pay": { 105 | "scapyproto": "RAW", 106 | "load": str 107 | } 108 | } 109 | 110 | def help_analyze(self): 111 | print('USAGE: analyze ') 112 | print('Analyze packets from ') 113 | 114 | def do_analyze(self, line): 115 | if line != '': 116 | if os.path.isfile(line): 117 | self.inpcap = line 118 | self.packets = rdpcap(self.inpcap) 119 | 120 | for packet in self.packets: 121 | if packet.haslayer(IP): packet.getlayer(IP).chksum = None 122 | if packet.haslayer(TCP): packet.getlayer(TCP).chksum = None 123 | if packet.haslayer(UDP): packet.getlayer(UDP).chksum = None 124 | 125 | self.editid = -1 126 | self.outpcap = None 127 | self.prompt = '(%s) >>> ' % (self.inpcap) 128 | 129 | print('Read %d packets from %s' % (len(self.packets), self.inpcap)) 130 | else: 131 | print('%s doesn\'t exist!' % (line)) 132 | else: 133 | self.help_analyze() 134 | 135 | def complete_analyze(self, text, line, begidx, endidx): 136 | index_dict = \ 137 | { 138 | 1: self.path_complete, 139 | } 140 | 141 | return self.index_based_complete(text, line, begidx, endidx, index_dict=index_dict) 142 | 143 | def help_back(self): 144 | print('USAGE: back') 145 | print('Move one level backwards from current context') 146 | 147 | def do_back(self, line): 148 | if self.inpcap: 149 | if self.editid != -1: 150 | self.editid = -1 151 | self.prompt = '(%s) >>> ' % (self.inpcap) 152 | else: 153 | self.prompt = '>>> ' 154 | self.packets = [] 155 | self.inpcap = None 156 | self.outpcap = None 157 | 158 | def help_ls(self): 159 | print('USAGE: ls [packetid]') 160 | print('Show ls for packetid') 161 | print('If no packetid is passed, use editid instead') 162 | 163 | def do_ls(self, line): 164 | if self.packets and len(self.packets) > 0: 165 | if line != '': 166 | id = int(line) 167 | if id >= 0 and id <= (len(self.packets) - 1): 168 | print(ls(self.packets[id])) 169 | else: 170 | print('Packet %d not found! Available %d - %d' % (id, 0, (len(self.packets) - 1))) 171 | elif self.editid != -1: 172 | print(ls(self.packets[self.editid])) 173 | else: 174 | print('No packetid to ls! Pass one as argument or use \'edit\' first.') 175 | self.help_ls() 176 | return 177 | else: 178 | print('Nothing to ls! Use \'analyze\' first.') 179 | 180 | def help_summary(self): 181 | print('USAGE: summary [packetid]') 182 | print('Show summary for packetid') 183 | print('If no packetid is passed, use editid instead') 184 | 185 | def do_summary(self, line): 186 | if self.packets and len(self.packets) > 0: 187 | if line != '': 188 | id = int(line) 189 | if id < 0 or id > (len(self.packets) - 1): 190 | id = -1 191 | elif self.editid != -1: 192 | id = self.editid 193 | else: 194 | id = -1 195 | 196 | count = 0 197 | for packet in self.packets: 198 | if id != -1 and count != id: 199 | count += 1 200 | continue 201 | 202 | ptime = datetime.fromtimestamp(packet.time).strftime('%Y/%m/%d %H:%M:%S') 203 | data = None 204 | 205 | if packet.haslayer(IP): 206 | sip = packet.getlayer(IP).src 207 | dip = packet.getlayer(IP).dst 208 | 209 | if packet.haslayer(TCP): 210 | sport = packet.getlayer(TCP).sport 211 | dport = packet.getlayer(TCP).dport 212 | flags = packet.getlayer(TCP).flags 213 | 214 | flaglist = [] 215 | if flags & 1: flaglist.append('F') 216 | if flags & 2: flaglist.append('S') 217 | if flags & 4: flaglist.append('R') 218 | if flags & 8: flaglist.append('P') 219 | if flags & 16: flaglist.append('A') 220 | if flags & 32: flaglist.append('U') 221 | if flags & 64: flaglist.append('E') 222 | if flags & 128: flaglist.append('C') 223 | if flags & 256: flaglist.append('N') 224 | flagstr = ''.join(flaglist) 225 | 226 | if Raw in packet: 227 | data = packet[Raw] 228 | else: 229 | data = '' 230 | 231 | if len(data) > 0: 232 | summary = '%s (%d bytes)' % (flagstr, len(data)) 233 | else: 234 | summary = '%s' % (flagstr) 235 | 236 | print('%6d: %-15s %23s -> %-23s TCP %s' % ( 237 | count, 238 | ptime, 239 | '%s:%s' % (sip, sport), 240 | '%s:%s' % (dip, dport), 241 | summary)) 242 | 243 | elif packet.haslayer(UDP): 244 | sport = packet.getlayer(UDP).sport 245 | dport = packet.getlayer(UDP).dport 246 | 247 | if Raw in packet: 248 | data = packet[Raw] 249 | else: 250 | data = '' 251 | 252 | if len(data) > 0: 253 | summary = '(%d bytes)' % (len(data)) 254 | else: 255 | summary = '(%d bytes)' % (len(packet[3])) 256 | 257 | print('%6d: %-15s %23s -> %-23s UDP %s' % ( 258 | count, 259 | ptime, 260 | '%s:%s' % (sip, sport), 261 | '%s:%s' % (dip, dport), 262 | summary)) 263 | 264 | else: 265 | if Raw in packet: 266 | data = packet[Raw] 267 | else: 268 | data = '' 269 | 270 | print('%6d: %-15s %23s -> %-23s IP (%d bytes)' % ( 271 | count, 272 | ptime, 273 | sip, 274 | dip, 275 | len(data))) 276 | 277 | count += 1 278 | else: 279 | print('Nothing to summarize! Use \'analyze\' first.') 280 | 281 | def help_hexdump(self): 282 | print('USAGE: hexdump [packetid]') 283 | print('Show hexdump for packetid') 284 | print('If no packetid is passed, use editid instead') 285 | 286 | def do_hexdump(self, line): 287 | if self.packets and len(self.packets) > 0: 288 | if line != '': 289 | id = int(line) 290 | if id >= 0 and id <= (len(self.packets) - 1): 291 | print(hexdump(self.packets[id])) 292 | else: 293 | print('Packet %d not found! Available %d - %d' % (id, 0, (len(self.packets) - 1))) 294 | elif self.editid != -1: 295 | print(hexdump(self.packets[self.editid])) 296 | else: 297 | print('No packetid to hexdump! Pass one as argument or use \'edit\' first.') 298 | self.help_hexdump() 299 | return 300 | else: 301 | print('Nothing to hexdump! Use \'analyze\' first.') 302 | 303 | def help_pdfdump(self): 304 | print('USAGE: pdfdump [packetid]') 305 | print('Dump packetid to a PDF') 306 | print('If no packetid is passed, use editid instead') 307 | 308 | def do_pdfdump(self, line): 309 | if self.packets and len(self.packets) > 0: 310 | if line != '': 311 | id = int(line) 312 | if id >= 0 and id <= (len(self.packets) - 1): 313 | print(self.packets[id].pdfdump()) 314 | else: 315 | print('Packet %d not found! Available %d - %d' % (id, 0, (len(self.packets) - 1))) 316 | elif self.editid != -1: 317 | print(self.packets[self.editid].pdfdump()) 318 | else: 319 | print('No packetid to dump! Pass one as argument or use \'edit\' first.') 320 | self.help_pdfdump() 321 | return 322 | else: 323 | print('Nothing to dump! Use \'analyze\' first.') 324 | 325 | def help_scapycmd(self): 326 | print('USAGE: scapycmd [packetid]') 327 | print('Show Scapy command to generate packetid') 328 | print('If no packetid is passed, use editid instead') 329 | 330 | def do_scapycmd(self, line): 331 | if self.packets and len(self.packets) > 0: 332 | if line != '': 333 | id = int(line) 334 | if id >= 0 and id <= (len(self.packets) - 1): 335 | print(self.packets[id].command()) 336 | else: 337 | print('Packet %d not found! Available %d - %d' % (id, 0, (len(self.packets) - 1))) 338 | elif self.editid != -1: 339 | print(self.packets[self.editid].command()) 340 | else: 341 | print('No packetid to show as Scapy command! Pass one as argument or use \'edit\' first.') 342 | self.help_scapycmd() 343 | return 344 | else: 345 | print('Nothing to show as Scapy command! Use \'analyze\' first.') 346 | 347 | def help_wireshark(self): 348 | print('USAGE: wireshark [packetid]') 349 | print('Show packetid in Wireshark') 350 | print('If no packetid is passed, use editid instead') 351 | 352 | def do_wireshark(self, line): 353 | if self.packets and len(self.packets) > 0: 354 | if line != '': 355 | id = int(line) 356 | if id >= 0 and id <= (len(self.packets) - 1): 357 | wireshark(self.packets[id]) 358 | else: 359 | print('Packet %d not found! Available %d - %d' % (id, 0, (len(self.packets) - 1))) 360 | elif self.editid != -1: 361 | print(wireshark(self.packets[self.editid])) 362 | else: 363 | print('No packetid to show in wireshark! Pass one as argument or use \'edit\' first.') 364 | self.help_wireshark() 365 | return 366 | else: 367 | print('Nothing to show in wireshark! Use \'analyze\' first.') 368 | 369 | def help_edit(self): 370 | print('USAGE: edit [packetid]') 371 | print('Use for analysis/editing operations') 372 | print('To stop editing, use edit without arguments') 373 | 374 | def do_edit(self, line): 375 | if self.packets and len(self.packets) > 0: 376 | if line != '': 377 | id = int(line) 378 | if id >= 0 and id <= (len(self.packets) - 1): 379 | self.editid = id 380 | self.prompt = '(%s|#%d) >>> ' % (self.inpcap, self.editid) 381 | print('Editing packet id: %d' % (self.editid)) 382 | self.do_summary(line) 383 | else: 384 | print('Packet %d not found! Available %d - %d' % (id, 0, (len(self.packets) - 1))) 385 | else: 386 | print('Nothing to edit! Use \'analyze\' first.') 387 | 388 | def help_outpcap(self): 389 | print('USAGE: outpcap [pcapname]') 390 | print('Use \'pcapname\' as the name of the pcap for \'save\'') 391 | print('To clear such usage, use \'outpcap\' without arguments') 392 | 393 | def do_outpcap(self, line): 394 | if line != '': self.outpcap = line 395 | else: self.outpcap = None 396 | print('outpcap: %s' % (self.outpcap)) 397 | 398 | def help_search(self): 399 | print('USAGE: search ') 400 | print('Where key: ((ether|ip|tcp|udp|dns).field|data)') 401 | print('Valid fields are the ones listed in \'ls\'') 402 | 403 | argparser = argparse.ArgumentParser() 404 | argparser.add_argument("-k", "--key", action="store", help="search key (ether|ip|tcp|udp|dns|pay).field") 405 | argparser.add_argument("-v", "--value", action="store", help="search value") 406 | @with_argparser(argparser) 407 | def do_search(self, args): 408 | if not self.packets or len(self.packets) == 0: 409 | print('Nothing to search! Use \'analyze\' first.') 410 | return 411 | if not args.key or not args.value: 412 | self.help_search() 413 | return 414 | searchproto = args.key.split(".")[0].lower() 415 | searchfield = args.key.split(".")[1].lower() 416 | searchvalue = args.value 417 | if searchproto in self.protodict and searchfield in self.protodict[searchproto]: 418 | # cast searchvalue as per expected protofield datatype 419 | try: 420 | searchvalue = self.protodict[searchproto][searchfield](searchvalue) 421 | except: 422 | print("Incorrect searchvalue '%s' for protofield '%s.%s', expected %s" % (searchvalue, searchproto, searchfield, self.protodict[searchproto][searchfield])) 423 | return 424 | scapyproto = self.protodict[searchproto]["scapyproto"] 425 | if self.editid == -1: 426 | count, matches = 0, [] 427 | for idx, packet in enumerate(self.packets): 428 | if packet.haslayer(scapyproto) and searchfield in packet[scapyproto].fields.keys(): 429 | if packet[scapyproto].fields[searchfield] == searchvalue: 430 | matches.append(idx+1) 431 | # searchfield is of no signfifcance for searchproto == pay; but enforcing this scheme 432 | if searchproto == "pay" and searchfield == "load": 433 | if Raw in self.packets[idx] and re.search(searchvalue, self.protodict[searchproto][searchfield](self.packets[idx][Raw])): 434 | matches.append(idx+1) 435 | print("Found %d matches for search query '%s in %s.%s': %s" % (len(matches), searchvalue, searchproto.lower(), searchfield, ", ".join([str(x) for x in sorted(matches)]))) 436 | else: 437 | print("searching packet #%d" % (self.editid)) 438 | else: 439 | self.help_search() 440 | return 441 | 442 | def help_set(self): 443 | print('USAGE: set [ ]') 444 | print('Where key: (ether|ip|tcp|udp|dns).field') 445 | print('Valid fields are the ones listed in \'ls\'') 446 | 447 | def do_set(self, line): 448 | if self.packets and len(self.packets) > 0: 449 | if line != '': 450 | setargslist = line.split() 451 | if len(setargslist) <= 1: 452 | self.help_set() 453 | return 454 | 455 | if len(setargslist) >= 4 and self.editid == -1: 456 | setkey = setargslist[0] 457 | setproto = setkey.split('.')[0] 458 | setfield = setkey.split('.')[1] 459 | setvalue = setargslist[1] 460 | 461 | searchkey = setargslist[2] 462 | searchproto = searchkey.split('.')[0] 463 | searchfield = searchkey.split('.')[1] 464 | searchvalue = setargslist[3] 465 | 466 | if re.search(r'(?i)^ether$', setproto): setproto = 'Ether' 467 | if re.search(r'(?i)^ip$', setproto): setproto = 'IP' 468 | if re.search(r'(?i)^tcp$', setproto): setproto = 'TCP' 469 | if re.search(r'(?i)^udp$', setproto): setproto = 'UDP' 470 | if re.search(r'(?i)^dns$', setproto): setproto = 'DNS' 471 | if re.search(r'(?i)^pay$', setproto) and re.search(r'(?i)^load$', setfield): setproto = 'Raw' 472 | 473 | if re.search(r'(?i)^ether$', searchproto): searchproto = 'Ether' 474 | if re.search(r'(?i)^ip$', searchproto): searchproto = 'IP' 475 | if re.search(r'(?i)^tcp$', searchproto): searchproto = 'TCP' 476 | if re.search(r'(?i)^udp$', searchproto): searchproto = 'UDP' 477 | if re.search(r'(?i)^dns$', searchproto): searchproto = 'DNS' 478 | if re.search(r'(?i)^pay$', searchproto) and re.search(r'(?i)^load$', searchfield): searchproto = 'Raw' 479 | 480 | if setproto == 'Raw' and searchproto == 'Raw': 481 | print('Replacing %s.%s with regex \'%s\' where %s.%s matches regex \'%s\'' % ( 482 | setproto, 483 | setfield, 484 | setvalue, 485 | searchproto, 486 | searchfield, 487 | searchvalue)) 488 | 489 | for packet in self.packets: 490 | if packet.haslayer(Raw): 491 | packet[Raw] = re.sub(searchvalue, setvalue, str(packet[Raw])) 492 | 493 | return 494 | 495 | else: 496 | print('Replacing %s.%s to \'%s\') where %s.%s is \'%s\'' % ( 497 | setproto, 498 | setfield, 499 | setvalue, 500 | searchproto, 501 | searchfield, 502 | searchvalue)) 503 | 504 | count = 0 505 | for packet in self.packets: 506 | if packet.haslayer(searchproto) and searchfield in packet[searchproto].fields.keys(): 507 | for field in packet[searchproto].fields.keys(): 508 | if field == searchfield: 509 | if searchproto == 'Ether': 510 | if searchfield == 'src': searchvalue = str(searchvalue) 511 | elif searchfield == 'dst': searchvalue = str(searchvalue) 512 | else: searchvalue = int(searchvalue) 513 | elif searchproto == 'IP': 514 | if searchfield == 'src': searchvalue = str(searchvalue) 515 | elif searchfield == 'dst': searchvalue = str(searchvalue) 516 | elif searchfield == 'options': searchvalue = str(searchvalue) 517 | else: searchvalue = int(searchvalue) 518 | else: 519 | searchvalue = int(searchvalue) 520 | 521 | if packet[searchproto].fields[field] == searchvalue: 522 | if packet.haslayer(setproto) and setfield in packet[setproto].fields.keys(): 523 | for key in packet[setproto].fields.keys(): 524 | if setproto == 'Ether': 525 | if key == 'src' and setfield == 'src': 526 | oldeditvalue = packet[setproto].src 527 | packet[setproto].src = str(setvalue) 528 | elif key == 'dst' and setfield == 'dst': 529 | oldeditvalue = packet[setproto].dst 530 | packet[setproto].dst = str(setvalue) 531 | elif key == 'type' and setfield == 'type': 532 | oldeditvalue = packet[setproto].type 533 | packet[setproto].type = int(setvalue) 534 | 535 | elif setproto == 'IP': 536 | if key == 'version' and setfield == 'version': 537 | oldeditvalue = packet[setproto].version 538 | packet[setproto].version = int(setvalue) 539 | elif key == 'ihl' and setfield == 'ihl': 540 | oldeditvalue = packet[setproto].ihl 541 | packet[setproto].ihl = int(setvalue) 542 | elif key == 'tos' and setfield == 'tos': 543 | oldeditvalue = packet[setproto].tos 544 | packet[setproto].tos = int(setvalue) 545 | elif key == 'len' and setfield == 'len': 546 | oldeditvalue = packet[setproto].len 547 | packet[setproto].len = int(setvalue) 548 | elif key == 'id' and setfield == 'id': 549 | oldeditvalue = packet[setproto].id 550 | packet[setproto].id = int(setvalue) 551 | elif key == 'flags' and setfield == 'flags': 552 | oldeditvalue = packet[setproto].flags 553 | packet[setproto].flags = int(setvalue) 554 | elif key == 'frag' and setfield == 'frag': 555 | oldeditvalue = packet[setproto].frag 556 | packet[IP].frag = int(setvalue) 557 | elif key == 'ttl' and setfield == 'ttl': 558 | oldeditvalue = packet[setproto].ttl 559 | packet[setproto].ttl = int(setvalue) 560 | elif key == 'proto' and setfield == 'proto': 561 | oldeditvalue = packet[setproto].proto 562 | packet[setproto].proto = int(setvalue) 563 | elif key == 'chksum' and setfield == 'chksum': 564 | oldeditvalue = packet[setproto].chksum 565 | packet[setproto].chksum = int(setvalue) 566 | self.customipchksum = True 567 | elif key == 'src' and setfield == 'src': 568 | oldeditvalue = packet[setproto].src 569 | packet[setproto].src = str(setvalue) 570 | elif key == 'dst' and setfield == 'dst': 571 | oldeditvalue = packet[setproto].dst 572 | packet[setproto].dst = str(setvalue) 573 | elif key == 'options' and setfield == 'options': 574 | oldeditvalue = packet[setproto].options 575 | packet[setproto].options = str(setvalue) 576 | 577 | elif setproto == 'TCP': 578 | if key == 'sport' and setfield == 'sport': 579 | oldeditvalue = packet[setproto].sport 580 | packet[setproto].sport = int(setvalue) 581 | if key == 'dport' and setfield == 'dport': 582 | oldeditvalue = packet[setproto].dport 583 | packet[setproto].dport = int(setvalue) 584 | if key == 'seq' and setfield == 'seq': 585 | oldeditvalue = packet[setproto].seq 586 | packet[setproto].seq = int(setvalue) 587 | if key == 'ack' and setfield == 'ack': 588 | oldeditvalue = packet[setproto].ack 589 | packet[setproto].ack = int(setvalue) 590 | if key == 'dataofs' and setfield == 'dataofs': 591 | oldeditvalue = packet[setproto].dataofs 592 | packet[setproto].dataofs = int(setvalue) 593 | if key == 'reserved' and setfield == 'reserved': 594 | oldeditvalue = packet[setproto].reserved 595 | packet[setproto].reserved = int(setvalue) 596 | if key == 'flags' and setfield == 'flags': 597 | oldeditvalue = packet[setproto].flags 598 | packet[setproto].flags = int(setvalue) 599 | if key == 'window' and setfield == 'window': 600 | oldeditvalue = packet[setproto].window 601 | packet[setproto].window = int(setvalue) 602 | if key == 'chksum' and setfield == 'chksum': 603 | oldeditvalue = packet[setproto].chksum 604 | packet[setproto].chksum = int(setvalue) 605 | self.customtcpchksum = True 606 | if key == 'urgptr' and setfield == 'urgptr': 607 | oldeditvalue = packet[setproto].urgptr 608 | packet[setproto].urgptr = int(setvalue) 609 | if key == 'options' and setfield == 'options': 610 | oldeditvalue = packet[setproto].options 611 | packet[setproto].options = int(setvalue) 612 | 613 | print('%6d: %s.%s: %s -> %s (coz %s.%s is %s)' % ( 614 | count, 615 | setproto, 616 | setfield, 617 | oldeditvalue, 618 | setvalue, 619 | searchproto, 620 | searchfield, 621 | searchvalue)) 622 | 623 | count += 1 624 | 625 | elif self.editid != -1: 626 | editkey = setargslist[0] 627 | editproto = editkey.split('.')[0] 628 | editfield = editkey.split('.')[1] 629 | editvalue = setargslist[1] 630 | 631 | if re.search(r'(?i)^ether$', editproto): 632 | editproto = 'Ether' 633 | if self.packets[self.editid].haslayer(editproto): 634 | if re.search(r'(?i)^src$', editfield): 635 | oldeditvalue = self.packets[self.editid][Ether].src 636 | self.packets[self.editid].getlayer(Ether).src = str(editvalue) 637 | print('%6d: Ether.src: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(Ether).src)) 638 | elif re.search(r'(?i)^dst$', editfield): 639 | oldeditvalue = self.packets[self.editid][Ether].dst 640 | self.packets[self.editid].getlayer(Ether).dst = str(editvalue) 641 | print('%6d: Ether.dst: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(Ether).dst)) 642 | elif re.search(r'(?i)^type$', editfield): 643 | oldeditvalue = self.packets[self.editid][Ether].type 644 | self.packets[self.editid].getlayer(Ether).type = int(editvalue) 645 | print('%6d: Ether.type: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(Ether).type)) 646 | 647 | elif re.search(r'(?i)^ip$', editproto): 648 | editproto = 'IP' 649 | if self.packets[self.editid].haslayer(editproto): 650 | if re.search(r'(?i)^version$', editfield): 651 | oldeditvalue = self.packets[self.editid][IP].version 652 | self.packets[self.editid].getlayer(IP).version = int(editvalue) 653 | print('%6d: IP.version: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).version)) 654 | elif re.search(r'(?i)^ihl$', editfield): 655 | oldeditvalue = self.packets[self.editid][IP].ihl 656 | self.packets[self.editid].getlayer(IP).ihl = int(editvalue) 657 | print('%6d: IP.ihl: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).ihl)) 658 | elif re.search(r'(?i)^tos$', editfield): 659 | oldeditvalue = self.packets[self.editid][IP].tos 660 | self.packets[self.editid].getlayer(IP).tos = int(editvalue) 661 | print('%6d: IP.tos: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).tos)) 662 | elif re.search(r'(?i)^len$', editfield): 663 | oldeditvalue = self.packets[self.editid][IP].len 664 | self.packets[self.editid].getlayer(IP).len = int(editvalue) 665 | print('%6d: IP.len: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).len)) 666 | elif re.search(r'(?i)^id$', editfield): 667 | oldeditvalue = self.packets[self.editid][IP].id 668 | self.packets[self.editid].getlayer(IP).id = int(editvalue) 669 | print('%6d: IP.id: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).id)) 670 | elif re.search(r'(?i)^flags$', editfield): 671 | oldeditvalue = self.packets[self.editid][IP].flags 672 | self.packets[self.editid].getlayer(IP).flags = int(editvalue) 673 | print('%6d: IP.flags: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).flags)) 674 | elif re.search(r'(?i)^frag$', editfield): 675 | oldeditvalue = self.packets[self.editid][IP].frag 676 | self.packets[self.editid].getlayer(IP).frag = int(editvalue) 677 | print('%6d: IP.frag: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).frag)) 678 | elif re.search(r'(?i)^ttl$', editfield): 679 | oldeditvalue = self.packets[self.editid][IP].ttl 680 | self.packets[self.editid].getlayer(IP).ttl = int(editvalue) 681 | print('%6d: IP.ttl: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).ttl)) 682 | elif re.search(r'(?i)^proto$', editfield): 683 | oldeditvalue = self.packets[self.editid][IP].proto 684 | self.packets[self.editid].getlayer(IP).proto = int(editvalue) 685 | print('%6d: IP.proto: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).proto)) 686 | elif re.search(r'(?i)^chksum$', editfield): 687 | oldeditvalue = self.packets[self.editid][IP].chksum 688 | self.packets[self.editid].getlayer(IP).chksum = int(editvalue) 689 | print('%6d: IP.chksum: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).chksum)) 690 | elif re.search(r'(?i)^src$', editfield): 691 | oldeditvalue = self.packets[self.editid][IP].src 692 | self.packets[self.editid].getlayer(IP).src = str(editvalue) 693 | print('%6d: IP.src: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).src)) 694 | elif re.search(r'(?i)^dst$', editfield): 695 | oldeditvalue = self.packets[self.editid][IP].dst 696 | self.packets[self.editid].getlayer(IP).dst = str(editvalue) 697 | print('%6d: IP.dst: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).dst)) 698 | elif re.search(r'(?i)^options$', editfield): 699 | oldeditvalue = self.packets[self.editid][IP].options 700 | self.packets[self.editid].getlayer(IP).options = str(editvalue) 701 | print('%6d: IP.options: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(IP).options)) 702 | 703 | elif re.search(r'(?i)^tcp$', editproto): 704 | editproto = 'TCP' 705 | if self.packets[self.editid].haslayer(editproto): 706 | if re.search(r'(?i)^sport$', editfield): 707 | oldeditvalue = self.packets[self.editid][TCP].sport 708 | self.packets[self.editid].getlayer(TCP).sport = int(editvalue) 709 | print('%6d: TCP.sport: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).sport)) 710 | elif re.search(r'(?i)^dport$', editfield): 711 | oldeditvalue = self.packets[self.editid][TCP].dport 712 | self.packets[self.editid].getlayer(TCP).dport = int(editvalue) 713 | print('%6d: TCP.dport: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).dport)) 714 | elif re.search(r'(?i)^seq$', editfield): 715 | oldeditvalue = self.packets[self.editid][TCP].seq 716 | self.packets[self.editid].getlayer(TCP).seq = int(editvalue) 717 | print('%6d: TCP.seq: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).seq)) 718 | elif re.search(r'(?i)^ack$', editfield): 719 | oldeditvalue = self.packets[self.editid][TCP].ack 720 | self.packets[self.editid].getlayer(TCP).ack = int(editvalue) 721 | print('%6d: TCP.ack: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).ack)) 722 | elif re.search(r'(?i)^dataofs$', editfield): 723 | oldeditvalue = self.packets[self.editid][TCP].dataofs 724 | self.packets[self.editid].getlayer(TCP).dataofs = int(editvalue) 725 | print('%6d: TCP.dataofs: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).dataofs)) 726 | elif re.search(r'(?i)^reserved$', editfield): 727 | oldeditvalue = self.packets[self.editid][TCP].reserved 728 | self.packets[self.editid].getlayer(TCP).reserved = int(editvalue) 729 | print('%6d: TCP.reserved: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).reserved)) 730 | elif re.search(r'(?i)^ttl$', editfield): 731 | oldeditvalue = self.packets[self.editid][TCP].ttl 732 | self.packets[self.editid].getlayer(TCP).ttl = int(editvalue) 733 | print('%6d: TCP.ttl: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).ttl)) 734 | elif re.search(r'(?i)^flags$', editfield): 735 | oldeditvalue = self.packets[self.editid][TCP].flags 736 | self.packets[self.editid].getlayer(TCP).flags = int(editvalue) 737 | print('%6d: TCP.flags: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).flags)) 738 | elif re.search(r'(?i)^window$', editfield): 739 | oldeditvalue = self.packets[self.editid][TCP].window 740 | self.packets[self.editid].getlayer(TCP).window = int(editvalue) 741 | print('%6d: TCP.window: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).window)) 742 | elif re.search(r'(?i)^chksum$', editfield): 743 | oldeditvalue = self.packets[self.editid][TCP].chksum 744 | self.packets[self.editid].getlayer(TCP).chksum = int(editvalue) 745 | print('%6d: TCP.chksum: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).chksum)) 746 | elif re.search(r'(?i)^urgptr$', editfield): 747 | oldeditvalue = self.packets[self.editid][TCP].urgptr 748 | self.packets[self.editid].getlayer(TCP).urgptr = int(editvalue) 749 | print('%6d: TCP.urgptr: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).urgptr)) 750 | elif re.search(r'(?i)^options$', editfield): 751 | oldeditvalue = self.packets[self.editid][TCP].options 752 | #self.packets[self.editid].getlayer(TCP).options = dict(editvalue) 753 | print('%6d: TCP.options: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(TCP).options)) 754 | 755 | elif re.search(r'(?i)^udp$', editproto): 756 | editproto = 'UDP' 757 | if self.packets[self.editid].haslayer(editproto): 758 | if re.search(r'(?i)^sport$', editfield): 759 | oldeditvalue = self.packets[self.editid][UDP].sport 760 | self.packets[self.editid].getlayer(UDP).sport = int(editvalue) 761 | print('%6d: UDP.sport: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(UDP).sport)) 762 | elif re.search(r'(?i)^dport$', editfield): 763 | oldeditvalue = self.packets[self.editid][UDP].dport 764 | self.packets[self.editid].getlayer(UDP).dport = int(editvalue) 765 | print('%6d: UDP.sport: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(UDP).dport)) 766 | if re.search(r'(?i)^len$', editfield): 767 | oldeditvalue = self.packets[self.editid][UDP].len 768 | self.packets[self.editid].getlayer(UDP).len = int(editvalue) 769 | print('%6d: UDP.len: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(UDP).len)) 770 | elif re.search(r'(?i)^chksum$', editfield): 771 | oldeditvalue = self.packets[self.editid][UDP].chksum 772 | self.packets[self.editid].getlayer(UDP).chksum = int(editvalue) 773 | print('%6d: UDP.chksum: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(UDP).chksum)) 774 | 775 | elif re.search(r'(?i)^dns$', editproto): 776 | editproto = 'DNS' 777 | if self.packets[self.editid].haslayer(editproto): 778 | if re.search(r'(?i)^id$', editfield): 779 | oldeditvalue = self.packets[self.editid][DNS].id 780 | self.packets[self.editid].getlayer(DNS).id = int(editvalue) 781 | print('%6d: DNS.id: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).id)) 782 | elif re.search(r'(?i)^qr$', editfield): 783 | oldeditvalue = self.packets[self.editid][DNS].qr 784 | self.packets[self.editid].getlayer(DNS).qr = int(editvalue) 785 | print('%6d: DNS.qr: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).qr)) 786 | elif re.search(r'(?i)^opcode$', editfield): 787 | oldeditvalue = self.packets[self.editid][DNS].opcode 788 | self.packets[self.editid].getlayer(DNS).opcode = int(editvalue) 789 | print('%6d: DNS.opcode: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).opcode)) 790 | elif re.search(r'(?i)^aa$', editfield): 791 | oldeditvalue = self.packets[self.editid][DNS].aa 792 | self.packets[self.editid].getlayer(DNS).aa = int(editvalue) 793 | print('%6d: DNS.aa: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).aa)) 794 | elif re.search(r'(?i)^tc$', editfield): 795 | oldeditvalue = self.packets[self.editid][DNS].tc 796 | self.packets[self.editid].getlayer(DNS).tc = int(editvalue) 797 | print('%6d: DNS.tc: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).tc)) 798 | elif re.search(r'(?i)^rd$', editfield): 799 | oldeditvalue = self.packets[self.editid][DNS].rd 800 | self.packets[self.editid].getlayer(DNS).rd = int(editvalue) 801 | print('%6d: DNS.rd: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).rd)) 802 | elif re.search(r'(?i)^ra$', editfield): 803 | oldeditvalue = self.packets[self.editid][DNS].ra 804 | self.packets[self.editid].getlayer(DNS).ra = int(editvalue) 805 | print('%6d: DNS.ra: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).ra)) 806 | elif re.search(r'(?i)^z$', editfield): 807 | oldeditvalue = self.packets[self.editid][DNS].z 808 | self.packets[self.editid].getlayer(DNS).z = int(editvalue) 809 | print('%6d: DNS.z: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).z)) 810 | elif re.search(r'(?i)^rcode$', editfield): 811 | oldeditvalue = self.packets[self.editid][DNS].rcode 812 | self.packets[self.editid].getlayer(DNS).rcode = int(editvalue) 813 | print('%6d: DNS.rcode: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).rcode)) 814 | elif re.search(r'(?i)^qdcount$', editfield): 815 | oldeditvalue = self.packets[self.editid][DNS].qdcount 816 | self.packets[self.editid].getlayer(DNS).qdcount = int(editvalue) 817 | print('%6d: DNS.qdcount: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).qdcount)) 818 | elif re.search(r'(?i)^ancount$', editfield): 819 | oldeditvalue = self.packets[self.editid][DNS].ancount 820 | self.packets[self.editid].getlayer(DNS).ancount = int(editvalue) 821 | print('%6d: DNS.ancount: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).ancount)) 822 | elif re.search(r'(?i)^nscount$', editfield): 823 | oldeditvalue = self.packets[self.editid][DNS].nscount 824 | self.packets[self.editid].getlayer(DNS).nscount = int(editvalue) 825 | print('%6d: DNS.nscount: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).nscount)) 826 | elif re.search(r'(?i)^arcount$', editfield): 827 | oldeditvalue = self.packets[self.editid][DNS].arcount 828 | self.packets[self.editid].getlayer(DNS).arcount = int(editvalue) 829 | print('%6d: DNS.arcount: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).arcount)) 830 | elif re.search(r'(?i)^qd$', editfield): 831 | oldeditvalue = self.packets[self.editid][DNS].qd 832 | self.packets[self.editid].getlayer(DNS).qd = int(editvalue) 833 | print('%6d: DNS.qd: %s -> %s' % (self.editid, ''.join(c for c in str(oldeditvalue) if 31 < ord(c) < 127), self.packets[self.editid].getlayer(DNS).qd)) 834 | elif re.search(r'(?i)^an$', editfield): 835 | oldeditvalue = self.packets[self.editid][DNS].an 836 | self.packets[self.editid].getlayer(DNS).an = int(editvalue) 837 | print('%6d: DNS.an: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).an)) 838 | elif re.search(r'(?i)^ns$', editfield): 839 | oldeditvalue = self.packets[self.editid][DNS].ns 840 | self.packets[self.editid].getlayer(DNS).ns = int(editvalue) 841 | print('%6d: DNS.ns: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).ns)) 842 | elif re.search(r'(?i)^ar$', editfield): 843 | oldeditvalue = self.packets[self.editid][DNS].ar 844 | self.packets[self.editid].getlayer(DNS).ar = int(editvalue) 845 | print('%6d: DNS.ar: %s -> %s' % (self.editid, oldeditvalue, self.packets[self.editid].getlayer(DNS).ar)) 846 | 847 | elif re.search(r'(?i)^pay$', editproto) and re.search(r'(?i)^load$', editfield): 848 | if Raw in self.packets[self.editid]: 849 | self.packets[self.editid][Raw] = editvalue 850 | print('%6d: pay.load: %s' % (self.editid, self.packets[self.editid].getlayer(Raw))) 851 | 852 | else: 853 | print('Unknown proto: %s' % (editproto)) 854 | 855 | else: 856 | print('No editid to set! Pass one as argument or use \'edit\' first.') 857 | else: 858 | self.help_set() 859 | return 860 | else: 861 | print('Nothing to set! Use \'analyze\' first.') 862 | 863 | def help_save(line): 864 | print('USAGE: save [packetid]') 865 | print('Save a packetid to pcap') 866 | print('Pass packet ranges as \'save 0-20\' | \'save 5-\' | \'save -10\' | \'save 3-7\'') 867 | print('Pass a list of packetids as \'save 3 5 6 10 12\'') 868 | print('To save all packets, use \'save\' without arguments') 869 | 870 | def do_save(self, line): 871 | if self.packets and len(self.packets) > 0: 872 | outpackets = [] 873 | if line != '': 874 | if re.search(r'(\d+)?\s*-\s*(\d+)?', line): 875 | offsetlist = re.findall(r'\d+', line) 876 | if len(offsetlist) == 0: 877 | self.help_save() 878 | return 879 | 880 | if len(offsetlist) > 1: 881 | start = int(offsetlist[0]) 882 | end = int(offsetlist[-1]) 883 | 884 | elif re.search(r'\d+\s*-', line): 885 | start = int(re.findall(r'\d+', line)[0]) 886 | end = (len(self.packets) - 1) 887 | 888 | elif re.search(r'\s*-\s*\d+', line): 889 | print('') 890 | end = int(re.findall(r'\d+', line)[0]) 891 | start = 0 892 | 893 | if start < 0 or start > (len(self.packets) - 1): 894 | start = 0 895 | if end >= (len(self.packets) - 1): 896 | end = (len(self.packets) - 1) 897 | 898 | if start > end: 899 | start = start ^ end 900 | end = start ^ end 901 | start = start ^ end 902 | 903 | for id in range(start, end+1): 904 | outpackets.append(self.packets[id]) 905 | 906 | else: 907 | idlist = line.split() 908 | for id in idlist: 909 | id = int(id) 910 | if id >= 0 and id <= (len(self.packets) - 1): 911 | outpackets.append(self.packets[id]) 912 | 913 | elif self.editid != -1: 914 | outpackets.append(self.packets[self.editid]) 915 | 916 | else: 917 | for packet in self.packets: 918 | outpackets.append(packet) 919 | 920 | if not self.outpcap: 921 | pcapnamelist = self.inpcap.split('.') 922 | ext = pcapnamelist[-1] 923 | del pcapnamelist[-1] 924 | pcapnamelist.append('mod') 925 | pcapnamelist.append(ext) 926 | self.outpcap = '.'.join(pcapnamelist) 927 | 928 | wrpcap(self.outpcap, outpackets) 929 | print('Wrote %d packet(s) to %s' % (len(outpackets), self.outpcap)) 930 | 931 | else: 932 | print('Nothing to save! Use \'analyze\' first.') 933 | 934 | def help_commands(self): 935 | print('USAGE: commands') 936 | print('Show a listing of available pcapedit commands') 937 | 938 | def do_commands(self, line): 939 | print 940 | print('\t[01] analyze ......... load a pcap for analysis') 941 | print('\t[02] ls .............. list packet details') 942 | print('\t[03] summary ......... show summary of a packet') 943 | print('\t[04] hexdump ......... show hexdump of a packet') 944 | print('\t[05] pdfdump ......... dump packet to a PDF') 945 | print('\t[06] scapycmd ........ show Scapy command to generate a packet') 946 | print('\t[07] wireshark ....... show a packet in Wireshark') 947 | print('\t[08] edit ............ select a packet for set operations') 948 | print('\t[09] outpcap ......... set name for output pcap') 949 | print('\t[10] set ............. change value of a protocol field') 950 | print('\t[11] save ............ save packets to a pcap') 951 | print 952 | 953 | if __name__ == '__main__': 954 | ed = editor() 955 | ed.cmdloop() 956 | 957 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cmd2==0.8.9 2 | contextlib2==0.5.5 3 | enum34==1.1.6 4 | pyparsing==2.2.0 5 | pyperclip==1.6.4 6 | scapy==2.4.0 7 | six==1.11.0 8 | subprocess32==3.5.2 9 | wcwidth==0.1.7 10 | -------------------------------------------------------------------------------- /todo: -------------------------------------------------------------------------------- 1 | [ ] HTTP editing 2 | [x] outpcap command 3 | [ ] bpf command 4 | [x] regex to edit payload 5 | 6 | --------------------------------------------------------------------------------