├── .gitignore ├── CyberScan.py ├── GeoLiteCity.dat ├── LICENSE ├── PCAP Files └── test.pcap ├── README.md ├── banner.txt ├── doc └── Usage.md ├── images └── demo.png ├── libs ├── FileUtils.py ├── __init__.py └── colorama │ ├── __init__.py │ ├── ansi.py │ ├── ansitowin32.py │ ├── initialise.py │ ├── win32.py │ └── winterm.py ├── pygeoip ├── __init__.py ├── const.py ├── timezone.py └── util.py ├── scapy ├── __init__.py ├── all.py ├── ansmachine.py ├── arch │ ├── __init__.py │ ├── bsd.py │ ├── linux.py │ ├── pcapdnet.py │ ├── solaris.py │ ├── unix.py │ └── windows │ │ └── __init__.py ├── as_resolvers.py ├── asn1 │ ├── __init__.py │ ├── asn1.py │ ├── ber.py │ └── mib.py ├── asn1fields.py ├── asn1packet.py ├── automaton.py ├── autorun.py ├── base_classes.py ├── config.py ├── crypto │ ├── __init__.py │ └── cert.py ├── dadict.py ├── data.py ├── error.py ├── fields.py ├── layers │ ├── __init__.py │ ├── all.py │ ├── bluetooth.py │ ├── dhcp.py │ ├── dhcp6.py │ ├── dns.py │ ├── dot11.py │ ├── gprs.py │ ├── hsrp.py │ ├── inet.py │ ├── inet6.py │ ├── ir.py │ ├── isakmp.py │ ├── l2.py │ ├── l2tp.py │ ├── llmnr.py │ ├── mgcp.py │ ├── mobileip.py │ ├── netbios.py │ ├── netflow.py │ ├── ntp.py │ ├── pflog.py │ ├── ppp.py │ ├── radius.py │ ├── rip.py │ ├── rtp.py │ ├── sctp.py │ ├── sebek.py │ ├── skinny.py │ ├── smb.py │ ├── snmp.py │ ├── tftp.py │ ├── vrrp.py │ └── x509.py ├── main.py ├── modules │ ├── __init__.py │ ├── geoip.py │ ├── nmap.py │ ├── p0f.py │ ├── queso.py │ └── voip.py ├── packet.py ├── plist.py ├── pton_ntop.py ├── route.py ├── route6.py ├── sendrecv.py ├── supersocket.py ├── themes.py ├── tools │ ├── UTscapy.py │ ├── __init__.py │ └── check_asdis.py ├── utils.py ├── utils6.py └── volatile.py └── test.pcap /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /GeoLiteCity.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/medbenali/CyberScan/ca85794cfce5e83e9cc5fca1512ba6edf2f14dee/GeoLiteCity.dat -------------------------------------------------------------------------------- /PCAP Files/test.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/medbenali/CyberScan/ca85794cfce5e83e9cc5fca1512ba6edf2f14dee/PCAP Files/test.pcap -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CyberScan 2 | 3 | [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/License-GPL%20v3-red.svg)](http://www.gnu.org/licenses/gpl-3.0) 4 | 5 | CyberScan is an open source penetration testing tool that 6 | can analyse packets , decoding , scanning ports, pinging and geolocation of an IP including (latitude, longitude , region , country ...) 7 | 8 | Screenshots 9 | ---- 10 | 11 | ![Screenshot](https://github.com/medbenali/CyberScan/blob/master/images/demo.png) 12 | 13 | Operating Systems Supported 14 | ---- 15 | 16 | - Windows XP/7/8/8.1/10 17 | - GNU/Linux 18 | - MacOSX 19 | 20 | Installation 21 | ---- 22 | 23 | You can download CyberScan by cloning the [Git](https://github.com/medbenali/CyberScan) repository: 24 | 25 | git clone https://github.com/medbenali/CyberScan.git 26 | cd CyberScan/ 27 | python CyberScan.py -v 28 | 29 | CyberScan works out of the box with [Python](http://www.python.org/download/) version **2.6.x** and **2.7.x**. 30 | 31 | # The CyberScan Module Usage 32 | 33 | 34 | [CyberScan](https://github.com/medbenali/CyberScan) is able to send and capture packets of several protocols, forging and decoding them to be used to most network tasks such as scanning, pinging, probing, and attacks. 35 | 36 | Make sure you have CyberScan in your machine: 37 | 38 | ```sh 39 | $ git clone https://github.com/medbenali/CyberScan.git 40 | ``` 41 | 42 | You can test the installation firing up CyberScan iteratively. These are some useful functions: 43 | 44 | ```sh 45 | $ CyberScan -h 46 | ``` 47 | --- 48 | 49 | ## Pinging The Network 50 | 51 | We can perform **ping** operations with several protocols using CyberScan The fastest way to discover hosts on a local Ethernet network is to use ARP: 52 | 53 | ### ARP Ping 54 | 55 | ```sh 56 | $ CyberScan -s 192.168.1.0/24 -p arp 57 | [*] Starting Ping ARP for 192.168.1.0/24 58 | Begin emission: 59 | Finished to send 256 packets. 60 | 61 | Received 0 packets, got 0 answers, remaining 256 packets 62 | ``` 63 | 64 | ### ICMP Ping 65 | 66 | In other cases we can use ICMP ping: 67 | 68 | ```sh 69 | $ CyberScan -s 192.168.1.1-254 -p icmp 70 | [*] Starting Ping ARP for 192.168.1.0/24 71 | Begin emission: 72 | Finished to send 256 packets. 73 | 74 | Received 0 packets, got 0 answers, remaining 256 packets 75 | ``` 76 | 77 | ### TCP Ping 78 | 79 | In case when ICMP echo requests are blocked, we can still use TCP: 80 | 81 | ```sh 82 | $ CyberScan -s 192.168.1.1-254 -p tcp -d 80 83 | ``` 84 | 85 | ### UDP Ping 86 | 87 | Or even UDP (which produces ICMP port unreachable errors from live hosts). We can pick any port which is most likely to be closed, such as port 0: 88 | 89 | ```sh 90 | $ CyberScan -s 192.168.*.1-10 -p udp 91 | ``` 92 | 93 | --- 94 | 95 | ## Network Scanning 96 | 97 | ### Port Scanner 98 | 99 | In CyberSan Tool we can scan with or without specify start and end port 100 | 101 | ```sh 102 | $ CyberScan -s 192.168.1.1 -p scan -d 1 -t 100 103 | WARNING: No route found for IPv6 destination :: (no default route?) 104 | [*] CyberScan Port Scanner 105 | [*] Scanning 192.168.1.1 From Port 1 To 100: 106 | [*] Starting CyberScan 1.01 at 2017-07-14 14:00 CEST 107 | [*] Scan In Progress ... 108 | [*] Connecting To Port : 100 109 | [*] Scanning Completed at 2017-07-14 14:00 CEST 110 | [*] CyberScan done: 1IP address (1host up) scanned in 0.32 seconds 111 | [*] Open Ports: 112 | 23 TELNET: Open 113 | 53 DNS: Open 114 | 80 HTTP: Open 115 | ``` 116 | 117 | ```sh 118 | $ CyberScan -s 8.8.8.8 -p scan 119 | WARNING: No route found for IPv6 destination :: (no default route?) 120 | [*] CyberScan Port Scanner 121 | [*] Scanning For Most Common Ports On 8.8.8.8 122 | [*] Starting CyberScan 1.01 at 2017-07-14 14:03 CEST 123 | [*] Scan In Progress ... 124 | [*] Connecting To Port : 10000 109 110 123 137 138 139 143 156 2082 2083 2086 2087 21 22 23 25 3306 389 546 547 69 80 8443 993 995 125 | [*] Scanning Completed at 2017-07-14 14:03 CEST 126 | [*] CyberScan done: 1IP address (1host up) scanned in 13.11 seconds 127 | [*] Open Ports: 128 | 53 DNS: Open 129 | 443 HTTPS: Open 130 | ``` 131 | 132 | 133 | ------ 134 | ## Geolocalisation IP 135 | 136 | ```sh 137 | $ CyberScan -s 72.229.28.185 -p geoip 138 | WARNING: No route found for IPv6 destination :: (no default route?) 139 | [*] IP Address: 72.229.28.185 140 | [*] City: New York 141 | [*] Region Code: NY 142 | [*] Area Code: 212 143 | [*] Time Zone: America/New_York 144 | [*] Dma Code: 501 145 | [*] Metro Code: New York, NY 146 | [*] Latitude: 40.7605 147 | [*] Longitude: -73.9933 148 | [*] Zip Code: 10036 149 | [*] Country Name: United States 150 | [*] Country Code: US 151 | [*] Country Code3: USA 152 | [*] Continent: NA 153 | ``` 154 | 155 | ------ 156 | ## Analyzing and Decoding Packets 157 | 158 | CyberScan can analyse pcap files in order to extract and decode ethernet, ip, tcp, icmp, udp headers. 159 | 160 | ### Ethernet Headers 161 | 162 | ```sh 163 | $ CyberScan -f test.pcap -p eth 164 | WARNING: No route found for IPv6 destination :: (no default route?) 165 | ---------------------------------------- 166 | [*] Packet : 1 167 | [+] ### [ Ethernet ] ### 168 | [*] Mac Destination : 00:1f:f3:3c:e1:13 169 | [*] Mac Source : f8:1e:df:e5:84:3a 170 | [*] Ethernet Type : 2048 171 | ``` 172 | 173 | ### IP Headers 174 | 175 | ```sh 176 | $ CyberScan -f test.pcap -p ip 177 | WARNING: No route found for IPv6 destination :: (no default route?) 178 | ---------------------------------------- 179 | [*] Packet : 1 180 | [+] ###[ IP ] ### 181 | [*] IP Source : 172.16.11.12 182 | [*] IP Destination : 74.125.19.17 183 | [*] IP Version : 4 184 | [*] IP Ihl : 5 185 | [*] IP Tos : 0 186 | [*] IP Len : 79 187 | [*] IP Id : 56915 188 | [*] IP Flags : 2 189 | [*] IP Frag : 0 190 | [*] IP Ttl : 64 191 | [*] IP Protocol : 6 192 | [*] IP Chksum : 18347 193 | [*] IP Options : [] 194 | [*] IP Dump : 195 | 0000 45 00 00 4F DE 53 40 00 40 06 47 AB AC 10 0B 0C E..O.S@.@.G..... 196 | 0010 4A 7D 13 11 FC 35 01 BB C6 D9 14 D0 C5 1E 2D BF J}...5........-. 197 | 0020 80 18 FF FF CB 8C 00 00 01 01 08 0A 1A 7D 84 2C .............}., 198 | 0030 37 C5 58 B0 15 03 01 00 16 43 1A 88 1E FA 7A BC 7.X......C....z. 199 | 0040 22 6E E6 32 7A 53 47 00 A7 5D CC 64 EA 8E 92 "n.2zSG..].d... 200 | ``` 201 | 202 | ### TCP Headers 203 | 204 | ```sh 205 | $ CyberScan -f test.pcap -p tcp 206 | WARNING: No route found for IPv6 destination :: (no default route?) 207 | ---------------------------------------- 208 | [*] Packet : 1 209 | [+] ###[ TCP ] ### 210 | [*] TCP Source Port : 64565 211 | [*] TCP Destination Port : 443 212 | [*] TCP Seq : 3336115408 213 | [*] TCP Ack : 3307089343 214 | [*] TCP Dataofs : 8 215 | [*] TCP Reserved : 0 216 | [*] TCP Flags : 24 217 | [*] TCP Window : 65535 218 | [*] TCP Chksum : 52108 219 | [*] TCP Urgptr : 0 220 | [*] TCP Options : [('NOP', None), ('NOP', None), ('Timestamp', (444433452, 935680176))] 221 | [*] TCP Dump : 222 | 0000 FC 35 01 BB C6 D9 14 D0 C5 1E 2D BF 80 18 FF FF .5........-..... 223 | 0010 CB 8C 00 00 01 01 08 0A 1A 7D 84 2C 37 C5 58 B0 .........}.,7.X. 224 | ``` 225 | 226 | 227 | ### UDP Headers 228 | 229 | ```sh 230 | $ CyberScan -f test.pcap -p udp 231 | WARNING: No route found for IPv6 destination :: (no default route?) 232 | ---------------------------------------- 233 | [*] Packet : 1 234 | [+] ###[ UDP ] ### 235 | [*] UDP Source Port : 54639 236 | [*] UDP Destination Port : 53 237 | [*] UDP Len : 47 238 | [*] UDP Chksum : 30084 239 | [*] UDP Dump : 240 | 0000 D5 6F 00 35 00 2F 75 84 13 A2 01 00 00 01 00 00 .o.5./u......... 241 | 0010 00 00 00 00 04 65 38 37 32 01 67 0A 61 6B 61 6D .....e872.g.akam 242 | 0020 61 69 65 64 67 65 03 6E 65 74 00 00 01 00 01 aiedge.net..... 243 | ``` 244 | 245 | ### ICMP Headers 246 | 247 | ```sh 248 | $ CyberScan -f test.pcap -p icmp 249 | WARNING: No route found for IPv6 destination :: (no default route?) 250 | ---------------------------------------- 251 | [*] Packet : 1 252 | [+] ###[ ICMP ] ### 253 | [*] ICMP Type : 3 254 | [*] ICMP Code : 3 255 | [*] ICMP Chksum : 5296 256 | [*] ICMP Id : None 257 | [*] ICMP Seq : None 258 | [*] ICMP Dump : 259 | 0000 03 03 14 B0 00 00 00 00 45 00 00 43 C1 80 00 00 ........E..C.... 260 | 0010 40 11 4A FC AC 10 0B 01 AC 10 0B 0C 00 35 E7 E8 @.J..........5.. 261 | 0020 00 2F 00 00 ./.. 262 | ``` 263 | 264 | Contact 265 | ---- 266 | 267 | 268 | 269 | [10.1]: http://i.imgur.com/tXSoThF.png (twitter icon with padding) 270 | [20.1]: http://i.imgur.com/P3YfQoD.png (facebook icon with padding) 271 | [30.1]: http://i.imgur.com/0o48UoR.png (github icon with padding) 272 | 273 | 274 | 275 | 276 | 277 | 278 | [10]: https://twitter.com/007Hamoud 279 | [20]: https://www.facebook.com/hammouda.benali 280 | [30]: https://www.github.com/medbenali 281 | 282 | 283 | 284 | #### BEN ALI Mohamed 285 | [![alt text][10.1]][10] 286 | [![alt text][20.1]][20] 287 | [![alt text][30.1]][30] 288 | ##### Email : mohamed.benali@esprit.tn 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | -------------------------------------------------------------------------------- /banner.txt: -------------------------------------------------------------------------------- 1 | ____ _ 2 | / ___| _| |__ ___ _ __ ___ ___ __ _ _ __ 3 | | | | | | | '_ \ / _ \ '__/ __|/ __/ _` | '_ \ 4 | | |__| |_| | |_) | __/ | \__ \ (_| (_| | | | | v{MAYOR_VERSION}.{MINOR_VERSION}.{REVISION} 5 | \____\__, |_.__/ \___|_| |___/\___\__,_|_| |_| 6 | |___/ 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/Usage.md: -------------------------------------------------------------------------------- 1 | # The CyberScan Module Usage 2 | 3 | 4 | [CyberScan](https://github.com/medbenali/CyberScan) is able to send and capture packets of several protocols, forging and decoding them to be used to most network tasks such as scanning, pinging, probing, and attacks. 5 | 6 | Make sure you have CyberScan in your machine: 7 | 8 | ```sh 9 | $ git clone https://github.com/medbenali/CyberScan.git 10 | ``` 11 | 12 | You can test the installation firing up CyberScan iteratively. These are some useful functions: 13 | 14 | ```sh 15 | $ CyberScan -h 16 | ``` 17 | --- 18 | 19 | ## Pinging The Network 20 | 21 | We can perform **ping** operations with several protocols using CyberScan The fastest way to discover hosts on a local Ethernet network is to use ARP: 22 | 23 | ### ARP Ping 24 | 25 | ```sh 26 | $ CyberScan -s 192.168.1.0/24 -p arp 27 | [*] Starting Ping ARP for 192.168.1.0/24 28 | Begin emission: 29 | Finished to send 256 packets. 30 | 31 | Received 0 packets, got 0 answers, remaining 256 packets 32 | ``` 33 | 34 | ### ICMP Ping 35 | 36 | In other cases we can use ICMP ping: 37 | 38 | ```sh 39 | $ CyberScan -s 192.168.1.1-254 -p icmp 40 | [*] Starting Ping ARP for 192.168.1.0/24 41 | Begin emission: 42 | Finished to send 256 packets. 43 | 44 | Received 0 packets, got 0 answers, remaining 256 packets 45 | ``` 46 | 47 | ### TCP Ping 48 | 49 | In case when ICMP echo requests are blocked, we can still use TCP: 50 | 51 | ```sh 52 | $ CyberScan -s 192.168.1.1-254 -p tcp -d 80 53 | ``` 54 | 55 | ### UDP Ping 56 | 57 | Or even UDP (which produces ICMP port unreachable errors from live hosts). We can pick any port which is most likely to be closed, such as port 0: 58 | 59 | ```sh 60 | $ CyberScan -s 192.168.*.1-10 -p udp 61 | ``` 62 | 63 | --- 64 | 65 | ## Network Scanning 66 | 67 | ### Port Scanner 68 | 69 | In CyberSan Tool we can scan with or without specify start and end port 70 | 71 | ```sh 72 | $ CyberScan -s 192.168.1.1 -p scan -d 1 -t 100 73 | WARNING: No route found for IPv6 destination :: (no default route?) 74 | [*] CyberScan Port Scanner 75 | [*] Scanning 192.168.1.1 From Port 1 To 100: 76 | [*] Starting CyberScan 1.01 at 2017-07-14 14:00 CEST 77 | [*] Scan In Progress ... 78 | [*] Connecting To Port : 100 79 | [*] Scanning Completed at 2017-07-14 14:00 CEST 80 | [*] CyberScan done: 1IP address (1host up) scanned in 0.32 seconds 81 | [*] Open Ports: 82 | 23 TELNET: Open 83 | 53 DNS: Open 84 | 80 HTTP: Open 85 | ``` 86 | 87 | ```sh 88 | $ CyberScan -s 8.8.8.8 -p scan 89 | WARNING: No route found for IPv6 destination :: (no default route?) 90 | [*] CyberScan Port Scanner 91 | [*] Scanning For Most Common Ports On 8.8.8.8 92 | [*] Starting CyberScan 1.01 at 2017-07-14 14:03 CEST 93 | [*] Scan In Progress ... 94 | [*] Connecting To Port : 10000 109 110 123 137 138 139 143 156 2082 2083 2086 2087 21 22 23 25 3306 389 546 547 69 80 8443 993 995 95 | [*] Scanning Completed at 2017-07-14 14:03 CEST 96 | [*] CyberScan done: 1IP address (1host up) scanned in 13.11 seconds 97 | [*] Open Ports: 98 | 53 DNS: Open 99 | 443 HTTPS: Open 100 | ``` 101 | 102 | 103 | ------ 104 | ## Geolicalisation IP 105 | 106 | ```sh 107 | $ CyberScan -s 72.229.28.185 -p geoip 108 | WARNING: No route found for IPv6 destination :: (no default route?) 109 | [*] IP Adress: 72.229.28.185 110 | [*] City: New York 111 | [*] Region Code: NY 112 | [*] Area Code: 212 113 | [*] Time Zone: America/New_York 114 | [*] Dma Code: 501 115 | [*] Metro Code: New York, NY 116 | [*] Latitude: 40.7605 117 | [*] Longitude: -73.9933 118 | [*] Zip Code: 10036 119 | [*] Country Name: United States 120 | [*] Country Code: US 121 | [*] Country Code3: USA 122 | [*] Countinent: NA 123 | ``` 124 | 125 | ------ 126 | ## Analyzing and Decoding Packets 127 | 128 | CyberScan can analyse pcap files in order to extract and decode ethernet ,ip , tcp , icmp ,udp headrers . 129 | 130 | ### Ethernet Headers 131 | 132 | ```sh 133 | $ CyberScan -f test.pcap -p eth 134 | WARNING: No route found for IPv6 destination :: (no default route?) 135 | ---------------------------------------- 136 | [*] Packet : 1 137 | [+] ### [ Ethernet ] ### 138 | [*] Mac Destination : 00:1f:f3:3c:e1:13 139 | [*] Mac Source : f8:1e:df:e5:84:3a 140 | [*] Ethernet Type : 2048 141 | ``` 142 | 143 | ### IP Headers 144 | 145 | ```sh 146 | $ CyberScan -f test.pcap -p ip 147 | WARNING: No route found for IPv6 destination :: (no default route?) 148 | ---------------------------------------- 149 | [*] Packet : 1 150 | [+] ###[ IP ] ### 151 | [*] IP Source : 172.16.11.12 152 | [*] IP Destination : 74.125.19.17 153 | [*] IP Version : 4 154 | [*] IP Ihl : 5 155 | [*] IP Tos : 0 156 | [*] IP Len : 79 157 | [*] IP Id : 56915 158 | [*] IP Flags : 2 159 | [*] IP Frag : 0 160 | [*] IP Ttl : 64 161 | [*] IP Protocol : 6 162 | [*] IP Chksum : 18347 163 | [*] IP Options : [] 164 | [*] IP Dump : 165 | 0000 45 00 00 4F DE 53 40 00 40 06 47 AB AC 10 0B 0C E..O.S@.@.G..... 166 | 0010 4A 7D 13 11 FC 35 01 BB C6 D9 14 D0 C5 1E 2D BF J}...5........-. 167 | 0020 80 18 FF FF CB 8C 00 00 01 01 08 0A 1A 7D 84 2C .............}., 168 | 0030 37 C5 58 B0 15 03 01 00 16 43 1A 88 1E FA 7A BC 7.X......C....z. 169 | 0040 22 6E E6 32 7A 53 47 00 A7 5D CC 64 EA 8E 92 "n.2zSG..].d... 170 | ``` 171 | 172 | ### TCP Headers 173 | 174 | ```sh 175 | $ CyberScan -f test.pcap -p tcp 176 | WARNING: No route found for IPv6 destination :: (no default route?) 177 | ---------------------------------------- 178 | [*] Packet : 1 179 | [+] ###[ TCP ] ### 180 | [*] TCP Source Port : 64565 181 | [*] TCP Destination Port : 443 182 | [*] TCP Seq : 3336115408 183 | [*] TCP Ack : 3307089343 184 | [*] TCP Dataofs : 8 185 | [*] TCP Reserved : 0 186 | [*] TCP Flags : 24 187 | [*] TCP Window : 65535 188 | [*] TCP Chksum : 52108 189 | [*] TCP Urgptr : 0 190 | [*] TCP Options : [('NOP', None), ('NOP', None), ('Timestamp', (444433452, 935680176))] 191 | [*] TCP Dump : 192 | 0000 FC 35 01 BB C6 D9 14 D0 C5 1E 2D BF 80 18 FF FF .5........-..... 193 | 0010 CB 8C 00 00 01 01 08 0A 1A 7D 84 2C 37 C5 58 B0 .........}.,7.X. 194 | ``` 195 | 196 | 197 | ### UDP Headers 198 | 199 | ```sh 200 | $ CyberScan -f test.pcap -p udp 201 | WARNING: No route found for IPv6 destination :: (no default route?) 202 | ---------------------------------------- 203 | [*] Packet : 1 204 | [+] ###[ UDP ] ### 205 | [*] UDP Source Port : 54639 206 | [*] UDP Destination Port : 53 207 | [*] UDP Len : 47 208 | [*] UDP Chksum : 30084 209 | [*] UDP Dump : 210 | 0000 D5 6F 00 35 00 2F 75 84 13 A2 01 00 00 01 00 00 .o.5./u......... 211 | 0010 00 00 00 00 04 65 38 37 32 01 67 0A 61 6B 61 6D .....e872.g.akam 212 | 0020 61 69 65 64 67 65 03 6E 65 74 00 00 01 00 01 aiedge.net..... 213 | ``` 214 | 215 | ### ICMP Headers 216 | 217 | ```sh 218 | $ CyberScan -f test.pcap -p icmp 219 | WARNING: No route found for IPv6 destination :: (no default route?) 220 | ---------------------------------------- 221 | [*] Packet : 1 222 | [+] ###[ ICMP ] ### 223 | [*] ICMP Type : 3 224 | [*] ICMP Code : 3 225 | [*] ICMP Chksum : 5296 226 | [*] ICMP Id : None 227 | [*] ICMP Seq : None 228 | [*] ICMP Dump : 229 | 0000 03 03 14 B0 00 00 00 00 45 00 00 43 C1 80 00 00 ........E..C.... 230 | 0010 40 11 4A FC AC 10 0B 01 AC 10 0B 0C 00 35 E7 E8 @.J..........5.. 231 | 0020 00 2F 00 00 ./.. 232 | ``` 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/medbenali/CyberScan/ca85794cfce5e83e9cc5fca1512ba6edf2f14dee/images/demo.png -------------------------------------------------------------------------------- /libs/FileUtils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding utf-8 -*- 3 | # 4 | # This file is part of CyberScan 5 | # 6 | # CyberScan is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # CyberScan is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, 19 | # MA 02110-1301, USA. 20 | # 21 | # Author: Mohamed BEN ALI 22 | 23 | import os 24 | import os.path 25 | 26 | 27 | class File(object): 28 | def __init__(self, *pathComponents): 29 | self._path = FileUtils.buildPath(*pathComponents) 30 | self.content = None 31 | 32 | @property 33 | def path(self): 34 | return self._path 35 | 36 | @path.setter 37 | def path(self, value): 38 | raise NotImplemented 39 | 40 | def isValid(self): 41 | return FileUtils.isFile(self.path) 42 | 43 | def exists(self): 44 | return FileUtils.exists(self.path) 45 | 46 | def canRead(self): 47 | return FileUtils.canRead(self.path) 48 | 49 | def canWrite(self): 50 | return FileUtils.canWrite(self.path) 51 | 52 | def read(self): 53 | return FileUtils.read(self.path) 54 | 55 | def update(self): 56 | self.content = self.read() 57 | 58 | def content(self): 59 | if not self.content: 60 | self.content = FileUtils.read() 61 | return self.content() 62 | 63 | def getLines(self): 64 | for line in FileUtils.getLines(self.path): 65 | yield line 66 | 67 | def __cmp__(self, other): 68 | if not isinstance(other, File): 69 | raise NotImplemented 70 | return cmp(self.content(), other.content()) 71 | 72 | def __enter__(self): 73 | return self 74 | 75 | def __exit__(self, type, value, tb): 76 | pass 77 | 78 | 79 | class FileUtils(object): 80 | @staticmethod 81 | def buildPath(*pathComponents): 82 | if pathComponents: 83 | path = os.path.join(*pathComponents) 84 | else: 85 | path = '' 86 | return path 87 | 88 | @staticmethod 89 | def exists(fileName): 90 | return os.access(fileName, os.F_OK) 91 | 92 | @staticmethod 93 | def canRead(fileName): 94 | if not os.access(fileName, os.R_OK): 95 | return False 96 | try: 97 | with open(fileName): 98 | pass 99 | except IOError: 100 | return False 101 | return True 102 | 103 | @staticmethod 104 | def canWrite(fileName): 105 | return os.access(fileName, os.W_OK) 106 | 107 | @staticmethod 108 | def read(fileName): 109 | result = '' 110 | with open(fileName, 'r') as fd: 111 | for line in fd.readlines(): 112 | result += line 113 | return result 114 | 115 | @staticmethod 116 | def getLines(fileName): 117 | with open(fileName, 'r', errors="replace") as fd: 118 | return fd.read().splitlines() 119 | 120 | @staticmethod 121 | def isDir(fileName): 122 | return os.path.isdir(fileName) 123 | 124 | @staticmethod 125 | def isFile(fileName): 126 | return os.path.isfile(fileName) 127 | 128 | @staticmethod 129 | def createDirectory(directory): 130 | if not FileUtils.exists(directory): 131 | os.makedirs(directory) 132 | 133 | @staticmethod 134 | def sizeHuman(num): 135 | base = 1024 136 | for x in ['B ', 'KB', 'MB', 'GB']: 137 | if num < base and num > -base: 138 | return "%3.0f%s" % (num, x) 139 | num /= base 140 | return "%3.0f %s" % (num, 'TB') 141 | 142 | @staticmethod 143 | def writeLines(fileName, lines): 144 | content = None 145 | if type(lines) is list: 146 | content = "\n".join(lines) 147 | else: 148 | content = lines 149 | with open(fileName, "w") as f: 150 | f.writelines(content) 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /libs/__init__.py: -------------------------------------------------------------------------------- 1 | from .FileUtils import * 2 | pass 3 | -------------------------------------------------------------------------------- /libs/colorama/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | from .initialise import init, deinit, reinit, colorama_text 3 | from .ansi import Fore, Back, Style, Cursor 4 | from .ansitowin32 import AnsiToWin32 5 | 6 | __version__ = '0.3.7' 7 | 8 | -------------------------------------------------------------------------------- /libs/colorama/ansi.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | ''' 3 | This module generates ANSI character codes to printing colors to terminals. 4 | See: http://en.wikipedia.org/wiki/ANSI_escape_code 5 | ''' 6 | 7 | CSI = '\033[' 8 | OSC = '\033]' 9 | BEL = '\007' 10 | 11 | 12 | def code_to_chars(code): 13 | return CSI + str(code) + 'm' 14 | 15 | def set_title(title): 16 | return OSC + '2;' + title + BEL 17 | 18 | def clear_screen(mode=2): 19 | return CSI + str(mode) + 'J' 20 | 21 | def clear_line(mode=2): 22 | return CSI + str(mode) + 'K' 23 | 24 | 25 | class AnsiCodes(object): 26 | def __init__(self): 27 | # the subclasses declare class attributes which are numbers. 28 | # Upon instantiation we define instance attributes, which are the same 29 | # as the class attributes but wrapped with the ANSI escape sequence 30 | for name in dir(self): 31 | if not name.startswith('_'): 32 | value = getattr(self, name) 33 | setattr(self, name, code_to_chars(value)) 34 | 35 | 36 | class AnsiCursor(object): 37 | def UP(self, n=1): 38 | return CSI + str(n) + 'A' 39 | def DOWN(self, n=1): 40 | return CSI + str(n) + 'B' 41 | def FORWARD(self, n=1): 42 | return CSI + str(n) + 'C' 43 | def BACK(self, n=1): 44 | return CSI + str(n) + 'D' 45 | def POS(self, x=1, y=1): 46 | return CSI + str(y) + ';' + str(x) + 'H' 47 | 48 | 49 | class AnsiFore(AnsiCodes): 50 | BLACK = 30 51 | RED = 31 52 | GREEN = 32 53 | YELLOW = 33 54 | BLUE = 34 55 | MAGENTA = 35 56 | CYAN = 36 57 | WHITE = 37 58 | RESET = 39 59 | 60 | # These are fairly well supported, but not part of the standard. 61 | LIGHTBLACK_EX = 90 62 | LIGHTRED_EX = 91 63 | LIGHTGREEN_EX = 92 64 | LIGHTYELLOW_EX = 93 65 | LIGHTBLUE_EX = 94 66 | LIGHTMAGENTA_EX = 95 67 | LIGHTCYAN_EX = 96 68 | LIGHTWHITE_EX = 97 69 | 70 | 71 | class AnsiBack(AnsiCodes): 72 | BLACK = 40 73 | RED = 41 74 | GREEN = 42 75 | YELLOW = 43 76 | BLUE = 44 77 | MAGENTA = 45 78 | CYAN = 46 79 | WHITE = 47 80 | RESET = 49 81 | 82 | # These are fairly well supported, but not part of the standard. 83 | LIGHTBLACK_EX = 100 84 | LIGHTRED_EX = 101 85 | LIGHTGREEN_EX = 102 86 | LIGHTYELLOW_EX = 103 87 | LIGHTBLUE_EX = 104 88 | LIGHTMAGENTA_EX = 105 89 | LIGHTCYAN_EX = 106 90 | LIGHTWHITE_EX = 107 91 | 92 | 93 | class AnsiStyle(AnsiCodes): 94 | BRIGHT = 1 95 | DIM = 2 96 | NORMAL = 22 97 | RESET_ALL = 0 98 | 99 | Fore = AnsiFore() 100 | Back = AnsiBack() 101 | Style = AnsiStyle() 102 | Cursor = AnsiCursor() 103 | -------------------------------------------------------------------------------- /libs/colorama/ansitowin32.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | import re 3 | import sys 4 | import os 5 | 6 | from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style 7 | from .winterm import WinTerm, WinColor, WinStyle 8 | from .win32 import windll, winapi_test 9 | 10 | 11 | winterm = None 12 | if windll is not None: 13 | winterm = WinTerm() 14 | 15 | 16 | def is_stream_closed(stream): 17 | return not hasattr(stream, 'closed') or stream.closed 18 | 19 | 20 | def is_a_tty(stream): 21 | return hasattr(stream, 'isatty') and stream.isatty() 22 | 23 | 24 | class StreamWrapper(object): 25 | ''' 26 | Wraps a stream (such as stdout), acting as a transparent proxy for all 27 | attribute access apart from method 'write()', which is delegated to our 28 | Converter instance. 29 | ''' 30 | def __init__(self, wrapped, converter): 31 | # double-underscore everything to prevent clashes with names of 32 | # attributes on the wrapped stream object. 33 | self.__wrapped = wrapped 34 | self.__convertor = converter 35 | 36 | def __getattr__(self, name): 37 | return getattr(self.__wrapped, name) 38 | 39 | def write(self, text): 40 | self.__convertor.write(text) 41 | 42 | def fileno(): 43 | raise OSError() 44 | 45 | 46 | class AnsiToWin32(object): 47 | ''' 48 | Implements a 'write()' method which, on Windows, will strip ANSI character 49 | sequences from the text, and if outputting to a tty, will convert them into 50 | win32 function calls. 51 | ''' 52 | ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer 53 | ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command 54 | 55 | def __init__(self, wrapped, convert=None, strip=None, autoreset=False): 56 | # The wrapped stream (normally sys.stdout or sys.stderr) 57 | self.wrapped = wrapped 58 | 59 | # should we reset colors to defaults after every .write() 60 | self.autoreset = autoreset 61 | 62 | # create the proxy wrapping our output stream 63 | self.stream = StreamWrapper(wrapped, self) 64 | 65 | on_windows = os.name == 'nt' 66 | # We test if the WinAPI works, because even if we are on Windows 67 | # we may be using a terminal that doesn't support the WinAPI 68 | # (e.g. Cygwin Terminal). In this case it's up to the terminal 69 | # to support the ANSI codes. 70 | conversion_supported = on_windows and winapi_test() 71 | 72 | # should we strip ANSI sequences from our output? 73 | if strip is None: 74 | strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) 75 | self.strip = strip 76 | 77 | # should we should convert ANSI sequences into win32 calls? 78 | if convert is None: 79 | convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) 80 | self.convert = convert 81 | 82 | # dict of ansi codes to win32 functions and parameters 83 | self.win32_calls = self.get_win32_calls() 84 | 85 | # are we wrapping stderr? 86 | self.on_stderr = self.wrapped is sys.stderr 87 | 88 | def should_wrap(self): 89 | ''' 90 | True if this class is actually needed. If false, then the output 91 | stream will not be affected, nor will win32 calls be issued, so 92 | wrapping stdout is not actually required. This will generally be 93 | False on non-Windows platforms, unless optional functionality like 94 | autoreset has been requested using kwargs to init() 95 | ''' 96 | return self.convert or self.strip or self.autoreset 97 | 98 | def get_win32_calls(self): 99 | if self.convert and winterm: 100 | return { 101 | AnsiStyle.RESET_ALL: (winterm.reset_all, ), 102 | AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), 103 | AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), 104 | AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), 105 | AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), 106 | AnsiFore.RED: (winterm.fore, WinColor.RED), 107 | AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), 108 | AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), 109 | AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), 110 | AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), 111 | AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), 112 | AnsiFore.WHITE: (winterm.fore, WinColor.GREY), 113 | AnsiFore.RESET: (winterm.fore, ), 114 | AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), 115 | AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), 116 | AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), 117 | AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), 118 | AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), 119 | AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), 120 | AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), 121 | AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), 122 | AnsiBack.BLACK: (winterm.back, WinColor.BLACK), 123 | AnsiBack.RED: (winterm.back, WinColor.RED), 124 | AnsiBack.GREEN: (winterm.back, WinColor.GREEN), 125 | AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), 126 | AnsiBack.BLUE: (winterm.back, WinColor.BLUE), 127 | AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), 128 | AnsiBack.CYAN: (winterm.back, WinColor.CYAN), 129 | AnsiBack.WHITE: (winterm.back, WinColor.GREY), 130 | AnsiBack.RESET: (winterm.back, ), 131 | AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), 132 | AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), 133 | AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), 134 | AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), 135 | AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), 136 | AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), 137 | AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), 138 | AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), 139 | } 140 | return dict() 141 | 142 | def write(self, text): 143 | if self.strip or self.convert: 144 | self.write_and_convert(text) 145 | else: 146 | self.wrapped.write(text) 147 | self.wrapped.flush() 148 | if self.autoreset: 149 | self.reset_all() 150 | 151 | 152 | def reset_all(self): 153 | if self.convert: 154 | self.call_win32('m', (0,)) 155 | elif not self.strip and not is_stream_closed(self.wrapped): 156 | self.wrapped.write(Style.RESET_ALL) 157 | 158 | 159 | def write_and_convert(self, text): 160 | ''' 161 | Write the given text to our wrapped stream, stripping any ANSI 162 | sequences from the text, and optionally converting them into win32 163 | calls. 164 | ''' 165 | cursor = 0 166 | text = self.convert_osc(text) 167 | for match in self.ANSI_CSI_RE.finditer(text): 168 | start, end = match.span() 169 | self.write_plain_text(text, cursor, start) 170 | self.convert_ansi(*match.groups()) 171 | cursor = end 172 | self.write_plain_text(text, cursor, len(text)) 173 | 174 | 175 | def write_plain_text(self, text, start, end): 176 | if start < end: 177 | self.wrapped.write(text[start:end]) 178 | self.wrapped.flush() 179 | 180 | 181 | def convert_ansi(self, paramstring, command): 182 | if self.convert: 183 | params = self.extract_params(command, paramstring) 184 | self.call_win32(command, params) 185 | 186 | 187 | def extract_params(self, command, paramstring): 188 | if command in 'Hf': 189 | params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) 190 | while len(params) < 2: 191 | # defaults: 192 | params = params + (1,) 193 | else: 194 | params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) 195 | if len(params) == 0: 196 | # defaults: 197 | if command in 'JKm': 198 | params = (0,) 199 | elif command in 'ABCD': 200 | params = (1,) 201 | 202 | return params 203 | 204 | 205 | def call_win32(self, command, params): 206 | if command == 'm': 207 | for param in params: 208 | if param in self.win32_calls: 209 | func_args = self.win32_calls[param] 210 | func = func_args[0] 211 | args = func_args[1:] 212 | kwargs = dict(on_stderr=self.on_stderr) 213 | func(*args, **kwargs) 214 | elif command in 'J': 215 | winterm.erase_screen(params[0], on_stderr=self.on_stderr) 216 | elif command in 'K': 217 | winterm.erase_line(params[0], on_stderr=self.on_stderr) 218 | elif command in 'Hf': # cursor position - absolute 219 | winterm.set_cursor_position(params, on_stderr=self.on_stderr) 220 | elif command in 'ABCD': # cursor position - relative 221 | n = params[0] 222 | # A - up, B - down, C - forward, D - back 223 | x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] 224 | winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) 225 | 226 | 227 | def convert_osc(self, text): 228 | for match in self.ANSI_OSC_RE.finditer(text): 229 | start, end = match.span() 230 | text = text[:start] + text[end:] 231 | paramstring, command = match.groups() 232 | if command in '\x07': # \x07 = BEL 233 | params = paramstring.split(";") 234 | # 0 - change title and icon (we will only change title) 235 | # 1 - change icon (we don't support this) 236 | # 2 - change title 237 | if params[0] in '02': 238 | winterm.set_title(params[1]) 239 | return text 240 | -------------------------------------------------------------------------------- /libs/colorama/initialise.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | import atexit 3 | import contextlib 4 | import sys 5 | 6 | from .ansitowin32 import AnsiToWin32 7 | 8 | 9 | orig_stdout = None 10 | orig_stderr = None 11 | 12 | wrapped_stdout = None 13 | wrapped_stderr = None 14 | 15 | atexit_done = False 16 | 17 | 18 | def reset_all(): 19 | if AnsiToWin32 is not None: # Issue #74: objects might become None at exit 20 | AnsiToWin32(orig_stdout).reset_all() 21 | 22 | 23 | def init(autoreset=False, convert=None, strip=None, wrap=True): 24 | 25 | if not wrap and any([autoreset, convert, strip]): 26 | raise ValueError('wrap=False conflicts with any other arg=True') 27 | 28 | global wrapped_stdout, wrapped_stderr 29 | global orig_stdout, orig_stderr 30 | 31 | orig_stdout = sys.stdout 32 | orig_stderr = sys.stderr 33 | 34 | if sys.stdout is None: 35 | wrapped_stdout = None 36 | else: 37 | sys.stdout = wrapped_stdout = \ 38 | wrap_stream(orig_stdout, convert, strip, autoreset, wrap) 39 | if sys.stderr is None: 40 | wrapped_stderr = None 41 | else: 42 | sys.stderr = wrapped_stderr = \ 43 | wrap_stream(orig_stderr, convert, strip, autoreset, wrap) 44 | 45 | global atexit_done 46 | if not atexit_done: 47 | atexit.register(reset_all) 48 | atexit_done = True 49 | 50 | 51 | def deinit(): 52 | if orig_stdout is not None: 53 | sys.stdout = orig_stdout 54 | if orig_stderr is not None: 55 | sys.stderr = orig_stderr 56 | 57 | 58 | @contextlib.contextmanager 59 | def colorama_text(*args, **kwargs): 60 | init(*args, **kwargs) 61 | try: 62 | yield 63 | finally: 64 | deinit() 65 | 66 | 67 | def reinit(): 68 | if wrapped_stdout is not None: 69 | sys.stdout = wrapped_stdout 70 | if wrapped_stderr is not None: 71 | sys.stderr = wrapped_stderr 72 | 73 | 74 | def wrap_stream(stream, convert, strip, autoreset, wrap): 75 | if wrap: 76 | wrapper = AnsiToWin32(stream, 77 | convert=convert, strip=strip, autoreset=autoreset) 78 | if wrapper.should_wrap(): 79 | stream = wrapper.stream 80 | return stream 81 | 82 | 83 | -------------------------------------------------------------------------------- /libs/colorama/win32.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | 3 | # from winbase.h 4 | STDOUT = -11 5 | STDERR = -12 6 | 7 | try: 8 | import ctypes 9 | from ctypes import LibraryLoader 10 | windll = LibraryLoader(ctypes.WinDLL) 11 | from ctypes import wintypes 12 | except (AttributeError, ImportError): 13 | windll = None 14 | SetConsoleTextAttribute = lambda *_: None 15 | winapi_test = lambda *_: None 16 | else: 17 | from ctypes import byref, Structure, c_char, POINTER 18 | 19 | COORD = wintypes._COORD 20 | 21 | class CONSOLE_SCREEN_BUFFER_INFO(Structure): 22 | """struct in wincon.h.""" 23 | _fields_ = [ 24 | ("dwSize", COORD), 25 | ("dwCursorPosition", COORD), 26 | ("wAttributes", wintypes.WORD), 27 | ("srWindow", wintypes.SMALL_RECT), 28 | ("dwMaximumWindowSize", COORD), 29 | ] 30 | def __str__(self): 31 | return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( 32 | self.dwSize.Y, self.dwSize.X 33 | , self.dwCursorPosition.Y, self.dwCursorPosition.X 34 | , self.wAttributes 35 | , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right 36 | , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X 37 | ) 38 | 39 | _GetStdHandle = windll.kernel32.GetStdHandle 40 | _GetStdHandle.argtypes = [ 41 | wintypes.DWORD, 42 | ] 43 | _GetStdHandle.restype = wintypes.HANDLE 44 | 45 | _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo 46 | _GetConsoleScreenBufferInfo.argtypes = [ 47 | wintypes.HANDLE, 48 | POINTER(CONSOLE_SCREEN_BUFFER_INFO), 49 | ] 50 | _GetConsoleScreenBufferInfo.restype = wintypes.BOOL 51 | 52 | _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute 53 | _SetConsoleTextAttribute.argtypes = [ 54 | wintypes.HANDLE, 55 | wintypes.WORD, 56 | ] 57 | _SetConsoleTextAttribute.restype = wintypes.BOOL 58 | 59 | _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition 60 | _SetConsoleCursorPosition.argtypes = [ 61 | wintypes.HANDLE, 62 | COORD, 63 | ] 64 | _SetConsoleCursorPosition.restype = wintypes.BOOL 65 | 66 | _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA 67 | _FillConsoleOutputCharacterA.argtypes = [ 68 | wintypes.HANDLE, 69 | c_char, 70 | wintypes.DWORD, 71 | COORD, 72 | POINTER(wintypes.DWORD), 73 | ] 74 | _FillConsoleOutputCharacterA.restype = wintypes.BOOL 75 | 76 | _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute 77 | _FillConsoleOutputAttribute.argtypes = [ 78 | wintypes.HANDLE, 79 | wintypes.WORD, 80 | wintypes.DWORD, 81 | COORD, 82 | POINTER(wintypes.DWORD), 83 | ] 84 | _FillConsoleOutputAttribute.restype = wintypes.BOOL 85 | 86 | _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW 87 | _SetConsoleTitleW.argtypes = [ 88 | wintypes.LPCWSTR 89 | ] 90 | _SetConsoleTitleW.restype = wintypes.BOOL 91 | 92 | handles = { 93 | STDOUT: _GetStdHandle(STDOUT), 94 | STDERR: _GetStdHandle(STDERR), 95 | } 96 | 97 | def _winapi_test(handle): 98 | csbi = CONSOLE_SCREEN_BUFFER_INFO() 99 | success = _GetConsoleScreenBufferInfo( 100 | handle, byref(csbi)) 101 | return bool(success) 102 | 103 | def winapi_test(): 104 | return any(_winapi_test(h) for h in handles.values()) 105 | 106 | def GetConsoleScreenBufferInfo(stream_id=STDOUT): 107 | handle = handles[stream_id] 108 | csbi = CONSOLE_SCREEN_BUFFER_INFO() 109 | success = _GetConsoleScreenBufferInfo( 110 | handle, byref(csbi)) 111 | return csbi 112 | 113 | def SetConsoleTextAttribute(stream_id, attrs): 114 | handle = handles[stream_id] 115 | return _SetConsoleTextAttribute(handle, attrs) 116 | 117 | def SetConsoleCursorPosition(stream_id, position, adjust=True): 118 | position = COORD(*position) 119 | # If the position is out of range, do nothing. 120 | if position.Y <= 0 or position.X <= 0: 121 | return 122 | # Adjust for Windows' SetConsoleCursorPosition: 123 | # 1. being 0-based, while ANSI is 1-based. 124 | # 2. expecting (x,y), while ANSI uses (y,x). 125 | adjusted_position = COORD(position.Y - 1, position.X - 1) 126 | if adjust: 127 | # Adjust for viewport's scroll position 128 | sr = GetConsoleScreenBufferInfo(STDOUT).srWindow 129 | adjusted_position.Y += sr.Top 130 | adjusted_position.X += sr.Left 131 | # Resume normal processing 132 | handle = handles[stream_id] 133 | return _SetConsoleCursorPosition(handle, adjusted_position) 134 | 135 | def FillConsoleOutputCharacter(stream_id, char, length, start): 136 | handle = handles[stream_id] 137 | char = c_char(char.encode()) 138 | length = wintypes.DWORD(length) 139 | num_written = wintypes.DWORD(0) 140 | # Note that this is hard-coded for ANSI (vs wide) bytes. 141 | success = _FillConsoleOutputCharacterA( 142 | handle, char, length, start, byref(num_written)) 143 | return num_written.value 144 | 145 | def FillConsoleOutputAttribute(stream_id, attr, length, start): 146 | ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' 147 | handle = handles[stream_id] 148 | attribute = wintypes.WORD(attr) 149 | length = wintypes.DWORD(length) 150 | num_written = wintypes.DWORD(0) 151 | # Note that this is hard-coded for ANSI (vs wide) bytes. 152 | return _FillConsoleOutputAttribute( 153 | handle, attribute, length, start, byref(num_written)) 154 | 155 | def SetConsoleTitle(title): 156 | return _SetConsoleTitleW(title) 157 | -------------------------------------------------------------------------------- /libs/colorama/winterm.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | from . import win32 3 | 4 | 5 | # from wincon.h 6 | class WinColor(object): 7 | BLACK = 0 8 | BLUE = 1 9 | GREEN = 2 10 | CYAN = 3 11 | RED = 4 12 | MAGENTA = 5 13 | YELLOW = 6 14 | GREY = 7 15 | 16 | # from wincon.h 17 | class WinStyle(object): 18 | NORMAL = 0x00 # dim text, dim background 19 | BRIGHT = 0x08 # bright text, dim background 20 | BRIGHT_BACKGROUND = 0x80 # dim text, bright background 21 | 22 | class WinTerm(object): 23 | 24 | def __init__(self): 25 | self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes 26 | self.set_attrs(self._default) 27 | self._default_fore = self._fore 28 | self._default_back = self._back 29 | self._default_style = self._style 30 | # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. 31 | # So that LIGHT_EX colors and BRIGHT style do not clobber each other, 32 | # we track them separately, since LIGHT_EX is overwritten by Fore/Back 33 | # and BRIGHT is overwritten by Style codes. 34 | self._light = 0 35 | 36 | def get_attrs(self): 37 | return self._fore + self._back * 16 + (self._style | self._light) 38 | 39 | def set_attrs(self, value): 40 | self._fore = value & 7 41 | self._back = (value >> 4) & 7 42 | self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) 43 | 44 | def reset_all(self, on_stderr=None): 45 | self.set_attrs(self._default) 46 | self.set_console(attrs=self._default) 47 | 48 | def fore(self, fore=None, light=False, on_stderr=False): 49 | if fore is None: 50 | fore = self._default_fore 51 | self._fore = fore 52 | # Emulate LIGHT_EX with BRIGHT Style 53 | if light: 54 | self._light |= WinStyle.BRIGHT 55 | else: 56 | self._light &= ~WinStyle.BRIGHT 57 | self.set_console(on_stderr=on_stderr) 58 | 59 | def back(self, back=None, light=False, on_stderr=False): 60 | if back is None: 61 | back = self._default_back 62 | self._back = back 63 | # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style 64 | if light: 65 | self._light |= WinStyle.BRIGHT_BACKGROUND 66 | else: 67 | self._light &= ~WinStyle.BRIGHT_BACKGROUND 68 | self.set_console(on_stderr=on_stderr) 69 | 70 | def style(self, style=None, on_stderr=False): 71 | if style is None: 72 | style = self._default_style 73 | self._style = style 74 | self.set_console(on_stderr=on_stderr) 75 | 76 | def set_console(self, attrs=None, on_stderr=False): 77 | if attrs is None: 78 | attrs = self.get_attrs() 79 | handle = win32.STDOUT 80 | if on_stderr: 81 | handle = win32.STDERR 82 | win32.SetConsoleTextAttribute(handle, attrs) 83 | 84 | def get_position(self, handle): 85 | position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition 86 | # Because Windows coordinates are 0-based, 87 | # and win32.SetConsoleCursorPosition expects 1-based. 88 | position.X += 1 89 | position.Y += 1 90 | return position 91 | 92 | def set_cursor_position(self, position=None, on_stderr=False): 93 | if position is None: 94 | # I'm not currently tracking the position, so there is no default. 95 | # position = self.get_position() 96 | return 97 | handle = win32.STDOUT 98 | if on_stderr: 99 | handle = win32.STDERR 100 | win32.SetConsoleCursorPosition(handle, position) 101 | 102 | def cursor_adjust(self, x, y, on_stderr=False): 103 | handle = win32.STDOUT 104 | if on_stderr: 105 | handle = win32.STDERR 106 | position = self.get_position(handle) 107 | adjusted_position = (position.Y + y, position.X + x) 108 | win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) 109 | 110 | def erase_screen(self, mode=0, on_stderr=False): 111 | # 0 should clear from the cursor to the end of the screen. 112 | # 1 should clear from the cursor to the beginning of the screen. 113 | # 2 should clear the entire screen, and move cursor to (1,1) 114 | handle = win32.STDOUT 115 | if on_stderr: 116 | handle = win32.STDERR 117 | csbi = win32.GetConsoleScreenBufferInfo(handle) 118 | # get the number of character cells in the current buffer 119 | cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y 120 | # get number of character cells before current cursor position 121 | cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X 122 | if mode == 0: 123 | from_coord = csbi.dwCursorPosition 124 | cells_to_erase = cells_in_screen - cells_before_cursor 125 | if mode == 1: 126 | from_coord = win32.COORD(0, 0) 127 | cells_to_erase = cells_before_cursor 128 | elif mode == 2: 129 | from_coord = win32.COORD(0, 0) 130 | cells_to_erase = cells_in_screen 131 | # fill the entire screen with blanks 132 | win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) 133 | # now set the buffer's attributes accordingly 134 | win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) 135 | if mode == 2: 136 | # put the cursor where needed 137 | win32.SetConsoleCursorPosition(handle, (1, 1)) 138 | 139 | def erase_line(self, mode=0, on_stderr=False): 140 | # 0 should clear from the cursor to the end of the line. 141 | # 1 should clear from the cursor to the beginning of the line. 142 | # 2 should clear the entire line. 143 | handle = win32.STDOUT 144 | if on_stderr: 145 | handle = win32.STDERR 146 | csbi = win32.GetConsoleScreenBufferInfo(handle) 147 | if mode == 0: 148 | from_coord = csbi.dwCursorPosition 149 | cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X 150 | if mode == 1: 151 | from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) 152 | cells_to_erase = csbi.dwCursorPosition.X 153 | elif mode == 2: 154 | from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) 155 | cells_to_erase = csbi.dwSize.X 156 | # fill the entire screen with blanks 157 | win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) 158 | # now set the buffer's attributes accordingly 159 | win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) 160 | 161 | def set_title(self, title): 162 | win32.SetConsoleTitle(title) 163 | -------------------------------------------------------------------------------- /pygeoip/util.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Copyright (c) 2010-2014 Jennifer Ennis, William Tisäter. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program. If not, see . 17 | """ 18 | 19 | import socket 20 | import binascii 21 | 22 | try: 23 | from StringIO import StringIO 24 | except ImportError: 25 | from io import StringIO, BytesIO 26 | 27 | from pygeoip import const 28 | 29 | 30 | def ip2long(ip): 31 | """ 32 | Wrapper function for IPv4 and IPv6 converters. 33 | 34 | :arg ip: IPv4 or IPv6 address 35 | """ 36 | try: 37 | return int(binascii.hexlify(socket.inet_aton(ip)), 16) 38 | except socket.error: 39 | return int(binascii.hexlify(socket.inet_pton(socket.AF_INET6, ip)), 16) 40 | 41 | 42 | def str2fp(data): 43 | """ 44 | Convert bytes data to file handle object (StringIO or BytesIO). 45 | 46 | :arg data: String data to transform 47 | """ 48 | return BytesIO(bytearray(data, const.ENCODING)) if const.PY3 else StringIO(data) 49 | -------------------------------------------------------------------------------- /scapy/__init__.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Scapy: create, send, sniff, dissect and manipulate network packets. 8 | 9 | Usable either from an interactive console or as a Python library. 10 | http://www.secdev.org/projects/scapy 11 | """ 12 | 13 | if __name__ == "__main__": 14 | from scapy.main import interact 15 | interact() 16 | -------------------------------------------------------------------------------- /scapy/all.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Aggregate top level objects from all Scapy modules. 8 | """ 9 | 10 | from base_classes import * 11 | from config import * 12 | from dadict import * 13 | from data import * 14 | from error import * 15 | from themes import * 16 | from arch import * 17 | 18 | from plist import * 19 | from fields import * 20 | from packet import * 21 | from asn1fields import * 22 | from asn1packet import * 23 | 24 | from utils import * 25 | from route import * 26 | if conf.ipv6_enabled: 27 | from utils6 import * 28 | from route6 import * 29 | from sendrecv import * 30 | from supersocket import * 31 | from volatile import * 32 | from as_resolvers import * 33 | 34 | from ansmachine import * 35 | from automaton import * 36 | from autorun import * 37 | 38 | from main import * 39 | 40 | from layers.all import * 41 | 42 | from asn1.asn1 import * 43 | from asn1.ber import * 44 | from asn1.mib import * 45 | 46 | from crypto import * 47 | -------------------------------------------------------------------------------- /scapy/ansmachine.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Answering machines. 8 | """ 9 | 10 | ######################## 11 | ## Answering machines ## 12 | ######################## 13 | 14 | from sendrecv import send,sendp,sniff 15 | from config import conf 16 | from error import log_interactive 17 | 18 | class ReferenceAM(type): 19 | def __new__(cls, name, bases, dct): 20 | o = super(ReferenceAM, cls).__new__(cls, name, bases, dct) 21 | if o.function_name: 22 | globals()[o.function_name] = lambda o=o,*args,**kargs: o(*args,**kargs)() 23 | return o 24 | 25 | 26 | class AnsweringMachine(object): 27 | __metaclass__ = ReferenceAM 28 | function_name = "" 29 | filter = None 30 | sniff_options = { "store":0 } 31 | sniff_options_list = [ "store", "iface", "count", "promisc", "filter", "type", "prn", "stop_filter" ] 32 | send_options = { "verbose":0 } 33 | send_options_list = ["iface", "inter", "loop", "verbose"] 34 | send_function = staticmethod(send) 35 | 36 | 37 | def __init__(self, **kargs): 38 | self.mode = 0 39 | if self.filter: 40 | kargs.setdefault("filter",self.filter) 41 | kargs.setdefault("prn", self.reply) 42 | self.optam1 = {} 43 | self.optam2 = {} 44 | self.optam0 = {} 45 | doptsend,doptsniff = self.parse_all_options(1, kargs) 46 | self.defoptsend = self.send_options.copy() 47 | self.defoptsend.update(doptsend) 48 | self.defoptsniff = self.sniff_options.copy() 49 | self.defoptsniff.update(doptsniff) 50 | self.optsend,self.optsniff = [{},{}] 51 | 52 | def __getattr__(self, attr): 53 | for d in [self.optam2, self.optam1]: 54 | if attr in d: 55 | return d[attr] 56 | raise AttributeError,attr 57 | 58 | def __setattr__(self, attr, val): 59 | mode = self.__dict__.get("mode",0) 60 | if mode == 0: 61 | self.__dict__[attr] = val 62 | else: 63 | [self.optam1, self.optam2][mode-1][attr] = val 64 | 65 | def parse_options(self): 66 | pass 67 | 68 | def parse_all_options(self, mode, kargs): 69 | sniffopt = {} 70 | sendopt = {} 71 | for k in kargs.keys(): 72 | if k in self.sniff_options_list: 73 | sniffopt[k] = kargs[k] 74 | if k in self.send_options_list: 75 | sendopt[k] = kargs[k] 76 | if k in self.sniff_options_list+self.send_options_list: 77 | del(kargs[k]) 78 | if mode != 2 or kargs: 79 | if mode == 1: 80 | self.optam0 = kargs 81 | elif mode == 2 and kargs: 82 | k = self.optam0.copy() 83 | k.update(kargs) 84 | self.parse_options(**k) 85 | kargs = k 86 | omode = self.__dict__.get("mode",0) 87 | self.__dict__["mode"] = mode 88 | self.parse_options(**kargs) 89 | self.__dict__["mode"] = omode 90 | return sendopt,sniffopt 91 | 92 | def is_request(self, req): 93 | return 1 94 | 95 | def make_reply(self, req): 96 | return req 97 | 98 | def send_reply(self, reply): 99 | self.send_function(reply, **self.optsend) 100 | 101 | def print_reply(self, req, reply): 102 | print "%s ==> %s" % (req.summary(),reply.summary()) 103 | 104 | def reply(self, pkt): 105 | if not self.is_request(pkt): 106 | return 107 | reply = self.make_reply(pkt) 108 | self.send_reply(reply) 109 | if conf.verb >= 0: 110 | self.print_reply(pkt, reply) 111 | 112 | def run(self, *args, **kargs): 113 | log_interactive.warning("run() method deprecated. The intance is now callable") 114 | self(*args,**kargs) 115 | 116 | def __call__(self, *args, **kargs): 117 | optsend,optsniff = self.parse_all_options(2,kargs) 118 | self.optsend=self.defoptsend.copy() 119 | self.optsend.update(optsend) 120 | self.optsniff=self.defoptsniff.copy() 121 | self.optsniff.update(optsniff) 122 | 123 | try: 124 | self.sniff() 125 | except KeyboardInterrupt: 126 | print "Interrupted by user" 127 | 128 | def sniff(self): 129 | sniff(**self.optsniff) 130 | 131 | -------------------------------------------------------------------------------- /scapy/arch/__init__.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Operating system specific functionality. 8 | """ 9 | 10 | 11 | import sys,os,socket 12 | from scapy.error import * 13 | import scapy.config 14 | 15 | try: 16 | import Gnuplot 17 | GNUPLOT=1 18 | except ImportError: 19 | log_loading.info("Can't import python gnuplot wrapper . Won't be able to plot.") 20 | GNUPLOT=0 21 | 22 | try: 23 | import pyx 24 | PYX=1 25 | except ImportError: 26 | log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump().") 27 | PYX=0 28 | 29 | 30 | def str2mac(s): 31 | return ("%02x:"*6)[:-1] % tuple(map(ord, s)) 32 | 33 | 34 | 35 | def get_if_addr(iff): 36 | return socket.inet_ntoa(get_if_raw_addr(iff)) 37 | 38 | def get_if_hwaddr(iff): 39 | addrfamily, mac = get_if_raw_hwaddr(iff) 40 | if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]: 41 | return str2mac(mac) 42 | else: 43 | raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily,iff)) 44 | 45 | 46 | LINUX=sys.platform.startswith("linux") 47 | OPENBSD=sys.platform.startswith("openbsd") 48 | FREEBSD=sys.platform.startswith("freebsd") 49 | NETBSD = sys.platform.startswith("netbsd") 50 | DARWIN=sys.platform.startswith("darwin") 51 | SOLARIS=sys.platform.startswith("sunos") 52 | WINDOWS=sys.platform.startswith("win32") 53 | 54 | X86_64 = not WINDOWS and (os.uname()[4] == 'x86_64') 55 | 56 | 57 | # Next step is to import following architecture specific functions: 58 | # def get_if_raw_hwaddr(iff) 59 | # def get_if_raw_addr(iff): 60 | # def get_if_list(): 61 | # def get_working_if(): 62 | # def attach_filter(s, filter): 63 | # def set_promisc(s,iff,val=1): 64 | # def read_routes(): 65 | # def get_if(iff,cmd): 66 | # def get_if_index(iff): 67 | 68 | 69 | 70 | if LINUX: 71 | from linux import * 72 | if scapy.config.conf.use_pcap or scapy.config.conf.use_dnet: 73 | from pcapdnet import * 74 | elif OPENBSD or FREEBSD or NETBSD or DARWIN: 75 | from bsd import * 76 | elif SOLARIS: 77 | from solaris import * 78 | elif WINDOWS: 79 | from windows import * 80 | 81 | if scapy.config.conf.iface is None: 82 | scapy.config.conf.iface = LOOPBACK_NAME 83 | 84 | 85 | def get_if_raw_addr6(iff): 86 | """ 87 | Returns the main global unicast address associated with provided 88 | interface, in network format. If no global address is found, None 89 | is returned. 90 | """ 91 | r = filter(lambda x: x[2] == iff and x[1] == IPV6_ADDR_GLOBAL, in6_getifaddr()) 92 | if len(r) == 0: 93 | return None 94 | else: 95 | r = r[0][0] 96 | return inet_pton(socket.AF_INET6, r) 97 | -------------------------------------------------------------------------------- /scapy/arch/bsd.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Support for BSD-like operating systems such as FreeBSD, OpenBSD and Mac OS X. 8 | """ 9 | 10 | LOOPBACK_NAME="lo0" 11 | 12 | from unix import * 13 | -------------------------------------------------------------------------------- /scapy/arch/solaris.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Customization for the Solaris operation system. 8 | """ 9 | 10 | # IPPROTO_GRE is missing on Solaris 11 | import socket 12 | socket.IPPROTO_GRE = 47 13 | 14 | LOOPBACK_NAME="lo0" 15 | 16 | from unix import * 17 | -------------------------------------------------------------------------------- /scapy/arch/unix.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Common customizations for all Unix-like operating systems other than Linux 8 | """ 9 | 10 | import sys,os,struct,socket,time 11 | from fcntl import ioctl 12 | from scapy.error import warning 13 | import scapy.config 14 | import scapy.utils 15 | import scapy.utils6 16 | import scapy.arch 17 | 18 | scapy.config.conf.use_pcap = 1 19 | scapy.config.conf.use_dnet = 1 20 | from pcapdnet import * 21 | 22 | 23 | 24 | 25 | 26 | ################## 27 | ## Routes stuff ## 28 | ################## 29 | 30 | 31 | def read_routes(): 32 | if scapy.arch.SOLARIS: 33 | f=os.popen("netstat -rvn") # -f inet 34 | elif scapy.arch.FREEBSD: 35 | f=os.popen("netstat -rnW") # -W to handle long interface names 36 | else: 37 | f=os.popen("netstat -rn") # -f inet 38 | ok = 0 39 | mtu_present = False 40 | prio_present = False 41 | routes = [] 42 | pending_if = [] 43 | for l in f.readlines(): 44 | if not l: 45 | break 46 | l = l.strip() 47 | if l.find("----") >= 0: # a separation line 48 | continue 49 | if not ok: 50 | if l.find("Destination") >= 0: 51 | ok = 1 52 | mtu_present = l.find("Mtu") >= 0 53 | prio_present = l.find("Prio") >= 0 54 | continue 55 | if not l: 56 | break 57 | if scapy.arch.SOLARIS: 58 | lspl = l.split() 59 | if len(lspl) == 10: 60 | dest,mask,gw,netif,mxfrg,rtt,ref,flg = lspl[:8] 61 | else: # missing interface 62 | dest,mask,gw,mxfrg,rtt,ref,flg = lspl[:7] 63 | netif=None 64 | else: 65 | rt = l.split() 66 | dest,gw,flg = rt[:3] 67 | netif = rt[5+mtu_present+prio_present] 68 | if flg.find("Lc") >= 0: 69 | continue 70 | if dest == "default": 71 | dest = 0L 72 | netmask = 0L 73 | else: 74 | if scapy.arch.SOLARIS: 75 | netmask = scapy.utils.atol(mask) 76 | elif "/" in dest: 77 | dest,netmask = dest.split("/") 78 | netmask = scapy.utils.itom(int(netmask)) 79 | else: 80 | netmask = scapy.utils.itom((dest.count(".") + 1) * 8) 81 | dest += ".0"*(3-dest.count(".")) 82 | dest = scapy.utils.atol(dest) 83 | if not "G" in flg: 84 | gw = '0.0.0.0' 85 | if netif is not None: 86 | ifaddr = scapy.arch.get_if_addr(netif) 87 | routes.append((dest,netmask,gw,netif,ifaddr)) 88 | else: 89 | pending_if.append((dest,netmask,gw)) 90 | f.close() 91 | 92 | # On Solaris, netstat does not provide output interfaces for some routes 93 | # We need to parse completely the routing table to route their gw and 94 | # know their output interface 95 | for dest,netmask,gw in pending_if: 96 | gw_l = scapy.utils.atol(gw) 97 | max_rtmask,gw_if,gw_if_addr, = 0,None,None 98 | for rtdst,rtmask,_,rtif,rtaddr in routes[:]: 99 | if gw_l & rtmask == rtdst: 100 | if rtmask >= max_rtmask: 101 | max_rtmask = rtmask 102 | gw_if = rtif 103 | gw_if_addr = rtaddr 104 | if gw_if: 105 | routes.append((dest,netmask,gw,gw_if,gw_if_addr)) 106 | else: 107 | warning("Did not find output interface to reach gateway %s" % gw) 108 | 109 | return routes 110 | 111 | ############ 112 | ### IPv6 ### 113 | ############ 114 | 115 | def in6_getifaddr(): 116 | """ 117 | Returns a list of 3-tuples of the form (addr, scope, iface) where 118 | 'addr' is the address of scope 'scope' associated to the interface 119 | 'ifcace'. 120 | 121 | This is the list of all addresses of all interfaces available on 122 | the system. 123 | """ 124 | 125 | ret = [] 126 | i = dnet.intf() 127 | for int in i: 128 | ifname = int['name'] 129 | v6 = [] 130 | if int.has_key('alias_addrs'): 131 | v6 = int['alias_addrs'] 132 | for a in v6: 133 | if a.type != dnet.ADDR_TYPE_IP6: 134 | continue 135 | 136 | xx = str(a).split('/')[0] 137 | addr = scapy.utils6.in6_ptop(xx) 138 | 139 | scope = scapy.utils6.in6_getscope(addr) 140 | 141 | ret.append((xx, scope, ifname)) 142 | return ret 143 | 144 | def read_routes6(): 145 | f = os.popen("netstat -rn -f inet6") 146 | ok = False 147 | mtu_present = False 148 | prio_present = False 149 | routes = [] 150 | lifaddr = in6_getifaddr() 151 | for l in f.readlines(): 152 | if not l: 153 | break 154 | l = l.strip() 155 | if not ok: 156 | if l.find("Destination") >= 0: 157 | ok = 1 158 | mtu_present = l.find("Mtu") >= 0 159 | prio_present = l.find("Prio") >= 0 160 | continue 161 | # gv 12/12/06: under debugging 162 | if scapy.arch.NETBSD or scapy.arch.OPENBSD: 163 | lspl = l.split() 164 | d,nh,fl = lspl[:3] 165 | dev = lspl[5+mtu_present+prio_present] 166 | else: # FREEBSD or DARWIN 167 | d,nh,fl,dev = l.split()[:4] 168 | if filter(lambda x: x[2] == dev, lifaddr) == []: 169 | continue 170 | if 'L' in fl: # drop MAC addresses 171 | continue 172 | 173 | if 'link' in nh: 174 | nh = '::' 175 | 176 | cset = [] # candidate set (possible source addresses) 177 | dp = 128 178 | if d == 'default': 179 | d = '::' 180 | dp = 0 181 | if '/' in d: 182 | d,dp = d.split("/") 183 | dp = int(dp) 184 | if '%' in d: 185 | d,dev = d.split('%') 186 | if '%' in nh: 187 | nh,dev = nh.split('%') 188 | if scapy.arch.LOOPBACK_NAME in dev: 189 | cset = ['::1'] 190 | nh = '::' 191 | else: 192 | devaddrs = filter(lambda x: x[2] == dev, lifaddr) 193 | cset = scapy.utils6.construct_source_candidate_set(d, dp, devaddrs, scapy.arch.LOOPBACK_NAME) 194 | 195 | if len(cset) != 0: 196 | routes.append((d, dp, nh, dev, cset)) 197 | 198 | f.close() 199 | return routes 200 | 201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /scapy/as_resolvers.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Resolve Autonomous Systems (AS). 8 | """ 9 | 10 | 11 | import socket 12 | from config import conf 13 | 14 | class AS_resolver: 15 | server = None 16 | options = "-k" 17 | def __init__(self, server=None, port=43, options=None): 18 | if server is not None: 19 | self.server = server 20 | self.port = port 21 | if options is not None: 22 | self.options = options 23 | 24 | def _start(self): 25 | self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 26 | self.s.connect((self.server,self.port)) 27 | if self.options: 28 | self.s.send(self.options+"\n") 29 | self.s.recv(8192) 30 | def _stop(self): 31 | self.s.close() 32 | 33 | def _parse_whois(self, txt): 34 | asn,desc = None,"" 35 | for l in txt.splitlines(): 36 | if not asn and l.startswith("origin:"): 37 | asn = l[7:].strip() 38 | if l.startswith("descr:"): 39 | if desc: 40 | desc += r"\n" 41 | desc += l[6:].strip() 42 | if asn is not None and desc: 43 | break 44 | return asn,desc.strip() 45 | 46 | def _resolve_one(self, ip): 47 | self.s.send("%s\n" % ip) 48 | x = "" 49 | while not ("%" in x or "source" in x): 50 | x += self.s.recv(8192) 51 | asn, desc = self._parse_whois(x) 52 | return ip,asn,desc 53 | def resolve(self, *ips): 54 | self._start() 55 | ret = [] 56 | for ip in ips: 57 | ip,asn,desc = self._resolve_one(ip) 58 | if asn is not None: 59 | ret.append((ip,asn,desc)) 60 | self._stop() 61 | return ret 62 | 63 | class AS_resolver_riswhois(AS_resolver): 64 | server = "riswhois.ripe.net" 65 | options = "-k -M -1" 66 | 67 | 68 | class AS_resolver_radb(AS_resolver): 69 | server = "whois.ra.net" 70 | options = "-k -M" 71 | 72 | 73 | class AS_resolver_cymru(AS_resolver): 74 | server = "whois.cymru.com" 75 | options = None 76 | def resolve(self, *ips): 77 | ASNlist = [] 78 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 79 | s.connect((self.server,self.port)) 80 | s.send("begin\r\n"+"\r\n".join(ips)+"\r\nend\r\n") 81 | r = "" 82 | while 1: 83 | l = s.recv(8192) 84 | if l == "": 85 | break 86 | r += l 87 | s.close() 88 | for l in r.splitlines()[1:]: 89 | if "|" not in l: 90 | continue 91 | asn,ip,desc = map(str.strip, l.split("|")) 92 | if asn == "NA": 93 | continue 94 | asn = int(asn) 95 | ASNlist.append((ip,asn,desc)) 96 | return ASNlist 97 | 98 | class AS_resolver_multi(AS_resolver): 99 | resolvers_list = ( AS_resolver_cymru(),AS_resolver_riswhois(),AS_resolver_radb() ) 100 | def __init__(self, *reslist): 101 | if reslist: 102 | self.resolvers_list = reslist 103 | def resolve(self, *ips): 104 | todo = ips 105 | ret = [] 106 | for ASres in self.resolvers_list: 107 | res = ASres.resolve(*todo) 108 | resolved = [ ip for ip,asn,desc in res ] 109 | todo = [ ip for ip in todo if ip not in resolved ] 110 | ret += res 111 | return ret 112 | 113 | 114 | conf.AS_resolver = AS_resolver_multi() 115 | -------------------------------------------------------------------------------- /scapy/asn1/__init__.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Package holding ASN.1 related modules. 8 | """ 9 | 10 | # We do not import mib.py because it is more bound to scapy and 11 | # less prone to be used in a standalone fashion 12 | __all__ = ["asn1","ber"] 13 | -------------------------------------------------------------------------------- /scapy/asn1/asn1.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | ASN.1 (Abstract Syntax Notation One) 8 | """ 9 | 10 | import random 11 | from scapy.config import conf 12 | from scapy.error import Scapy_Exception,warning 13 | from scapy.volatile import RandField 14 | from scapy.utils import Enum_metaclass, EnumElement 15 | 16 | class RandASN1Object(RandField): 17 | def __init__(self, objlist=None): 18 | if objlist is None: 19 | objlist = map(lambda x:x._asn1_obj, 20 | filter(lambda x:hasattr(x,"_asn1_obj"), ASN1_Class_UNIVERSAL.__rdict__.values())) 21 | self.objlist = objlist 22 | self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 23 | def _fix(self, n=0): 24 | o = random.choice(self.objlist) 25 | if issubclass(o, ASN1_INTEGER): 26 | return o(int(random.gauss(0,1000))) 27 | elif issubclass(o, ASN1_IPADDRESS): 28 | z = RandIP()._fix() 29 | return o(z) 30 | elif issubclass(o, ASN1_STRING): 31 | z = int(random.expovariate(0.05)+1) 32 | return o("".join([random.choice(self.chars) for i in range(z)])) 33 | elif issubclass(o, ASN1_SEQUENCE) and (n < 10): 34 | z = int(random.expovariate(0.08)+1) 35 | return o(map(lambda x:x._fix(n+1), [self.__class__(objlist=self.objlist)]*z)) 36 | return ASN1_INTEGER(int(random.gauss(0,1000))) 37 | 38 | 39 | ############## 40 | #### ASN1 #### 41 | ############## 42 | 43 | class ASN1_Error(Scapy_Exception): 44 | pass 45 | 46 | class ASN1_Encoding_Error(ASN1_Error): 47 | pass 48 | 49 | class ASN1_Decoding_Error(ASN1_Error): 50 | pass 51 | 52 | class ASN1_BadTag_Decoding_Error(ASN1_Decoding_Error): 53 | pass 54 | 55 | 56 | 57 | class ASN1Codec(EnumElement): 58 | def register_stem(cls, stem): 59 | cls._stem = stem 60 | def dec(cls, s, context=None): 61 | return cls._stem.dec(s, context=context) 62 | def safedec(cls, s, context=None): 63 | return cls._stem.safedec(s, context=context) 64 | def get_stem(cls): 65 | return cls.stem 66 | 67 | 68 | class ASN1_Codecs_metaclass(Enum_metaclass): 69 | element_class = ASN1Codec 70 | 71 | class ASN1_Codecs: 72 | __metaclass__ = ASN1_Codecs_metaclass 73 | BER = 1 74 | DER = 2 75 | PER = 3 76 | CER = 4 77 | LWER = 5 78 | BACnet = 6 79 | OER = 7 80 | SER = 8 81 | XER = 9 82 | 83 | class ASN1Tag(EnumElement): 84 | def __init__(self, key, value, context=None, codec=None): 85 | EnumElement.__init__(self, key, value) 86 | self._context = context 87 | if codec == None: 88 | codec = {} 89 | self._codec = codec 90 | def clone(self): # /!\ not a real deep copy. self.codec is shared 91 | return self.__class__(self._key, self._value, self._context, self._codec) 92 | def register_asn1_object(self, asn1obj): 93 | self._asn1_obj = asn1obj 94 | def asn1_object(self, val): 95 | if hasattr(self,"_asn1_obj"): 96 | return self._asn1_obj(val) 97 | raise ASN1_Error("%r does not have any assigned ASN1 object" % self) 98 | def register(self, codecnum, codec): 99 | self._codec[codecnum] = codec 100 | def get_codec(self, codec): 101 | try: 102 | c = self._codec[codec] 103 | except KeyError,msg: 104 | raise ASN1_Error("Codec %r not found for tag %r" % (codec, self)) 105 | return c 106 | 107 | class ASN1_Class_metaclass(Enum_metaclass): 108 | element_class = ASN1Tag 109 | def __new__(cls, name, bases, dct): # XXX factorise a bit with Enum_metaclass.__new__() 110 | for b in bases: 111 | for k,v in b.__dict__.iteritems(): 112 | if k not in dct and isinstance(v,ASN1Tag): 113 | dct[k] = v.clone() 114 | 115 | rdict = {} 116 | for k,v in dct.iteritems(): 117 | if type(v) is int: 118 | v = ASN1Tag(k,v) 119 | dct[k] = v 120 | rdict[v] = v 121 | elif isinstance(v, ASN1Tag): 122 | rdict[v] = v 123 | dct["__rdict__"] = rdict 124 | 125 | cls = type.__new__(cls, name, bases, dct) 126 | for v in cls.__dict__.values(): 127 | if isinstance(v, ASN1Tag): 128 | v.context = cls # overwrite ASN1Tag contexts, even cloned ones 129 | return cls 130 | 131 | 132 | class ASN1_Class: 133 | __metaclass__ = ASN1_Class_metaclass 134 | 135 | class ASN1_Class_UNIVERSAL(ASN1_Class): 136 | name = "UNIVERSAL" 137 | ERROR = -3 138 | RAW = -2 139 | NONE = -1 140 | ANY = 0 141 | BOOLEAN = 1 142 | INTEGER = 2 143 | BIT_STRING = 3 144 | STRING = 4 145 | NULL = 5 146 | OID = 6 147 | OBJECT_DESCRIPTOR = 7 148 | EXTERNAL = 8 149 | REAL = 9 150 | ENUMERATED = 10 151 | EMBEDDED_PDF = 11 152 | UTF8_STRING = 12 153 | RELATIVE_OID = 13 154 | SEQUENCE = 0x30#XXX 16 ?? 155 | SET = 0x31 #XXX 17 ?? 156 | NUMERIC_STRING = 18 157 | PRINTABLE_STRING = 19 158 | T61_STRING = 20 159 | VIDEOTEX_STRING = 21 160 | IA5_STRING = 22 161 | UTC_TIME = 23 162 | GENERALIZED_TIME = 24 163 | GRAPHIC_STRING = 25 164 | ISO646_STRING = 26 165 | GENERAL_STRING = 27 166 | UNIVERSAL_STRING = 28 167 | CHAR_STRING = 29 168 | BMP_STRING = 30 169 | IPADDRESS = 0x40 170 | COUNTER32 = 0x41 171 | GAUGE32 = 0x42 172 | TIME_TICKS = 0x43 173 | SEP = 0x80 174 | 175 | class ASN1_Object_metaclass(type): 176 | def __new__(cls, name, bases, dct): 177 | c = super(ASN1_Object_metaclass, cls).__new__(cls, name, bases, dct) 178 | try: 179 | c.tag.register_asn1_object(c) 180 | except: 181 | warning("Error registering %r for %r" % (c.tag, c.codec)) 182 | return c 183 | 184 | 185 | class ASN1_Object: 186 | __metaclass__ = ASN1_Object_metaclass 187 | tag = ASN1_Class_UNIVERSAL.ANY 188 | def __init__(self, val): 189 | self.val = val 190 | def enc(self, codec): 191 | return self.tag.get_codec(codec).enc(self.val) 192 | def __repr__(self): 193 | return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val) 194 | def __str__(self): 195 | return self.enc(conf.ASN1_default_codec) 196 | def strshow(self, lvl=0): 197 | return (" "*lvl)+repr(self)+"\n" 198 | def show(self, lvl=0): 199 | print self.strshow(lvl) 200 | def __eq__(self, other): 201 | return self.val == other 202 | def __cmp__(self, other): 203 | return cmp(self.val, other) 204 | 205 | class ASN1_DECODING_ERROR(ASN1_Object): 206 | tag = ASN1_Class_UNIVERSAL.ERROR 207 | def __init__(self, val, exc=None): 208 | ASN1_Object.__init__(self, val) 209 | self.exc = exc 210 | def __repr__(self): 211 | return "<%s[%r]{{%s}}>" % (self.__dict__.get("name", self.__class__.__name__), 212 | self.val, self.exc.args[0]) 213 | def enc(self, codec): 214 | if isinstance(self.val, ASN1_Object): 215 | return self.val.enc(codec) 216 | return self.val 217 | 218 | class ASN1_force(ASN1_Object): 219 | tag = ASN1_Class_UNIVERSAL.RAW 220 | def enc(self, codec): 221 | if isinstance(self.val, ASN1_Object): 222 | return self.val.enc(codec) 223 | return self.val 224 | 225 | class ASN1_BADTAG(ASN1_force): 226 | pass 227 | 228 | class ASN1_INTEGER(ASN1_Object): 229 | tag = ASN1_Class_UNIVERSAL.INTEGER 230 | 231 | class ASN1_STRING(ASN1_Object): 232 | tag = ASN1_Class_UNIVERSAL.STRING 233 | 234 | class ASN1_BIT_STRING(ASN1_STRING): 235 | tag = ASN1_Class_UNIVERSAL.BIT_STRING 236 | 237 | class ASN1_PRINTABLE_STRING(ASN1_STRING): 238 | tag = ASN1_Class_UNIVERSAL.PRINTABLE_STRING 239 | 240 | class ASN1_T61_STRING(ASN1_STRING): 241 | tag = ASN1_Class_UNIVERSAL.T61_STRING 242 | 243 | class ASN1_IA5_STRING(ASN1_STRING): 244 | tag = ASN1_Class_UNIVERSAL.IA5_STRING 245 | 246 | class ASN1_NUMERIC_STRING(ASN1_STRING): 247 | tag = ASN1_Class_UNIVERSAL.NUMERIC_STRING 248 | 249 | class ASN1_VIDEOTEX_STRING(ASN1_STRING): 250 | tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING 251 | 252 | class ASN1_IPADDRESS(ASN1_STRING): 253 | tag = ASN1_Class_UNIVERSAL.IPADDRESS 254 | 255 | class ASN1_UTC_TIME(ASN1_STRING): 256 | tag = ASN1_Class_UNIVERSAL.UTC_TIME 257 | 258 | class ASN1_GENERALIZED_TIME(ASN1_STRING): 259 | tag = ASN1_Class_UNIVERSAL.GENERALIZED_TIME 260 | 261 | class ASN1_TIME_TICKS(ASN1_INTEGER): 262 | tag = ASN1_Class_UNIVERSAL.TIME_TICKS 263 | 264 | class ASN1_BOOLEAN(ASN1_INTEGER): 265 | tag = ASN1_Class_UNIVERSAL.BOOLEAN 266 | 267 | class ASN1_ENUMERATED(ASN1_INTEGER): 268 | tag = ASN1_Class_UNIVERSAL.ENUMERATED 269 | 270 | class ASN1_NULL(ASN1_INTEGER): 271 | tag = ASN1_Class_UNIVERSAL.NULL 272 | 273 | class ASN1_SEP(ASN1_NULL): 274 | tag = ASN1_Class_UNIVERSAL.SEP 275 | 276 | class ASN1_GAUGE32(ASN1_INTEGER): 277 | tag = ASN1_Class_UNIVERSAL.GAUGE32 278 | 279 | class ASN1_COUNTER32(ASN1_INTEGER): 280 | tag = ASN1_Class_UNIVERSAL.COUNTER32 281 | 282 | class ASN1_SEQUENCE(ASN1_Object): 283 | tag = ASN1_Class_UNIVERSAL.SEQUENCE 284 | def strshow(self, lvl=0): 285 | s = (" "*lvl)+("# %s:" % self.__class__.__name__)+"\n" 286 | for o in self.val: 287 | s += o.strshow(lvl=lvl+1) 288 | return s 289 | 290 | class ASN1_SET(ASN1_SEQUENCE): 291 | tag = ASN1_Class_UNIVERSAL.SET 292 | 293 | class ASN1_OID(ASN1_Object): 294 | tag = ASN1_Class_UNIVERSAL.OID 295 | def __init__(self, val): 296 | val = conf.mib._oid(val) 297 | ASN1_Object.__init__(self, val) 298 | def __repr__(self): 299 | return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), conf.mib._oidname(self.val)) 300 | def __oidname__(self): 301 | return '%s'%conf.mib._oidname(self.val) 302 | 303 | 304 | 305 | conf.ASN1_default_codec = ASN1_Codecs.BER 306 | -------------------------------------------------------------------------------- /scapy/asn1/mib.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Management Information Base (MIB) parsing 8 | """ 9 | 10 | import re 11 | from glob import glob 12 | from scapy.dadict import DADict,fixname 13 | from scapy.config import conf 14 | from scapy.utils import do_graph 15 | 16 | ################# 17 | ## MIB parsing ## 18 | ################# 19 | 20 | _mib_re_integer = re.compile("^[0-9]+$") 21 | _mib_re_both = re.compile("^([a-zA-Z_][a-zA-Z0-9_-]*)\(([0-9]+)\)$") 22 | _mib_re_oiddecl = re.compile("$\s*([a-zA-Z0-9_-]+)\s+OBJECT([^:\{\}]|\{[^:]+\})+::=\s*\{([^\}]+)\}",re.M) 23 | _mib_re_strings = re.compile('"[^"]*"') 24 | _mib_re_comments = re.compile('--.*(\r|\n)') 25 | 26 | class MIBDict(DADict): 27 | def _findroot(self, x): 28 | if x.startswith("."): 29 | x = x[1:] 30 | if not x.endswith("."): 31 | x += "." 32 | max=0 33 | root="." 34 | for k in self.keys(): 35 | if x.startswith(self[k]+"."): 36 | if max < len(self[k]): 37 | max = len(self[k]) 38 | root = k 39 | return root, x[max:-1] 40 | def _oidname(self, x): 41 | root,remainder = self._findroot(x) 42 | return root+remainder 43 | def _oid(self, x): 44 | xl = x.strip(".").split(".") 45 | p = len(xl)-1 46 | while p >= 0 and _mib_re_integer.match(xl[p]): 47 | p -= 1 48 | if p != 0 or xl[p] not in self: 49 | return x 50 | xl[p] = self[xl[p]] 51 | return ".".join(xl[p:]) 52 | def _make_graph(self, other_keys=[], **kargs): 53 | nodes = [(k,self[k]) for k in self.keys()] 54 | oids = [self[k] for k in self.keys()] 55 | for k in other_keys: 56 | if k not in oids: 57 | nodes.append(self.oidname(k),k) 58 | s = 'digraph "mib" {\n\trankdir=LR;\n\n' 59 | for k,o in nodes: 60 | s += '\t"%s" [ label="%s" ];\n' % (o,k) 61 | s += "\n" 62 | for k,o in nodes: 63 | parent,remainder = self._findroot(o[:-1]) 64 | remainder = remainder[1:]+o[-1] 65 | if parent != ".": 66 | parent = self[parent] 67 | s += '\t"%s" -> "%s" [label="%s"];\n' % (parent, o,remainder) 68 | s += "}\n" 69 | do_graph(s, **kargs) 70 | def __len__(self): 71 | return len(self.keys()) 72 | 73 | 74 | def mib_register(ident, value, the_mib, unresolved): 75 | if ident in the_mib or ident in unresolved: 76 | return ident in the_mib 77 | resval = [] 78 | not_resolved = 0 79 | for v in value: 80 | if _mib_re_integer.match(v): 81 | resval.append(v) 82 | else: 83 | v = fixname(v) 84 | if v not in the_mib: 85 | not_resolved = 1 86 | if v in the_mib: 87 | v = the_mib[v] 88 | elif v in unresolved: 89 | v = unresolved[v] 90 | if type(v) is list: 91 | resval += v 92 | else: 93 | resval.append(v) 94 | if not_resolved: 95 | unresolved[ident] = resval 96 | return False 97 | else: 98 | the_mib[ident] = resval 99 | keys = unresolved.keys() 100 | i = 0 101 | while i < len(keys): 102 | k = keys[i] 103 | if mib_register(k,unresolved[k], the_mib, {}): 104 | del(unresolved[k]) 105 | del(keys[i]) 106 | i = 0 107 | else: 108 | i += 1 109 | 110 | return True 111 | 112 | 113 | def load_mib(filenames): 114 | the_mib = {'iso': ['1']} 115 | unresolved = {} 116 | for k in conf.mib.keys(): 117 | mib_register(k, conf.mib[k].split("."), the_mib, unresolved) 118 | 119 | if type(filenames) is str: 120 | filenames = [filenames] 121 | for fnames in filenames: 122 | for fname in glob(fnames): 123 | f = open(fname) 124 | text = f.read() 125 | cleantext = " ".join(_mib_re_strings.split(" ".join(_mib_re_comments.split(text)))) 126 | for m in _mib_re_oiddecl.finditer(cleantext): 127 | gr = m.groups() 128 | ident,oid = gr[0],gr[-1] 129 | ident=fixname(ident) 130 | oid = oid.split() 131 | for i in range(len(oid)): 132 | m = _mib_re_both.match(oid[i]) 133 | if m: 134 | oid[i] = m.groups()[1] 135 | mib_register(ident, oid, the_mib, unresolved) 136 | 137 | newmib = MIBDict(_name="MIB") 138 | for k,o in the_mib.iteritems(): 139 | newmib[k]=".".join(o) 140 | for k,o in unresolved.iteritems(): 141 | newmib[k]=".".join(o) 142 | 143 | conf.mib=newmib 144 | 145 | 146 | 147 | conf.mib = MIBDict(_name="MIB") 148 | -------------------------------------------------------------------------------- /scapy/asn1packet.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Packet holding data in Abstract Syntax Notation (ASN.1). 8 | """ 9 | 10 | from packet import * 11 | 12 | class ASN1_Packet(Packet): 13 | ASN1_root = None 14 | ASN1_codec = None 15 | def init_fields(self): 16 | flist = self.ASN1_root.get_fields_list() 17 | self.do_init_fields(flist) 18 | self.fields_desc = flist 19 | def self_build(self): 20 | return self.ASN1_root.build(self) 21 | def do_dissect(self, x): 22 | return self.ASN1_root.dissect(self, x) 23 | 24 | 25 | -------------------------------------------------------------------------------- /scapy/autorun.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Run commands when the Scapy interpreter starts. 8 | """ 9 | 10 | import code,sys 11 | from config import conf 12 | from themes import * 13 | from error import Scapy_Exception 14 | from utils import tex_escape 15 | 16 | 17 | ######################### 18 | ##### Autorun stuff ##### 19 | ######################### 20 | 21 | class StopAutorun(Scapy_Exception): 22 | code_run = "" 23 | 24 | class ScapyAutorunInterpreter(code.InteractiveInterpreter): 25 | def __init__(self, *args, **kargs): 26 | code.InteractiveInterpreter.__init__(self, *args, **kargs) 27 | self.error = 0 28 | def showsyntaxerror(self, *args, **kargs): 29 | self.error = 1 30 | return code.InteractiveInterpreter.showsyntaxerror(self, *args, **kargs) 31 | def showtraceback(self, *args, **kargs): 32 | self.error = 1 33 | exc_type, exc_value, exc_tb = sys.exc_info() 34 | if isinstance(exc_value, StopAutorun): 35 | raise exc_value 36 | return code.InteractiveInterpreter.showtraceback(self, *args, **kargs) 37 | 38 | 39 | def autorun_commands(cmds,my_globals=None,verb=0): 40 | sv = conf.verb 41 | import __builtin__ 42 | try: 43 | try: 44 | if my_globals is None: 45 | my_globals = __import__("scapy.all").all.__dict__ 46 | conf.verb = verb 47 | interp = ScapyAutorunInterpreter(my_globals) 48 | cmd = "" 49 | cmds = cmds.splitlines() 50 | cmds.append("") # ensure we finish multiline commands 51 | cmds.reverse() 52 | __builtin__.__dict__["_"] = None 53 | while 1: 54 | if cmd: 55 | sys.stderr.write(sys.__dict__.get("ps2","... ")) 56 | else: 57 | sys.stderr.write(str(sys.__dict__.get("ps1",ColorPrompt()))) 58 | 59 | l = cmds.pop() 60 | print l 61 | cmd += "\n"+l 62 | if interp.runsource(cmd): 63 | continue 64 | if interp.error: 65 | return 0 66 | cmd = "" 67 | if len(cmds) <= 1: 68 | break 69 | except SystemExit: 70 | pass 71 | finally: 72 | conf.verb = sv 73 | return _ 74 | 75 | def autorun_get_interactive_session(cmds, **kargs): 76 | class StringWriter: 77 | def __init__(self): 78 | self.s = "" 79 | def write(self, x): 80 | self.s += x 81 | 82 | sw = StringWriter() 83 | sstdout,sstderr = sys.stdout,sys.stderr 84 | try: 85 | try: 86 | sys.stdout = sys.stderr = sw 87 | res = autorun_commands(cmds, **kargs) 88 | except StopAutorun,e: 89 | e.code_run = sw.s 90 | raise 91 | finally: 92 | sys.stdout,sys.stderr = sstdout,sstderr 93 | return sw.s,res 94 | 95 | def autorun_get_text_interactive_session(cmds, **kargs): 96 | ct = conf.color_theme 97 | try: 98 | conf.color_theme = NoTheme() 99 | s,res = autorun_get_interactive_session(cmds, **kargs) 100 | finally: 101 | conf.color_theme = ct 102 | return s,res 103 | 104 | def autorun_get_ansi_interactive_session(cmds, **kargs): 105 | ct = conf.color_theme 106 | try: 107 | conf.color_theme = DefaultTheme() 108 | s,res = autorun_get_interactive_session(cmds, **kargs) 109 | finally: 110 | conf.color_theme = ct 111 | return s,res 112 | 113 | def autorun_get_html_interactive_session(cmds, **kargs): 114 | ct = conf.color_theme 115 | to_html = lambda s: s.replace("<","<").replace(">",">").replace("#[#","<").replace("#]#",">") 116 | try: 117 | try: 118 | conf.color_theme = HTMLTheme2() 119 | s,res = autorun_get_interactive_session(cmds, **kargs) 120 | except StopAutorun,e: 121 | e.code_run = to_html(e.code_run) 122 | raise 123 | finally: 124 | conf.color_theme = ct 125 | 126 | return to_html(s),res 127 | 128 | def autorun_get_latex_interactive_session(cmds, **kargs): 129 | ct = conf.color_theme 130 | to_latex = lambda s: tex_escape(s).replace("@[@","{").replace("@]@","}").replace("@`@","\\") 131 | try: 132 | try: 133 | conf.color_theme = LatexTheme2() 134 | s,res = autorun_get_interactive_session(cmds, **kargs) 135 | except StopAutorun,e: 136 | e.code_run = to_latex(e.code_run) 137 | raise 138 | finally: 139 | conf.color_theme = ct 140 | return to_latex(s),res 141 | 142 | 143 | -------------------------------------------------------------------------------- /scapy/base_classes.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Generators and packet meta classes. 8 | """ 9 | 10 | ############### 11 | ## Generators ## 12 | ################ 13 | 14 | import re,random,socket 15 | import config 16 | import error 17 | 18 | class Gen(object): 19 | def __iter__(self): 20 | return iter([]) 21 | 22 | class SetGen(Gen): 23 | def __init__(self, set, _iterpacket=1): 24 | self._iterpacket=_iterpacket 25 | if type(set) is list: 26 | self.set = set 27 | elif isinstance(set, BasePacketList): 28 | self.set = list(set) 29 | else: 30 | self.set = [set] 31 | def transf(self, element): 32 | return element 33 | def __iter__(self): 34 | for i in self.set: 35 | if (type(i) is tuple) and (len(i) == 2) and type(i[0]) is int and type(i[1]) is int: 36 | if (i[0] <= i[1]): 37 | j=i[0] 38 | while j <= i[1]: 39 | yield j 40 | j += 1 41 | elif isinstance(i, Gen) and (self._iterpacket or not isinstance(i,BasePacket)): 42 | for j in i: 43 | yield j 44 | else: 45 | yield i 46 | def __repr__(self): 47 | return "" % self.set.__repr__() 48 | 49 | class Net(Gen): 50 | """Generate a list of IPs from a network address or a name""" 51 | name = "ip" 52 | ipaddress = re.compile(r"^(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$") 53 | 54 | @staticmethod 55 | def _parse_digit(a,netmask): 56 | netmask = min(8,max(netmask,0)) 57 | if a == "*": 58 | a = (0,256) 59 | elif a.find("-") >= 0: 60 | x,y = map(int,a.split("-")) 61 | if x > y: 62 | y = x 63 | a = (x & (0xffL<>(8-netmask))))+1) 64 | else: 65 | a = (int(a) & (0xffL<>(8-netmask)))+1) 66 | return a 67 | 68 | @classmethod 69 | def _parse_net(cls, net): 70 | tmp=net.split('/')+["32"] 71 | if not cls.ipaddress.match(net): 72 | tmp[0]=socket.gethostbyname(tmp[0]) 73 | netmask = int(tmp[1]) 74 | return map(lambda x,y: cls._parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32))),netmask 75 | 76 | def __init__(self, net): 77 | self.repr=net 78 | self.parsed,self.netmask = self._parse_net(net) 79 | 80 | 81 | 82 | def __iter__(self): 83 | for d in xrange(*self.parsed[3]): 84 | for c in xrange(*self.parsed[2]): 85 | for b in xrange(*self.parsed[1]): 86 | for a in xrange(*self.parsed[0]): 87 | yield "%i.%i.%i.%i" % (a,b,c,d) 88 | def choice(self): 89 | ip = [] 90 | for v in self.parsed: 91 | ip.append(str(random.randint(v[0],v[1]-1))) 92 | return ".".join(ip) 93 | 94 | def __repr__(self): 95 | return "Net(%r)" % self.repr 96 | def __eq__(self, other): 97 | if hasattr(other, "parsed"): 98 | p2 = other.parsed 99 | else: 100 | p2,nm2 = self._parse_net(other) 101 | return self.parsed == p2 102 | def __contains__(self, other): 103 | if hasattr(other, "parsed"): 104 | p2 = other.parsed 105 | else: 106 | p2,nm2 = self._parse_net(other) 107 | for (a1,b1),(a2,b2) in zip(self.parsed,p2): 108 | if a1 > a2 or b1 < b2: 109 | return False 110 | return True 111 | def __rcontains__(self, other): 112 | return self in self.__class__(other) 113 | 114 | 115 | class OID(Gen): 116 | name = "OID" 117 | def __init__(self, oid): 118 | self.oid = oid 119 | self.cmpt = [] 120 | fmt = [] 121 | for i in oid.split("."): 122 | if "-" in i: 123 | fmt.append("%i") 124 | self.cmpt.append(tuple(map(int, i.split("-")))) 125 | else: 126 | fmt.append(i) 127 | self.fmt = ".".join(fmt) 128 | def __repr__(self): 129 | return "OID(%r)" % self.oid 130 | def __iter__(self): 131 | ii = [k[0] for k in self.cmpt] 132 | while 1: 133 | yield self.fmt % tuple(ii) 134 | i = 0 135 | while 1: 136 | if i >= len(ii): 137 | raise StopIteration 138 | if ii[i] < self.cmpt[i][1]: 139 | ii[i]+=1 140 | break 141 | else: 142 | ii[i] = self.cmpt[i][0] 143 | i += 1 144 | 145 | 146 | 147 | ###################################### 148 | ## Packet abstract and base classes ## 149 | ###################################### 150 | 151 | class Packet_metaclass(type): 152 | def __new__(cls, name, bases, dct): 153 | if "fields_desc" in dct: # perform resolution of references to other packets 154 | current_fld = dct["fields_desc"] 155 | resolved_fld = [] 156 | for f in current_fld: 157 | if isinstance(f, Packet_metaclass): # reference to another fields_desc 158 | for f2 in f.fields_desc: 159 | resolved_fld.append(f2) 160 | else: 161 | resolved_fld.append(f) 162 | else: # look for a field_desc in parent classes 163 | resolved_fld = None 164 | for b in bases: 165 | if hasattr(b,"fields_desc"): 166 | resolved_fld = b.fields_desc 167 | break 168 | 169 | if resolved_fld: # perform default value replacements 170 | final_fld = [] 171 | for f in resolved_fld: 172 | if f.name in dct: 173 | f = f.copy() 174 | f.default = dct[f.name] 175 | del(dct[f.name]) 176 | final_fld.append(f) 177 | 178 | dct["fields_desc"] = final_fld 179 | 180 | newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct) 181 | if hasattr(newcls,"register_variant"): 182 | newcls.register_variant() 183 | for f in newcls.fields_desc: 184 | f.register_owner(newcls) 185 | config.conf.layers.register(newcls) 186 | return newcls 187 | 188 | def __getattr__(self, attr): 189 | for k in self.fields_desc: 190 | if k.name == attr: 191 | return k 192 | raise AttributeError(attr) 193 | 194 | def __call__(cls, *args, **kargs): 195 | if "dispatch_hook" in cls.__dict__: 196 | cls = cls.dispatch_hook(*args, **kargs) 197 | i = cls.__new__(cls, cls.__name__, cls.__bases__, cls.__dict__) 198 | i.__init__(*args, **kargs) 199 | return i 200 | 201 | 202 | class NewDefaultValues(Packet_metaclass): 203 | """NewDefaultValues is deprecated (not needed anymore) 204 | 205 | remove this: 206 | __metaclass__ = NewDefaultValues 207 | and it should still work. 208 | """ 209 | def __new__(cls, name, bases, dct): 210 | from error import log_loading 211 | import traceback 212 | try: 213 | for tb in traceback.extract_stack()+[("??",-1,None,"")]: 214 | f,l,_,line = tb 215 | if line.startswith("class"): 216 | break 217 | except: 218 | f,l="??",-1 219 | raise 220 | log_loading.warning("Deprecated (no more needed) use of NewDefaultValues (%s l. %i)." % (f,l)) 221 | 222 | return super(NewDefaultValues, cls).__new__(cls, name, bases, dct) 223 | 224 | class BasePacket(Gen): 225 | pass 226 | 227 | 228 | ############################# 229 | ## Packet list base classe ## 230 | ############################# 231 | 232 | class BasePacketList: 233 | pass 234 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /scapy/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Arnaud Ebalard 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Tools for handling with digital certificates. 8 | """ 9 | 10 | try: 11 | import Crypto 12 | except ImportError: 13 | import logging 14 | log_loading = logging.getLogger("scapy.loading") 15 | log_loading.info("Can't import python Crypto lib. Disabled certificate manipulation tools") 16 | else: 17 | from scapy.crypto.cert import * 18 | -------------------------------------------------------------------------------- /scapy/dadict.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Direct Access dictionary. 8 | """ 9 | 10 | from error import Scapy_Exception 11 | 12 | ############################### 13 | ## Direct Access dictionnary ## 14 | ############################### 15 | 16 | def fixname(x): 17 | if x and x[0] in "0123456789": 18 | x = "n_"+x 19 | return x.translate("________________________________________________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz_____________________________________________________________________________________________________________________________________") 20 | 21 | 22 | class DADict_Exception(Scapy_Exception): 23 | pass 24 | 25 | class DADict: 26 | def __init__(self, _name="DADict", **kargs): 27 | self._name=_name 28 | self.__dict__.update(kargs) 29 | def fixname(self,val): 30 | return fixname(val) 31 | def __contains__(self, val): 32 | return val in self.__dict__ 33 | def __getitem__(self, attr): 34 | return getattr(self, attr) 35 | def __setitem__(self, attr, val): 36 | return setattr(self, self.fixname(attr), val) 37 | def __iter__(self): 38 | return iter(map(lambda (x,y):y,filter(lambda (x,y):x and x[0]!="_", self.__dict__.items()))) 39 | def _show(self): 40 | for k in self.__dict__.keys(): 41 | if k and k[0] != "_": 42 | print "%10s = %r" % (k,getattr(self,k)) 43 | def __repr__(self): 44 | return "<%s/ %s>" % (self._name," ".join(filter(lambda x:x and x[0]!="_",self.__dict__.keys()))) 45 | 46 | def _branch(self, br, uniq=0): 47 | if uniq and br._name in self: 48 | raise DADict_Exception("DADict: [%s] already branched in [%s]" % (br._name, self._name)) 49 | self[br._name] = br 50 | 51 | def _my_find(self, *args, **kargs): 52 | if args and self._name not in args: 53 | return False 54 | for k in kargs: 55 | if k not in self or self[k] != kargs[k]: 56 | return False 57 | return True 58 | 59 | def _find(self, *args, **kargs): 60 | return self._recurs_find((), *args, **kargs) 61 | def _recurs_find(self, path, *args, **kargs): 62 | if self in path: 63 | return None 64 | if self._my_find(*args, **kargs): 65 | return self 66 | for o in self: 67 | if isinstance(o, DADict): 68 | p = o._recurs_find(path+(self,), *args, **kargs) 69 | if p is not None: 70 | return p 71 | return None 72 | def _find_all(self, *args, **kargs): 73 | return self._recurs_find_all((), *args, **kargs) 74 | def _recurs_find_all(self, path, *args, **kargs): 75 | r = [] 76 | if self in path: 77 | return r 78 | if self._my_find(*args, **kargs): 79 | r.append(self) 80 | for o in self: 81 | if isinstance(o, DADict): 82 | p = o._recurs_find_all(path+(self,), *args, **kargs) 83 | r += p 84 | return r 85 | def keys(self): 86 | return filter(lambda x:x and x[0]!="_", self.__dict__.keys()) 87 | 88 | -------------------------------------------------------------------------------- /scapy/data.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Global variables and functions for handling external data sets. 8 | """ 9 | 10 | import os,sys,re 11 | from dadict import DADict 12 | from error import log_loading 13 | 14 | ############ 15 | ## Consts ## 16 | ############ 17 | 18 | ETHER_ANY = "\x00"*6 19 | ETHER_BROADCAST = "\xff"*6 20 | 21 | ETH_P_ALL = 3 22 | ETH_P_IP = 0x800 23 | ETH_P_ARP = 0x806 24 | ETH_P_IPV6 = 0x86dd 25 | 26 | # From net/if_arp.h 27 | ARPHDR_ETHER = 1 28 | ARPHDR_METRICOM = 23 29 | ARPHDR_PPP = 512 30 | ARPHDR_LOOPBACK = 772 31 | ARPHDR_TUN = 65534 32 | 33 | 34 | # From net/ipv6.h on Linux (+ Additions) 35 | IPV6_ADDR_UNICAST = 0x01 36 | IPV6_ADDR_MULTICAST = 0x02 37 | IPV6_ADDR_CAST_MASK = 0x0F 38 | IPV6_ADDR_LOOPBACK = 0x10 39 | IPV6_ADDR_GLOBAL = 0x00 40 | IPV6_ADDR_LINKLOCAL = 0x20 41 | IPV6_ADDR_SITELOCAL = 0x40 # deprecated since Sept. 2004 by RFC 3879 42 | IPV6_ADDR_SCOPE_MASK = 0xF0 43 | #IPV6_ADDR_COMPATv4 = 0x80 # deprecated; i.e. ::/96 44 | #IPV6_ADDR_MAPPED = 0x1000 # i.e.; ::ffff:0.0.0.0/96 45 | IPV6_ADDR_6TO4 = 0x0100 # Added to have more specific info (should be 0x0101 ?) 46 | IPV6_ADDR_UNSPECIFIED = 0x10000 47 | 48 | 49 | 50 | 51 | MTU = 0x7fff # a.k.a give me all you have 52 | 53 | WINDOWS=sys.platform.startswith("win") 54 | 55 | 56 | # file parsing to get some values : 57 | 58 | def load_protocols(filename): 59 | spaces = re.compile("[ \t]+|\n") 60 | dct = DADict(_name=filename) 61 | try: 62 | for l in open(filename): 63 | try: 64 | shrp = l.find("#") 65 | if shrp >= 0: 66 | l = l[:shrp] 67 | l = l.strip() 68 | if not l: 69 | continue 70 | lt = tuple(re.split(spaces, l)) 71 | if len(lt) < 2 or not lt[0]: 72 | continue 73 | dct[lt[0]] = int(lt[1]) 74 | except Exception,e: 75 | log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e)) 76 | except IOError: 77 | log_loading.info("Can't open %s file" % filename) 78 | return dct 79 | 80 | def load_ethertypes(filename): 81 | spaces = re.compile("[ \t]+|\n") 82 | dct = DADict(_name=filename) 83 | try: 84 | f=open(filename) 85 | for l in f: 86 | try: 87 | shrp = l.find("#") 88 | if shrp >= 0: 89 | l = l[:shrp] 90 | l = l.strip() 91 | if not l: 92 | continue 93 | lt = tuple(re.split(spaces, l)) 94 | if len(lt) < 2 or not lt[0]: 95 | continue 96 | dct[lt[0]] = int(lt[1], 16) 97 | except Exception,e: 98 | log_loading.info("Couldn't parse file [%s]: line [%r] (%s)" % (filename,l,e)) 99 | f.close() 100 | except IOError,msg: 101 | pass 102 | return dct 103 | 104 | def load_services(filename): 105 | spaces = re.compile("[ \t]+|\n") 106 | tdct=DADict(_name="%s-tcp"%filename) 107 | udct=DADict(_name="%s-udp"%filename) 108 | try: 109 | f=open(filename) 110 | for l in f: 111 | try: 112 | shrp = l.find("#") 113 | if shrp >= 0: 114 | l = l[:shrp] 115 | l = l.strip() 116 | if not l: 117 | continue 118 | lt = tuple(re.split(spaces, l)) 119 | if len(lt) < 2 or not lt[0]: 120 | continue 121 | if lt[1].endswith("/tcp"): 122 | tdct[lt[0]] = int(lt[1].split('/')[0]) 123 | elif lt[1].endswith("/udp"): 124 | udct[lt[0]] = int(lt[1].split('/')[0]) 125 | except Exception,e: 126 | log_loading.warning("Couldn't file [%s]: line [%r] (%s)" % (filename,l,e)) 127 | f.close() 128 | except IOError: 129 | log_loading.info("Can't open /etc/services file") 130 | return tdct,udct 131 | 132 | 133 | class ManufDA(DADict): 134 | def fixname(self, val): 135 | return val 136 | def _get_manuf_couple(self, mac): 137 | oui = ":".join(mac.split(":")[:3]).upper() 138 | return self.__dict__.get(oui,(mac,mac)) 139 | def _get_manuf(self, mac): 140 | return self._get_manuf_couple(mac)[1] 141 | def _get_short_manuf(self, mac): 142 | return self._get_manuf_couple(mac)[0] 143 | def _resolve_MAC(self, mac): 144 | oui = ":".join(mac.split(":")[:3]).upper() 145 | if oui in self: 146 | return ":".join([self[oui][0]]+ mac.split(":")[3:]) 147 | return mac 148 | 149 | 150 | 151 | 152 | def load_manuf(filename): 153 | try: 154 | manufdb=ManufDA(_name=filename) 155 | for l in open(filename): 156 | try: 157 | l = l.strip() 158 | if not l or l.startswith("#"): 159 | continue 160 | oui,shrt=l.split()[:2] 161 | i = l.find("#") 162 | if i < 0: 163 | lng=shrt 164 | else: 165 | lng = l[i+2:] 166 | manufdb[oui] = shrt,lng 167 | except Exception,e: 168 | log_loading.warning("Couldn't parse one line from [%s] [%r] (%s)" % (filename, l, e)) 169 | except IOError: 170 | #log_loading.warning("Couldn't open [%s] file" % filename) 171 | pass 172 | return manufdb 173 | 174 | 175 | 176 | if WINDOWS: 177 | ETHER_TYPES=load_ethertypes("ethertypes") 178 | IP_PROTOS=load_protocols(os.environ["SystemRoot"]+"\system32\drivers\etc\protocol") 179 | TCP_SERVICES,UDP_SERVICES=load_services(os.environ["SystemRoot"] + "\system32\drivers\etc\services") 180 | MANUFDB = load_manuf(os.environ["ProgramFiles"] + "\\wireshark\\manuf") 181 | else: 182 | IP_PROTOS=load_protocols("/etc/protocols") 183 | ETHER_TYPES=load_ethertypes("/etc/ethertypes") 184 | TCP_SERVICES,UDP_SERVICES=load_services("/etc/services") 185 | MANUFDB = load_manuf("/usr/share/wireshark/wireshark/manuf") 186 | 187 | 188 | 189 | ##################### 190 | ## knowledge bases ## 191 | ##################### 192 | 193 | class KnowledgeBase: 194 | def __init__(self, filename): 195 | self.filename = filename 196 | self.base = None 197 | 198 | def lazy_init(self): 199 | self.base = "" 200 | 201 | def reload(self, filename = None): 202 | if filename is not None: 203 | self.filename = filename 204 | oldbase = self.base 205 | self.base = None 206 | self.lazy_init() 207 | if self.base is None: 208 | self.base = oldbase 209 | 210 | def get_base(self): 211 | if self.base is None: 212 | self.lazy_init() 213 | return self.base 214 | 215 | 216 | -------------------------------------------------------------------------------- /scapy/error.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Logging subsystem and basic exception class. 8 | """ 9 | 10 | ############################# 11 | ##### Logging subsystem ##### 12 | ############################# 13 | 14 | class Scapy_Exception(Exception): 15 | pass 16 | 17 | import logging,traceback,time 18 | 19 | class ScapyFreqFilter(logging.Filter): 20 | def __init__(self): 21 | logging.Filter.__init__(self) 22 | self.warning_table = {} 23 | def filter(self, record): 24 | from config import conf 25 | wt = conf.warning_threshold 26 | if wt > 0: 27 | stk = traceback.extract_stack() 28 | caller=None 29 | for f,l,n,c in stk: 30 | if n == 'warning': 31 | break 32 | caller = l 33 | tm,nb = self.warning_table.get(caller, (0,0)) 34 | ltm = time.time() 35 | if ltm-tm > wt: 36 | tm = ltm 37 | nb = 0 38 | else: 39 | if nb < 2: 40 | nb += 1 41 | if nb == 2: 42 | record.msg = "more "+record.msg 43 | else: 44 | return 0 45 | self.warning_table[caller] = (tm,nb) 46 | return 1 47 | 48 | log_scapy = logging.getLogger("scapy") 49 | console_handler = logging.StreamHandler() 50 | console_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s")) 51 | log_scapy.addHandler(console_handler) 52 | log_runtime = logging.getLogger("scapy.runtime") # logs at runtime 53 | log_runtime.addFilter(ScapyFreqFilter()) 54 | log_interactive = logging.getLogger("scapy.interactive") # logs in interactive functions 55 | log_loading = logging.getLogger("scapy.loading") # logs when loading scapy 56 | 57 | 58 | def warning(x): 59 | log_runtime.warning(x) 60 | 61 | -------------------------------------------------------------------------------- /scapy/layers/__init__.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Layer package. 8 | """ 9 | -------------------------------------------------------------------------------- /scapy/layers/all.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | All layers. Configurable with conf.load_layers. 8 | """ 9 | 10 | from scapy.config import conf 11 | from scapy.error import log_loading 12 | import logging 13 | log = logging.getLogger("scapy.loading") 14 | 15 | def _import_star(m): 16 | mod = __import__(m, globals(), locals()) 17 | for k,v in mod.__dict__.iteritems(): 18 | globals()[k] = v 19 | 20 | for _l in conf.load_layers: 21 | log_loading.debug("Loading layer %s" % _l) 22 | try: 23 | _import_star(_l) 24 | except Exception,e: 25 | log.warning("can't import layer %s: %s" % (_l,e)) 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /scapy/layers/bluetooth.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Bluetooth layers, sockets and send/receive functions. 8 | """ 9 | 10 | import socket,struct 11 | 12 | from scapy.config import conf 13 | from scapy.packet import * 14 | from scapy.fields import * 15 | from scapy.supersocket import SuperSocket 16 | from scapy.data import MTU 17 | 18 | 19 | class HCI_Hdr(Packet): 20 | name = "HCI header" 21 | fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),] 22 | 23 | def mysummary(self): 24 | return self.sprintf("HCI %type%") 25 | 26 | class HCI_ACL_Hdr(Packet): 27 | name = "HCI ACL header" 28 | fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4. 29 | ByteField("flags",0), # I wait to write a LEBitField 30 | LEShortField("len",None), ] 31 | def post_build(self, p, pay): 32 | p += pay 33 | if self.len is None: 34 | l = len(p)-4 35 | p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:] 36 | return p 37 | 38 | 39 | class L2CAP_Hdr(Packet): 40 | name = "L2CAP header" 41 | fields_desc = [ LEShortField("len",None), 42 | LEShortEnumField("cid",0,{1:"control"}),] 43 | 44 | def post_build(self, p, pay): 45 | p += pay 46 | if self.len is None: 47 | l = len(p)-4 48 | p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:] 49 | return p 50 | 51 | 52 | 53 | class L2CAP_CmdHdr(Packet): 54 | name = "L2CAP command header" 55 | fields_desc = [ 56 | ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp", 57 | 4:"conf_req",5:"conf_resp",6:"disconn_req", 58 | 7:"disconn_resp",8:"echo_req",9:"echo_resp", 59 | 10:"info_req",11:"info_resp"}), 60 | ByteField("id",0), 61 | LEShortField("len",None) ] 62 | def post_build(self, p, pay): 63 | p += pay 64 | if self.len is None: 65 | l = len(p)-4 66 | p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:] 67 | return p 68 | def answers(self, other): 69 | if other.id == self.id: 70 | if self.code == 1: 71 | return 1 72 | if other.code in [2,4,6,8,10] and self.code == other.code+1: 73 | if other.code == 8: 74 | return 1 75 | return self.payload.answers(other.payload) 76 | return 0 77 | 78 | class L2CAP_ConnReq(Packet): 79 | name = "L2CAP Conn Req" 80 | fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}), 81 | LEShortField("scid",0), 82 | ] 83 | 84 | class L2CAP_ConnResp(Packet): 85 | name = "L2CAP Conn Resp" 86 | fields_desc = [ LEShortField("dcid",0), 87 | LEShortField("scid",0), 88 | LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]), 89 | LEShortEnumField("status",0,["success","pend","bad_psm", 90 | "cr_sec_block","cr_no_mem"]), 91 | ] 92 | def answers(self, other): 93 | return self.scid == other.scid 94 | 95 | class L2CAP_CmdRej(Packet): 96 | name = "L2CAP Command Rej" 97 | fields_desc = [ LEShortField("reason",0), 98 | ] 99 | 100 | 101 | class L2CAP_ConfReq(Packet): 102 | name = "L2CAP Conf Req" 103 | fields_desc = [ LEShortField("dcid",0), 104 | LEShortField("flags",0), 105 | ] 106 | 107 | class L2CAP_ConfResp(Packet): 108 | name = "L2CAP Conf Resp" 109 | fields_desc = [ LEShortField("scid",0), 110 | LEShortField("flags",0), 111 | LEShortEnumField("result",0,["success","unaccept","reject","unknown"]), 112 | ] 113 | def answers(self, other): 114 | return self.scid == other.scid 115 | 116 | 117 | class L2CAP_DisconnReq(Packet): 118 | name = "L2CAP Disconn Req" 119 | fields_desc = [ LEShortField("dcid",0), 120 | LEShortField("scid",0), ] 121 | 122 | class L2CAP_DisconnResp(Packet): 123 | name = "L2CAP Disconn Resp" 124 | fields_desc = [ LEShortField("dcid",0), 125 | LEShortField("scid",0), ] 126 | def answers(self, other): 127 | return self.scid == other.scid 128 | 129 | 130 | 131 | class L2CAP_InfoReq(Packet): 132 | name = "L2CAP Info Req" 133 | fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}), 134 | StrField("data","") 135 | ] 136 | 137 | 138 | class L2CAP_InfoResp(Packet): 139 | name = "L2CAP Info Resp" 140 | fields_desc = [ LEShortField("type",0), 141 | LEShortEnumField("result",0,["success","not_supp"]), 142 | StrField("data",""), ] 143 | def answers(self, other): 144 | return self.type == other.type 145 | 146 | 147 | 148 | bind_layers( HCI_Hdr, HCI_ACL_Hdr, type=2) 149 | bind_layers( HCI_Hdr, Raw, ) 150 | bind_layers( HCI_ACL_Hdr, L2CAP_Hdr, ) 151 | bind_layers( L2CAP_Hdr, L2CAP_CmdHdr, cid=1) 152 | bind_layers( L2CAP_CmdHdr, L2CAP_CmdRej, code=1) 153 | bind_layers( L2CAP_CmdHdr, L2CAP_ConnReq, code=2) 154 | bind_layers( L2CAP_CmdHdr, L2CAP_ConnResp, code=3) 155 | bind_layers( L2CAP_CmdHdr, L2CAP_ConfReq, code=4) 156 | bind_layers( L2CAP_CmdHdr, L2CAP_ConfResp, code=5) 157 | bind_layers( L2CAP_CmdHdr, L2CAP_DisconnReq, code=6) 158 | bind_layers( L2CAP_CmdHdr, L2CAP_DisconnResp, code=7) 159 | bind_layers( L2CAP_CmdHdr, L2CAP_InfoReq, code=10) 160 | bind_layers( L2CAP_CmdHdr, L2CAP_InfoResp, code=11) 161 | 162 | class BluetoothL2CAPSocket(SuperSocket): 163 | desc = "read/write packets on a connected L2CAP socket" 164 | def __init__(self, peer): 165 | s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, 166 | socket.BTPROTO_L2CAP) 167 | s.connect((peer,0)) 168 | 169 | self.ins = self.outs = s 170 | 171 | def recv(self, x=MTU): 172 | return L2CAP_CmdHdr(self.ins.recv(x)) 173 | 174 | 175 | class BluetoothHCISocket(SuperSocket): 176 | desc = "read/write on a BlueTooth HCI socket" 177 | def __init__(self, iface=0x10000, type=None): 178 | s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) 179 | s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1) 180 | s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1) 181 | s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffffL,0xffffffffL,0xffffffffL,0)) #type mask, event mask, event mask, opcode 182 | s.bind((iface,)) 183 | self.ins = self.outs = s 184 | # s.connect((peer,0)) 185 | 186 | 187 | def recv(self, x): 188 | return HCI_Hdr(self.ins.recv(x)) 189 | 190 | ## Bluetooth 191 | 192 | 193 | @conf.commands.register 194 | def srbt(peer, pkts, inter=0.1, *args, **kargs): 195 | """send and receive using a bluetooth socket""" 196 | s = conf.BTsocket(peer=peer) 197 | a,b = sndrcv(s,pkts,inter=inter,*args,**kargs) 198 | s.close() 199 | return a,b 200 | 201 | @conf.commands.register 202 | def srbt1(peer, pkts, *args, **kargs): 203 | """send and receive 1 packet using a bluetooth socket""" 204 | a,b = srbt(peer, pkts, *args, **kargs) 205 | if len(a) > 0: 206 | return a[0][1] 207 | 208 | 209 | 210 | conf.BTsocket = BluetoothL2CAPSocket 211 | -------------------------------------------------------------------------------- /scapy/layers/gprs.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | GPRS (General Packet Radio Service) for mobile data communication. 8 | """ 9 | 10 | from scapy.fields import * 11 | from scapy.packet import * 12 | from scapy.layers.inet import IP 13 | 14 | class GPRS(Packet): 15 | name = "GPRSdummy" 16 | fields_desc = [ 17 | StrStopField("dummy","","\x65\x00\x00",1) 18 | ] 19 | 20 | 21 | bind_layers( GPRS, IP, ) 22 | -------------------------------------------------------------------------------- /scapy/layers/hsrp.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | HSRP (Hot Standby Router Protocol): proprietary redundancy protocol for Cisco routers. 8 | """ 9 | 10 | from scapy.fields import * 11 | from scapy.packet import * 12 | from scapy.layers.inet import UDP 13 | 14 | class HSRP(Packet): 15 | name = "HSRP" 16 | fields_desc = [ 17 | ByteField("version", 0), 18 | ByteEnumField("opcode", 0, { 0:"Hello", 1:"Coup", 2:"Resign", 3:"Advertise"}), 19 | ByteEnumField("state", 16, { 0:"Initial", 1:"Learn", 2:"Listen", 4:"Speak", 8:"Standby", 16:"Active"}), 20 | ByteField("hellotime", 3), 21 | ByteField("holdtime", 10), 22 | ByteField("priority", 120), 23 | ByteField("group", 1), 24 | ByteField("reserved", 0), 25 | StrFixedLenField("auth","cisco",8), 26 | IPField("virtualIP","192.168.1.1") ] 27 | 28 | 29 | 30 | 31 | 32 | bind_layers( UDP, HSRP, dport=1985, sport=1985) 33 | -------------------------------------------------------------------------------- /scapy/layers/ir.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | IrDA infrared data communication. 8 | """ 9 | 10 | from scapy.packet import * 11 | from scapy.fields import * 12 | from scapy.layers.l2 import CookedLinux 13 | 14 | 15 | 16 | # IR 17 | 18 | class IrLAPHead(Packet): 19 | name = "IrDA Link Access Protocol Header" 20 | fields_desc = [ XBitField("Address", 0x7f, 7), 21 | BitEnumField("Type", 1, 1, {"Response":0, 22 | "Command":1})] 23 | 24 | class IrLAPCommand(Packet): 25 | name = "IrDA Link Access Protocol Command" 26 | fields_desc = [ XByteField("Control", 0), 27 | XByteField("Format identifier", 0), 28 | XIntField("Source address", 0), 29 | XIntField("Destination address", 0xffffffffL), 30 | XByteField("Discovery flags", 0x1), 31 | ByteEnumField("Slot number", 255, {"final":255}), 32 | XByteField("Version", 0)] 33 | 34 | 35 | class IrLMP(Packet): 36 | name = "IrDA Link Management Protocol" 37 | fields_desc = [ XShortField("Service hints", 0), 38 | XByteField("Character set", 0), 39 | StrField("Device name", "") ] 40 | 41 | 42 | bind_layers( CookedLinux, IrLAPHead, proto=23) 43 | bind_layers( IrLAPHead, IrLAPCommand, Type=1) 44 | bind_layers( IrLAPCommand, IrLMP, ) 45 | -------------------------------------------------------------------------------- /scapy/layers/l2tp.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | L2TP (Layer 2 Tunneling Protocol) for VPNs. 8 | 9 | [RFC 2661] 10 | """ 11 | 12 | import struct 13 | 14 | from scapy.packet import * 15 | from scapy.fields import * 16 | from scapy.layers.inet import UDP 17 | from scapy.layers.ppp import PPP 18 | 19 | class L2TP(Packet): 20 | fields_desc = [ ShortEnumField("pkt_type",2,{2:"data"}), 21 | ShortField("len", None), 22 | ShortField("tunnel_id", 0), 23 | ShortField("session_id", 0), 24 | ShortField("ns", 0), 25 | ShortField("nr", 0), 26 | ShortField("offset", 0) ] 27 | 28 | def post_build(self, pkt, pay): 29 | if self.len is None: 30 | l = len(pkt)+len(pay) 31 | pkt = pkt[:2]+struct.pack("!H", l)+pkt[4:] 32 | return pkt+pay 33 | 34 | 35 | bind_layers( UDP, L2TP, sport=1701, dport=1701) 36 | bind_layers( L2TP, PPP, ) 37 | -------------------------------------------------------------------------------- /scapy/layers/llmnr.py: -------------------------------------------------------------------------------- 1 | from scapy.fields import * 2 | from scapy.packet import * 3 | from scapy.layers.inet import UDP 4 | from scapy.layers.dns import DNSQRField, DNSRRField, DNSRRCountField 5 | 6 | """ 7 | LLMNR (Link Local Multicast Node Resolution). 8 | 9 | [RFC 4795] 10 | """ 11 | 12 | ############################################################################# 13 | ### LLMNR (RFC4795) ### 14 | ############################################################################# 15 | # LLMNR is based on the DNS packet format (RFC1035 Section 4) 16 | # RFC also envisions LLMNR over TCP. Like vista, we don't support it -- arno 17 | 18 | _LLMNR_IPv6_mcast_Addr = "FF02:0:0:0:0:0:1:3" 19 | _LLMNR_IPv4_mcast_addr = "224.0.0.252" 20 | 21 | class LLMNRQuery(Packet): 22 | name = "Link Local Multicast Node Resolution - Query" 23 | fields_desc = [ ShortField("id", 0), 24 | BitField("qr", 0, 1), 25 | BitEnumField("opcode", 0, 4, { 0:"QUERY" }), 26 | BitField("c", 0, 1), 27 | BitField("tc", 0, 2), 28 | BitField("z", 0, 4), 29 | BitEnumField("rcode", 0, 4, { 0:"ok" }), 30 | DNSRRCountField("qdcount", None, "qd"), 31 | DNSRRCountField("ancount", None, "an"), 32 | DNSRRCountField("nscount", None, "ns"), 33 | DNSRRCountField("arcount", None, "ar"), 34 | DNSQRField("qd", "qdcount"), 35 | DNSRRField("an", "ancount"), 36 | DNSRRField("ns", "nscount"), 37 | DNSRRField("ar", "arcount",0)] 38 | overload_fields = {UDP: {"sport": 5355, "dport": 5355 }} 39 | def hashret(self): 40 | return struct.pack("!H", self.id) 41 | 42 | class LLMNRResponse(LLMNRQuery): 43 | name = "Link Local Multicast Node Resolution - Response" 44 | qr = 1 45 | fields_desc = [] 46 | 47 | def answers(self, other): 48 | return (isinstance(other, LLMNRQuery) and 49 | self.id == other.id and 50 | self.qr == 1 and 51 | other.qr == 0) 52 | 53 | def _llmnr_dispatcher(x, *args, **kargs): 54 | cls = Raw 55 | if len(x) >= 3: 56 | if (ord(x[4]) & 0x80): # Response 57 | cls = LLMNRResponse 58 | else: # Query 59 | cls = LLMNRQuery 60 | return cls(x, *args, **kargs) 61 | 62 | bind_bottom_up(UDP, _llmnr_dispatcher, { "dport": 5355 }) 63 | bind_bottom_up(UDP, _llmnr_dispatcher, { "sport": 5355 }) 64 | 65 | # LLMNRQuery(id=RandShort(), qd=DNSQR(qname="vista."))) 66 | 67 | 68 | -------------------------------------------------------------------------------- /scapy/layers/mgcp.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | MGCP (Media Gateway Control Protocol) 8 | 9 | [RFC 2805] 10 | """ 11 | 12 | from scapy.packet import * 13 | from scapy.fields import * 14 | from scapy.layers.inet import UDP 15 | 16 | class MGCP(Packet): 17 | name = "MGCP" 18 | longname = "Media Gateway Control Protocol" 19 | fields_desc = [ StrStopField("verb","AUEP"," ", -1), 20 | StrFixedLenField("sep1"," ",1), 21 | StrStopField("transaction_id","1234567"," ", -1), 22 | StrFixedLenField("sep2"," ",1), 23 | StrStopField("endpoint","dummy@dummy.net"," ", -1), 24 | StrFixedLenField("sep3"," ",1), 25 | StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1), 26 | StrFixedLenField("sep4","\x0a",1), 27 | ] 28 | 29 | 30 | #class MGCP(Packet): 31 | # name = "MGCP" 32 | # longname = "Media Gateway Control Protocol" 33 | # fields_desc = [ ByteEnumField("type",0, ["request","response","others"]), 34 | # ByteField("code0",0), 35 | # ByteField("code1",0), 36 | # ByteField("code2",0), 37 | # ByteField("code3",0), 38 | # ByteField("code4",0), 39 | # IntField("trasid",0), 40 | # IntField("req_time",0), 41 | # ByteField("is_duplicate",0), 42 | # ByteField("req_available",0) ] 43 | # 44 | bind_layers( UDP, MGCP, dport=2727) 45 | bind_layers( UDP, MGCP, sport=2727) 46 | -------------------------------------------------------------------------------- /scapy/layers/mobileip.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Mobile IP. 8 | """ 9 | 10 | from scapy.fields import * 11 | from scapy.packet import * 12 | from scapy.layers.inet import IP,UDP 13 | 14 | 15 | class MobileIP(Packet): 16 | name = "Mobile IP (RFC3344)" 17 | fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ] 18 | 19 | class MobileIPRRQ(Packet): 20 | name = "Mobile IP Registration Request (RFC3344)" 21 | fields_desc = [ XByteField("flags", 0), 22 | ShortField("lifetime", 180), 23 | IPField("homeaddr", "0.0.0.0"), 24 | IPField("haaddr", "0.0.0.0"), 25 | IPField("coaddr", "0.0.0.0"), 26 | LongField("id", 0), ] 27 | 28 | class MobileIPRRP(Packet): 29 | name = "Mobile IP Registration Reply (RFC3344)" 30 | fields_desc = [ ByteField("code", 0), 31 | ShortField("lifetime", 180), 32 | IPField("homeaddr", "0.0.0.0"), 33 | IPField("haaddr", "0.0.0.0"), 34 | LongField("id", 0), ] 35 | 36 | class MobileIPTunnelData(Packet): 37 | name = "Mobile IP Tunnel Data Message (RFC3519)" 38 | fields_desc = [ ByteField("nexthdr", 4), 39 | ShortField("res", 0) ] 40 | 41 | 42 | bind_layers( UDP, MobileIP, sport=434) 43 | bind_layers( UDP, MobileIP, dport=434) 44 | bind_layers( MobileIP, MobileIPRRQ, type=1) 45 | bind_layers( MobileIP, MobileIPRRP, type=3) 46 | bind_layers( MobileIP, MobileIPTunnelData, type=4) 47 | bind_layers( MobileIPTunnelData, IP, nexthdr=4) 48 | -------------------------------------------------------------------------------- /scapy/layers/netflow.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Cisco NetFlow protocol v1 8 | """ 9 | 10 | 11 | from scapy.fields import * 12 | from scapy.packet import * 13 | 14 | # Cisco Netflow Protocol version 1 15 | class NetflowHeader(Packet): 16 | name = "Netflow Header" 17 | fields_desc = [ ShortField("version", 1) ] 18 | 19 | class NetflowHeaderV1(Packet): 20 | name = "Netflow Header V1" 21 | fields_desc = [ ShortField("count", 0), 22 | IntField("sysUptime", 0), 23 | IntField("unixSecs", 0), 24 | IntField("unixNanoSeconds", 0) ] 25 | 26 | 27 | class NetflowRecordV1(Packet): 28 | name = "Netflow Record" 29 | fields_desc = [ IPField("ipsrc", "0.0.0.0"), 30 | IPField("ipdst", "0.0.0.0"), 31 | IPField("nexthop", "0.0.0.0"), 32 | ShortField("inputIfIndex", 0), 33 | ShortField("outpuIfIndex", 0), 34 | IntField("dpkts", 0), 35 | IntField("dbytes", 0), 36 | IntField("starttime", 0), 37 | IntField("endtime", 0), 38 | ShortField("srcport", 0), 39 | ShortField("dstport", 0), 40 | ShortField("padding", 0), 41 | ByteField("proto", 0), 42 | ByteField("tos", 0), 43 | IntField("padding1", 0), 44 | IntField("padding2", 0) ] 45 | 46 | 47 | bind_layers( NetflowHeader, NetflowHeaderV1, version=1) 48 | bind_layers( NetflowHeaderV1, NetflowRecordV1, ) 49 | -------------------------------------------------------------------------------- /scapy/layers/ntp.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | NTP (Network Time Protocol). 8 | """ 9 | 10 | import time 11 | from scapy.packet import * 12 | from scapy.fields import * 13 | from scapy.layers.inet import UDP 14 | 15 | 16 | # seconds between 01-01-1900 and 01-01-1970 17 | _NTP_BASETIME = 2208988800 18 | 19 | class TimeStampField(FixedPointField): 20 | def __init__(self, name, default): 21 | FixedPointField.__init__(self, name, default, 64, 32) 22 | 23 | def i2repr(self, pkt, val): 24 | if val is None: 25 | return "--" 26 | val = self.i2h(pkt,val) 27 | if val < _NTP_BASETIME: 28 | return val 29 | return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(val-_NTP_BASETIME)) 30 | 31 | def any2i(self, pkt, val): 32 | if type(val) is str: 33 | return int(time.mktime(time.strptime(val))) + _NTP_BASETIME + 3600 # XXX 34 | return FixedPointField.any2i(self,pkt,val) 35 | 36 | def i2m(self, pkt, val): 37 | if val is None: 38 | val = FixedPointField.any2i(self, pkt, time.time()+_NTP_BASETIME) 39 | return FixedPointField.i2m(self, pkt, val) 40 | 41 | 42 | 43 | class NTP(Packet): 44 | # RFC 1769 45 | name = "NTP" 46 | fields_desc = [ 47 | BitEnumField('leap', 0, 2, 48 | { 0: 'nowarning', 49 | 1: 'longminute', 50 | 2: 'shortminute', 51 | 3: 'notsync'}), 52 | BitField('version', 3, 3), 53 | BitEnumField('mode', 3, 3, 54 | { 0: 'reserved', 55 | 1: 'sym_active', 56 | 2: 'sym_passive', 57 | 3: 'client', 58 | 4: 'server', 59 | 5: 'broadcast', 60 | 6: 'control', 61 | 7: 'private'}), 62 | BitField('stratum', 2, 8), 63 | BitField('poll', 0xa, 8), ### XXX : it's a signed int 64 | BitField('precision', 0, 8), ### XXX : it's a signed int 65 | FixedPointField('delay', 0, size=32, frac_bits=16), 66 | FixedPointField('dispersion', 0, size=32, frac_bits=16), 67 | IPField('id', "127.0.0.1"), 68 | TimeStampField('ref', 0), 69 | TimeStampField('orig', None), # None means current time 70 | TimeStampField('recv', 0), 71 | TimeStampField('sent', None) 72 | ] 73 | def mysummary(self): 74 | return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%") 75 | 76 | 77 | bind_layers( UDP, NTP, dport=123, sport=123) 78 | -------------------------------------------------------------------------------- /scapy/layers/pflog.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | PFLog: OpenBSD PF packet filter logging. 8 | """ 9 | 10 | from scapy.packet import * 11 | from scapy.fields import * 12 | from scapy.layers.inet import IP 13 | if conf.ipv6_enabled: 14 | from scapy.layers.inet6 import IPv6 15 | from scapy.config import conf 16 | 17 | class PFLog(Packet): 18 | name = "PFLog" 19 | # from OpenBSD src/sys/net/pfvar.h and src/sys/net/if_pflog.h 20 | fields_desc = [ ByteField("hdrlen", 0), 21 | ByteEnumField("addrfamily", 2, {socket.AF_INET: "IPv4", 22 | socket.AF_INET6: "IPv6"}), 23 | ByteEnumField("action", 1, {0: "pass", 1: "drop", 24 | 2: "scrub", 3: "no-scrub", 25 | 4: "nat", 5: "no-nat", 26 | 6: "binat", 7: "no-binat", 27 | 8: "rdr", 9: "no-rdr", 28 | 10: "syn-proxy-drop" }), 29 | ByteEnumField("reason", 0, {0: "match", 1: "bad-offset", 30 | 2: "fragment", 3: "short", 31 | 4: "normalize", 5: "memory", 32 | 6: "bad-timestamp", 33 | 7: "congestion", 34 | 8: "ip-options", 35 | 9: "proto-cksum", 36 | 10: "state-mismatch", 37 | 11: "state-insert", 38 | 12: "state-limit", 39 | 13: "src-limit", 40 | 14: "syn-proxy" }), 41 | StrFixedLenField("iface", "", 16), 42 | StrFixedLenField("ruleset", "", 16), 43 | SignedIntField("rulenumber", 0), 44 | SignedIntField("subrulenumber", 0), 45 | SignedIntField("uid", 0), 46 | IntField("pid", 0), 47 | SignedIntField("ruleuid", 0), 48 | IntField("rulepid", 0), 49 | ByteEnumField("direction", 255, {0: "inout", 1: "in", 50 | 2:"out", 255: "unknown"}), 51 | StrFixedLenField("pad", "\x00\x00\x00", 3 ) ] 52 | def mysummary(self): 53 | return self.sprintf("%PFLog.addrfamily% %PFLog.action% on %PFLog.iface% by rule %PFLog.rulenumber%") 54 | 55 | bind_layers(PFLog, IP, addrfamily=socket.AF_INET) 56 | if conf.ipv6_enabled: 57 | bind_layers(PFLog, IPv6, addrfamily=socket.AF_INET6) 58 | 59 | conf.l2types.register(117, PFLog) 60 | -------------------------------------------------------------------------------- /scapy/layers/radius.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | RADIUS (Remote Authentication Dial In User Service) 8 | """ 9 | 10 | import struct 11 | from scapy.packet import * 12 | from scapy.fields import * 13 | 14 | class Radius(Packet): 15 | name = "Radius" 16 | fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request", 17 | 2: "Access-Accept", 18 | 3: "Access-Reject", 19 | 4: "Accounting-Request", 20 | 5: "Accounting-Accept", 21 | 6: "Accounting-Status", 22 | 7: "Password-Request", 23 | 8: "Password-Ack", 24 | 9: "Password-Reject", 25 | 10: "Accounting-Message", 26 | 11: "Access-Challenge", 27 | 12: "Status-Server", 28 | 13: "Status-Client", 29 | 21: "Resource-Free-Request", 30 | 22: "Resource-Free-Response", 31 | 23: "Resource-Query-Request", 32 | 24: "Resource-Query-Response", 33 | 25: "Alternate-Resource-Reclaim-Request", 34 | 26: "NAS-Reboot-Request", 35 | 27: "NAS-Reboot-Response", 36 | 29: "Next-Passcode", 37 | 30: "New-Pin", 38 | 31: "Terminate-Session", 39 | 32: "Password-Expired", 40 | 33: "Event-Request", 41 | 34: "Event-Response", 42 | 40: "Disconnect-Request", 43 | 41: "Disconnect-ACK", 44 | 42: "Disconnect-NAK", 45 | 43: "CoA-Request", 46 | 44: "CoA-ACK", 47 | 45: "CoA-NAK", 48 | 50: "IP-Address-Allocate", 49 | 51: "IP-Address-Release", 50 | 253: "Experimental-use", 51 | 254: "Reserved", 52 | 255: "Reserved"} ), 53 | ByteField("id", 0), 54 | ShortField("len", None), 55 | StrFixedLenField("authenticator","",16) ] 56 | def post_build(self, p, pay): 57 | p += pay 58 | l = self.len 59 | if l is None: 60 | l = len(p) 61 | p = p[:2]+struct.pack("!H",l)+p[4:] 62 | return p 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /scapy/layers/rip.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | RIP (Routing Information Protocol). 8 | """ 9 | 10 | from scapy.packet import * 11 | from scapy.fields import * 12 | from scapy.layers.inet import UDP 13 | 14 | class RIP(Packet): 15 | name = "RIP header" 16 | fields_desc = [ 17 | ByteEnumField("cmd", 1, {1:"req", 2:"resp", 3:"traceOn", 4:"traceOff", 18 | 5:"sun", 6:"trigReq", 7:"trigResp", 8:"trigAck", 19 | 9:"updateReq", 10:"updateResp", 11:"updateAck"}), 20 | ByteField("version", 1), 21 | ShortField("null", 0), 22 | ] 23 | 24 | def guess_payload_class(self, payload): 25 | if payload[:2] == "\xff\xff": 26 | return RIPAuth 27 | else: 28 | return Packet.guess_payload_class(self, payload) 29 | 30 | class RIPEntry(RIP): 31 | name = "RIP entry" 32 | fields_desc = [ 33 | ShortEnumField("AF", 2, {2:"IP"}), 34 | ShortField("RouteTag", 0), 35 | IPField("addr", "0.0.0.0"), 36 | IPField("mask", "0.0.0.0"), 37 | IPField("nextHop", "0.0.0.0"), 38 | IntEnumField("metric", 1, {16:"Unreach"}), 39 | ] 40 | 41 | class RIPAuth(Packet): 42 | name = "RIP authentication" 43 | fields_desc = [ 44 | ShortEnumField("AF", 0xffff, {0xffff:"Auth"}), 45 | ShortEnumField("authtype", 2, {1:"md5authdata", 2:"simple", 3:"md5"}), 46 | ConditionalField(StrFixedLenField("password", None, 16), 47 | lambda pkt: pkt.authtype == 2), 48 | ConditionalField(ShortField("digestoffset", 0), 49 | lambda pkt: pkt.authtype == 3), 50 | ConditionalField(ByteField("keyid", 0), 51 | lambda pkt: pkt.authtype == 3), 52 | ConditionalField(ByteField("authdatalen", 0), 53 | lambda pkt: pkt.authtype == 3), 54 | ConditionalField(IntField("seqnum", 0), 55 | lambda pkt: pkt.authtype == 3), 56 | ConditionalField(StrFixedLenField("zeropad", None, 8), 57 | lambda pkt: pkt.authtype == 3), 58 | ConditionalField(StrLenField("authdata", None, 59 | length_from=lambda pkt: pkt.md5datalen), 60 | lambda pkt: pkt.authtype == 1) 61 | ] 62 | 63 | def pre_dissect(self, s): 64 | if s[2:4] == "\x00\x01": 65 | self.md5datalen = len(s) - 4 66 | 67 | return s 68 | 69 | 70 | bind_layers( UDP, RIP, sport=520) 71 | bind_layers( UDP, RIP, dport=520) 72 | bind_layers( RIP, RIPEntry, ) 73 | bind_layers( RIPEntry, RIPEntry, ) 74 | bind_layers( RIPAuth, RIPEntry, ) 75 | -------------------------------------------------------------------------------- /scapy/layers/rtp.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | RTP (Real-time Transport Protocol). 8 | """ 9 | 10 | from scapy.packet import * 11 | from scapy.fields import * 12 | 13 | _rtp_payload_types = { 14 | # http://www.iana.org/assignments/rtp-parameters 15 | 0: 'G.711 PCMU', 3: 'GSM', 16 | 4: 'G723', 5: 'DVI4', 17 | 6: 'DVI4', 7: 'LPC', 18 | 8: 'PCMA', 9: 'G722', 19 | 10: 'L16', 11: 'L16', 20 | 12: 'QCELP', 13: 'CN', 21 | 14: 'MPA', 15: 'G728', 22 | 16: 'DVI4', 17: 'DVI4', 23 | 18: 'G729', 25: 'CelB', 24 | 26: 'JPEG', 28: 'nv', 25 | 31: 'H261', 32: 'MPV', 26 | 33: 'MP2T', 34: 'H263' } 27 | 28 | class RTP(Packet): 29 | name="RTP" 30 | fields_desc = [ BitField('version', 2, 2), 31 | BitField('padding', 0, 1), 32 | BitField('extension', 0, 1), 33 | BitFieldLenField('numsync', None, 4, count_of='sync'), 34 | BitField('marker', 0, 1), 35 | BitEnumField('payload', 0, 7, _rtp_payload_types), 36 | ShortField('sequence', 0), 37 | IntField('timestamp', 0), 38 | IntField('sourcesync', 0), 39 | FieldListField('sync', [], IntField("id",0), count_from=lambda pkt:pkt.numsync) ] 40 | 41 | -------------------------------------------------------------------------------- /scapy/layers/sebek.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Sebek: Linux kernel module for data collection on honeypots. 8 | """ 9 | 10 | from scapy.fields import * 11 | from scapy.packet import * 12 | from scapy.layers.inet import UDP 13 | 14 | 15 | ### SEBEK 16 | 17 | 18 | class SebekHead(Packet): 19 | name = "Sebek header" 20 | fields_desc = [ XIntField("magic", 0xd0d0d0), 21 | ShortField("version", 1), 22 | ShortEnumField("type", 0, {"read":0, "write":1, 23 | "socket":2, "open":3}), 24 | IntField("counter", 0), 25 | IntField("time_sec", 0), 26 | IntField("time_usec", 0) ] 27 | def mysummary(self): 28 | return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%") 29 | 30 | # we need this because Sebek headers differ between v1 and v3, and 31 | # between v3 type socket and v3 others 32 | 33 | class SebekV1(Packet): 34 | name = "Sebek v1" 35 | fields_desc = [ IntField("pid", 0), 36 | IntField("uid", 0), 37 | IntField("fd", 0), 38 | StrFixedLenField("command", "", 12), 39 | FieldLenField("data_length", None, "data",fmt="I"), 40 | StrLenField("data", "", length_from=lambda x:x.data_length) ] 41 | def mysummary(self): 42 | if isinstance(self.underlayer, SebekHead): 43 | return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)") 44 | else: 45 | return self.sprintf("Sebek v1 (%SebekV1.command%)") 46 | 47 | class SebekV3(Packet): 48 | name = "Sebek v3" 49 | fields_desc = [ IntField("parent_pid", 0), 50 | IntField("pid", 0), 51 | IntField("uid", 0), 52 | IntField("fd", 0), 53 | IntField("inode", 0), 54 | StrFixedLenField("command", "", 12), 55 | FieldLenField("data_length", None, "data",fmt="I"), 56 | StrLenField("data", "", length_from=lambda x:x.data_length) ] 57 | def mysummary(self): 58 | if isinstance(self.underlayer, SebekHead): 59 | return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)") 60 | else: 61 | return self.sprintf("Sebek v3 (%SebekV3.command%)") 62 | 63 | class SebekV2(SebekV3): 64 | def mysummary(self): 65 | if isinstance(self.underlayer, SebekHead): 66 | return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)") 67 | else: 68 | return self.sprintf("Sebek v2 (%SebekV2.command%)") 69 | 70 | class SebekV3Sock(Packet): 71 | name = "Sebek v2 socket" 72 | fields_desc = [ IntField("parent_pid", 0), 73 | IntField("pid", 0), 74 | IntField("uid", 0), 75 | IntField("fd", 0), 76 | IntField("inode", 0), 77 | StrFixedLenField("command", "", 12), 78 | IntField("data_length", 15), 79 | IPField("dip", "127.0.0.1"), 80 | ShortField("dport", 0), 81 | IPField("sip", "127.0.0.1"), 82 | ShortField("sport", 0), 83 | ShortEnumField("call", 0, { "bind":2, 84 | "connect":3, "listen":4, 85 | "accept":5, "sendmsg":16, 86 | "recvmsg":17, "sendto":11, 87 | "recvfrom":12}), 88 | ByteEnumField("proto", 0, IP_PROTOS) ] 89 | def mysummary(self): 90 | if isinstance(self.underlayer, SebekHead): 91 | return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)") 92 | else: 93 | return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)") 94 | 95 | class SebekV2Sock(SebekV3Sock): 96 | def mysummary(self): 97 | if isinstance(self.underlayer, SebekHead): 98 | return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)") 99 | else: 100 | return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)") 101 | 102 | bind_layers( UDP, SebekHead, sport=1101) 103 | bind_layers( UDP, SebekHead, dport=1101) 104 | bind_layers( UDP, SebekHead, dport=1101, sport=1101) 105 | bind_layers( SebekHead, SebekV1, version=1) 106 | bind_layers( SebekHead, SebekV2Sock, version=2, type=2) 107 | bind_layers( SebekHead, SebekV2, version=2) 108 | bind_layers( SebekHead, SebekV3Sock, version=3, type=2) 109 | bind_layers( SebekHead, SebekV3, version=3) 110 | -------------------------------------------------------------------------------- /scapy/layers/skinny.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Cisco Skinny protocol. 8 | """ 9 | 10 | from scapy.packet import * 11 | from scapy.fields import * 12 | from scapy.layers.inet import TCP 13 | 14 | # shamelessly ripped from Ethereal dissector 15 | skinny_messages = { 16 | # Station -> Callmanager 17 | 0x0000: "KeepAliveMessage", 18 | 0x0001: "RegisterMessage", 19 | 0x0002: "IpPortMessage", 20 | 0x0003: "KeypadButtonMessage", 21 | 0x0004: "EnblocCallMessage", 22 | 0x0005: "StimulusMessage", 23 | 0x0006: "OffHookMessage", 24 | 0x0007: "OnHookMessage", 25 | 0x0008: "HookFlashMessage", 26 | 0x0009: "ForwardStatReqMessage", 27 | 0x000A: "SpeedDialStatReqMessage", 28 | 0x000B: "LineStatReqMessage", 29 | 0x000C: "ConfigStatReqMessage", 30 | 0x000D: "TimeDateReqMessage", 31 | 0x000E: "ButtonTemplateReqMessage", 32 | 0x000F: "VersionReqMessage", 33 | 0x0010: "CapabilitiesResMessage", 34 | 0x0011: "MediaPortListMessage", 35 | 0x0012: "ServerReqMessage", 36 | 0x0020: "AlarmMessage", 37 | 0x0021: "MulticastMediaReceptionAck", 38 | 0x0022: "OpenReceiveChannelAck", 39 | 0x0023: "ConnectionStatisticsRes", 40 | 0x0024: "OffHookWithCgpnMessage", 41 | 0x0025: "SoftKeySetReqMessage", 42 | 0x0026: "SoftKeyEventMessage", 43 | 0x0027: "UnregisterMessage", 44 | 0x0028: "SoftKeyTemplateReqMessage", 45 | 0x0029: "RegisterTokenReq", 46 | 0x002A: "MediaTransmissionFailure", 47 | 0x002B: "HeadsetStatusMessage", 48 | 0x002C: "MediaResourceNotification", 49 | 0x002D: "RegisterAvailableLinesMessage", 50 | 0x002E: "DeviceToUserDataMessage", 51 | 0x002F: "DeviceToUserDataResponseMessage", 52 | 0x0030: "UpdateCapabilitiesMessage", 53 | 0x0031: "OpenMultiMediaReceiveChannelAckMessage", 54 | 0x0032: "ClearConferenceMessage", 55 | 0x0033: "ServiceURLStatReqMessage", 56 | 0x0034: "FeatureStatReqMessage", 57 | 0x0035: "CreateConferenceResMessage", 58 | 0x0036: "DeleteConferenceResMessage", 59 | 0x0037: "ModifyConferenceResMessage", 60 | 0x0038: "AddParticipantResMessage", 61 | 0x0039: "AuditConferenceResMessage", 62 | 0x0040: "AuditParticipantResMessage", 63 | 0x0041: "DeviceToUserDataVersion1Message", 64 | # Callmanager -> Station */ 65 | 0x0081: "RegisterAckMessage", 66 | 0x0082: "StartToneMessage", 67 | 0x0083: "StopToneMessage", 68 | 0x0085: "SetRingerMessage", 69 | 0x0086: "SetLampMessage", 70 | 0x0087: "SetHkFDetectMessage", 71 | 0x0088: "SetSpeakerModeMessage", 72 | 0x0089: "SetMicroModeMessage", 73 | 0x008A: "StartMediaTransmission", 74 | 0x008B: "StopMediaTransmission", 75 | 0x008C: "StartMediaReception", 76 | 0x008D: "StopMediaReception", 77 | 0x008F: "CallInfoMessage", 78 | 0x0090: "ForwardStatMessage", 79 | 0x0091: "SpeedDialStatMessage", 80 | 0x0092: "LineStatMessage", 81 | 0x0093: "ConfigStatMessage", 82 | 0x0094: "DefineTimeDate", 83 | 0x0095: "StartSessionTransmission", 84 | 0x0096: "StopSessionTransmission", 85 | 0x0097: "ButtonTemplateMessage", 86 | 0x0098: "VersionMessage", 87 | 0x0099: "DisplayTextMessage", 88 | 0x009A: "ClearDisplay", 89 | 0x009B: "CapabilitiesReqMessage", 90 | 0x009C: "EnunciatorCommandMessage", 91 | 0x009D: "RegisterRejectMessage", 92 | 0x009E: "ServerResMessage", 93 | 0x009F: "Reset", 94 | 0x0100: "KeepAliveAckMessage", 95 | 0x0101: "StartMulticastMediaReception", 96 | 0x0102: "StartMulticastMediaTransmission", 97 | 0x0103: "StopMulticastMediaReception", 98 | 0x0104: "StopMulticastMediaTransmission", 99 | 0x0105: "OpenReceiveChannel", 100 | 0x0106: "CloseReceiveChannel", 101 | 0x0107: "ConnectionStatisticsReq", 102 | 0x0108: "SoftKeyTemplateResMessage", 103 | 0x0109: "SoftKeySetResMessage", 104 | 0x0110: "SelectSoftKeysMessage", 105 | 0x0111: "CallStateMessage", 106 | 0x0112: "DisplayPromptStatusMessage", 107 | 0x0113: "ClearPromptStatusMessage", 108 | 0x0114: "DisplayNotifyMessage", 109 | 0x0115: "ClearNotifyMessage", 110 | 0x0116: "ActivateCallPlaneMessage", 111 | 0x0117: "DeactivateCallPlaneMessage", 112 | 0x0118: "UnregisterAckMessage", 113 | 0x0119: "BackSpaceReqMessage", 114 | 0x011A: "RegisterTokenAck", 115 | 0x011B: "RegisterTokenReject", 116 | 0x0042: "DeviceToUserDataResponseVersion1Message", 117 | 0x011C: "StartMediaFailureDetection", 118 | 0x011D: "DialedNumberMessage", 119 | 0x011E: "UserToDeviceDataMessage", 120 | 0x011F: "FeatureStatMessage", 121 | 0x0120: "DisplayPriNotifyMessage", 122 | 0x0121: "ClearPriNotifyMessage", 123 | 0x0122: "StartAnnouncementMessage", 124 | 0x0123: "StopAnnouncementMessage", 125 | 0x0124: "AnnouncementFinishMessage", 126 | 0x0127: "NotifyDtmfToneMessage", 127 | 0x0128: "SendDtmfToneMessage", 128 | 0x0129: "SubscribeDtmfPayloadReqMessage", 129 | 0x012A: "SubscribeDtmfPayloadResMessage", 130 | 0x012B: "SubscribeDtmfPayloadErrMessage", 131 | 0x012C: "UnSubscribeDtmfPayloadReqMessage", 132 | 0x012D: "UnSubscribeDtmfPayloadResMessage", 133 | 0x012E: "UnSubscribeDtmfPayloadErrMessage", 134 | 0x012F: "ServiceURLStatMessage", 135 | 0x0130: "CallSelectStatMessage", 136 | 0x0131: "OpenMultiMediaChannelMessage", 137 | 0x0132: "StartMultiMediaTransmission", 138 | 0x0133: "StopMultiMediaTransmission", 139 | 0x0134: "MiscellaneousCommandMessage", 140 | 0x0135: "FlowControlCommandMessage", 141 | 0x0136: "CloseMultiMediaReceiveChannel", 142 | 0x0137: "CreateConferenceReqMessage", 143 | 0x0138: "DeleteConferenceReqMessage", 144 | 0x0139: "ModifyConferenceReqMessage", 145 | 0x013A: "AddParticipantReqMessage", 146 | 0x013B: "DropParticipantReqMessage", 147 | 0x013C: "AuditConferenceReqMessage", 148 | 0x013D: "AuditParticipantReqMessage", 149 | 0x013F: "UserToDeviceDataVersion1Message", 150 | } 151 | 152 | 153 | 154 | class Skinny(Packet): 155 | name="Skinny" 156 | fields_desc = [ LEIntField("len",0), 157 | LEIntField("res",0), 158 | LEIntEnumField("msg",0,skinny_messages) ] 159 | 160 | bind_layers( TCP, Skinny, dport=2000) 161 | bind_layers( TCP, Skinny, sport=2000) 162 | -------------------------------------------------------------------------------- /scapy/layers/snmp.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | SNMP (Simple Network Management Protocol). 8 | """ 9 | 10 | from scapy.asn1packet import * 11 | from scapy.asn1fields import * 12 | from scapy.layers.inet import UDP 13 | 14 | ########## 15 | ## SNMP ## 16 | ########## 17 | 18 | ######[ ASN1 class ]###### 19 | 20 | class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL): 21 | name="SNMP" 22 | PDU_GET = 0xa0 23 | PDU_NEXT = 0xa1 24 | PDU_RESPONSE = 0xa2 25 | PDU_SET = 0xa3 26 | PDU_TRAPv1 = 0xa4 27 | PDU_BULK = 0xa5 28 | PDU_INFORM = 0xa6 29 | PDU_TRAPv2 = 0xa7 30 | 31 | 32 | class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE): 33 | tag = ASN1_Class_SNMP.PDU_GET 34 | 35 | class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE): 36 | tag = ASN1_Class_SNMP.PDU_NEXT 37 | 38 | class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE): 39 | tag = ASN1_Class_SNMP.PDU_RESPONSE 40 | 41 | class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE): 42 | tag = ASN1_Class_SNMP.PDU_SET 43 | 44 | class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE): 45 | tag = ASN1_Class_SNMP.PDU_TRAPv1 46 | 47 | class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE): 48 | tag = ASN1_Class_SNMP.PDU_BULK 49 | 50 | class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE): 51 | tag = ASN1_Class_SNMP.PDU_INFORM 52 | 53 | class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE): 54 | tag = ASN1_Class_SNMP.PDU_TRAPv2 55 | 56 | 57 | ######[ BER codecs ]####### 58 | 59 | class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE): 60 | tag = ASN1_Class_SNMP.PDU_GET 61 | 62 | class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE): 63 | tag = ASN1_Class_SNMP.PDU_NEXT 64 | 65 | class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE): 66 | tag = ASN1_Class_SNMP.PDU_RESPONSE 67 | 68 | class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE): 69 | tag = ASN1_Class_SNMP.PDU_SET 70 | 71 | class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE): 72 | tag = ASN1_Class_SNMP.PDU_TRAPv1 73 | 74 | class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE): 75 | tag = ASN1_Class_SNMP.PDU_BULK 76 | 77 | class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE): 78 | tag = ASN1_Class_SNMP.PDU_INFORM 79 | 80 | class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE): 81 | tag = ASN1_Class_SNMP.PDU_TRAPv2 82 | 83 | 84 | 85 | ######[ ASN1 fields ]###### 86 | 87 | class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE): 88 | ASN1_tag = ASN1_Class_SNMP.PDU_GET 89 | 90 | class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE): 91 | ASN1_tag = ASN1_Class_SNMP.PDU_NEXT 92 | 93 | class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE): 94 | ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE 95 | 96 | class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE): 97 | ASN1_tag = ASN1_Class_SNMP.PDU_SET 98 | 99 | class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE): 100 | ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1 101 | 102 | class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE): 103 | ASN1_tag = ASN1_Class_SNMP.PDU_BULK 104 | 105 | class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE): 106 | ASN1_tag = ASN1_Class_SNMP.PDU_INFORM 107 | 108 | class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE): 109 | ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2 110 | 111 | 112 | 113 | ######[ SNMP Packet ]###### 114 | 115 | SNMP_error = { 0: "no_error", 116 | 1: "too_big", 117 | 2: "no_such_name", 118 | 3: "bad_value", 119 | 4: "read_only", 120 | 5: "generic_error", 121 | 6: "no_access", 122 | 7: "wrong_type", 123 | 8: "wrong_length", 124 | 9: "wrong_encoding", 125 | 10: "wrong_value", 126 | 11: "no_creation", 127 | 12: "inconsistent_value", 128 | 13: "ressource_unavailable", 129 | 14: "commit_failed", 130 | 15: "undo_failed", 131 | 16: "authorization_error", 132 | 17: "not_writable", 133 | 18: "inconsistent_name", 134 | } 135 | 136 | SNMP_trap_types = { 0: "cold_start", 137 | 1: "warm_start", 138 | 2: "link_down", 139 | 3: "link_up", 140 | 4: "auth_failure", 141 | 5: "egp_neigh_loss", 142 | 6: "enterprise_specific", 143 | } 144 | 145 | class SNMPvarbind(ASN1_Packet): 146 | ASN1_codec = ASN1_Codecs.BER 147 | ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"), 148 | ASN1F_field("value",ASN1_NULL(0)) 149 | ) 150 | 151 | 152 | class SNMPget(ASN1_Packet): 153 | ASN1_codec = ASN1_Codecs.BER 154 | ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0), 155 | ASN1F_enum_INTEGER("error",0, SNMP_error), 156 | ASN1F_INTEGER("error_index",0), 157 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 158 | ) 159 | 160 | class SNMPnext(ASN1_Packet): 161 | ASN1_codec = ASN1_Codecs.BER 162 | ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0), 163 | ASN1F_enum_INTEGER("error",0, SNMP_error), 164 | ASN1F_INTEGER("error_index",0), 165 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 166 | ) 167 | 168 | class SNMPresponse(ASN1_Packet): 169 | ASN1_codec = ASN1_Codecs.BER 170 | ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0), 171 | ASN1F_enum_INTEGER("error",0, SNMP_error), 172 | ASN1F_INTEGER("error_index",0), 173 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 174 | ) 175 | 176 | class SNMPset(ASN1_Packet): 177 | ASN1_codec = ASN1_Codecs.BER 178 | ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0), 179 | ASN1F_enum_INTEGER("error",0, SNMP_error), 180 | ASN1F_INTEGER("error_index",0), 181 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 182 | ) 183 | 184 | class SNMPtrapv1(ASN1_Packet): 185 | ASN1_codec = ASN1_Codecs.BER 186 | ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_OID("enterprise", "1.3"), 187 | ASN1F_IPADDRESS("agent_addr","0.0.0.0"), 188 | ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types), 189 | ASN1F_INTEGER("specific_trap", 0), 190 | ASN1F_TIME_TICKS("time_stamp", IntAutoTime()), 191 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 192 | ) 193 | 194 | class SNMPbulk(ASN1_Packet): 195 | ASN1_codec = ASN1_Codecs.BER 196 | ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0), 197 | ASN1F_INTEGER("non_repeaters",0), 198 | ASN1F_INTEGER("max_repetitions",0), 199 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 200 | ) 201 | 202 | class SNMPinform(ASN1_Packet): 203 | ASN1_codec = ASN1_Codecs.BER 204 | ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0), 205 | ASN1F_enum_INTEGER("error",0, SNMP_error), 206 | ASN1F_INTEGER("error_index",0), 207 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 208 | ) 209 | 210 | class SNMPtrapv2(ASN1_Packet): 211 | ASN1_codec = ASN1_Codecs.BER 212 | ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0), 213 | ASN1F_enum_INTEGER("error",0, SNMP_error), 214 | ASN1F_INTEGER("error_index",0), 215 | ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 216 | ) 217 | 218 | 219 | class SNMP(ASN1_Packet): 220 | ASN1_codec = ASN1_Codecs.BER 221 | ASN1_root = ASN1F_SEQUENCE( 222 | ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}), 223 | ASN1F_STRING("community","public"), 224 | ASN1F_CHOICE("PDU", SNMPget(), 225 | SNMPget, SNMPnext, SNMPresponse, SNMPset, 226 | SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2) 227 | ) 228 | def answers(self, other): 229 | return ( isinstance(self.PDU, SNMPresponse) and 230 | ( isinstance(other.PDU, SNMPget) or 231 | isinstance(other.PDU, SNMPnext) or 232 | isinstance(other.PDU, SNMPset) ) and 233 | self.PDU.id == other.PDU.id ) 234 | 235 | bind_layers( UDP, SNMP, sport=161) 236 | bind_layers( UDP, SNMP, dport=161) 237 | bind_layers( UDP, SNMP, sport=162) 238 | bind_layers( UDP, SNMP, dport=162) 239 | 240 | def snmpwalk(dst, oid="1", community="public"): 241 | try: 242 | while 1: 243 | r = sr1(IP(dst=dst)/UDP(sport=RandShort())/SNMP(community=community, PDU=SNMPnext(varbindlist=[SNMPvarbind(oid=oid)])),timeout=2, chainCC=1, verbose=0, retry=2) 244 | if ICMP in r: 245 | print repr(r) 246 | break 247 | if r is None: 248 | print "No answers" 249 | break 250 | print "%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value) 251 | oid = r[SNMPvarbind].oid 252 | 253 | except KeyboardInterrupt: 254 | pass 255 | 256 | -------------------------------------------------------------------------------- /scapy/layers/vrrp.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## Copyright (C) 6WIND 5 | ## This program is published under a GPLv2 license 6 | 7 | """ 8 | VRRP (Virtual Router Redundancy Protocol). 9 | """ 10 | 11 | from scapy.packet import * 12 | from scapy.fields import * 13 | from scapy.layers.inet import IP 14 | 15 | IPPROTO_VRRP=112 16 | 17 | # RFC 3768 - Virtual Router Redundancy Protocol (VRRP) 18 | class VRRP(Packet): 19 | fields_desc = [ 20 | BitField("version" , 2, 4), 21 | BitField("type" , 1, 4), 22 | ByteField("vrid", 1), 23 | ByteField("priority", 100), 24 | FieldLenField("ipcount", None, count_of="addrlist", fmt="B"), 25 | ByteField("authtype", 0), 26 | ByteField("adv", 1), 27 | XShortField("chksum", None), 28 | FieldListField("addrlist", [], IPField("", "0.0.0.0"), 29 | count_from = lambda pkt: pkt.ipcount), 30 | IntField("auth1", 0), 31 | IntField("auth2", 0) ] 32 | 33 | def post_build(self, p, pay): 34 | if self.chksum is None: 35 | ck = checksum(p) 36 | p = p[:6]+chr(ck>>8)+chr(ck&0xff)+p[8:] 37 | return p 38 | 39 | bind_layers( IP, VRRP, proto=IPPROTO_VRRP) 40 | -------------------------------------------------------------------------------- /scapy/layers/x509.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | X.509 certificates. 8 | """ 9 | 10 | from scapy.asn1packet import * 11 | from scapy.asn1fields import * 12 | 13 | ########## 14 | ## X509 ## 15 | ########## 16 | 17 | ######[ ASN1 class ]###### 18 | 19 | class ASN1_Class_X509(ASN1_Class_UNIVERSAL): 20 | name="X509" 21 | CONT0 = 0xa0 22 | CONT1 = 0xa1 23 | CONT2 = 0xa2 24 | CONT3 = 0xa3 25 | 26 | class ASN1_X509_CONT0(ASN1_SEQUENCE): 27 | tag = ASN1_Class_X509.CONT0 28 | 29 | class ASN1_X509_CONT1(ASN1_SEQUENCE): 30 | tag = ASN1_Class_X509.CONT1 31 | 32 | class ASN1_X509_CONT2(ASN1_SEQUENCE): 33 | tag = ASN1_Class_X509.CONT2 34 | 35 | class ASN1_X509_CONT3(ASN1_SEQUENCE): 36 | tag = ASN1_Class_X509.CONT3 37 | 38 | ######[ BER codecs ]####### 39 | 40 | class BERcodec_X509_CONT0(BERcodec_SEQUENCE): 41 | tag = ASN1_Class_X509.CONT0 42 | 43 | class BERcodec_X509_CONT1(BERcodec_SEQUENCE): 44 | tag = ASN1_Class_X509.CONT1 45 | 46 | class BERcodec_X509_CONT2(BERcodec_SEQUENCE): 47 | tag = ASN1_Class_X509.CONT2 48 | 49 | class BERcodec_X509_CONT3(BERcodec_SEQUENCE): 50 | tag = ASN1_Class_X509.CONT3 51 | 52 | ######[ ASN1 fields ]###### 53 | 54 | class ASN1F_X509_CONT0(ASN1F_SEQUENCE): 55 | ASN1_tag = ASN1_Class_X509.CONT0 56 | 57 | class ASN1F_X509_CONT1(ASN1F_SEQUENCE): 58 | ASN1_tag = ASN1_Class_X509.CONT1 59 | 60 | class ASN1F_X509_CONT2(ASN1F_SEQUENCE): 61 | ASN1_tag = ASN1_Class_X509.CONT2 62 | 63 | class ASN1F_X509_CONT3(ASN1F_SEQUENCE): 64 | ASN1_tag = ASN1_Class_X509.CONT3 65 | 66 | ######[ X509 packets ]###### 67 | 68 | class X509RDN(ASN1_Packet): 69 | ASN1_codec = ASN1_Codecs.BER 70 | ASN1_root = ASN1F_SET( 71 | ASN1F_SEQUENCE( ASN1F_OID("oid","2.5.4.6"), 72 | ASN1F_PRINTABLE_STRING("value","") 73 | ) 74 | ) 75 | 76 | class X509v3Ext(ASN1_Packet): 77 | ASN1_codec = ASN1_Codecs.BER 78 | ASN1_root = ASN1F_field("val",ASN1_NULL(0)) 79 | 80 | 81 | class X509Cert(ASN1_Packet): 82 | ASN1_codec = ASN1_Codecs.BER 83 | ASN1_root = ASN1F_SEQUENCE( 84 | ASN1F_SEQUENCE( 85 | ASN1F_optionnal(ASN1F_X509_CONT0(ASN1F_INTEGER("version",3))), 86 | ASN1F_INTEGER("sn",1), 87 | ASN1F_SEQUENCE(ASN1F_OID("sign_algo","1.2.840.113549.1.1.5"), 88 | ASN1F_field("sa_value",ASN1_NULL(0))), 89 | ASN1F_SEQUENCE_OF("issuer",[],X509RDN), 90 | ASN1F_SEQUENCE(ASN1F_UTC_TIME("not_before",ZuluTime(-600)), # ten minutes ago 91 | ASN1F_UTC_TIME("not_after",ZuluTime(+86400))), # for 24h 92 | ASN1F_SEQUENCE_OF("subject",[],X509RDN), 93 | ASN1F_SEQUENCE( 94 | ASN1F_SEQUENCE(ASN1F_OID("pubkey_algo","1.2.840.113549.1.1.1"), 95 | ASN1F_field("pk_value",ASN1_NULL(0))), 96 | ASN1F_BIT_STRING("pubkey","") 97 | ), 98 | ASN1F_optionnal(ASN1F_X509_CONT3(ASN1F_SEQUENCE_OF("x509v3ext",[],X509v3Ext))), 99 | 100 | ), 101 | ASN1F_SEQUENCE(ASN1F_OID("sign_algo2","1.2.840.113549.1.1.5"), 102 | ASN1F_field("sa2_value",ASN1_NULL(0))), 103 | ASN1F_BIT_STRING("signature","") 104 | ) 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /scapy/modules/__init__.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Package of extension modules that have to be loaded explicitly. 8 | """ 9 | -------------------------------------------------------------------------------- /scapy/modules/geoip.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | GeoIP: find out the geographical location of IP addresses 8 | """ 9 | 10 | from scapy.data import KnowledgeBase 11 | from scapy.config import conf 12 | 13 | conf.IPCountry_base = "GeoIPCountry4Scapy.gz" 14 | conf.countryLoc_base = "countryLoc.csv" 15 | conf.gnuplot_world = "world.dat" 16 | 17 | 18 | ########################## 19 | ## IP location database ## 20 | ########################## 21 | 22 | class IPCountryKnowledgeBase(KnowledgeBase): 23 | """ 24 | How to generate the base : 25 | db = [] 26 | for l in open("GeoIPCountryWhois.csv").readlines(): 27 | s,e,c = l.split(",")[2:5] 28 | db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1])) 29 | cPickle.dump(gzip.open("xxx","w"),db) 30 | """ 31 | def lazy_init(self): 32 | self.base = load_object(self.filename) 33 | 34 | 35 | class CountryLocKnowledgeBase(KnowledgeBase): 36 | def lazy_init(self): 37 | f=open(self.filename) 38 | self.base = {} 39 | while 1: 40 | l = f.readline() 41 | if not l: 42 | break 43 | l = l.strip().split(",") 44 | if len(l) != 3: 45 | continue 46 | c,lat,long = l 47 | 48 | self.base[c] = (float(long),float(lat)) 49 | f.close() 50 | 51 | 52 | 53 | @conf.commands.register 54 | def locate_ip(ip): 55 | """Get geographic coordinates from IP using geoip database""" 56 | ip=map(int,ip.split(".")) 57 | ip = ip[3]+(ip[2]<<8L)+(ip[1]<<16L)+(ip[0]<<24L) 58 | 59 | cloc = country_loc_kdb.get_base() 60 | db = IP_country_kdb.get_base() 61 | 62 | d=0 63 | f=len(db)-1 64 | while (f-d) > 1: 65 | guess = (d+f)/2 66 | if ip > db[guess][0]: 67 | d = guess 68 | else: 69 | f = guess 70 | s,e,c = db[guess] 71 | if s <= ip and ip <= e: 72 | return cloc.get(c,None) 73 | 74 | 75 | 76 | 77 | 78 | conf.IP_country_kdb = IPCountryKnowledgeBase(conf.IPCountry_base) 79 | conf.country_loc_kdb = CountryLocKnowledgeBase(conf.countryLoc_base) 80 | -------------------------------------------------------------------------------- /scapy/modules/nmap.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Clone of Nmap's first generation OS fingerprinting. 8 | """ 9 | 10 | import os 11 | 12 | from scapy.data import KnowledgeBase 13 | from scapy.config import conf 14 | from scapy.arch import WINDOWS 15 | 16 | 17 | if WINDOWS: 18 | conf.nmap_base=os.environ["ProgramFiles"] + "\\nmap\\nmap-os-fingerprints" 19 | else: 20 | conf.nmap_base ="/usr/share/nmap/nmap-os-fingerprints" 21 | 22 | 23 | ###################### 24 | ## nmap OS fp stuff ## 25 | ###################### 26 | 27 | 28 | class NmapKnowledgeBase(KnowledgeBase): 29 | def lazy_init(self): 30 | try: 31 | f=open(self.filename) 32 | except IOError: 33 | return 34 | 35 | self.base = [] 36 | name = None 37 | try: 38 | for l in f: 39 | l = l.strip() 40 | if not l or l[0] == "#": 41 | continue 42 | if l[:12] == "Fingerprint ": 43 | if name is not None: 44 | self.base.append((name,sig)) 45 | name = l[12:].strip() 46 | sig={} 47 | p = self.base 48 | continue 49 | elif l[:6] == "Class ": 50 | continue 51 | op = l.find("(") 52 | cl = l.find(")") 53 | if op < 0 or cl < 0: 54 | warning("error reading nmap os fp base file") 55 | continue 56 | test = l[:op] 57 | s = map(lambda x: x.split("="), l[op+1:cl].split("%")) 58 | si = {} 59 | for n,v in s: 60 | si[n] = v 61 | sig[test]=si 62 | if name is not None: 63 | self.base.append((name,sig)) 64 | except: 65 | self.base = None 66 | warning("Can't read nmap database [%s](new nmap version ?)" % self.filename) 67 | f.close() 68 | 69 | nmap_kdb = NmapKnowledgeBase(conf.nmap_base) 70 | 71 | def TCPflags2str(f): 72 | fl="FSRPAUEC" 73 | s="" 74 | for i in range(len(fl)): 75 | if f & 1: 76 | s = fl[i]+s 77 | f >>= 1 78 | return s 79 | 80 | def nmap_tcppacket_sig(pkt): 81 | r = {} 82 | if pkt is not None: 83 | # r["Resp"] = "Y" 84 | r["DF"] = (pkt.flags & 2) and "Y" or "N" 85 | r["W"] = "%X" % pkt.window 86 | r["ACK"] = pkt.ack==2 and "S++" or pkt.ack==1 and "S" or "O" 87 | r["Flags"] = TCPflags2str(pkt.payload.flags) 88 | r["Ops"] = "".join(map(lambda x: x[0][0],pkt.payload.options)) 89 | else: 90 | r["Resp"] = "N" 91 | return r 92 | 93 | 94 | def nmap_udppacket_sig(S,T): 95 | r={} 96 | if T is None: 97 | r["Resp"] = "N" 98 | else: 99 | r["DF"] = (T.flags & 2) and "Y" or "N" 100 | r["TOS"] = "%X" % T.tos 101 | r["IPLEN"] = "%X" % T.len 102 | r["RIPTL"] = "%X" % T.payload.payload.len 103 | r["RID"] = S.id == T.payload.payload.id and "E" or "F" 104 | r["RIPCK"] = S.chksum == T.getlayer(IPerror).chksum and "E" or T.getlayer(IPerror).chksum == 0 and "0" or "F" 105 | r["UCK"] = S.payload.chksum == T.getlayer(UDPerror).chksum and "E" or T.getlayer(UDPerror).chksum ==0 and "0" or "F" 106 | r["ULEN"] = "%X" % T.getlayer(UDPerror).len 107 | r["DAT"] = T.getlayer(Raw) is None and "E" or S.getlayer(Raw).load == T.getlayer(Raw).load and "E" or "F" 108 | return r 109 | 110 | 111 | 112 | def nmap_match_one_sig(seen, ref): 113 | c = 0 114 | for k in seen.keys(): 115 | if ref.has_key(k): 116 | if seen[k] in ref[k].split("|"): 117 | c += 1 118 | if c == 0 and seen.get("Resp") == "N": 119 | return 0.7 120 | else: 121 | return 1.0*c/len(seen.keys()) 122 | 123 | 124 | def nmap_sig(target, oport=80, cport=81, ucport=1): 125 | res = {} 126 | 127 | tcpopt = [ ("WScale", 10), 128 | ("NOP",None), 129 | ("MSS", 256), 130 | ("Timestamp",(123,0)) ] 131 | tests = [ IP(dst=target, id=1)/TCP(seq=1, sport=5001, dport=oport, options=tcpopt, flags="CS"), 132 | IP(dst=target, id=1)/TCP(seq=1, sport=5002, dport=oport, options=tcpopt, flags=0), 133 | IP(dst=target, id=1)/TCP(seq=1, sport=5003, dport=oport, options=tcpopt, flags="SFUP"), 134 | IP(dst=target, id=1)/TCP(seq=1, sport=5004, dport=oport, options=tcpopt, flags="A"), 135 | IP(dst=target, id=1)/TCP(seq=1, sport=5005, dport=cport, options=tcpopt, flags="S"), 136 | IP(dst=target, id=1)/TCP(seq=1, sport=5006, dport=cport, options=tcpopt, flags="A"), 137 | IP(dst=target, id=1)/TCP(seq=1, sport=5007, dport=cport, options=tcpopt, flags="FPU"), 138 | IP(str(IP(dst=target)/UDP(sport=5008,dport=ucport)/(300*"i"))) ] 139 | 140 | ans, unans = sr(tests, timeout=2) 141 | ans += map(lambda x: (x,None), unans) 142 | 143 | for S,T in ans: 144 | if S.sport == 5008: 145 | res["PU"] = nmap_udppacket_sig(S,T) 146 | else: 147 | t = "T%i" % (S.sport-5000) 148 | if T is not None and T.haslayer(ICMP): 149 | warning("Test %s answered by an ICMP" % t) 150 | T=None 151 | res[t] = nmap_tcppacket_sig(T) 152 | 153 | return res 154 | 155 | def nmap_probes2sig(tests): 156 | tests=tests.copy() 157 | res = {} 158 | if "PU" in tests: 159 | res["PU"] = nmap_udppacket_sig(*tests["PU"]) 160 | del(tests["PU"]) 161 | for k in tests: 162 | res[k] = nmap_tcppacket_sig(tests[k]) 163 | return res 164 | 165 | 166 | def nmap_search(sigs): 167 | guess = 0,[] 168 | for os,fp in nmap_kdb.get_base(): 169 | c = 0.0 170 | for t in sigs.keys(): 171 | if t in fp: 172 | c += nmap_match_one_sig(sigs[t], fp[t]) 173 | c /= len(sigs.keys()) 174 | if c > guess[0]: 175 | guess = c,[ os ] 176 | elif c == guess[0]: 177 | guess[1].append(os) 178 | return guess 179 | 180 | 181 | @conf.commands.register 182 | def nmap_fp(target, oport=80, cport=81): 183 | """nmap fingerprinting 184 | nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy 185 | """ 186 | sigs = nmap_sig(target, oport, cport) 187 | return nmap_search(sigs) 188 | 189 | 190 | @conf.commands.register 191 | def nmap_sig2txt(sig): 192 | torder = ["TSeq","T1","T2","T3","T4","T5","T6","T7","PU"] 193 | korder = ["Class", "gcd", "SI", "IPID", "TS", 194 | "Resp", "DF", "W", "ACK", "Flags", "Ops", 195 | "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT" ] 196 | txt=[] 197 | for i in sig.keys(): 198 | if i not in torder: 199 | torder.append(i) 200 | for t in torder: 201 | sl = sig.get(t) 202 | if sl is None: 203 | continue 204 | s = [] 205 | for k in korder: 206 | v = sl.get(k) 207 | if v is None: 208 | continue 209 | s.append("%s=%s"%(k,v)) 210 | txt.append("%s(%s)" % (t, "%".join(s))) 211 | return "\n".join(txt) 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /scapy/modules/queso.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Clone of queso OS fingerprinting 8 | """ 9 | 10 | from scapy.data import KnowledgeBase 11 | from scapy.config import conf 12 | from scapy.layers.inet import IP,TCP 13 | #from 14 | 15 | conf.queso_base ="/etc/queso.conf" 16 | 17 | 18 | ################# 19 | ## Queso stuff ## 20 | ################# 21 | 22 | 23 | def quesoTCPflags(flags): 24 | if flags == "-": 25 | return "-" 26 | flv = "FSRPAUXY" 27 | v = 0 28 | for i in flags: 29 | v |= 2**flv.index(i) 30 | return "%x" % v 31 | 32 | class QuesoKnowledgeBase(KnowledgeBase): 33 | def lazy_init(self): 34 | try: 35 | f = open(self.filename) 36 | except IOError: 37 | return 38 | self.base = {} 39 | p = None 40 | try: 41 | for l in f: 42 | l = l.strip() 43 | if not l or l[0] == ';': 44 | continue 45 | if l[0] == '*': 46 | if p is not None: 47 | p[""] = name 48 | name = l[1:].strip() 49 | p = self.base 50 | continue 51 | if l[0] not in list("0123456"): 52 | continue 53 | res = l[2:].split() 54 | res[-1] = quesoTCPflags(res[-1]) 55 | res = " ".join(res) 56 | if not p.has_key(res): 57 | p[res] = {} 58 | p = p[res] 59 | if p is not None: 60 | p[""] = name 61 | except: 62 | self.base = None 63 | warning("Can't load queso base [%s]", self.filename) 64 | f.close() 65 | 66 | 67 | queso_kdb = QuesoKnowledgeBase(conf.queso_base) 68 | 69 | 70 | def queso_sig(target, dport=80, timeout=3): 71 | p = queso_kdb.get_base() 72 | ret = [] 73 | for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]: 74 | ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()), 75 | timeout=timeout, verbose=0) 76 | if len(ans) == 0: 77 | rs = "- - - -" 78 | else: 79 | s,r = ans[0] 80 | rs = "%i" % (r.seq != 0) 81 | if not r.ack: 82 | r += " 0" 83 | elif r.ack-s.seq > 666: 84 | rs += " R" % 0 85 | else: 86 | rs += " +%i" % (r.ack-s.seq) 87 | rs += " %X" % r.window 88 | rs += " %x" % r.payload.flags 89 | ret.append(rs) 90 | return ret 91 | 92 | def queso_search(sig): 93 | p = queso_kdb.get_base() 94 | sig.reverse() 95 | ret = [] 96 | try: 97 | while sig: 98 | s = sig.pop() 99 | p = p[s] 100 | if p.has_key(""): 101 | ret.append(p[""]) 102 | except KeyError: 103 | pass 104 | return ret 105 | 106 | 107 | @conf.commands.register 108 | def queso(*args,**kargs): 109 | """Queso OS fingerprinting 110 | queso(target, dport=80, timeout=3)""" 111 | return queso_search(queso_sig(*args, **kargs)) 112 | 113 | 114 | -------------------------------------------------------------------------------- /scapy/modules/voip.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | VoIP (Voice over IP) related functions 8 | """ 9 | 10 | import os 11 | ################### 12 | ## Testing stuff ## 13 | ################### 14 | 15 | from fcntl import fcntl 16 | from scapy.sendrecv import sniff 17 | from scapy.packet import Raw 18 | from scapy.layers.inet import IP,UDP 19 | from scapy.layers.rtp import RTP 20 | from scapy.utils import get_temp_file 21 | 22 | 23 | def merge(x,y,sample_size=2): 24 | if len(x) > len(y): 25 | y += "\x00"*(len(x)-len(y)) 26 | elif len(x) < len(y): 27 | x += "\x00"*(len(y)-len(x)) 28 | m = "" 29 | ss=sample_size 30 | for i in range(len(x)/ss): 31 | m += x[ss*i:ss*(i+1)]+y[ss*i:ss*(i+1)] 32 | return m 33 | # return "".join(map(str.__add__, x, y)) 34 | 35 | 36 | def voip_play(s1,list=None,**kargs): 37 | FIFO=get_temp_file() 38 | FIFO1=FIFO % 1 39 | FIFO2=FIFO % 2 40 | 41 | os.mkfifo(FIFO1) 42 | os.mkfifo(FIFO2) 43 | try: 44 | os.system("soxmix -t .ul %s -t .ul %s -t ossdsp /dev/dsp &" % (FIFO1,FIFO2)) 45 | 46 | c1=open(FIFO1,"w", 4096) 47 | c2=open(FIFO2,"w", 4096) 48 | fcntl.fcntl(c1.fileno(),fcntl.F_SETFL, os.O_NONBLOCK) 49 | fcntl.fcntl(c2.fileno(),fcntl.F_SETFL, os.O_NONBLOCK) 50 | 51 | # dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp") 52 | def play(pkt,last=[]): 53 | if not pkt: 54 | return 55 | if not pkt.haslayer(UDP): 56 | return 57 | ip=pkt.getlayer(IP) 58 | if s1 in [ip.src, ip.dst]: 59 | if not last: 60 | last.append(pkt) 61 | return 62 | load=last.pop() 63 | # x1 = load.load[12:] 64 | c1.write(load.load[12:]) 65 | if load.getlayer(IP).src == ip.src: 66 | # x2 = "" 67 | c2.write("\x00"*len(load.load[12:])) 68 | last.append(pkt) 69 | else: 70 | # x2 = pkt.load[:12] 71 | c2.write(pkt.load[12:]) 72 | # dsp.write(merge(x1,x2)) 73 | 74 | if list is None: 75 | sniff(store=0, prn=play, **kargs) 76 | else: 77 | for p in list: 78 | play(p) 79 | finally: 80 | os.unlink(FIFO1) 81 | os.unlink(FIFO2) 82 | 83 | 84 | 85 | def voip_play1(s1,list=None,**kargs): 86 | 87 | 88 | dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp") 89 | def play(pkt): 90 | if not pkt: 91 | return 92 | if not pkt.haslayer(UDP): 93 | return 94 | ip=pkt.getlayer(IP) 95 | if s1 in [ip.src, ip.dst]: 96 | dsp.write(pkt.getlayer(Raw).load[12:]) 97 | try: 98 | if list is None: 99 | sniff(store=0, prn=play, **kargs) 100 | else: 101 | for p in list: 102 | play(p) 103 | finally: 104 | dsp.close() 105 | rd.close() 106 | 107 | def voip_play2(s1,**kargs): 108 | dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp") 109 | def play(pkt,last=[]): 110 | if not pkt: 111 | return 112 | if not pkt.haslayer(UDP): 113 | return 114 | ip=pkt.getlayer(IP) 115 | if s1 in [ip.src, ip.dst]: 116 | if not last: 117 | last.append(pkt) 118 | return 119 | load=last.pop() 120 | x1 = load.load[12:] 121 | # c1.write(load.load[12:]) 122 | if load.getlayer(IP).src == ip.src: 123 | x2 = "" 124 | # c2.write("\x00"*len(load.load[12:])) 125 | last.append(pkt) 126 | else: 127 | x2 = pkt.load[:12] 128 | # c2.write(pkt.load[12:]) 129 | dsp.write(merge(x1,x2)) 130 | 131 | sniff(store=0, prn=play, **kargs) 132 | 133 | def voip_play3(lst=None,**kargs): 134 | dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp") 135 | try: 136 | def play(pkt, dsp=dsp): 137 | if pkt and pkt.haslayer(UDP) and pkt.haslayer(Raw): 138 | dsp.write(pkt.getlayer(RTP).load) 139 | if lst is None: 140 | sniff(store=0, prn=play, **kargs) 141 | else: 142 | for p in lst: 143 | play(p) 144 | finally: 145 | try: 146 | dsp.close() 147 | rd.close() 148 | except: 149 | pass 150 | 151 | -------------------------------------------------------------------------------- /scapy/pton_ntop.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Convert IPv6 addresses between textual representation and binary. 8 | 9 | These functions are missing when python is compiled 10 | without IPv6 support, on Windows for instance. 11 | """ 12 | 13 | import socket,struct 14 | 15 | def inet_pton(af, addr): 16 | """Convert an IP address from text representation into binary form""" 17 | if af == socket.AF_INET: 18 | return inet_aton(addr) 19 | elif af == socket.AF_INET6: 20 | # IPv6: The use of "::" indicates one or more groups of 16 bits of zeros. 21 | # We deal with this form of wildcard using a special marker. 22 | JOKER = "*" 23 | while "::" in addr: 24 | addr = addr.replace("::", ":" + JOKER + ":") 25 | joker_pos = None 26 | 27 | # The last part of an IPv6 address can be an IPv4 address 28 | ipv4_addr = None 29 | if "." in addr: 30 | ipv4_addr = addr.split(":")[-1] 31 | 32 | result = "" 33 | parts = addr.split(":") 34 | for part in parts: 35 | if part == JOKER: 36 | # Wildcard is only allowed once 37 | if joker_pos is None: 38 | joker_pos = len(result) 39 | else: 40 | raise Exception("Illegal syntax for IP address") 41 | elif part == ipv4_addr: # FIXME: Make sure IPv4 can only be last part 42 | # FIXME: inet_aton allows IPv4 addresses with less than 4 octets 43 | result += socket.inet_aton(ipv4_addr) 44 | else: 45 | # Each part must be 16bit. Add missing zeroes before decoding. 46 | try: 47 | result += part.rjust(4, "0").decode("hex") 48 | except TypeError: 49 | raise Exception("Illegal syntax for IP address") 50 | 51 | # If there's a wildcard, fill up with zeros to reach 128bit (16 bytes) 52 | if JOKER in addr: 53 | result = (result[:joker_pos] + "\x00" * (16 - len(result)) 54 | + result[joker_pos:]) 55 | 56 | if len(result) != 16: 57 | raise Exception("Illegal syntax for IP address") 58 | return result 59 | else: 60 | raise Exception("Address family not supported") 61 | 62 | 63 | def inet_ntop(af, addr): 64 | """Convert an IP address from binary form into text represenation""" 65 | if af == socket.AF_INET: 66 | return inet_ntoa(addr) 67 | elif af == socket.AF_INET6: 68 | # IPv6 addresses have 128bits (16 bytes) 69 | if len(addr) != 16: 70 | raise Exception("Illegal syntax for IP address") 71 | parts = [] 72 | for left in [0, 2, 4, 6, 8, 10, 12, 14]: 73 | try: 74 | value = struct.unpack("!H", addr[left:left+2])[0] 75 | hexstr = hex(value)[2:] 76 | except TypeError: 77 | raise Exception("Illegal syntax for IP address") 78 | parts.append(hexstr.lstrip("0").lower()) 79 | result = ":".join(parts) 80 | while ":::" in result: 81 | result = result.replace(":::", "::") 82 | # Leaving out leading and trailing zeros is only allowed with :: 83 | if result.endswith(":") and not result.endswith("::"): 84 | result = result + "0" 85 | if result.startswith(":") and not result.startswith("::"): 86 | result = "0" + result 87 | return result 88 | else: 89 | raise Exception("Address family not supported yet") 90 | -------------------------------------------------------------------------------- /scapy/route.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Routing and handling of network interfaces. 8 | """ 9 | 10 | import socket 11 | from arch import read_routes,get_if_addr,LOOPBACK_NAME 12 | from utils import atol,ltoa,itom 13 | from config import conf 14 | from error import Scapy_Exception,warning 15 | 16 | ############################## 17 | ## Routing/Interfaces stuff ## 18 | ############################## 19 | 20 | class Route: 21 | def __init__(self): 22 | self.resync() 23 | self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 24 | self.cache = {} 25 | 26 | def invalidate_cache(self): 27 | self.cache = {} 28 | 29 | def resync(self): 30 | self.invalidate_cache() 31 | self.routes = read_routes() 32 | 33 | def __repr__(self): 34 | rt = "Network Netmask Gateway Iface Output IP\n" 35 | for net,msk,gw,iface,addr in self.routes: 36 | rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net), 37 | ltoa(msk), 38 | gw, 39 | iface, 40 | addr) 41 | return rt 42 | 43 | def make_route(self, host=None, net=None, gw=None, dev=None): 44 | if host is not None: 45 | thenet,msk = host,32 46 | elif net is not None: 47 | thenet,msk = net.split("/") 48 | msk = int(msk) 49 | else: 50 | raise Scapy_Exception("make_route: Incorrect parameters. You should specify a host or a net") 51 | if gw is None: 52 | gw="0.0.0.0" 53 | if dev is None: 54 | if gw: 55 | nhop = gw 56 | else: 57 | nhop = thenet 58 | dev,ifaddr,x = self.route(nhop) 59 | else: 60 | ifaddr = get_if_addr(dev) 61 | return (atol(thenet), itom(msk), gw, dev, ifaddr) 62 | 63 | def add(self, *args, **kargs): 64 | """Ex: 65 | add(net="192.168.1.0/24",gw="1.2.3.4") 66 | """ 67 | self.invalidate_cache() 68 | self.routes.append(self.make_route(*args,**kargs)) 69 | 70 | 71 | def delt(self, *args, **kargs): 72 | """delt(host|net, gw|dev)""" 73 | self.invalidate_cache() 74 | route = self.make_route(*args,**kargs) 75 | try: 76 | i=self.routes.index(route) 77 | del(self.routes[i]) 78 | except ValueError: 79 | warning("no matching route found") 80 | 81 | def ifchange(self, iff, addr): 82 | self.invalidate_cache() 83 | the_addr,the_msk = (addr.split("/")+["32"])[:2] 84 | the_msk = itom(int(the_msk)) 85 | the_rawaddr = atol(the_addr) 86 | the_net = the_rawaddr & the_msk 87 | 88 | 89 | for i in range(len(self.routes)): 90 | net,msk,gw,iface,addr = self.routes[i] 91 | if iface != iff: 92 | continue 93 | if gw == '0.0.0.0': 94 | self.routes[i] = (the_net,the_msk,gw,iface,the_addr) 95 | else: 96 | self.routes[i] = (net,msk,gw,iface,the_addr) 97 | conf.netcache.flush() 98 | 99 | 100 | 101 | def ifdel(self, iff): 102 | self.invalidate_cache() 103 | new_routes=[] 104 | for rt in self.routes: 105 | if rt[3] != iff: 106 | new_routes.append(rt) 107 | self.routes=new_routes 108 | 109 | def ifadd(self, iff, addr): 110 | self.invalidate_cache() 111 | the_addr,the_msk = (addr.split("/")+["32"])[:2] 112 | the_msk = itom(int(the_msk)) 113 | the_rawaddr = atol(the_addr) 114 | the_net = the_rawaddr & the_msk 115 | self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr)) 116 | 117 | 118 | def route(self,dest,verbose=None): 119 | if type(dest) is list and dest: 120 | dest = dest[0] 121 | if dest in self.cache: 122 | return self.cache[dest] 123 | if verbose is None: 124 | verbose=conf.verb 125 | # Transform "192.168.*.1-5" to one IP of the set 126 | dst = dest.split("/")[0] 127 | dst = dst.replace("*","0") 128 | while 1: 129 | l = dst.find("-") 130 | if l < 0: 131 | break 132 | m = (dst[l:]+".").find(".") 133 | dst = dst[:l]+dst[l+m:] 134 | 135 | 136 | dst = atol(dst) 137 | pathes=[] 138 | for d,m,gw,i,a in self.routes: 139 | aa = atol(a) 140 | if aa == dst: 141 | pathes.append((0xffffffffL,(LOOPBACK_NAME,a,"0.0.0.0"))) 142 | if (dst & m) == (d & m): 143 | pathes.append((m,(i,a,gw))) 144 | if not pathes: 145 | if verbose: 146 | warning("No route found (no default route?)") 147 | return LOOPBACK_NAME,"0.0.0.0","0.0.0.0" #XXX linux specific! 148 | # Choose the more specific route (greatest netmask). 149 | # XXX: we don't care about metrics 150 | pathes.sort() 151 | ret = pathes[-1][1] 152 | self.cache[dest] = ret 153 | return ret 154 | 155 | def get_if_bcast(self, iff): 156 | for net, msk, gw, iface, addr in self.routes: 157 | if (iff == iface and net != 0L): 158 | bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol() 159 | return ltoa(bcast); 160 | warning("No broadcast address found for iface %s\n" % iff); 161 | 162 | conf.route=Route() 163 | 164 | #XXX use "with" 165 | _betteriface = conf.route.route("0.0.0.0", verbose=0)[0] 166 | if _betteriface != LOOPBACK_NAME: 167 | conf.iface = _betteriface 168 | del(_betteriface) 169 | -------------------------------------------------------------------------------- /scapy/route6.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | ## Copyright (C) 2005 Guillaume Valadon 7 | ## Arnaud Ebalard 8 | 9 | """ 10 | Routing and network interface handling for IPv6. 11 | """ 12 | 13 | ############################################################################# 14 | ############################################################################# 15 | ### Routing/Interfaces stuff ### 16 | ############################################################################# 17 | ############################################################################# 18 | 19 | import socket 20 | from config import conf 21 | from utils6 import * 22 | from arch import * 23 | 24 | 25 | class Route6: 26 | 27 | def __init__(self): 28 | self.invalidate_cache() 29 | self.resync() 30 | 31 | def invalidate_cache(self): 32 | self.cache = {} 33 | 34 | def flush(self): 35 | self.invalidate_cache() 36 | self.routes = [] 37 | 38 | def resync(self): 39 | # TODO : At the moment, resync will drop existing Teredo routes 40 | # if any. Change that ... 41 | self.invalidate_cache() 42 | self.routes = read_routes6() 43 | if self.routes == []: 44 | log_loading.info("No IPv6 support in kernel") 45 | 46 | def __repr__(self): 47 | rtlst = [('Destination', 'Next Hop', "iface", "src candidates")] 48 | 49 | for net,msk,gw,iface,cset in self.routes: 50 | rtlst.append(('%s/%i'% (net,msk), gw, iface, ", ".join(cset))) 51 | 52 | colwidth = map(lambda x: max(map(lambda y: len(y), x)), apply(zip, rtlst)) 53 | fmt = " ".join(map(lambda x: "%%-%ds"%x, colwidth)) 54 | rt = "\n".join(map(lambda x: fmt % x, rtlst)) 55 | 56 | return rt 57 | 58 | 59 | # Unlike Scapy's Route.make_route() function, we do not have 'host' and 'net' 60 | # parameters. We only have a 'dst' parameter that accepts 'prefix' and 61 | # 'prefix/prefixlen' values. 62 | # WARNING: Providing a specific device will at the moment not work correctly. 63 | def make_route(self, dst, gw=None, dev=None): 64 | """Internal function : create a route for 'dst' via 'gw'. 65 | """ 66 | prefix, plen = (dst.split("/")+["128"])[:2] 67 | plen = int(plen) 68 | 69 | if gw is None: 70 | gw = "::" 71 | if dev is None: 72 | dev, ifaddr, x = self.route(gw) 73 | else: 74 | # TODO: do better than that 75 | # replace that unique address by the list of all addresses 76 | lifaddr = in6_getifaddr() 77 | devaddrs = filter(lambda x: x[2] == dev, lifaddr) 78 | ifaddr = construct_source_candidate_set(prefix, plen, devaddrs, LOOPBACK_NAME) 79 | 80 | return (prefix, plen, gw, dev, ifaddr) 81 | 82 | 83 | def add(self, *args, **kargs): 84 | """Ex: 85 | add(dst="2001:db8:cafe:f000::/56") 86 | add(dst="2001:db8:cafe:f000::/56", gw="2001:db8:cafe::1") 87 | add(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1", dev="eth0") 88 | """ 89 | self.invalidate_cache() 90 | self.routes.append(self.make_route(*args, **kargs)) 91 | 92 | 93 | def delt(self, dst, gw=None): 94 | """ Ex: 95 | delt(dst="::/0") 96 | delt(dst="2001:db8:cafe:f000::/56") 97 | delt(dst="2001:db8:cafe:f000::/56", gw="2001:db8:deca::1") 98 | """ 99 | tmp = dst+"/128" 100 | dst, plen = tmp.split('/')[:2] 101 | dst = in6_ptop(dst) 102 | plen = int(plen) 103 | l = filter(lambda x: in6_ptop(x[0]) == dst and x[1] == plen, self.routes) 104 | if gw: 105 | gw = in6_ptop(gw) 106 | l = filter(lambda x: in6_ptop(x[0]) == gw, self.routes) 107 | if len(l) == 0: 108 | warning("No matching route found") 109 | elif len(l) > 1: 110 | warning("Found more than one match. Aborting.") 111 | else: 112 | i=self.routes.index(l[0]) 113 | self.invalidate_cache() 114 | del(self.routes[i]) 115 | 116 | def ifchange(self, iff, addr): 117 | the_addr, the_plen = (addr.split("/")+["128"])[:2] 118 | the_plen = int(the_plen) 119 | 120 | naddr = inet_pton(socket.AF_INET6, the_addr) 121 | nmask = in6_cidr2mask(the_plen) 122 | the_net = inet_ntop(socket.AF_INET6, in6_and(nmask,naddr)) 123 | 124 | for i in range(len(self.routes)): 125 | net,plen,gw,iface,addr = self.routes[i] 126 | if iface != iff: 127 | continue 128 | if gw == '::': 129 | self.routes[i] = (the_net,the_plen,gw,iface,the_addr) 130 | else: 131 | self.routes[i] = (net,the_plen,gw,iface,the_addr) 132 | self.invalidate_cache() 133 | ip6_neigh_cache.flush() 134 | 135 | def ifdel(self, iff): 136 | """ removes all route entries that uses 'iff' interface. """ 137 | new_routes=[] 138 | for rt in self.routes: 139 | if rt[3] != iff: 140 | new_routes.append(rt) 141 | self.invalidate_cache() 142 | self.routes = new_routes 143 | 144 | 145 | def ifadd(self, iff, addr): 146 | """ 147 | Add an interface 'iff' with provided address into routing table. 148 | 149 | Ex: ifadd('eth0', '2001:bd8:cafe:1::1/64') will add following entry into 150 | Scapy6 internal routing table: 151 | 152 | Destination Next Hop iface Def src @ 153 | 2001:bd8:cafe:1::/64 :: eth0 2001:bd8:cafe:1::1 154 | 155 | prefix length value can be omitted. In that case, a value of 128 156 | will be used. 157 | """ 158 | addr, plen = (addr.split("/")+["128"])[:2] 159 | addr = in6_ptop(addr) 160 | plen = int(plen) 161 | naddr = inet_pton(socket.AF_INET6, addr) 162 | nmask = in6_cidr2mask(plen) 163 | prefix = inet_ntop(socket.AF_INET6, in6_and(nmask,naddr)) 164 | self.invalidate_cache() 165 | self.routes.append((prefix,plen,'::',iff,[addr])) 166 | 167 | def route(self, dst, dev=None): 168 | """ 169 | Provide best route to IPv6 destination address, based on Scapy6 170 | internal routing table content. 171 | 172 | When a set of address is passed (e.g. 2001:db8:cafe:*::1-5) an address 173 | of the set is used. Be aware of that behavior when using wildcards in 174 | upper parts of addresses ! 175 | 176 | If 'dst' parameter is a FQDN, name resolution is performed and result 177 | is used. 178 | 179 | if optional 'dev' parameter is provided a specific interface, filtering 180 | is performed to limit search to route associated to that interface. 181 | """ 182 | # Transform "2001:db8:cafe:*::1-5:0/120" to one IPv6 address of the set 183 | dst = dst.split("/")[0] 184 | savedst = dst # In case following inet_pton() fails 185 | dst = dst.replace("*","0") 186 | l = dst.find("-") 187 | while l >= 0: 188 | m = (dst[l:]+":").find(":") 189 | dst = dst[:l]+dst[l+m:] 190 | l = dst.find("-") 191 | 192 | try: 193 | inet_pton(socket.AF_INET6, dst) 194 | except socket.error: 195 | dst = socket.getaddrinfo(savedst, None, socket.AF_INET6)[0][-1][0] 196 | # TODO : Check if name resolution went well 197 | 198 | # Deal with dev-specific request for cache search 199 | k = dst 200 | if dev is not None: 201 | k = dst + "%%" + dev 202 | if k in self.cache: 203 | return self.cache[k] 204 | 205 | pathes = [] 206 | 207 | # TODO : review all kinds of addresses (scope and *cast) to see 208 | # if we are able to cope with everything possible. I'm convinced 209 | # it's not the case. 210 | # -- arnaud 211 | for p, plen, gw, iface, cset in self.routes: 212 | if dev is not None and iface != dev: 213 | continue 214 | if in6_isincluded(dst, p, plen): 215 | pathes.append((plen, (iface, cset, gw))) 216 | elif (in6_ismlladdr(dst) and in6_islladdr(p) and in6_islladdr(cset[0])): 217 | pathes.append((plen, (iface, cset, gw))) 218 | 219 | if not pathes: 220 | warning("No route found for IPv6 destination %s (no default route?)" % dst) 221 | return (LOOPBACK_NAME, "::", "::") # XXX Linux specific 222 | 223 | # Sort with longest prefix first 224 | pathes.sort(reverse=True) 225 | 226 | best_plen = pathes[0][0] 227 | pathes = filter(lambda x: x[0] == best_plen, pathes) 228 | 229 | res = [] 230 | for p in pathes: # Here we select best source address for every route 231 | tmp = p[1] 232 | srcaddr = get_source_addr_from_candidate_set(dst, p[1][1]) 233 | if srcaddr is not None: 234 | res.append((p[0], (tmp[0], srcaddr, tmp[2]))) 235 | 236 | # Symptom : 2 routes with same weight (our weight is plen) 237 | # Solution : 238 | # - dst is unicast global. Check if it is 6to4 and we have a source 239 | # 6to4 address in those available 240 | # - dst is link local (unicast or multicast) and multiple output 241 | # interfaces are available. Take main one (conf.iface6) 242 | # - if none of the previous or ambiguity persists, be lazy and keep 243 | # first one 244 | # XXX TODO : in a _near_ future, include metric in the game 245 | 246 | if len(res) > 1: 247 | tmp = [] 248 | if in6_isgladdr(dst) and in6_isaddr6to4(dst): 249 | # TODO : see if taking the longest match between dst and 250 | # every source addresses would provide better results 251 | tmp = filter(lambda x: in6_isaddr6to4(x[1][1]), res) 252 | elif in6_ismaddr(dst) or in6_islladdr(dst): 253 | # TODO : I'm sure we are not covering all addresses. Check that 254 | tmp = filter(lambda x: x[1][0] == conf.iface6, res) 255 | 256 | if tmp: 257 | res = tmp 258 | 259 | # Fill the cache (including dev-specific request) 260 | k = dst 261 | if dev is not None: 262 | k = dst + "%%" + dev 263 | self.cache[k] = res[0][1] 264 | 265 | return res[0][1] 266 | 267 | conf.route6 = Route6() 268 | 269 | _res = conf.route6.route("::/0") 270 | if _res: 271 | iff, gw, addr = _res 272 | conf.iface6 = iff 273 | del(_res) 274 | 275 | -------------------------------------------------------------------------------- /scapy/supersocket.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | SuperSocket. 8 | """ 9 | 10 | import socket,time 11 | from config import conf 12 | from data import * 13 | from scapy.error import warning 14 | 15 | class _SuperSocket_metaclass(type): 16 | def __repr__(self): 17 | if self.desc is not None: 18 | return "<%s: %s>" % (self.__name__,self.desc) 19 | else: 20 | return "<%s>" % self.__name__ 21 | 22 | 23 | class SuperSocket: 24 | __metaclass__ = _SuperSocket_metaclass 25 | desc = None 26 | closed=0 27 | def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0): 28 | self.ins = socket.socket(family, type, proto) 29 | self.outs = self.ins 30 | self.promisc=None 31 | def send(self, x): 32 | sx = str(x) 33 | x.sent_time = time.time() 34 | return self.outs.send(sx) 35 | def recv(self, x=MTU): 36 | return conf.raw_layer(self.ins.recv(x)) 37 | def fileno(self): 38 | return self.ins.fileno() 39 | def close(self): 40 | if self.closed: 41 | return 42 | self.closed=1 43 | if self.ins != self.outs: 44 | if self.outs and self.outs.fileno() != -1: 45 | self.outs.close() 46 | if self.ins and self.ins.fileno() != -1: 47 | self.ins.close() 48 | def sr(self, *args, **kargs): 49 | return sendrecv.sndrcv(self, *args, **kargs) 50 | def sr1(self, *args, **kargs): 51 | a,b = sendrecv.sndrcv(self, *args, **kargs) 52 | if len(a) > 0: 53 | return a[0][1] 54 | else: 55 | return None 56 | def sniff(self, *args, **kargs): 57 | return sendrecv.sniff(opened_socket=self, *args, **kargs) 58 | 59 | class L3RawSocket(SuperSocket): 60 | desc = "Layer 3 using Raw sockets (PF_INET/SOCK_RAW)" 61 | def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0): 62 | self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) 63 | self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1) 64 | self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type)) 65 | if iface is not None: 66 | self.ins.bind((iface, type)) 67 | def recv(self, x=MTU): 68 | pkt, sa_ll = self.ins.recvfrom(x) 69 | if sa_ll[2] == socket.PACKET_OUTGOING: 70 | return None 71 | if sa_ll[3] in conf.l2types: 72 | cls = conf.l2types[sa_ll[3]] 73 | lvl = 2 74 | elif sa_ll[1] in conf.l3types: 75 | cls = conf.l3types[sa_ll[1]] 76 | lvl = 3 77 | else: 78 | cls = conf.default_l2 79 | warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s" % (sa_ll[0],sa_ll[1],sa_ll[3],cls.name)) 80 | lvl = 3 81 | 82 | try: 83 | pkt = cls(pkt) 84 | except KeyboardInterrupt: 85 | raise 86 | except: 87 | if conf.debug_dissector: 88 | raise 89 | pkt = conf.raw_layer(pkt) 90 | if lvl == 2: 91 | pkt = pkt.payload 92 | 93 | if pkt is not None: 94 | from arch import get_last_packet_timestamp 95 | pkt.time = get_last_packet_timestamp(self.ins) 96 | return pkt 97 | def send(self, x): 98 | try: 99 | sx = str(x) 100 | x.sent_time = time.time() 101 | self.outs.sendto(sx,(x.dst,0)) 102 | except socket.error,msg: 103 | log_runtime.error(msg) 104 | 105 | class SimpleSocket(SuperSocket): 106 | desc = "wrapper arround a classic socket" 107 | def __init__(self, sock): 108 | self.ins = sock 109 | self.outs = sock 110 | 111 | 112 | class StreamSocket(SimpleSocket): 113 | desc = "transforms a stream socket into a layer 2" 114 | def __init__(self, sock, basecls=None): 115 | if basecls is None: 116 | basecls = conf.raw_layer 117 | SimpleSocket.__init__(self, sock) 118 | self.basecls = basecls 119 | 120 | def recv(self, x=MTU): 121 | pkt = self.ins.recv(x, socket.MSG_PEEK) 122 | x = len(pkt) 123 | if x == 0: 124 | raise socket.error((100,"Underlying stream socket tore down")) 125 | pkt = self.basecls(pkt) 126 | pad = pkt.getlayer(Padding) 127 | if pad is not None and pad.underlayer is not None: 128 | del(pad.underlayer.payload) 129 | while pad is not None and not isinstance(pad, NoPayload): 130 | x -= len(pad.load) 131 | pad = pad.payload 132 | self.ins.recv(x) 133 | return pkt 134 | 135 | 136 | 137 | if conf.L3socket is None: 138 | conf.L3socket = L3RawSocket 139 | 140 | import sendrecv 141 | -------------------------------------------------------------------------------- /scapy/tools/__init__.py: -------------------------------------------------------------------------------- 1 | ## This file is part of Scapy 2 | ## See http://www.secdev.org/projects/scapy for more informations 3 | ## Copyright (C) Philippe Biondi 4 | ## This program is published under a GPLv2 license 5 | 6 | """ 7 | Additional tools to be run separately 8 | """ 9 | -------------------------------------------------------------------------------- /scapy/tools/check_asdis.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import getopt 4 | 5 | def usage(): 6 | print >>sys.stderr,"""Usage: check_asdis -i [-o ] 7 | -v increase verbosity 8 | -d hexdiff packets that differ 9 | -z compress output pcap 10 | -a open pcap file in append mode""" 11 | 12 | def main(argv): 13 | PCAP_IN = None 14 | PCAP_OUT = None 15 | COMPRESS=False 16 | APPEND=False 17 | DIFF=False 18 | VERBOSE=0 19 | try: 20 | opts=getopt.getopt(argv, "hi:o:azdv") 21 | for opt, parm in opts[0]: 22 | if opt == "-h": 23 | usage() 24 | raise SystemExit 25 | elif opt == "-i": 26 | PCAP_IN = parm 27 | elif opt == "-o": 28 | PCAP_OUT = parm 29 | elif opt == "-v": 30 | VERBOSE += 1 31 | elif opt == "-d": 32 | DIFF = True 33 | elif opt == "-a": 34 | APPEND = True 35 | elif opt == "-z": 36 | COMPRESS = True 37 | 38 | 39 | if PCAP_IN is None: 40 | raise getopt.GetoptError("Missing pcap file (-i)") 41 | 42 | except getopt.GetoptError,e: 43 | print >>sys.stderr,"ERROR: %s" % e 44 | raise SystemExit 45 | 46 | 47 | 48 | from scapy.config import conf 49 | from scapy.utils import RawPcapReader,RawPcapWriter,hexdiff 50 | from scapy.layers import all 51 | 52 | 53 | pcap = RawPcapReader(PCAP_IN) 54 | pcap_out = None 55 | if PCAP_OUT: 56 | pcap_out = RawPcapWriter(PCAP_OUT, append=APPEND, gz=COMPRESS, linktype=pcap.linktype) 57 | pcap_out._write_header(None) 58 | 59 | LLcls = conf.l2types.get(pcap.linktype) 60 | if LLcls is None: 61 | print >>sys.stderr," Unknown link type [%i]. Can't test anything!" % pcap.linktype 62 | raise SystemExit 63 | 64 | 65 | i=-1 66 | differ=0 67 | failed=0 68 | for p1,meta in pcap: 69 | i += 1 70 | try: 71 | p2d = LLcls(p1) 72 | p2 = str(p2d) 73 | except KeyboardInterrupt: 74 | raise 75 | except Exception,e: 76 | print "Dissection error on packet %i" % i 77 | failed += 1 78 | else: 79 | if p1 == p2: 80 | if VERBOSE >= 2: 81 | print "Packet %i ok" % i 82 | continue 83 | else: 84 | print "Packet %i differs" % i 85 | differ += 1 86 | if VERBOSE >= 1: 87 | print repr(p2d) 88 | if DIFF: 89 | hexdiff(p1,p2) 90 | if pcap_out is not None: 91 | pcap_out.write(p1) 92 | i+=1 93 | correct = i-differ-failed 94 | print "%i total packets. %i ok, %i differed, %i failed. %.2f%% correct." % (i, correct, differ, 95 | failed, i and 100.0*(correct)/i) 96 | 97 | 98 | if __name__ == "__main__": 99 | import sys 100 | try: 101 | main(sys.argv[1:]) 102 | except KeyboardInterrupt: 103 | print >>sys.stderr,"Interrupted by user." 104 | -------------------------------------------------------------------------------- /test.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/medbenali/CyberScan/ca85794cfce5e83e9cc5fca1512ba6edf2f14dee/test.pcap --------------------------------------------------------------------------------