├── .gitattributes ├── .github └── workflows │ └── unittests.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── VULNINFO.md ├── bin └── .gitignore ├── data ├── afl-http.pcap ├── exclude.conf └── flush_all.pcap ├── debian ├── .gitignore ├── README.Debian ├── changelog ├── compat ├── control ├── copyright ├── masscan.dirs ├── masscan.docs ├── masscan.install ├── masscan.manpages ├── rules ├── source │ └── format └── watch ├── doc ├── algorithm.js ├── bot.html ├── faq │ ├── FAQ0001-slow.md │ ├── FAQ0002-drops.md │ ├── FAQ0003-excludelist.md │ ├── FAQ0004-serverlogs.md │ └── README.md ├── howto-afl.md ├── masscan.8 └── masscan.8.markdown ├── src ├── crypto-base64.c ├── crypto-base64.h ├── crypto-blackrock.c ├── crypto-blackrock.h ├── crypto-blackrock2.c ├── crypto-lcg.c ├── crypto-lcg.h ├── crypto-primegen.c ├── crypto-primegen.h ├── crypto-siphash24.c ├── crypto-siphash24.h ├── event-timeout.c ├── event-timeout.h ├── in-binary.c ├── in-binary.h ├── in-filter.c ├── in-filter.h ├── in-report.c ├── in-report.h ├── main-conf.c ├── main-dedup.c ├── main-dedup.h ├── main-globals.h ├── main-initadapter.c ├── main-listscan.c ├── main-ptrace.c ├── main-ptrace.h ├── main-readrange.c ├── main-readrange.h ├── main-status.c ├── main-status.h ├── main-throttle.c ├── main-throttle.h ├── main.c ├── masscan-app.c ├── masscan-app.h ├── masscan-status.h ├── masscan-version.h ├── masscan.h ├── massip-addr.c ├── massip-addr.h ├── massip-parse.c ├── massip-parse.h ├── massip-port.h ├── massip-rangesv4.c ├── massip-rangesv4.h ├── massip-rangesv6.c ├── massip-rangesv6.h ├── massip.c ├── massip.h ├── misc-rstfilter.c ├── misc-rstfilter.h ├── out-binary.c ├── out-certs.c ├── out-grepable.c ├── out-hostonly.c ├── out-json.c ├── out-ndjson.c ├── out-null.c ├── out-record.h ├── out-redis.c ├── out-tcp-services.c ├── out-tcp-services.h ├── out-text.c ├── out-unicornscan.c ├── out-xml.c ├── output.c ├── output.h ├── pixie-backtrace.c ├── pixie-backtrace.h ├── pixie-file.c ├── pixie-file.h ├── pixie-sockets.h ├── pixie-threads.c ├── pixie-threads.h ├── pixie-timer.c ├── pixie-timer.h ├── proto-arp.c ├── proto-arp.h ├── proto-banner1.c ├── proto-banner1.h ├── proto-banout.c ├── proto-banout.h ├── proto-coap.c ├── proto-coap.h ├── proto-dns-parse.h ├── proto-dns.c ├── proto-dns.h ├── proto-ftp.c ├── proto-ftp.h ├── proto-http.c ├── proto-http.h ├── proto-icmp.c ├── proto-icmp.h ├── proto-imap4.c ├── proto-imap4.h ├── proto-isakmp.c ├── proto-isakmp.h ├── proto-mc.c ├── proto-mc.h ├── proto-memcached.c ├── proto-memcached.h ├── proto-netbios.c ├── proto-netbios.h ├── proto-ntlmssp.c ├── proto-ntlmssp.h ├── proto-ntp.c ├── proto-ntp.h ├── proto-oproto.c ├── proto-oproto.h ├── proto-pop3.c ├── proto-pop3.h ├── proto-preprocess.c ├── proto-preprocess.h ├── proto-sctp.c ├── proto-sctp.h ├── proto-smb.c ├── proto-smb.h ├── proto-smtp.c ├── proto-smtp.h ├── proto-snmp.c ├── proto-snmp.h ├── proto-spnego.h ├── proto-ssh.c ├── proto-ssh.h ├── proto-ssl-test.c ├── proto-ssl.c ├── proto-ssl.h ├── proto-tcp-rdp.c ├── proto-tcp-rdp.h ├── proto-tcp-telnet.c ├── proto-tcp-telnet.h ├── proto-udp.c ├── proto-udp.h ├── proto-versioning.c ├── proto-versioning.h ├── proto-vnc.c ├── proto-vnc.h ├── proto-x509.c ├── proto-x509.h ├── proto-zeroaccess.c ├── proto-zeroaccess.h ├── rawsock-adapter.h ├── rawsock-getif.c ├── rawsock-getip.c ├── rawsock-getip6.c ├── rawsock-getmac.c ├── rawsock-getroute.c ├── rawsock-pcapfile.c ├── rawsock-pcapfile.h ├── rawsock.c ├── rawsock.h ├── read-service-probes.c ├── read-service-probes.h ├── rte-ring.c ├── rte-ring.h ├── scripting-banner.c ├── scripting-masscan.c ├── scripting.c ├── scripting.h ├── smack.h ├── smack1.c ├── smackqueue.c ├── smackqueue.h ├── stack-arpv4.c ├── stack-arpv4.h ├── stack-if.c ├── stack-ndpv6.c ├── stack-ndpv6.h ├── stack-queue.c ├── stack-queue.h ├── stack-src.c ├── stack-src.h ├── stack-tcp-api.h ├── stack-tcp-app.c ├── stack-tcp-app.h ├── stack-tcp-core.c ├── stack-tcp-core.h ├── stub-lua.c ├── stub-lua.h ├── stub-pcap-dlt.h ├── stub-pcap.c ├── stub-pcap.h ├── stub-pfring.c ├── stub-pfring.h ├── syn-cookie.c ├── syn-cookie.h ├── templ-nmap-payloads.c ├── templ-nmap-payloads.h ├── templ-opts.h ├── templ-payloads.c ├── templ-payloads.h ├── templ-pkt.c ├── templ-pkt.h ├── templ-tcp-hdr.c ├── templ-tcp-hdr.h ├── unusedparm.h ├── util-bool.h ├── util-checksum.c ├── util-checksum.h ├── util-errormsg.c ├── util-errormsg.h ├── util-extract.c ├── util-extract.h ├── util-logger.c ├── util-logger.h ├── util-malloc.c ├── util-malloc.h ├── util-safefunc.c ├── util-safefunc.h ├── vulncheck-heartbleed.c ├── vulncheck-ntp-monlist.c ├── vulncheck-sslv3.c ├── vulncheck.c ├── vulncheck.h ├── xring.c └── xring.h ├── tmp └── .gitignore ├── vs10 ├── .gitignore ├── masscan.sln ├── masscan.vcxproj └── masscan.vcxproj.filters └── xcode4 ├── .gitignore └── masscan.xcodeproj ├── .gitignore └── project.pbxproj /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | 3 | *.c text eol=lf 4 | 5 | -------------------------------------------------------------------------------- /.github/workflows/unittests.yml: -------------------------------------------------------------------------------- 1 | name: masscan unit tests 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [master] 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | regress: 15 | name: Run regression tests 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | matrix: 19 | os: [ubuntu-latest, macos-latest] 20 | steps: 21 | - name: Checkout masscan 22 | uses: actions/checkout@v3 23 | - name: Install libpcap-dev 24 | if: ${{ vars.RUNNER_OS == 'Linux' }} 25 | run: sudo apt-get install -y libpcap-dev 26 | - name: Run regression tests 27 | run: make test 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | paused.conf 2 | .Makefile.swp 3 | .vscode 4 | vs10/.vs/ 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # If Windows, then assume the compiler is `gcc` for the 2 | # MinGW environment. I can't figure out how to tell if it's 3 | # actually MingGW. FIXME TODO 4 | ifeq ($(OS),Windows_NT) 5 | CC = gcc 6 | endif 7 | 8 | # Try to figure out the default compiler. I dont know the best 9 | # way to do this with `gmake`. If you have better ideas, please 10 | # submit a pull request on github. 11 | ifeq ($(CC),) 12 | ifneq (, $(shell which clang)) 13 | CC = clang 14 | else ifneq (, $(shell which gcc)) 15 | CC = gcc 16 | else 17 | CC = cc 18 | endif 19 | endif 20 | 21 | PREFIX ?= /usr 22 | BINDIR ?= $(PREFIX)/bin 23 | SYS := $(shell $(CC) -dumpmachine) 24 | GITVER := $(shell git describe --tags) 25 | INSTALL_DATA := -pDm755 26 | 27 | ifeq ($(GITVER),) 28 | GITVER = "unknown" 29 | endif 30 | 31 | # LINUX 32 | # The automated regression tests run on Linux, so this is the one 33 | # environment where things likely will work -- as well as anything 34 | # works on the bajillion of different Linux environments 35 | ifneq (, $(findstring linux, $(SYS))) 36 | ifneq (, $(findstring musl, $(SYS))) 37 | LIBS = 38 | else 39 | LIBS = -lm -lrt -ldl -lpthread 40 | endif 41 | INCLUDES = 42 | FLAGS2 = 43 | endif 44 | 45 | # MAC OS X 46 | # I occassionally develope code on Mac OS X, but it's not part of 47 | # my regularly regression-test environment. That means at any point 48 | # in time, something might be minorly broken in Mac OS X. 49 | ifneq (, $(findstring darwin, $(SYS))) 50 | LIBS = -lm 51 | INCLUDES = -I. 52 | FLAGS2 = 53 | INSTALL_DATA = -pm755 54 | endif 55 | 56 | # MinGW on Windows 57 | # I develope on Visual Studio 2010, so that's the Windows environment 58 | # that'll work. However, 'git' on Windows runs under MingGW, so one 59 | # day I acccidentally typed 'make' instead of 'git, and felt compelled 60 | # to then fix all the errors, so this kinda works now. It's not the 61 | # intended environment, so it make break in the future. 62 | ifneq (, $(findstring mingw, $(SYS))) 63 | INCLUDES = -Ivs10/include 64 | LIBS = -L vs10/lib -lIPHLPAPI -lWs2_32 65 | #FLAGS2 = -march=i686 66 | endif 67 | 68 | # Cygwin 69 | # I hate Cygwin, use Visual Studio or MingGW instead. I just put this 70 | # second here for completeness, or in case I gate tired of hitting my 71 | # head with a hammer and want to feel a different sort of pain. 72 | ifneq (, $(findstring cygwin, $(SYS))) 73 | INCLUDES = -I. 74 | LIBS = 75 | FLAGS2 = 76 | endif 77 | 78 | # OpenBSD 79 | ifneq (, $(findstring openbsd, $(SYS))) 80 | LIBS = -lm -lpthread 81 | INCLUDES = -I. 82 | FLAGS2 = 83 | endif 84 | 85 | # FreeBSD 86 | ifneq (, $(findstring freebsd, $(SYS))) 87 | LIBS = -lm -lpthread 88 | INCLUDES = -I. 89 | FLAGS2 = 90 | endif 91 | 92 | # NetBSD 93 | ifneq (, $(findstring netbsd, $(SYS))) 94 | LIBS = -lm -lpthread 95 | INCLUDES = -I. 96 | FLAGS2 = 97 | endif 98 | 99 | 100 | DEFINES = 101 | CFLAGS = -g -ggdb $(FLAGS2) $(INCLUDES) $(DEFINES) -Wall -O2 102 | .SUFFIXES: .c .cpp 103 | 104 | all: bin/masscan 105 | 106 | 107 | tmp/main-conf.o: src/main-conf.c src/*.h 108 | $(CC) $(CFLAGS) -c $< -o $@ -DGIT=\"$(GITVER)\" 109 | 110 | 111 | # just compile everything in the 'src' directory. Using this technique 112 | # means that include file dependencies are broken, so sometimes when 113 | # the program crashes unexpectedly, 'make clean' then 'make' fixes the 114 | # problem that a .h file was out of date 115 | tmp/%.o: src/%.c src/*.h 116 | $(CC) $(CFLAGS) -c $< -o $@ 117 | 118 | 119 | SRC = $(sort $(wildcard src/*.c)) 120 | OBJ = $(addprefix tmp/, $(notdir $(addsuffix .o, $(basename $(SRC))))) 121 | 122 | 123 | bin/masscan: $(OBJ) 124 | $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) 125 | 126 | clean: 127 | rm -f tmp/*.o 128 | rm -f bin/masscan 129 | 130 | regress: bin/masscan 131 | bin/masscan --selftest 132 | 133 | test: regress 134 | 135 | install: bin/masscan 136 | install $(INSTALL_DATA) bin/masscan $(DESTDIR)$(BINDIR)/masscan 137 | 138 | default: bin/masscan 139 | -------------------------------------------------------------------------------- /VULNINFO.md: -------------------------------------------------------------------------------- 1 | # Vulnerability Information and Policy 2 | 3 | This document contains information about robustness of this project against 4 | hacker attacks. It describes known vulnerabilities that have been found 5 | in previous versions, and describes policies how vulnerabilities are handled. 6 | 7 | ## Security contact 8 | 9 | robert_david_graham@yahoo.com 10 | @ErrataRob on twitter 11 | 12 | 13 | ## Known vulnerabilities and advisories 14 | 15 | none 16 | 17 | ## Bounty 18 | 19 | I'm offering $100, payable in cash or Bitcoin, for security vulnerabilities. 20 | This is primarily for remote vulnerabilities, such as the ability of a target 21 | to buffer-overflow the scanner, or even cause it to crash. 22 | 23 | But I'd consider other vulnerabilities as well. Does Kali ship this with suid 24 | and there's a preload bug? That's not really a vuln in this code, but if it's 25 | something I could fix, I'd consider paying a bounty for it. 26 | 27 | 28 | ## Disclosure policy 29 | 30 | If you've got a vuln, just announce it. Please send info to the contact above 31 | as well, please. 32 | 33 | I'll probably get around to fixing it within a month or so. This really isn't 34 | heavily used software, so I'm lax on this. 35 | 36 | ## Threats 37 | 38 | The primary threat is from hostile targets on the Internet sending back 39 | responses in order to: 40 | * exploit a buffer-overflow vulnerability 41 | * spoof packets trying to give fraudulent scan results (mitigated with our 42 | SYN cookies) 43 | * flood packets trying to overload bandwidth/storage 44 | * bad data, such as corrupting banners or DNS names trying to exploit 45 | downstream consumers with bad html or script tags. 46 | 47 | The secondary threat is from use of the program. For example, when a bad 48 | parameter is entered on the command-line, the program spits it back out 49 | in a helpful error message. This is fine for a command-line program that 50 | should run as `root` anyway, but if somebody tries to make it into a 51 | scriptable service, this becomes a potential vulnerability. 52 | 53 | ## Safe code policy 54 | 55 | Unsafe functions like `strcpy()` are banned. 56 | 57 | The code contains an automated regression test by running with the 58 | `--regress` option. However, currently the regression only tests 59 | a small percentage of the code. 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/afl-http.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertdavidgraham/masscan/a31feaf5c943fc517752e23423ea130a92f0d473/data/afl-http.pcap -------------------------------------------------------------------------------- /data/flush_all.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertdavidgraham/masscan/a31feaf5c943fc517752e23423ea130a92f0d473/data/flush_all.pcap -------------------------------------------------------------------------------- /debian/.gitignore: -------------------------------------------------------------------------------- 1 | files 2 | masscan 3 | masscan.debhelper.log 4 | masscan.substvars 5 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | masscan for Debian 2 | ------------------ 3 | 4 | Initial debianisation 5 | 6 | -- Vladimir Vitkov Fri, 24 Jan 2014 11:03:38 +0200 7 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | masscan (1.0.3-46+gbbadb7b-1) precise; urgency=low 2 | 3 | * Rebuild from current git 4 | * Use propper git hash versioning 5 | 6 | -- Vladimir Vitkov (Packaging Key) Tue, 10 Jun 2014 12:11:04 +0300 7 | 8 | masscan (1.0.1+git20140124-1) unstable; urgency=low 9 | 10 | * Rebuild from current git 11 | 12 | -- Vladimir Vitkov Fri, 24 Jan 2014 14:37:30 +0200 13 | 14 | masscan (1.0.1+git20140106-1) unstable; urgency=low 15 | 16 | * Initial release 17 | 18 | -- Vladimir Vitkov Fri, 24 Jan 2014 11:03:38 +0200 19 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: masscan 2 | Section: net 3 | Priority: extra 4 | Maintainer: Vladimir Vitkov 5 | Build-Depends: debhelper (>= 8.0.0), libpcap-dev 6 | Standards-Version: 3.9.3 7 | Homepage: https://github.com/robertdavidgraham/masscan 8 | #Vcs-Git: https://github.com/robertdavidgraham/masscan.git 9 | #Vcs-Browser: http://git.debian.org/?p=collab-maint/masscan.git;a=summary 10 | 11 | Package: masscan 12 | Architecture: any 13 | Depends: ${shlibs:Depends}, ${misc:Depends} 14 | Description: Mass IP port scanner 15 | This is the fastest Internet port scanner. It can scan the 16 | entire Internet in under 6 minutes, transmitting 10 million 17 | packets per second. 18 | . 19 | It produces results similar to nmap, the most famous port 20 | scanner. Internally, it operates more like scanrand, 21 | unicornscan, and ZMap, using asynchronous transmission. 22 | The major difference is that it's faster than these other 23 | scanners. In addition, it's more flexible, allowing 24 | arbitrary address ranges and port ranges. 25 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://dep.debian.net/deps/dep5 2 | Upstream-Name: masscan 3 | Source: https://github.com/robertdavidgraham/masscan 4 | 5 | Files: * 6 | Copyright: 2013 Robert David Graham 7 | License: AGPL 8 | This program, "masscan", is not completely free software. It may not be 9 | used by the United States Department of Defense (DoD) or National Security 10 | Agency (NSA), or by agents acting on their behalf, such as contractors, 11 | sub-contractors, and so on. These entitities must contact me to acquire 12 | a different license. 13 | . 14 | Barring the above exception, you can use, redistribute, and/or modify 15 | this code under the terms of the GNU Affero General Public License 16 | version 3. 17 | . 18 | This program is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | GNU Affero General Public License for more details. 22 | . 23 | You should have received a copy of the GNU Affero General Public License 24 | along with this program. If not, see . 25 | 26 | Files: debian/* 27 | Copyright: 2014 Vladimir Vitkov 28 | License: GPL-3.0+ 29 | 30 | License: GPL-3.0+ 31 | This program is free software: you can redistribute it and/or modify 32 | it under the terms of the GNU General Public License as published by 33 | the Free Software Foundation, either version 3 of the License, or 34 | (at your option) any later version. 35 | . 36 | This package is distributed in the hope that it will be useful, 37 | but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 39 | GNU General Public License for more details. 40 | . 41 | You should have received a copy of the GNU General Public License 42 | along with this program. If not, see . 43 | . 44 | On Debian systems, the complete text of the GNU General 45 | Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". 46 | -------------------------------------------------------------------------------- /debian/masscan.dirs: -------------------------------------------------------------------------------- 1 | usr/bin 2 | -------------------------------------------------------------------------------- /debian/masscan.docs: -------------------------------------------------------------------------------- 1 | README.md 2 | VULNINFO.md 3 | doc/algorithm.js 4 | doc/bot.html 5 | -------------------------------------------------------------------------------- /debian/masscan.install: -------------------------------------------------------------------------------- 1 | bin/masscan usr/bin/ 2 | -------------------------------------------------------------------------------- /debian/masscan.manpages: -------------------------------------------------------------------------------- 1 | doc/masscan.8 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ 14 | 15 | override_dh_auto_test: 16 | $(MAKE) regress 17 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=3 2 | 3 | # use the github release pages 4 | https://github.com/robertdavidgraham/masscan/releases .*/(\d\S*)\.(?:tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) 5 | -------------------------------------------------------------------------------- /doc/bot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Masscan/1.0 - fast port scanner 4 | 5 | 6 |

Masscan/1.0 - fast port scanner

7 | 8 |

This tool is not a web spider, but a port scanner. It'll make only one request to a website, usually for the root / webpage. It then records the Server: field from the HTTP header, the <title> from the page contents, and possibly a few other interesting fields.

9 | 10 |

This does not follow links, it doesn't scan your web pages, but the ports on your machine.

11 | 12 |

The source code for this tool is at https://github.com/robertdavidgraham/masscan/. This is an open source project, so that this means it's not me (Robert Graham) who is using this tool to scan your website, but likely somebody else. I can't speak for their intentions, but this tool is more useful at doing surveys of the Internet than trying to hack in (tools like 'nmap' or 'nessus' are more often used for that).

13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/faq/FAQ0001-slow.md: -------------------------------------------------------------------------------- 1 | # Why is it not as fast as I expect? 2 | 3 | ## Question 4 | 5 | Why is scanning speed only around 100,000 packets-per-second instead of a million packets-per-second? 6 | 7 | ## Answer 8 | 9 | I don't know. 10 | 11 | If you have the latest Linux distro on the latest hardware, you can sometime 12 | see scanning speeds of 1 million packets-per-second, even when virtualized. 13 | 14 | However, sometimes you also see only 100,000 packets-per-second. 15 | 16 | I've spent a lot of time trying to diagnose this situation and cannot 17 | figure out what's going on. The box I use in a colo does 500,000 packets-per-second. 18 | A relatively slow machine in my home lab does 1.2 million packets-per-second. 19 | 20 | The speed is determined by the operating system. The amount of CPU used by `masscan` 21 | itself is insignificant. 22 | 23 | My theory is various configuration options within the operating system that can make 24 | packet transmission very slow. Simple features that would not otherwise impact network 25 | stacks that run at lower rates become really important at high rates. 26 | 27 | One way around this is to install `PF_RING` and dedicate a network adapter to packet 28 | transmission completely bypassing the operating system. In that case, packet transmission 29 | rates can reach 15 million packets-per-second. 30 | -------------------------------------------------------------------------------- /doc/faq/FAQ0002-drops.md: -------------------------------------------------------------------------------- 1 | # Why are many results missing that I expect? 2 | 3 | # Question 4 | 5 | When I do a scan, results are missing that I know are there. 6 | They show up when I repeat the scan, but then others are missing. 7 | The faster I scan, the more results are missing. 8 | 9 | # Answer 10 | 11 | Network infrastructure does not like high rates of small packets. 12 | Even though they can handle high **bit-rates** then cannot handle 13 | high **packet-rates**. 14 | 15 | This is what makes `masscan` so unique. It transmits packets at rates 16 | far higher than other things can cope with. It often crashes networks. 17 | 18 | Therefore, the faster you transmit packets, the more it overloads network 19 | equipment, causing the packets to be dropped, causing probes to fail. 20 | 21 | As the issue #546 below indicates, they are experiencing this at very low 22 | rates of less than 10,000 packets-per-second. That seems excessively low. 23 | I assume the actual reason is because of policy enforcement limiting traffic 24 | rates rather than overloading network equipment. 25 | 26 | 27 | 28 | # Issues 29 | 30 | - [#546 fast scan get result](https://github.com/robertdavidgraham/masscan/issues/546) 31 | 32 | -------------------------------------------------------------------------------- /doc/faq/FAQ0003-excludelist.md: -------------------------------------------------------------------------------- 1 | # How can I add my IP address to an exclude list so that people stop scanning me? 2 | 3 | # Question 4 | 5 | I hate everyone probing me all the time and want them to stop. 6 | How can I add my IP address ranges to an exclude list? 7 | 8 | # Answer 9 | 10 | You can't. 11 | 12 | First of all, nobody is going to pay attention to a sample exclude list 13 | within this project. Sure, I can add IP addresses to the list, but that 14 | won't help you. 15 | 16 | Second, there's no way I can confirm who you are. So I can't simply 17 | add to an exclude list just because you ask. 18 | 19 | Thirdly, it'll just make you more of a target, as smart hackers know to 20 | use the exclude-list as one of their first include-lists, as it marks 21 | people who have something to hide. 22 | 23 | Fourthly, and most importantly, it's Wrong Think on how to manage your 24 | network. 25 | 26 | -------------------------------------------------------------------------------- /doc/faq/FAQ0004-serverlogs.md: -------------------------------------------------------------------------------- 1 | # Why is masscan in my server logs? 2 | 3 | ## Question 4 | 5 | Some example questions: 6 | * Why is `masscan` appearing in my server logs? 7 | * Why are you scanning me? 8 | * Why is my server trying to connect to this github repo? 9 | 10 | ## Answer 11 | 12 | When `masscan` connections to a webserver, it puts a link 13 | back to this repo in the `User-Agent` field. 14 | 15 | Since lots of people run Internet-wide scans using this tool, 16 | and an Internet wide scan hits every public web server, you'll 17 | see this appear in your web server logs several times a day. 18 | 19 | It's the **end-to-end** principle of the Internet. Having a public 20 | webserver on the Internet means that anybody can and will try to 21 | connect to the web server. 22 | 23 | It's nothing necessarily malicious. Lots of people run Internet-wide 24 | scans to gather information about the state of the Internet. Of course, 25 | some are indeed malicious, scanning to find vulnerabilities. However, 26 | even when malicious, they probably aren't targetting you in particular, 27 | but are instead scanning everybody. 28 | 29 | -------------------------------------------------------------------------------- /doc/faq/README.md: -------------------------------------------------------------------------------- 1 | # FAQs (frequently asked questions) 2 | 3 | This directory contains some documents discussing frequently asked 4 | questions 5 | 6 | - 1 - [Why is it not as fast as I expect?](FAQ0001-slow.md) 7 | - 2 - [Why are many results missing that I expect?](FAQ0002-drops.md) 8 | - 3 - [How can I add my IPs to an official exclude list, to get people to stop scanning me?](FAQ0003-excludelist.md) 9 | - 4 - [Why is this in my server logs?](FAQ0004-serverlogs.md) 10 | -------------------------------------------------------------------------------- /src/crypto-base64.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTO_BASE64_H 2 | #define CRYPTO_BASE64_H 3 | #include 4 | 5 | size_t base64_decode(void *dst, size_t sizeof_dst, const void *src, size_t sizeof_src); 6 | size_t base64_encode(void *dst, size_t sizeof_dst, const void *src, size_t sizeof_src); 7 | 8 | int base64_selftest(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/crypto-blackrock.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_BLACKROCK_H 2 | #define RAND_BLACKROCK_H 3 | #include 4 | 5 | struct BlackRock { 6 | uint64_t range; 7 | uint64_t a; 8 | uint64_t b; 9 | uint64_t seed; 10 | unsigned rounds; 11 | uint64_t a_bits; 12 | uint64_t a_mask; 13 | uint64_t b_bits; 14 | uint64_t b_mask; 15 | }; 16 | 17 | /** 18 | * Initializes a structure for shuffling numbers within 19 | * a range. 20 | * 21 | * @param range 22 | * The size of the range of numbers needing to be 23 | * shuffled/randomized. 24 | */ 25 | void 26 | blackrock_init(struct BlackRock *br, uint64_t range, uint64_t seed, unsigned rounds); 27 | void 28 | blackrock2_init(struct BlackRock *br, uint64_t range, uint64_t seed, unsigned rounds); 29 | 30 | /** 31 | * Given a number within a range, produce a different number with 32 | * the same range. There is a 1-to-1 mapping between the two, 33 | * so when linearly incrementing through the range, the output 34 | * of this function won't repeat. In other words, encrypt the index variable. 35 | * @param br 36 | * The randomization parameters created with 'blackrock_init()' 37 | * @param index 38 | * An input within the specified range. We call it an 'index' variable 39 | * because that's how we intend to use this function, shuffling a 40 | * monotonically increasing index variable, but in truth, any sort 41 | * of integer can be used. This must be within the 'range' specified 42 | * during the call to blackrock_init(), or the results are undefined. 43 | * @return 44 | * A one-to-one matching index that's in the same range. 45 | */ 46 | uint64_t 47 | blackrock_shuffle(const struct BlackRock *br, uint64_t index); 48 | uint64_t 49 | blackrock2_shuffle(const struct BlackRock *br, uint64_t index); 50 | 51 | /** 52 | * The reverse of the shuffle function above: given the shuffled/encrypted 53 | * integer, return the original index value before the shuffling/encryption. 54 | */ 55 | uint64_t 56 | blackrock_unshuffle(const struct BlackRock *br, uint64_t m); 57 | uint64_t 58 | blackrock2_unshuffle(const struct BlackRock *br, uint64_t m); 59 | 60 | 61 | /** 62 | * Do a regression test. 63 | * @return 64 | * 0 of the regression test succeeds or non-zero if it fails 65 | */ 66 | int 67 | blackrock_selftest(void); 68 | int 69 | blackrock2_selftest(void); 70 | 71 | /** 72 | * Do a benchmark of this module regression test. 73 | */ 74 | void 75 | blackrock_benchmark(unsigned rounds); 76 | void 77 | blackrock2_benchmark(unsigned rounds); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /src/crypto-lcg.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_LCG_H 2 | #define RAND_LCG_H 3 | #include 4 | 5 | 6 | void 7 | lcg_calculate_constants(uint64_t m, uint64_t *out_a, uint64_t *inout_c, int is_debug); 8 | 9 | uint64_t 10 | lcg_rand(uint64_t index, uint64_t a, uint64_t c, uint64_t range); 11 | 12 | /** 13 | * Performs a regression test on this module. 14 | * @return 15 | * 0 on success, or a positive integer on failure 16 | */ 17 | int 18 | lcg_selftest(void); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/crypto-primegen.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIMEGEN_H 2 | #define PRIMEGEN_H 3 | 4 | #include 5 | 6 | /** 7 | * This is B/32: the number of 32-bit words of space used in the primegen 8 | * inner loop. This should fit into the CPU's level-1 cache. 9 | * 10 | * 2048 works well on a Pentium-100. 11 | * 3600 works well on a Pentium II-350 12 | * 4004 works well on an UltraSPARC-I/167 13 | * 14 | * 2012-nov (Rob): This code was written 15 years ago. Processor caches 15 | * haven't really gotten any larger. A number like 8008 works slightly 16 | * better on an Ivy Bridge CPU, but works noticeably worse on an Atom 17 | * or ARM processor. The value 4004 seems to be a good compromise for 18 | * all these processors. In any case, modern CPUs will automatically 19 | * prefetch the buffers anyway, significantly lessoning the impact of 20 | * having a poor number defined here. I tried 16016, but it crashed, and 21 | * I don't know why, but I don't care because I'm not going to use such a 22 | * large size. 23 | */ 24 | #define PRIMEGEN_WORDS 4004 25 | 26 | typedef struct { 27 | uint32_t buf[16][PRIMEGEN_WORDS]; 28 | uint64_t p[512]; /* p[num-1] ... p[0], in that order */ 29 | int num; 30 | int pos; /* next entry to use in buf; WORDS to restart */ 31 | uint64_t base; 32 | uint64_t L; 33 | } primegen; 34 | 35 | extern void primegen_sieve(primegen *); 36 | extern void primegen_fill(primegen *); 37 | 38 | extern void primegen_init(primegen *); 39 | extern uint64_t primegen_next(primegen *); 40 | extern uint64_t primegen_peek(primegen *); 41 | extern uint64_t primegen_count(primegen *,uint64_t to); 42 | extern void primegen_skipto(primegen *,uint64_t to); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/crypto-siphash24.h: -------------------------------------------------------------------------------- 1 | #ifndef CRYPTO_SIPHASH24_H 2 | #define CRYPTO_SIPHASH24_H 3 | #include 4 | 5 | uint64_t 6 | siphash24(const void *in, size_t inlen, const uint64_t key[2]); 7 | 8 | /** 9 | * Regression-test this module. 10 | * @return 11 | * 0 on success, a positive integer otherwise. 12 | */ 13 | int 14 | siphash24_selftest(void); 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /src/event-timeout.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_TIMEOUT_H 2 | #define EVENT_TIMEOUT_H 3 | #include 4 | #include 5 | #include /* offsetof*/ 6 | #include "util-bool.h" /* */ 7 | #if defined(_MSC_VER) 8 | #undef inline 9 | #define inline _inline 10 | #endif 11 | struct Timeouts; 12 | 13 | 14 | 15 | 16 | /*************************************************************************** 17 | ***************************************************************************/ 18 | struct TimeoutEntry { 19 | /** 20 | * In units of 1/16384 of a second. We use power-of-two units here 21 | * to make the "modulus" operation a simple binary "and". 22 | * See the TICKS_FROM_TV() macro for getting the timestamp from 23 | * the current time. 24 | */ 25 | uint64_t timestamp; 26 | 27 | /** we build a doubly-linked list */ 28 | struct TimeoutEntry *next; 29 | struct TimeoutEntry **prev; 30 | 31 | /** The timeout entry is never allocated by itself, but instead 32 | * lives inside another data structure. This stores the value of 33 | * 'offsetof()', so given a pointer to this structure, we can find 34 | * the original structure that contains it */ 35 | unsigned offset; 36 | }; 37 | 38 | /*************************************************************************** 39 | ***************************************************************************/ 40 | static inline bool 41 | timeout_is_unlinked(const struct TimeoutEntry *entry) { 42 | if (entry->prev == 0 || entry->next == 0) 43 | return true; 44 | else 45 | return false; 46 | } 47 | 48 | /*************************************************************************** 49 | ***************************************************************************/ 50 | static inline void 51 | timeout_unlink(struct TimeoutEntry *entry) 52 | { 53 | if (entry->prev == 0 && entry->next == 0) 54 | return; 55 | *(entry->prev) = entry->next; 56 | if (entry->next) 57 | entry->next->prev = entry->prev; 58 | entry->next = 0; 59 | entry->prev = 0; 60 | entry->timestamp = 0; 61 | } 62 | 63 | /*************************************************************************** 64 | ***************************************************************************/ 65 | static inline void 66 | timeout_init(struct TimeoutEntry *entry) 67 | { 68 | entry->next = 0; 69 | entry->prev = 0; 70 | } 71 | 72 | /** 73 | * Create a timeout subsystem. 74 | * @param timestamp_now 75 | * The current timestamp indicating "now" when the thing starts. 76 | * This should be 'time(0) * TICKS_PER_SECOND'. 77 | */ 78 | struct Timeouts * 79 | timeouts_create(uint64_t timestamp_now); 80 | 81 | /** 82 | * Insert the timeout 'entry' into the future location in the timeout 83 | * ring, as determined by the timestamp. 84 | * @param timeouts 85 | * A ring of timeouts, with each slot corresponding to a specific 86 | * time in the future. 87 | * @param entry 88 | * The entry that we are going to insert into the ring. If it's 89 | * already in the ring, it'll be removed from the old location 90 | * first before inserting into the new location. 91 | * @param offset 92 | * The 'entry' field above is part of an existing structure. This 93 | * tells the offset_of() from the beginning of that structure. 94 | * In other words, this tells us the pointer to the object that 95 | * that is the subject of the timeout. 96 | * @param timestamp_expires 97 | * When this timeout will expire. This is in terms of internal 98 | * ticks, which in units of TICKS_PER_SECOND. 99 | */ 100 | void 101 | timeouts_add(struct Timeouts *timeouts, struct TimeoutEntry *entry, 102 | size_t offset, uint64_t timestamp_expires); 103 | 104 | /** 105 | * Remove an object from the timestamp system that is older than than 106 | * the specified timestamp. This function must be called repeatedly 107 | * until it returns NULL to remove all the objects that are older 108 | * than the given timestamp. 109 | * @param timeouts 110 | * A ring of timeouts. We'll walk the ring until we've caught 111 | * up with the current time. 112 | * @param timestamp_now 113 | * Usually, this timestmap will be "now", the current time, 114 | * and anything older than this will be aged out. 115 | * @return 116 | * an object older than the specified timestamp, or NULL 117 | * if there are no more objects to be found 118 | */ 119 | void * 120 | timeouts_remove(struct Timeouts *timeouts, uint64_t timestamp_now); 121 | 122 | /* 123 | * This macros convert a normal "timeval" structure into the timestamp 124 | * that we use for timeouts. The timeval structure probably will come 125 | * from the packets that we are capturing. 126 | */ 127 | #define TICKS_PER_SECOND (16384ULL) 128 | #define TICKS_FROM_SECS(secs) ((secs)*16384ULL) 129 | #define TICKS_FROM_USECS(usecs) ((usecs)/16384ULL) 130 | #define TICKS_FROM_TV(secs,usecs) (TICKS_FROM_SECS(secs)+TICKS_FROM_USECS(usecs)) 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /src/in-binary.h: -------------------------------------------------------------------------------- 1 | #ifndef IN_BINARY_H 2 | #define IN_BINARY_H 3 | struct Masscan; 4 | 5 | /** 6 | * Read that output of previous scans that were saved in the binary format 7 | * (i.e. using the -oB parameter or the '--output-format binary' parameter). 8 | * The intent is that the user can then re-output in another format like 9 | * JSON or XML. 10 | */ 11 | void 12 | readscan_binary_scanfile(struct Masscan *masscan, 13 | int arg_first, int arg_max, char *argv[]); 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /src/in-filter.c: -------------------------------------------------------------------------------- 1 | #include "in-filter.h" 2 | #include "massip.h" 3 | 4 | 5 | int 6 | readscan_filter_pass(ipaddress ip, unsigned port, unsigned type, 7 | const struct MassIP *filter, 8 | const struct RangeList *btypes) 9 | { 10 | if (filter && filter->count_ipv4s) { 11 | if (!massip_has_ip(filter, ip)) 12 | return 0; 13 | } 14 | if (filter && filter->count_ports) { 15 | if (!massip_has_port(filter, port)) 16 | return 0; 17 | } 18 | if (btypes && btypes->count) { 19 | if (!rangelist_is_contains(btypes, type)) 20 | return 0; 21 | } 22 | 23 | return 1; 24 | } 25 | -------------------------------------------------------------------------------- /src/in-filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | This is for filtering input in the "--readscan" feature 3 | */ 4 | #ifndef IN_FILTER_H 5 | #define IN_FILTER_H 6 | #include "massip-addr.h" 7 | struct RangeList; 8 | struct Range6List; 9 | struct MassIP; 10 | 11 | /** 12 | * Filters readscan record by IP address, port number, 13 | * or banner-type. 14 | */ 15 | int 16 | readscan_filter_pass(ipaddress ip, unsigned port, unsigned type, 17 | const struct MassIP *massip, 18 | const struct RangeList *btypes); 19 | 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/in-report.h: -------------------------------------------------------------------------------- 1 | #ifndef IN_REPORT_H 2 | #define IN_REPORT_H 3 | #include 4 | 5 | void 6 | readscan_report( unsigned ip, 7 | unsigned app_proto, 8 | unsigned char **data, 9 | size_t *data_length); 10 | 11 | void 12 | readscan_report_init(void); 13 | 14 | void 15 | readscan_report_print(void); 16 | 17 | 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/main-dedup.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_DEDUP_H 2 | #define MAIN_DEDUP_H 3 | #include "massip-addr.h" 4 | 5 | struct DedupTable * 6 | dedup_create(void); 7 | 8 | void 9 | dedup_destroy(struct DedupTable *table); 10 | 11 | unsigned 12 | dedup_is_duplicate( struct DedupTable *dedup, 13 | ipaddress ip_them, unsigned port_them, 14 | ipaddress ip_me, unsigned port_me); 15 | 16 | /** 17 | * Simple unit test 18 | * @return 0 on success, 1 on failure. 19 | */ 20 | int dedup_selftest(void); 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/main-globals.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_GLOBALS_H 2 | #define MAIN_GLOBALS_H 3 | #include 4 | 5 | extern unsigned volatile is_tx_done; 6 | extern unsigned volatile is_rx_done; 7 | extern time_t global_now; 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/main-listscan.c: -------------------------------------------------------------------------------- 1 | #include "masscan.h" 2 | #include "util-logger.h" 3 | #include "crypto-blackrock.h" 4 | 5 | 6 | void 7 | main_listscan(struct Masscan *masscan) 8 | { 9 | uint64_t i; 10 | uint64_t range; 11 | uint64_t start; 12 | uint64_t end; 13 | struct BlackRock blackrock; 14 | unsigned increment = masscan->shard.of; 15 | uint64_t seed = masscan->seed; 16 | 17 | /* If called with no ports, then create a pseudo-port needed 18 | * for the internal algorithm. */ 19 | if (!massip_has_target_ports(&masscan->targets)) 20 | rangelist_add_range(&masscan->targets.ports, 80, 80); 21 | massip_optimize(&masscan->targets); 22 | 23 | /* The "range" is the total number of IP/port combinations that 24 | * the scan can produce */ 25 | range = massip_range(&masscan->targets).lo; 26 | 27 | 28 | infinite: 29 | blackrock_init(&blackrock, range, seed, masscan->blackrock_rounds); 30 | 31 | start = masscan->resume.index + (masscan->shard.one-1); 32 | end = range; 33 | if (masscan->resume.count && end > start + masscan->resume.count) 34 | end = start + masscan->resume.count; 35 | end += (uint64_t)(masscan->retries * masscan->max_rate); 36 | 37 | for (i=start; itargets, xXx, &addr, &port); 45 | 46 | 47 | if (masscan->is_test_csv) { 48 | /* [KLUDGE] [TEST] 49 | * For testing randomness output, prints last two bytes of 50 | * IP address as CSV format for import into spreadsheet 51 | */ 52 | printf("%u,%u\n",(addr.ipv4>>8)&0xFF, (addr.ipv4>>0)&0xFF); 53 | } else if (masscan->targets.count_ports == 1) { 54 | ipaddress_formatted_t fmt = ipaddress_fmt(addr); 55 | /* This is the normal case */ 56 | printf("%s\n", fmt.string); 57 | } else { 58 | ipaddress_formatted_t fmt = ipaddress_fmt(addr); 59 | if (addr.version == 6) 60 | printf("[%s]:%u\n", fmt.string, port); 61 | else 62 | printf("%s:%u\n", fmt.string, port); 63 | } 64 | 65 | i += increment; /* <------ increment by 1 normally, more with shards/NICs */ 66 | } 67 | 68 | if (masscan->is_infinite) { 69 | seed++; 70 | goto infinite; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main-ptrace.c: -------------------------------------------------------------------------------- 1 | #include "main-ptrace.h" 2 | #include "proto-preprocess.h" 3 | #include "pixie-timer.h" 4 | #include "util-safefunc.h" 5 | 6 | 7 | /*************************************************************************** 8 | * Print packet info, when using nmap-style --packet-trace option 9 | ***************************************************************************/ 10 | void 11 | packet_trace(FILE *fp, double pt_start, const unsigned char *px, size_t length, unsigned is_sent) 12 | { 13 | unsigned x; 14 | struct PreprocessedInfo parsed; 15 | char from[64]; 16 | char to[64]; 17 | char sz_type[32]; 18 | unsigned type; 19 | double timestamp = 1.0 * pixie_gettime() / 1000000.0; 20 | unsigned offset; 21 | const char *direction; 22 | ipaddress_formatted_t fmt; 23 | 24 | if (is_sent) 25 | direction = "SENT"; 26 | else 27 | direction = "RCVD"; 28 | 29 | /* parse the packet */ 30 | x = preprocess_frame(px, (unsigned)length, 1, &parsed); 31 | if (!x) 32 | return; 33 | offset = parsed.found_offset; 34 | 35 | 36 | /* format the IP addresses into fixed-width fields */ 37 | fmt = ipaddress_fmt(parsed.src_ip); 38 | snprintf(from, sizeof(from), "[%s]:%u", fmt.string, parsed.port_src); 39 | 40 | fmt = ipaddress_fmt(parsed.dst_ip); 41 | snprintf(to, sizeof(to), "[%s]:%u", fmt.string, parsed.port_dst); 42 | 43 | switch (parsed.found) { 44 | case FOUND_ARP: 45 | type = px[offset+6]<<8 | px[offset+7]; 46 | *strchr(to, ':') = '\0'; 47 | *strchr(from, ':') = '\0'; 48 | switch (type) { 49 | case 1:safe_strcpy(sz_type, sizeof(sz_type), "request"); break; 50 | case 2:safe_strcpy(sz_type, sizeof(sz_type), "response"); break; 51 | default: snprintf(sz_type, sizeof(sz_type), "unknown(%u)", type); break; 52 | } 53 | fprintf(fp, "%s (%5.4f) ARP %-21s > %-21s %s\n", direction, 54 | timestamp - pt_start, from, to, sz_type); 55 | break; 56 | case FOUND_DNS: 57 | case FOUND_UDP: 58 | fprintf(fp, "%s (%5.4f) UDP %-21s > %-21s \n", direction, 59 | timestamp - pt_start, from, to); 60 | break; 61 | case FOUND_ICMP: 62 | fprintf(fp, "%s (%5.4f) ICMP %-21s > %-21s \n", direction, 63 | timestamp - pt_start, from, to); 64 | break; 65 | case FOUND_TCP: 66 | type = px[offset+13]; 67 | switch (type) { 68 | case 0x00: safe_strcpy(sz_type, sizeof(sz_type), "NULL"); break; 69 | case 0x01: safe_strcpy(sz_type, sizeof(sz_type), "FIN"); break; 70 | case 0x11: safe_strcpy(sz_type, sizeof(sz_type), "FIN-ACK"); break; 71 | case 0x19: safe_strcpy(sz_type, sizeof(sz_type), "FIN-ACK-PSH"); break; 72 | case 0x02: safe_strcpy(sz_type, sizeof(sz_type), "SYN"); break; 73 | case 0x12: safe_strcpy(sz_type, sizeof(sz_type), "SYN-ACK"); break; 74 | case 0x04: safe_strcpy(sz_type, sizeof(sz_type), "RST"); break; 75 | case 0x14: safe_strcpy(sz_type, sizeof(sz_type), "RST-ACK"); break; 76 | case 0x15: safe_strcpy(sz_type, sizeof(sz_type), "RST-FIN-ACK"); break; 77 | case 0x10: safe_strcpy(sz_type, sizeof(sz_type), "ACK"); break; 78 | case 0x18: safe_strcpy(sz_type, sizeof(sz_type), "ACK-PSH"); break; 79 | default: 80 | snprintf(sz_type, sizeof(sz_type), 81 | "%s%s%s%s%s%s%s%s", 82 | (type&0x01)?"FIN":"", 83 | (type&0x02)?"SYN":"", 84 | (type&0x04)?"RST":"", 85 | (type&0x08)?"PSH":"", 86 | (type&0x10)?"ACK":"", 87 | (type&0x20)?"URG":"", 88 | (type&0x40)?"ECE":"", 89 | (type&0x80)?"CWR":"" 90 | ); 91 | break; 92 | } 93 | if (parsed.app_length) 94 | fprintf(fp, "%s (%5.4f) TCP %-21s > %-21s %s %u-bytes\n", direction, 95 | timestamp - pt_start, from, to, sz_type, parsed.app_length); 96 | else 97 | fprintf(fp, "%s (%5.4f) TCP %-21s > %-21s %s\n", direction, 98 | timestamp - pt_start, from, to, sz_type); 99 | break; 100 | case FOUND_IPV6: 101 | break; 102 | default: 103 | fprintf(fp, "%s (%5.4f) UNK %-21s > %-21s [%u]\n", direction, 104 | timestamp - pt_start, from, to, parsed.found); 105 | break; 106 | } 107 | 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main-ptrace.h: -------------------------------------------------------------------------------- 1 | #ifndef masscan_main_ptrace_h 2 | #define masscan_main_ptrace_h 3 | #include 4 | #include 5 | 6 | 7 | void packet_trace(FILE *fp, double pt_trace, const unsigned char *px, size_t length, unsigned is_sent); 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/main-readrange.c: -------------------------------------------------------------------------------- 1 | #include "main-readrange.h" 2 | #include "masscan.h" 3 | #include 4 | 5 | /*************************************************************************** 6 | ***************************************************************************/ 7 | /*static unsigned 8 | count_cidr_bits(struct Range range) 9 | { 10 | unsigned i; 11 | 12 | for (i=0; i<32; i++) { 13 | unsigned mask = 0xFFFFFFFF >> i; 14 | 15 | if ((range.begin & ~mask) == (range.end & ~mask)) { 16 | if ((range.begin & mask) == 0 && (range.end & mask) == mask) 17 | return i; 18 | } 19 | } 20 | 21 | return 0; 22 | }*/ 23 | 24 | /*************************************************************************** 25 | ***************************************************************************/ 26 | static unsigned 27 | count_cidr6_bits(struct Range6 range) 28 | { 29 | uint64_t i; 30 | 31 | /* Kludge: can't handle more than 64-bits of CIDR ranges */ 32 | if (range.begin.hi != range.begin.lo) 33 | return 0; 34 | 35 | for (i=0; i<64; i++) { 36 | uint64_t mask = 0xFFFFFFFFffffffffull >> i; 37 | 38 | if ((range.begin.lo & ~mask) == (range.end.lo & ~mask)) { 39 | if ((range.begin.lo & mask) == 0 && (range.end.lo & mask) == mask) 40 | return (unsigned)i; 41 | } 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | /*************************************************************************** 48 | ***************************************************************************/ 49 | void 50 | main_readrange(struct Masscan *masscan) 51 | { 52 | struct RangeList *list4 = &masscan->targets.ipv4; 53 | struct Range6List *list6 = &masscan->targets.ipv6; 54 | unsigned i; 55 | FILE *fp = stdout; 56 | 57 | for (i=0; icount; i++) { 58 | unsigned prefix_length; 59 | struct Range range = list4->list[i]; 60 | 61 | if (range.begin == range.end) { 62 | fprintf(fp, "%u.%u.%u.%u\n", 63 | (range.begin>>24)&0xFF, 64 | (range.begin>>16)&0xFF, 65 | (range.begin>> 8)&0xFF, 66 | (range.begin>> 0)&0xFF 67 | ); 68 | } else if (range_is_cidr(range, &prefix_length)) { 69 | fprintf(fp, "%u.%u.%u.%u/%u\n", 70 | (range.begin>>24)&0xFF, 71 | (range.begin>>16)&0xFF, 72 | (range.begin>> 8)&0xFF, 73 | (range.begin>> 0)&0xFF, 74 | prefix_length 75 | ); 76 | } else { 77 | fprintf(fp, "%u.%u.%u.%u-%u.%u.%u.%u\n", 78 | (range.begin>>24)&0xFF, 79 | (range.begin>>16)&0xFF, 80 | (range.begin>> 8)&0xFF, 81 | (range.begin>> 0)&0xFF, 82 | (range.end>>24)&0xFF, 83 | (range.end>>16)&0xFF, 84 | (range.end>> 8)&0xFF, 85 | (range.end>> 0)&0xFF 86 | ); 87 | } 88 | } 89 | 90 | for (i=0; icount; i++) { 91 | struct Range6 range = list6->list[i]; 92 | ipaddress_formatted_t fmt = ipv6address_fmt(range.begin); 93 | fprintf(fp, "%s", fmt.string); 94 | if (!ipv6address_is_equal(range.begin, range.end)) { 95 | unsigned cidr_bits = count_cidr6_bits(range); 96 | if (cidr_bits) { 97 | fprintf(fp, "/%u", cidr_bits); 98 | } else { 99 | fmt = ipv6address_fmt(range.end); 100 | fprintf(fp, "-%s", fmt.string); 101 | } 102 | } 103 | fprintf(fp, "\n"); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/main-readrange.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_READRANGE_H 2 | #define MAIN_READRANGE_H 3 | struct Masscan; 4 | 5 | void 6 | main_readrange(struct Masscan *masscan); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/main-status.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_STATUS_H 2 | #define MAIN_STATUS_H 3 | #include 4 | #include 5 | #include "util-bool.h" 6 | 7 | struct Status 8 | { 9 | struct { 10 | double clock; 11 | time_t time; 12 | uint64_t count; 13 | } last; 14 | uint64_t timer; 15 | unsigned charcount; 16 | 17 | double last_rates[8]; 18 | unsigned last_count; 19 | 20 | unsigned is_infinite:1; 21 | 22 | uint64_t total_tcbs; 23 | uint64_t total_synacks; 24 | uint64_t total_syns; 25 | }; 26 | 27 | 28 | void status_print(struct Status *status, uint64_t count, uint64_t max_count, double x, uint64_t total_tcbs, uint64_t total_synacks, uint64_t total_syns, uint64_t exiting, bool json_status); 29 | void status_finish(struct Status *status); 30 | void status_start(struct Status *status); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/main-throttle.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_THROTTLE_H 2 | #define MAIN_THROTTLE_H 3 | #include 4 | 5 | struct Throttler 6 | { 7 | double max_rate; 8 | double current_rate; 9 | double batch_size; 10 | 11 | unsigned index; 12 | 13 | struct { 14 | uint64_t timestamp; 15 | uint64_t packet_count; 16 | } buckets[256]; 17 | 18 | uint64_t test_timestamp; 19 | uint64_t test_packet_count; 20 | 21 | }; 22 | 23 | 24 | uint64_t throttler_next_batch(struct Throttler *throttler, uint64_t count); 25 | void throttler_start(struct Throttler *status, double max_rate); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/masscan-app.h: -------------------------------------------------------------------------------- 1 | #ifndef MASSCAN_APP_H 2 | #define MASSCAN_APP_H 3 | 4 | /* 5 | * WARNING: these constants are used in files, so don't change the values. 6 | * Add new ones onto the end 7 | */ 8 | enum ApplicationProtocol { 9 | PROTO_NONE, 10 | PROTO_HEUR, 11 | PROTO_SSH1, 12 | PROTO_SSH2, 13 | PROTO_HTTP, 14 | PROTO_FTP, 15 | PROTO_DNS_VERSIONBIND, 16 | PROTO_SNMP, /* 7 - simple network management protocol, udp/161 */ 17 | PROTO_NBTSTAT, /* 8 - netbios, udp/137 */ 18 | PROTO_SSL3, 19 | PROTO_SMB, /* 10 - SMB tcp/139 and tcp/445 */ 20 | PROTO_SMTP, /* 11 - transfering email */ 21 | PROTO_POP3, /* 12 - fetching email */ 22 | PROTO_IMAP4, /* 13 - fetching email */ 23 | PROTO_UDP_ZEROACCESS, 24 | PROTO_X509_CERT, /* 15 - just the cert */ 25 | PROTO_X509_CACERT, 26 | PROTO_HTML_TITLE, 27 | PROTO_HTML_FULL, 28 | PROTO_NTP, /* 19 - network time protocol, udp/123 */ 29 | PROTO_VULN, 30 | PROTO_HEARTBLEED, 31 | PROTO_TICKETBLEED, 32 | PROTO_VNC_OLD, 33 | PROTO_SAFE, 34 | PROTO_MEMCACHED, /* 25 - memcached */ 35 | PROTO_SCRIPTING, 36 | PROTO_VERSIONING, 37 | PROTO_COAP, /* 28 - constrained app proto, udp/5683, RFC7252 */ 38 | PROTO_TELNET, /* 29 - ye old remote terminal */ 39 | PROTO_RDP, /* 30 - Microsoft Remote Desktop Protocol tcp/3389 */ 40 | PROTO_HTTP_SERVER, /* 31 - HTTP "Server:" field */ 41 | PROTO_MC, /* 32 - Minecraft server */ 42 | PROTO_VNC_RFB, 43 | PROTO_VNC_INFO, 44 | PROTO_ISAKMP, /* 35 - IPsec key exchange */ 45 | 46 | PROTO_ERROR, 47 | 48 | PROTO_end_of_list /* must be last one */ 49 | }; 50 | 51 | const char * 52 | masscan_app_to_string(enum ApplicationProtocol proto); 53 | 54 | enum ApplicationProtocol 55 | masscan_string_to_app(const char *str); 56 | 57 | int 58 | masscan_app_selftest(void); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/masscan-status.h: -------------------------------------------------------------------------------- 1 | #ifndef MASSCAN_STATUS_H 2 | #define MASSCAN_STATUS_H 3 | 4 | #if 0 5 | enum PortStatus { 6 | Port_Unknown, 7 | Port_Open, 8 | Port_Closed, 9 | Port_IcmpEchoResponse, 10 | Port_UdpOpen, 11 | Port_UdpClosed, 12 | Port_SctpOpen, 13 | Port_SctpClosed, 14 | Port_ArpOpen, 15 | }; 16 | #endif 17 | 18 | enum PortStatus { 19 | PortStatus_Unknown, 20 | PortStatus_Open, 21 | PortStatus_Closed, 22 | PortStatus_Arp, 23 | PortStatus_Count 24 | 25 | }; 26 | 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/masscan-version.h: -------------------------------------------------------------------------------- 1 | #ifndef MASSCAN_VERSION 2 | 3 | #define MASSCAN_VERSION "1.3.9-integration" 4 | 5 | #endif 6 | 7 | -------------------------------------------------------------------------------- /src/massip-parse.h: -------------------------------------------------------------------------------- 1 | /* 2 | massip-parse 3 | 4 | This module parses IPv4 and IPv6 addresses. 5 | 6 | It's not a typical parser. It's optimized around parsing large 7 | files containing millions of addresses and ranges using a 8 | "state-machine parser". 9 | */ 10 | #ifndef MASSIP_PARSE_H 11 | #define MASSIP_PARSE_H 12 | #include "massip-addr.h" 13 | 14 | struct MassIP; 15 | struct Range; 16 | struct Range6; 17 | 18 | /** 19 | * Parse a file, extracting all the IPv4 and IPv6 addresses and ranges. 20 | * This is optimized for speed, handling millions of entries in under 21 | * a second. This is especially tuned for IPv6 addresses, as while IPv4 22 | * scanning is mostly done with target rnages, IPv6 scanning is mostly 23 | * done with huge lists of target addresses. 24 | * @param filename 25 | * The name of the file that we'll open, parse, and close. 26 | * @param targets_ipv4 27 | * The list of IPv4 targets that we append any IPv4 addresses to. 28 | * @param targets_ipv6 29 | * The list of IPv6 targets that we append any IPv6 addresses/ranges to. 30 | * @return 31 | 0 on success, any other number on failure. 32 | */ 33 | int 34 | massip_parse_file(struct MassIP *massip, const char *filename); 35 | 36 | 37 | enum RangeParseResult { 38 | Bad_Address, 39 | Ipv4_Address=4, 40 | Ipv6_Address=6, 41 | }; 42 | 43 | /** 44 | * Parse the next IPv4/IPv6 range from a string. This is called 45 | * when parsing strings from the command-line. 46 | */ 47 | enum RangeParseResult 48 | massip_parse_range(const char *line, size_t *inout_offset, size_t max, struct Range *ipv4, struct Range6 *ipv6); 49 | 50 | 51 | 52 | /** 53 | * Parse a single IPv6 address. This is called when working with 54 | * the operating system stack, when querying addresses from 55 | * the local network adapters. 56 | */ 57 | ipv6address_t 58 | massip_parse_ipv6(const char *buf); 59 | 60 | ipv4address_t 61 | massip_parse_ipv4(const char *buf); 62 | 63 | 64 | /** 65 | * Do a simplistic unit test of the parser. 66 | * @return 0 on success, 1 on failure 67 | */ 68 | int 69 | massip_parse_selftest(void); 70 | 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /src/massip-port.h: -------------------------------------------------------------------------------- 1 | #ifndef MASSIP_PORT_H 2 | #define MASSIP_PORT_H 3 | 4 | /* 5 | * Ports are 16-bit numbers ([0..65535], but different 6 | * transports (TCP, UDP, SCTP) are distinct port ranges. Thus, we 7 | * instead of three 64k ranges we could instead treat this internally 8 | * as a 192k port range. We can expand this range to include other 9 | * things we scan for, such as ICMP pings or ARP requests. 10 | */ 11 | enum { 12 | Templ_TCP = 0, 13 | Templ_TCP_last = 65535, 14 | Templ_UDP = 65536, 15 | Templ_UDP_last = 65536 + 65535, 16 | Templ_SCTP = 65536*2, 17 | Templ_SCTP_last = 65536*2 + 65535, 18 | Templ_ICMP_echo = 65536*3+0, 19 | Templ_ICMP_timestamp = 65536*3+1, 20 | Templ_ARP = 65536*3+2, 21 | Templ_Oproto_first = 65536*3 + 256, 22 | Templ_Oproto_last = 65536*3 + 256 + 255, 23 | Templ_VulnCheck = 65536*4, 24 | 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/massip.c: -------------------------------------------------------------------------------- 1 | #include "massip.h" 2 | #include "massip-parse.h" 3 | #include "massip-rangesv4.h" 4 | #include "massip-rangesv6.h" 5 | #include 6 | #include 7 | 8 | void massip_apply_excludes(struct MassIP *targets, struct MassIP *exclude) 9 | { 10 | rangelist_exclude(&targets->ipv4, &exclude->ipv4); 11 | range6list_exclude(&targets->ipv6, &exclude->ipv6); 12 | rangelist_exclude(&targets->ports, &exclude->ports); 13 | } 14 | 15 | void massip_optimize(struct MassIP *targets) 16 | { 17 | rangelist_optimize(&targets->ipv4); 18 | range6list_optimize(&targets->ipv6); 19 | rangelist_optimize(&targets->ports); 20 | 21 | targets->count_ports = rangelist_count(&targets->ports); 22 | targets->count_ipv4s = rangelist_count(&targets->ipv4); 23 | targets->count_ipv6s = range6list_count(&targets->ipv6).lo; 24 | targets->ipv4_index_threshold = targets->count_ipv4s * rangelist_count(&targets->ports); 25 | } 26 | 27 | int massip_pick(const struct MassIP *massip, uint64_t index, ipaddress *addr, unsigned *port) 28 | { 29 | /* 30 | * We can return either IPv4 or IPv6 addresses 31 | */ 32 | if (index < massip->ipv4_index_threshold) { 33 | addr->version = 4; 34 | addr->ipv4 = rangelist_pick(&massip->ipv4, index % massip->count_ipv4s); 35 | *port = rangelist_pick(&massip->ports, index / massip->count_ipv4s); 36 | } else { 37 | addr->version = 6; 38 | index -= massip->ipv4_index_threshold; 39 | addr->ipv6 = range6list_pick(&massip->ipv6, index % massip->count_ipv6s); 40 | *port = rangelist_pick(&massip->ports, index / massip->count_ipv6s); 41 | } 42 | return 0; 43 | } 44 | 45 | int massip_has_ip(const struct MassIP *massip, ipaddress ip) 46 | { 47 | if (ip.version == 6) 48 | return range6list_is_contains(&massip->ipv6, ip.ipv6); 49 | else 50 | return rangelist_is_contains(&massip->ipv4, ip.ipv4); 51 | } 52 | 53 | int massip_has_port(const struct MassIP *massip, unsigned port) 54 | { 55 | return rangelist_is_contains(&massip->ports, port); 56 | } 57 | 58 | int massip_has_ipv4_targets(const struct MassIP *massip) 59 | { 60 | return massip->ipv4.count != 0; 61 | } 62 | int massip_has_target_ports(const struct MassIP *massip) 63 | { 64 | return massip->ports.count != 0; 65 | } 66 | int massip_has_ipv6_targets(const struct MassIP *massip) 67 | { 68 | return massip->ipv6.count != 0; 69 | } 70 | 71 | 72 | int massip_add_target_string(struct MassIP *massip, const char *string) 73 | { 74 | const char *ranges = string; 75 | size_t offset = 0; 76 | size_t max_offset = strlen(ranges); 77 | 78 | while (offset < max_offset) { 79 | struct Range range; 80 | struct Range6 range6; 81 | int err; 82 | 83 | /* Grab the next IPv4 or IPv6 range */ 84 | err = massip_parse_range(ranges, &offset, max_offset, &range, &range6); 85 | switch (err) { 86 | case Ipv4_Address: 87 | rangelist_add_range(&massip->ipv4, range.begin, range.end); 88 | break; 89 | case Ipv6_Address: 90 | range6list_add_range(&massip->ipv6, range6.begin, range6.end); 91 | break; 92 | default: 93 | offset = max_offset; /* An error means skipping the rest of the string */ 94 | return 1; 95 | } 96 | while (offset < max_offset && (isspace(ranges[offset]&0xFF) || ranges[offset] == ',')) 97 | offset++; 98 | } 99 | return 0; 100 | } 101 | 102 | int massip_add_port_string(struct MassIP *targets, const char *string, unsigned defaultrange) 103 | { 104 | unsigned is_error = 0; 105 | rangelist_parse_ports(&targets->ports, string, &is_error, defaultrange); 106 | if (is_error) 107 | return 1; 108 | else 109 | return 0; 110 | } 111 | 112 | int massip_selftest(void) 113 | { 114 | struct MassIP targets; 115 | struct MassIP excludes; 116 | int err; 117 | int line; 118 | massint128_t count; 119 | 120 | memset(&targets, 0, sizeof(targets)); 121 | memset(&excludes, 0, sizeof(targets)); 122 | 123 | rangelist_parse_ports(&targets.ports, "80", 0, 0); 124 | 125 | /* First, create a list of targets */ 126 | line = __LINE__; 127 | err = massip_add_target_string(&targets, "2607:f8b0:4002:801::2004/124,1111::1"); 128 | if (err) 129 | goto fail; 130 | 131 | /* Second, create an exclude list */ 132 | line = __LINE__; 133 | err = massip_add_target_string(&excludes, "2607:f8b0:4002:801::2004/126,1111::/16"); 134 | if (err) 135 | goto fail; 136 | 137 | /* Third, apply the excludes, causing ranges to be removed 138 | * from the target list */ 139 | massip_apply_excludes(&targets, &excludes); 140 | 141 | /* Now make sure the count equals the expected count */ 142 | line = __LINE__; 143 | count = massip_range(&targets); 144 | if (count.hi != 0 || count.lo != 12) 145 | goto fail; 146 | 147 | return 0; 148 | fail: 149 | fprintf(stderr, "[-] massip: test fail, line=%d\n", line); 150 | return 1; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /src/massip.h: -------------------------------------------------------------------------------- 1 | #ifndef MASSIP_H 2 | #define MASSIP_H 3 | #include 4 | #include "massip-rangesv4.h" 5 | #include "massip-rangesv6.h" 6 | 7 | struct MassIP { 8 | struct RangeList ipv4; 9 | struct Range6List ipv6; 10 | 11 | /** 12 | * The ports we are scanning for. The user can specify repeated ports 13 | * and overlapping ranges, but we'll deduplicate them, scanning ports 14 | * only once. 15 | * NOTE: TCP ports are stored 0-64k, but UDP ports are stored in the 16 | * range 64k-128k, thus, allowing us to scan both at the same time. 17 | */ 18 | struct RangeList ports; 19 | 20 | /** 21 | * Used internally to differentiate between indexes selecting an 22 | * IPv4 address and higher ones selecting an IPv6 address. 23 | */ 24 | uint64_t ipv4_index_threshold; 25 | 26 | uint64_t count_ports; 27 | uint64_t count_ipv4s; 28 | uint64_t count_ipv6s; 29 | }; 30 | 31 | /** 32 | * Count the total number of targets in a scan. This is calculated 33 | * the (IPv6 addresses * IPv4 addresses * ports). This can produce 34 | * a 128-bit number (larger, actually). 35 | */ 36 | massint128_t massip_range(struct MassIP *massip); 37 | 38 | /** 39 | * Remove everything in "targets" that's listed in the "exclude" 40 | * list. The reason for this is that we'll have a single policy 41 | * file of those address ranges which we are forbidden to scan. 42 | * Then, each time we run a scan with different targets, we 43 | * apply this policy file. 44 | */ 45 | void massip_apply_excludes(struct MassIP *targets, struct MassIP *exclude); 46 | 47 | /** 48 | * The last step after processing the configuration, setting up the 49 | * state to be used for scanning. This sorts the address, removes 50 | * duplicates, and creates an optimized 'picker' system to easily 51 | * find an address given an index, or find an index given an address. 52 | */ 53 | void massip_optimize(struct MassIP *targets); 54 | 55 | /** 56 | * This selects an IP+port combination given an index whose value 57 | * is [0..range], where 'range' is the value returned by the function 58 | * `massip_range()`. Since the optimization step (`massip_optimized()`) 59 | * sorted all addresses/ports, a monotonically increasing index will 60 | * list everything in sorted order. The intent, however, is to use the 61 | * "blackrock" algorithm to randomize the index before calling this function. 62 | * 63 | * It is this function, plus the 'blackrock' randomization algorithm, that 64 | * is at the heart of Masscan. 65 | */ 66 | int massip_pick(const struct MassIP *massip, uint64_t index, ipaddress *addr, unsigned *port); 67 | 68 | 69 | int massip_has_ip(const struct MassIP *massip, ipaddress ip); 70 | 71 | int massip_has_port(const struct MassIP *massip, unsigned port); 72 | 73 | int massip_add_target_string(struct MassIP *massip, const char *string); 74 | 75 | /** 76 | * Parse the string contain port specifier. 77 | */ 78 | int massip_add_port_string(struct MassIP *massip, const char *string, unsigned proto); 79 | 80 | 81 | /** 82 | * Indicates whether there are IPv4 targets. If so, we'll have to 83 | * initialize the IPv4 portion of the stack. 84 | * @return true if there are IPv4 targets to be scanned, false 85 | * otherwise 86 | */ 87 | int massip_has_ipv4_targets(const struct MassIP *massip); 88 | int massip_has_target_ports(const struct MassIP *massip); 89 | 90 | /** 91 | * Indicates whether there are IPv6 targets. If so, we'll have to 92 | * initialize the IPv6 portion of the stack. 93 | * @return true if there are IPv6 targets to be scanned, false 94 | * otherwise 95 | */ 96 | int massip_has_ipv6_targets(const struct MassIP *massip); 97 | 98 | 99 | int massip_selftest(void); 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /src/misc-rstfilter.c: -------------------------------------------------------------------------------- 1 | #include "misc-rstfilter.h" 2 | #include "util-malloc.h" 3 | #include "crypto-siphash24.h" 4 | #include 5 | 6 | struct ResetFilter 7 | { 8 | unsigned long long seed; 9 | size_t bucket_count; 10 | size_t bucket_mask; 11 | unsigned counter; 12 | unsigned char *buckets; 13 | }; 14 | 15 | static size_t 16 | next_pow2(size_t n) 17 | { 18 | size_t bit_count = 0; 19 | 20 | /* Always have at least one bit */ 21 | if (n == 0) 22 | return 1; 23 | 24 | /* If already a power-of-two, then return that */ 25 | if ((n & (n - 1)) == 0) 26 | return n; 27 | 28 | /* Count the number of bits */ 29 | while (n != 0) { 30 | n >>= 1; 31 | bit_count += 1; 32 | } 33 | 34 | return (size_t)1 << (size_t)bit_count; 35 | } 36 | 37 | struct ResetFilter * 38 | rstfilter_create(unsigned long long seed, size_t bucket_count) 39 | { 40 | struct ResetFilter *rf; 41 | 42 | rf = CALLOC(1, sizeof(*rf)); 43 | rf->seed = seed; 44 | rf->bucket_count = next_pow2(bucket_count); 45 | rf->bucket_mask = rf->bucket_count - 1; 46 | rf->buckets = CALLOC(rf->bucket_count/2, sizeof(*rf->buckets)); 47 | 48 | return rf; 49 | } 50 | 51 | 52 | void 53 | rstfilter_destroy(struct ResetFilter *rf) 54 | { 55 | if (rf == NULL) 56 | return; 57 | free(rf->buckets); 58 | free(rf); 59 | } 60 | 61 | int 62 | rstfilter_is_filter(struct ResetFilter *rf, 63 | ipaddress src_ip, unsigned src_port, 64 | ipaddress dst_ip, unsigned dst_port) 65 | { 66 | uint64_t hash; 67 | uint64_t input[5]; 68 | uint64_t key[2]; 69 | size_t index; 70 | unsigned char *p; 71 | int result = 0; 72 | 73 | /* 74 | * Setup the input 75 | */ 76 | switch (src_ip.version) { 77 | case 4: 78 | input[0] = src_ip.ipv4; 79 | input[1] = src_port; 80 | input[2] = dst_ip.ipv4; 81 | input[3] = dst_port; 82 | break; 83 | case 6: 84 | input[0] = src_ip.ipv6.hi; 85 | input[1] = src_ip.ipv6.lo; 86 | input[2] = dst_ip.ipv6.hi; 87 | input[3] = dst_ip.ipv6.lo; 88 | input[4] = src_port<<16 | dst_port; 89 | break; 90 | } 91 | key[0] = rf->seed; 92 | key[1] = rf->seed; 93 | 94 | /* 95 | * Grab the bucket 96 | */ 97 | hash = siphash24(input, sizeof(input), key); 98 | index = hash & rf->bucket_mask; 99 | 100 | /* 101 | * Find the result (1=filterout, 0=sendrst) 102 | */ 103 | p = &rf->buckets[index/2]; 104 | if (index & 1) { 105 | if ((*p & 0x0F) == 0x0F) 106 | result = 1; /* filter out */ 107 | else 108 | *p = (*p) + 0x01; 109 | } else { 110 | if ((*p & 0xF0) == 0xF0) 111 | result = 1; /* filter out */ 112 | else 113 | *p = (*p) + 0x10; 114 | } 115 | 116 | /* 117 | * Empty a random bucket 118 | */ 119 | input[0] = (unsigned)hash; 120 | input[1] = rf->counter++; 121 | hash = siphash24(input, sizeof(input), key); 122 | index = hash & rf->bucket_mask; 123 | p = &rf->buckets[index/2]; 124 | if (index & 1) { 125 | if ((*p & 0x0F)) 126 | *p = (*p) - 0x01; 127 | } else { 128 | if ((*p & 0xF0)) 129 | *p = (*p) - 0x10; 130 | } 131 | 132 | return result; 133 | } 134 | 135 | 136 | 137 | int 138 | rstfilter_selftest(void) 139 | { 140 | struct ResetFilter *rf; 141 | size_t i; 142 | unsigned count_filtered = 0; 143 | unsigned count_passed = 0; 144 | 145 | ipaddress src; 146 | ipaddress dst; 147 | 148 | src.version = 4; 149 | src.ipv4 = 1; 150 | dst.version = 4; 151 | dst.ipv4 = 3; 152 | 153 | rf = rstfilter_create(time(0), 64); 154 | 155 | /* Verify the first 15 packets pass the filter */ 156 | for (i=0; i<15; i++) { 157 | int x; 158 | 159 | x = rstfilter_is_filter(rf, src, 2, dst, 4); 160 | if (x) { 161 | fprintf(stderr, "[-] rstfilter failed, line=%u\n", __LINE__); 162 | return 1; 163 | } 164 | } 165 | 166 | /* Now run 10000 more times */ 167 | for (i=0; i<1000; i++) { 168 | int x; 169 | x = rstfilter_is_filter(rf, src, 2, dst, 4); 170 | count_filtered += x; 171 | count_passed += !x; 172 | } 173 | 174 | /* SOME must have passed, due to us emptying random buckets */ 175 | if (count_passed == 0) { 176 | fprintf(stderr, "[-] rstfilter failed, line=%u\n", __LINE__); 177 | return 1; 178 | } 179 | 180 | /* However, while some pass, the vast majority should be filtered */ 181 | if (count_passed > count_filtered/10) { 182 | fprintf(stderr, "[-] rstfilter failed, line=%u\n", __LINE__); 183 | return 1; 184 | } 185 | //printf("filtered=%u passed=%u\n", count_filtered, count_passed); 186 | return 0; 187 | } 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /src/misc-rstfilter.h: -------------------------------------------------------------------------------- 1 | /* 2 | RST filter 3 | 4 | In theory, we should transmit a RST packet every time we receive an invalid 5 | TCP packet. In practice, this can lead to endless transmits when the other 6 | size continues to transmit bad packets. This may happen accidentally, or this 7 | may happen on purpose from the other side trying to attack the scanner 8 | intentionally. In May 2019 I see this from somebody who I suspect is trying 9 | to do that, replying back as fast as the scanner transmits (when running 10 | at 10,000 packets per-second). This halts the scan, as it's throttle limit 11 | is filled sending RSTs and not doing something useful. 12 | 13 | The design is a simple non-deterministic algorithm. It hashes the 14 | IP/prot combo, then updates a counter at that bucket. When it reaches 15 | its limit, it stops transmitting resets. However, it'll also slowly 16 | empty buckets, so can occasionally transmit a RST now and then. 17 | */ 18 | #ifndef MISC_RSTFILTER_H 19 | #define MISC_RSTFILTER_H 20 | #include 21 | #include "massip-addr.h" 22 | 23 | struct ResetFilter; 24 | 25 | /** 26 | * Create a structure for this. 27 | * @param seed 28 | * A random seed chosen via entropy at startup, so that adversaries 29 | * can't predict where the buckets will be. 30 | * @param bucket_count 31 | * The number of buckets. This'll be rounded up to the nearest 32 | * power-of-two. 16384 is probably a good number. 33 | * @return an instance of this object that should be eventually 34 | * cleaned up with 'rstfilter_destroy()'. 35 | */ 36 | struct ResetFilter * 37 | rstfilter_create(unsigned long long seed, size_t bucket_count); 38 | 39 | /** 40 | * Cleans up the object that was created with 'rstfilter_create()'. 41 | */ 42 | void 43 | rstfilter_destroy(struct ResetFilter *rf); 44 | 45 | /** 46 | * Tests to see if we should ignore the given RST packet. This will 47 | * also slowly empty a random bucket 48 | * @return 1 if we should filter out the offending packet and ignore it, 49 | * or else 0 if we shouldn't ignore it. 50 | */ 51 | int 52 | rstfilter_is_filter(struct ResetFilter *rf, ipaddress src_ip, unsigned src_port, ipaddress dst_ip, unsigned dst_port); 53 | 54 | int 55 | rstfilter_selftest(void); 56 | 57 | 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /src/out-certs.c: -------------------------------------------------------------------------------- 1 | #include "output.h" 2 | #include "masscan-app.h" 3 | #include "masscan-status.h" 4 | #include "util-safefunc.h" 5 | #include 6 | 7 | 8 | /**************************************************************************** 9 | ****************************************************************************/ 10 | static void 11 | cert_out_open(struct Output *out, FILE *fp) 12 | { 13 | UNUSEDPARM(out); 14 | UNUSEDPARM(fp); 15 | } 16 | 17 | 18 | /**************************************************************************** 19 | ****************************************************************************/ 20 | static void 21 | cert_out_close(struct Output *out, FILE *fp) 22 | { 23 | UNUSEDPARM(out); 24 | fprintf(fp, "{finished: 1}\n"); 25 | } 26 | 27 | /****************************************************************************** 28 | ******************************************************************************/ 29 | static void 30 | cert_out_status(struct Output *out, FILE *fp, time_t timestamp, int status, 31 | ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl) 32 | { 33 | /* certificates only come with banner info, so there is no port info 34 | * to report */ 35 | UNUSEDPARM(out); 36 | UNUSEDPARM(fp); 37 | UNUSEDPARM(timestamp); 38 | UNUSEDPARM(status); 39 | UNUSEDPARM(ip); 40 | UNUSEDPARM(ip_proto); 41 | UNUSEDPARM(port); 42 | UNUSEDPARM(reason); 43 | UNUSEDPARM(ttl); 44 | } 45 | 46 | 47 | /****************************************************************************** 48 | ******************************************************************************/ 49 | static void 50 | cert_out_banner(struct Output *out, FILE *fp, time_t timestamp, 51 | ipaddress ip, unsigned ip_proto, unsigned port, 52 | enum ApplicationProtocol proto, 53 | unsigned ttl, 54 | const unsigned char *px, unsigned length) 55 | { 56 | unsigned i; 57 | 58 | UNUSEDPARM(ip_proto); 59 | UNUSEDPARM(ip); 60 | UNUSEDPARM(timestamp); 61 | UNUSEDPARM(fp); 62 | UNUSEDPARM(out); 63 | UNUSEDPARM(ttl); 64 | UNUSEDPARM(proto); 65 | UNUSEDPARM(port); 66 | 67 | if (length > 5 && memcmp(px, "cert:", 5) == 0) { 68 | px += 5; 69 | length -= 5; 70 | } 71 | 72 | printf("-----BEGIN CERTIFICATE-----\n"); 73 | for (i=0; i 72) 76 | len = 72; 77 | printf("%.*s\n", len, px+i); 78 | } 79 | printf("-----END CERTIFICATE-----\n"); 80 | } 81 | 82 | /**************************************************************************** 83 | ****************************************************************************/ 84 | const struct OutputType certs_output = { 85 | "cert", 86 | 0, 87 | cert_out_open, 88 | cert_out_close, 89 | cert_out_status, 90 | cert_out_banner 91 | }; 92 | 93 | -------------------------------------------------------------------------------- /src/out-hostonly.c: -------------------------------------------------------------------------------- 1 | #include "output.h" 2 | #include "masscan.h" 3 | #include "masscan-app.h" 4 | #include "masscan-status.h" 5 | #include "unusedparm.h" 6 | #include "out-tcp-services.h" 7 | 8 | 9 | 10 | 11 | 12 | static void 13 | hostonly_out_open(struct Output *out, FILE *fp) 14 | { 15 | UNUSEDPARM(fp); 16 | UNUSEDPARM(out); 17 | } 18 | 19 | 20 | static void 21 | hostonly_out_close(struct Output *out, FILE *fp) 22 | { 23 | UNUSEDPARM(fp); 24 | UNUSEDPARM(out); 25 | } 26 | 27 | static void 28 | hostonly_out_status(struct Output *out, FILE *fp, time_t timestamp, 29 | int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl) 30 | { 31 | ipaddress_formatted_t fmt = ipaddress_fmt(ip); 32 | UNUSEDPARM(reason); 33 | UNUSEDPARM(out); 34 | UNUSEDPARM(timestamp); 35 | UNUSEDPARM(ttl); 36 | UNUSEDPARM(port); 37 | UNUSEDPARM(ip_proto); 38 | UNUSEDPARM(status); 39 | fprintf(fp, "%s\n", fmt.string); 40 | } 41 | 42 | 43 | /*************************************** ************************************* 44 | ****************************************************************************/ 45 | static void 46 | hostonly_out_banner(struct Output *out, FILE *fp, time_t timestamp, 47 | ipaddress ip, unsigned ip_proto, unsigned port, 48 | enum ApplicationProtocol proto, unsigned ttl, 49 | const unsigned char *px, unsigned length) 50 | { /* SYN only - no banner */ 51 | ipaddress_formatted_t fmt = ipaddress_fmt(ip); 52 | UNUSEDPARM(out); 53 | UNUSEDPARM(ttl); 54 | UNUSEDPARM(port); 55 | UNUSEDPARM(fp); 56 | UNUSEDPARM(timestamp); 57 | UNUSEDPARM(ip); 58 | UNUSEDPARM(ip_proto); 59 | UNUSEDPARM(proto); 60 | UNUSEDPARM(px); 61 | UNUSEDPARM(length); 62 | fprintf(fp, "%s\n", fmt.string); 63 | 64 | return; 65 | } 66 | 67 | 68 | 69 | /**************************************************************************** 70 | ****************************************************************************/ 71 | const struct OutputType hostonly_output = { 72 | "hostonly", 73 | 0, 74 | hostonly_out_open, 75 | hostonly_out_close, 76 | hostonly_out_status, 77 | hostonly_out_banner 78 | }; 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/out-null.c: -------------------------------------------------------------------------------- 1 | #include "output.h" 2 | #include "masscan.h" 3 | 4 | 5 | /**************************************************************************** 6 | * This function doesn't really "open" the file. Instead, the purpose of 7 | * this function is to initialize the file by printing header information. 8 | ****************************************************************************/ 9 | static void 10 | null_out_open(struct Output *out, FILE *fp) 11 | { 12 | UNUSEDPARM(out); 13 | UNUSEDPARM(fp); 14 | } 15 | 16 | /**************************************************************************** 17 | * This function doesn't really "close" the file. Instead, it's purpose 18 | * is to print trailing information to the file. This is pretty much only 19 | * a concern for XML files that need stuff appended to the end. 20 | ****************************************************************************/ 21 | static void 22 | null_out_close(struct Output *out, FILE *fp) 23 | { 24 | UNUSEDPARM(out); 25 | UNUSEDPARM(fp); 26 | } 27 | 28 | /**************************************************************************** 29 | * Prints out the status of a port, which is almost always just "open" 30 | * or "closed". 31 | ****************************************************************************/ 32 | static void 33 | null_out_status(struct Output *out, FILE *fp, time_t timestamp, 34 | int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl) 35 | { 36 | UNUSEDPARM(timestamp); 37 | UNUSEDPARM(out); 38 | UNUSEDPARM(fp); 39 | UNUSEDPARM(status); 40 | UNUSEDPARM(ip_proto); 41 | UNUSEDPARM(ip); 42 | UNUSEDPARM(port); 43 | UNUSEDPARM(reason); 44 | UNUSEDPARM(ttl); 45 | 46 | } 47 | 48 | /**************************************************************************** 49 | * Prints out "banner" information for a port. This is done when there is 50 | * a protocol defined for a port, and we do some interaction to find out 51 | * more information about which protocol is running on a port, it's version, 52 | * and other useful information. 53 | ****************************************************************************/ 54 | static void 55 | null_out_banner(struct Output *out, FILE *fp, time_t timestamp, 56 | ipaddress ip, unsigned ip_proto, unsigned port, 57 | enum ApplicationProtocol proto, unsigned ttl, 58 | const unsigned char *px, unsigned length) 59 | { 60 | UNUSEDPARM(ttl); 61 | UNUSEDPARM(timestamp); 62 | UNUSEDPARM(out); 63 | UNUSEDPARM(fp); 64 | UNUSEDPARM(ip); 65 | UNUSEDPARM(ip_proto); 66 | UNUSEDPARM(port); 67 | UNUSEDPARM(proto); 68 | UNUSEDPARM(px); 69 | UNUSEDPARM(length); 70 | 71 | } 72 | 73 | 74 | /**************************************************************************** 75 | * This is the only structure exposed to the rest of the system. Everything 76 | * else in the file is defined 'static' or 'private'. 77 | ****************************************************************************/ 78 | const struct OutputType null_output = { 79 | "null", 80 | 0, 81 | null_out_open, 82 | null_out_close, 83 | null_out_status, 84 | null_out_banner 85 | }; 86 | -------------------------------------------------------------------------------- /src/out-record.h: -------------------------------------------------------------------------------- 1 | #ifndef OUT_RECORD_H 2 | #define OUT_RECORD_H 3 | 4 | enum OutputRecordType { 5 | Out_Open = 1, 6 | Out_Closed = 2, 7 | Out_Banner1 = 5, 8 | Out_Open2 = 6, 9 | Out_Closed2 = 7, 10 | Out_Arp2 = 8, 11 | Out_Banner9 = 9, 12 | Out_Open6 = 10, 13 | Out_Closed6 = 11, 14 | Out_Arp6 = 12, 15 | Out_Banner6 = 13, 16 | 17 | }; 18 | #endif 19 | -------------------------------------------------------------------------------- /src/out-tcp-services.c: -------------------------------------------------------------------------------- 1 | #include "out-tcp-services.h" 2 | #include 3 | #include 4 | 5 | #ifndef WIN32 6 | #include 7 | #else 8 | #include 9 | #endif 10 | #include 11 | 12 | /** 13 | * This is a stupid hack to avoid dependencies. I want to minimize the dependence 14 | * on network libraries. For example, I get a warning message on FreeBSD about 15 | * a missing `htons()`. I could just add a system header, but then this increases 16 | * dependencies on other things. Alternatively, I could just implement the 17 | * function myself. So I chose that route. 18 | */ 19 | static unsigned short my_htons(unsigned port) 20 | { 21 | static const char test[3] = "\x11\x22"; 22 | if (*(unsigned short*)test == 0x1122) 23 | return (unsigned short)(0xFFFF & port); 24 | else 25 | return (unsigned short)((port>>8)&0xFF) | ((port&0xFF)<<8); 26 | } 27 | 28 | #if _MSC_VER 29 | #define strdup _strdup 30 | #endif 31 | 32 | static char *tcp_services[65536]; 33 | static char *udp_services[65536]; 34 | static char *oproto_services[256]; 35 | 36 | 37 | const char * 38 | tcp_service_name(int port) 39 | { 40 | if (tcp_services[port]) 41 | return tcp_services[port]; 42 | 43 | #if defined(__linux__) && !defined(__TERMUX__) 44 | int r; 45 | struct servent result_buf; 46 | struct servent *result; 47 | char buf[2048]; 48 | 49 | r = getservbyport_r(my_htons(port), "tcp", &result_buf,buf, sizeof(buf), &result); 50 | 51 | /* ignore ERANGE - if the result can't fit in 2k, just return unknown */ 52 | if (r != 0 || result == NULL) 53 | return "unknown"; 54 | 55 | return tcp_services[port] = strdup(result_buf.s_name); 56 | #else 57 | { 58 | struct servent *result; 59 | 60 | result = getservbyport(my_htons((unsigned short)port), "tcp"); 61 | 62 | if (result == 0) 63 | return "unknown"; 64 | 65 | return tcp_services[port] = strdup(result->s_name); 66 | } 67 | #endif 68 | } 69 | 70 | const char * 71 | udp_service_name(int port) 72 | { 73 | if (udp_services[port]) 74 | return udp_services[port]; 75 | #if defined(__linux__) && !defined(__TERMUX__) 76 | int r; 77 | struct servent result_buf; 78 | struct servent *result; 79 | char buf[2048]; 80 | 81 | r = getservbyport_r(my_htons(port), "udp", &result_buf,buf, sizeof(buf), &result); 82 | 83 | /* ignore ERANGE - if the result can't fit in 2k, just return unknown */ 84 | if (r != 0 || result == NULL) 85 | return "unknown"; 86 | 87 | return udp_services[port] = strdup(result_buf.s_name); 88 | #else 89 | { 90 | struct servent *result; 91 | 92 | result = getservbyport(my_htons((unsigned short)port), "udp"); 93 | 94 | if (result == 0) 95 | return "unknown"; 96 | 97 | return udp_services[port] = strdup(result->s_name); 98 | } 99 | #endif 100 | } 101 | 102 | const char * 103 | oproto_service_name(int port) 104 | { 105 | if (oproto_services[port]) 106 | return oproto_services[port]; 107 | { 108 | struct protoent *result; 109 | 110 | result = getprotobynumber(port); 111 | 112 | if (result == 0) 113 | return "unknown"; 114 | 115 | return oproto_services[port] = strdup(result->p_name); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/out-tcp-services.h: -------------------------------------------------------------------------------- 1 | #ifndef OUT_TCP_SERVICES_H 2 | #define OUT_TCP_SERVICES_H 3 | 4 | const char *tcp_service_name(int port); 5 | const char *udp_service_name(int port); 6 | const char *oproto_service_name(int protocol_number); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /src/out-text.c: -------------------------------------------------------------------------------- 1 | #include "output.h" 2 | #include "masscan.h" 3 | #include "masscan-app.h" 4 | #include "masscan-status.h" 5 | #include "unusedparm.h" 6 | 7 | #include 8 | 9 | /**************************************************************************** 10 | ****************************************************************************/ 11 | static void 12 | text_out_open(struct Output *out, FILE *fp) 13 | { 14 | UNUSEDPARM(out); 15 | fprintf(fp, "#masscan\n"); 16 | } 17 | 18 | /**************************************************************************** 19 | ****************************************************************************/ 20 | static void 21 | text_out_close(struct Output *out, FILE *fp) 22 | { 23 | UNUSEDPARM(out); 24 | fprintf(fp, "# end\n"); 25 | } 26 | 27 | /**************************************************************************** 28 | ****************************************************************************/ 29 | static void 30 | text_out_status(struct Output *out, FILE *fp, time_t timestamp, 31 | int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl) 32 | { 33 | ipaddress_formatted_t fmt = ipaddress_fmt(ip); 34 | UNUSEDPARM(ttl); 35 | UNUSEDPARM(reason); 36 | UNUSEDPARM(out); 37 | 38 | 39 | fprintf(fp, "%s %s %u %s %u\n", 40 | status_string(status), 41 | name_from_ip_proto(ip_proto), 42 | port, 43 | fmt.string, 44 | (unsigned)timestamp 45 | ); 46 | } 47 | 48 | 49 | /*************************************** ************************************* 50 | ****************************************************************************/ 51 | static void 52 | text_out_banner(struct Output *out, FILE *fp, time_t timestamp, 53 | ipaddress ip, unsigned ip_proto, unsigned port, 54 | enum ApplicationProtocol proto, unsigned ttl, 55 | const unsigned char *px, unsigned length) 56 | { 57 | char banner_buffer[MAX_BANNER_LENGTH]; 58 | ipaddress_formatted_t fmt = ipaddress_fmt(ip); 59 | 60 | 61 | UNUSEDPARM(out); 62 | UNUSEDPARM(ttl); 63 | 64 | fprintf(fp, "%s %s %u %s %u %s %s\n", 65 | "banner", 66 | name_from_ip_proto(ip_proto), 67 | port, 68 | fmt.string, 69 | (unsigned)timestamp, 70 | masscan_app_to_string(proto), 71 | normalize_string(px, length, banner_buffer, sizeof(banner_buffer)) 72 | ); 73 | } 74 | 75 | 76 | /**************************************************************************** 77 | ****************************************************************************/ 78 | const struct OutputType text_output = { 79 | "txt", 80 | 0, 81 | text_out_open, 82 | text_out_close, 83 | text_out_status, 84 | text_out_banner 85 | }; 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/out-unicornscan.c: -------------------------------------------------------------------------------- 1 | #include "output.h" 2 | #include "masscan.h" 3 | #include "masscan-app.h" 4 | #include "masscan-status.h" 5 | #include "unusedparm.h" 6 | #include "out-tcp-services.h" 7 | 8 | 9 | 10 | 11 | 12 | static void 13 | unicornscan_out_open(struct Output *out, FILE *fp) 14 | { 15 | UNUSEDPARM(out); 16 | fprintf(fp, "#masscan\n"); 17 | } 18 | 19 | 20 | static void 21 | unicornscan_out_close(struct Output *out, FILE *fp) 22 | { 23 | UNUSEDPARM(out); 24 | fprintf(fp, "# end\n"); 25 | } 26 | 27 | static void 28 | unicornscan_out_status(struct Output *out, FILE *fp, time_t timestamp, 29 | int status, ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl) 30 | { 31 | ipaddress_formatted_t fmt = ipaddress_fmt(ip); 32 | UNUSEDPARM(reason); 33 | UNUSEDPARM(out); 34 | UNUSEDPARM(timestamp); 35 | 36 | if (ip_proto == 6) { 37 | fprintf(fp,"TCP %s\t%16s[%5d]\t\tfrom %s ttl %-3d\n", 38 | status_string(status), 39 | tcp_service_name(port), 40 | port, 41 | fmt.string, 42 | ttl); 43 | } else { 44 | /* unicornscan is TCP only, so just use grepable format for other protocols */ 45 | fprintf(fp, "Host: %s ()", fmt.string); 46 | fprintf(fp, "\tPorts: %u/%s/%s/%s/%s/%s/%s\n", 47 | port, 48 | status_string(status), //"open", "closed" 49 | name_from_ip_proto(ip_proto), //"tcp", "udp", "sctp" 50 | "", //owner 51 | "", //service 52 | "", //SunRPC info 53 | "" //Version info 54 | ); 55 | } 56 | } 57 | 58 | 59 | /*************************************** ************************************* 60 | ****************************************************************************/ 61 | static void 62 | unicornscan_out_banner(struct Output *out, FILE *fp, time_t timestamp, 63 | ipaddress ip, unsigned ip_proto, unsigned port, 64 | enum ApplicationProtocol proto, unsigned ttl, 65 | const unsigned char *px, unsigned length) 66 | { /* SYN only - no banner */ 67 | UNUSEDPARM(out); 68 | UNUSEDPARM(ttl); 69 | UNUSEDPARM(port); 70 | UNUSEDPARM(fp); 71 | UNUSEDPARM(timestamp); 72 | UNUSEDPARM(ip); 73 | UNUSEDPARM(ip_proto); 74 | UNUSEDPARM(proto); 75 | UNUSEDPARM(px); 76 | UNUSEDPARM(length); 77 | 78 | return; 79 | } 80 | 81 | 82 | 83 | /**************************************************************************** 84 | ****************************************************************************/ 85 | const struct OutputType unicornscan_output = { 86 | "uni", 87 | 0, 88 | unicornscan_out_open, 89 | unicornscan_out_close, 90 | unicornscan_out_status, 91 | unicornscan_out_banner 92 | }; 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /src/pixie-backtrace.h: -------------------------------------------------------------------------------- 1 | #ifndef PIXIE_BACKTRACE_H 2 | #define PIXIE_BACKTRACE_H 3 | 4 | /** 5 | * Call this function at program startup in order to insert a signal handler 6 | * that will be caught when the program crashes. This signal handler will 7 | * print debug information to the console, such as the line numbers where 8 | * the program crashes. 9 | */ 10 | void 11 | pixie_backtrace_init(const char *self); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /src/pixie-file.c: -------------------------------------------------------------------------------- 1 | #include "pixie-file.h" 2 | 3 | #if defined(WIN32) 4 | #include 5 | #include 6 | #include 7 | #define access _access 8 | #else 9 | #include 10 | #include 11 | #endif 12 | 13 | int 14 | pixie_fopen_shareable(FILE **in_fp, const char *filename, unsigned is_append) 15 | { 16 | FILE *fp; 17 | 18 | *in_fp = NULL; 19 | 20 | #if defined(WIN32) 21 | /* PORTABILITY: WINDOWS 22 | * This bit of code deals with the fact that on Windows, fopen() opens 23 | * a file so that it can't be moved. This code opens it a different 24 | * way so that we can move it. 25 | * 26 | * NOTE: this is probably overkill, it appears that there is a better 27 | * API _fsopen() that does what I want without all this nonsense. 28 | */ 29 | { 30 | HANDLE hFile; 31 | int fd; 32 | 33 | /* The normal POSIX C functions lock the file */ 34 | /* int fd = open(filename, O_RDWR | O_CREAT, _S_IREAD | _S_IWRITE); */ /* Fails */ 35 | /* int fd = _sopen(filename, O_RDWR | O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); */ /* Also fails */ 36 | 37 | /* We need to use WINAPI + _open_osfhandle to be able to use 38 | file descriptors (instead of WINAPI handles) */ 39 | hFile = CreateFileA( filename, 40 | GENERIC_WRITE | (is_append?FILE_APPEND_DATA:0), 41 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 42 | NULL, 43 | CREATE_ALWAYS, 44 | FILE_ATTRIBUTE_TEMPORARY, 45 | NULL); 46 | if (hFile == INVALID_HANDLE_VALUE) { 47 | return -1; 48 | } 49 | 50 | fd = _open_osfhandle((intptr_t)hFile, _O_CREAT | _O_RDONLY | _O_TEMPORARY); 51 | if (fd == -1) { 52 | perror("_open_osfhandle"); 53 | return -1; 54 | } 55 | 56 | fp = _fdopen(fd, "w"); 57 | } 58 | 59 | #else 60 | fp = fopen(filename, is_append?"a":"w"); 61 | if (fp == NULL) 62 | return errno; 63 | #endif 64 | 65 | *in_fp = fp; 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /src/pixie-file.h: -------------------------------------------------------------------------------- 1 | #ifndef PIXIE_FILE_H 2 | #define PIXIE_FILE_H 3 | #include 4 | 5 | #if defined(WIN32) 6 | #include 7 | #define access _access 8 | #else 9 | #include 10 | #endif 11 | 12 | /** 13 | * On Windows, files aren't shareable, so we need to have a portable function 14 | * to open files that can be shared and renamed while they are still open. 15 | */ 16 | int 17 | pixie_fopen_shareable(FILE **in_fp, const char *filename, unsigned is_append); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/pixie-sockets.h: -------------------------------------------------------------------------------- 1 | #ifndef PIXIE_SOCKETS_H 2 | #define PIXIE_SOCKETS_H 3 | #include 4 | #if defined(WIN32) 5 | #include 6 | #else 7 | #include 8 | #include 9 | #include 10 | typedef int SOCKET; 11 | #endif 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/pixie-threads.h: -------------------------------------------------------------------------------- 1 | #ifndef PORT_THREADS_H 2 | #define PORT_THREADS_H 3 | #include 4 | #include 5 | #if defined(_MSC_VER) 6 | #include 7 | #endif 8 | 9 | /** 10 | * Returns the number of CPUs in the system, including virtual CPUs. 11 | * On a single processor system, the number returned will be '1'. 12 | * On a dual socket, dual-core per socket, hyperthreaded system, the 13 | * count will be '8'. 14 | */ 15 | unsigned pixie_cpu_get_count(void); 16 | 17 | /** 18 | * Launch a thread 19 | */ 20 | size_t pixie_begin_thread(void (*worker_thread)(void*), 21 | unsigned flags, 22 | void *worker_data); 23 | 24 | void pixie_thread_join(size_t thread_handle); 25 | 26 | void pixie_cpu_set_affinity(unsigned processor); 27 | void pixie_cpu_raise_priority(void); 28 | 29 | void pixie_locked_subtract_u32(unsigned *lhs, unsigned rhs); 30 | 31 | 32 | 33 | #if defined(_MSC_VER) 34 | #define pixie_locked_add_u32(dst, src) _InterlockedExchangeAdd((volatile long*)(dst), (src)) 35 | #define pixie_locked_CAS32(dst, src, expected) (_InterlockedCompareExchange((volatile long*)dst, src, expected) == (expected)) 36 | #define pixie_locked_CAS64(dst, src, expected) (_InterlockedCompareExchange64((volatile long long*)dst, src, expected) == (expected)) 37 | #define rte_atomic32_cmpset(dst, exp, src) (_InterlockedCompareExchange((volatile long *)dst, (long)src, (long)exp)==(long)(exp)) 38 | 39 | #elif defined(__GNUC__) 40 | #define pixie_locked_add_u32(dst, src) __sync_add_and_fetch((volatile int*)(dst), (int)(src)); 41 | #define rte_atomic32_cmpset(dst, expected, src) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src) 42 | #define pixie_locked_CAS32(dst, src, expected) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src); 43 | #define pixie_locked_CAS64(dst, src, expected) __sync_bool_compare_and_swap((volatile long long int*)(dst),(long long int)expected,(long long int)src); 44 | 45 | #if !defined(__x86_64__) && !defined(__i386__) 46 | #define rte_wmb() __sync_synchronize() 47 | #define rte_rmb() __sync_synchronize() 48 | #define rte_pause() 49 | #else 50 | #define rte_wmb() asm volatile("sfence;" : : : "memory") 51 | #define rte_rmb() asm volatile("lfence;" : : : "memory") 52 | #define rte_pause() asm volatile ("pause") 53 | #endif 54 | #else 55 | unsigned pixie_locked_add_u32(volatile unsigned *lhs, unsigned rhs); 56 | int pixie_locked_CAS32(volatile unsigned *dst, unsigned src, unsigned expected); 57 | int pixie_locked_CAS64(volatile uint64_t *dst, uint64_t src, uint64_t expected); 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/pixie-timer.h: -------------------------------------------------------------------------------- 1 | #ifndef PIXIE_TIMER_H 2 | #define PIXIE_TIMER_H 3 | #include 4 | 5 | /** 6 | * The current time, in microseconds 7 | */ 8 | uint64_t pixie_gettime(void); 9 | 10 | /** 11 | * The current time, in nanoseconds 12 | */ 13 | uint64_t pixie_nanotime(void); 14 | 15 | /** 16 | * Wait the specified number of microseconds 17 | */ 18 | void pixie_usleep(uint64_t usec); 19 | 20 | /** 21 | * Wait the specified number of milliseconds 22 | */ 23 | void pixie_mssleep(unsigned milliseconds); 24 | 25 | /** 26 | * Do a self-test. Note that in some cases, this may 27 | * actually fail when there is no problem. So far it hasn't, but I should 28 | * probably add some code to fix this. 29 | */ 30 | int pixie_time_selftest(void); 31 | 32 | 33 | 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/proto-arp.c: -------------------------------------------------------------------------------- 1 | #include "proto-arp.h" 2 | #include "proto-preprocess.h" 3 | #include "util-logger.h" 4 | #include "output.h" 5 | #include "masscan-status.h" 6 | #include "unusedparm.h" 7 | 8 | 9 | 10 | /*************************************************************************** 11 | * Process an ARP packet received in response to an ARP-scan. 12 | ***************************************************************************/ 13 | void 14 | arp_recv_response(struct Output *out, time_t timestamp, const unsigned char *px, 15 | unsigned length, struct PreprocessedInfo *parsed) 16 | { 17 | ipaddress ip_them = parsed->src_ip; 18 | ipaddress_formatted_t fmt = ipaddress_fmt(ip_them); 19 | 20 | UNUSEDPARM(length); 21 | UNUSEDPARM(px); 22 | 23 | 24 | LOG(3, "ARP %s = [%02X:%02X:%02X:%02X:%02X:%02X]\n", 25 | fmt.string, 26 | parsed->mac_src[0], parsed->mac_src[1], parsed->mac_src[2], 27 | parsed->mac_src[3], parsed->mac_src[4], parsed->mac_src[5]); 28 | 29 | 30 | output_report_status( 31 | out, 32 | timestamp, 33 | PortStatus_Arp, 34 | ip_them, 35 | 0, /* ip proto */ 36 | 0, 37 | 0, 38 | 0, 39 | parsed->mac_src); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/proto-arp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_ARP_H 2 | #define PROTO_ARP_H 3 | #include 4 | struct Output; 5 | struct PreprocessedInfo; 6 | 7 | 8 | void 9 | arp_recv_response(struct Output *out, time_t timestamp, const unsigned char *px, unsigned length, struct PreprocessedInfo *parsed); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/proto-banout.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_BANOUT_H 2 | #define PROTO_BANOUT_H 3 | struct BannerBase64; 4 | 5 | /** 6 | * A structure for tracking one or more banners from a target. 7 | * There can be multiple banner information from a target, such 8 | * as SSL certificates, or HTTP headers separate from HTML 9 | * content, and so on. This will be exploited more in the future 10 | * for extracting multiple bits of information from the same 11 | * port, but giving them different labels. This will also be 12 | * used for doing optional stuff, such as grabbing the entire 13 | * default webpage when connecting to port 80. 14 | */ 15 | struct BannerOutput { 16 | struct BannerOutput *next; 17 | unsigned protocol; 18 | unsigned length; 19 | unsigned max_length; 20 | unsigned char banner[200]; 21 | }; 22 | 23 | /** 24 | * Initialize the list of banners. This doesn't allocate any 25 | * memory, such sets it to zero. 26 | */ 27 | void 28 | banout_init(struct BannerOutput *banout); 29 | 30 | /** 31 | * Release any memory. If the list contains only one short 32 | * banner, then no memory was allocated, so nothing gets 33 | * freed. 34 | */ 35 | void 36 | banout_release(struct BannerOutput *banout); 37 | 38 | /** 39 | * Just appends a newline '\n' character. In the future, this may do something 40 | * more interesting, which is why it's a separate function. 41 | */ 42 | void 43 | banout_newline(struct BannerOutput *banout, unsigned proto); 44 | 45 | /** 46 | * End the banner of the current. This is called when the protocol parser 47 | * knows it's at the end. The major reason for this is processing the 48 | * SSL certificates, so that each certificate comes back as a separate 49 | * banner. 50 | */ 51 | void 52 | banout_end(struct BannerOutput *banout, unsigned proto); 53 | 54 | /** 55 | * Append text onto the banner. If this exceeds the buffer, then the 56 | * buffer will be expanded. 57 | */ 58 | void 59 | banout_append(struct BannerOutput *banout, unsigned proto, const void *px, size_t length); 60 | #define AUTO_LEN ((size_t)~0) 61 | 62 | void 63 | banout_printf(struct BannerOutput *banout, unsigned proto, const char *fmt, ...); 64 | 65 | /** 66 | * Append a single character to the banner. 67 | */ 68 | void 69 | banout_append_char(struct BannerOutput *banout, unsigned proto, int c); 70 | 71 | /** 72 | * Append an integer, with hex digits, with the specified number of 73 | * digits 74 | */ 75 | void 76 | banout_append_hexint(struct BannerOutput *banout, unsigned proto, unsigned long long number, int digits); 77 | 78 | void 79 | banout_append_unicode(struct BannerOutput *banout, unsigned proto, unsigned c); 80 | 81 | /** 82 | * Select a specific string (of the specified protocol). 83 | * The "banner output" can have multiple protocol objects associated 84 | * with it, such as an SSL protocol object and an X.509 certificate. 85 | * Thus, instead of just grabbing the string, we need to grab the 86 | * specific protocol instead. 87 | */ 88 | const unsigned char * 89 | banout_string(const struct BannerOutput *banout, unsigned proto); 90 | 91 | /** 92 | * Get the length of a specific string of the specified protocol. 93 | * This is the matching function to banout_string. 94 | */ 95 | unsigned 96 | banout_string_length(const struct BannerOutput *banout, unsigned proto); 97 | 98 | 99 | /** 100 | * Prepare to start calling banout_append_base64() 101 | */ 102 | void 103 | banout_init_base64(struct BannerBase64 *base64); 104 | 105 | /** 106 | * Converts the string to BASE64 and appends it to the banner. 107 | * Since this can be called iteratively as new input arrives, 108 | * a call to banout_init_base64() must be called before the first fragment, 109 | * and a call to banout_finalize_base64() must be called after the last 110 | * fragment 111 | */ 112 | void 113 | banout_append_base64(struct BannerOutput *banout, unsigned proto, 114 | const void *px, size_t length, 115 | struct BannerBase64 *base64); 116 | 117 | /** 118 | * Finish encoding the BASE64 string, appending the '==' things on the 119 | * end if necessary 120 | */ 121 | void 122 | banout_finalize_base64(struct BannerOutput *banout, unsigned proto, 123 | struct BannerBase64 *base64); 124 | 125 | /** 126 | * Compares a banner string to a fixed string. This is primarily used 127 | * in the "self-test" feature in order to compare parsed banners from 128 | * expected banners. 129 | */ 130 | unsigned 131 | banout_is_equal(const struct BannerOutput *banout, unsigned proto, 132 | const char *string); 133 | 134 | unsigned 135 | banout_is_contains(const struct BannerOutput *banout, unsigned proto, 136 | const char *string); 137 | 138 | /** 139 | * Do the typical unit/regression test, for this module. 140 | */ 141 | int 142 | banout_selftest(void); 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /src/proto-coap.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_COAP_H 2 | #define PROTO_COAP_H 3 | #include "proto-banner1.h" 4 | struct Output; 5 | struct PreprocessedInfo; 6 | 7 | /* 8 | * For sending TCP requests and parsing TCP responses. 9 | */ 10 | extern const struct ProtocolParserStream banner_coap; 11 | 12 | /* 13 | * For parsing UDP responses 14 | */ 15 | unsigned 16 | coap_handle_response(struct Output *out, time_t timestamp, 17 | const unsigned char *px, unsigned length, 18 | struct PreprocessedInfo *parsed, 19 | uint64_t entropy 20 | ); 21 | 22 | /* 23 | * For creating UDP request 24 | */ 25 | unsigned 26 | coap_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno); 27 | 28 | int 29 | proto_coap_selftest(void); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/proto-dns-parse.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_DNS_PARSE_H 2 | #define PROTO_DNS_PARSE_H 3 | struct DomainPointer 4 | { 5 | const unsigned char *name; 6 | unsigned length; 7 | }; 8 | struct DNS_Incoming 9 | { 10 | unsigned id; /* transaction id */ 11 | unsigned is_valid:1; 12 | unsigned is_formerr:1; 13 | unsigned is_edns0:1;/* edns0 features found */ 14 | unsigned qr:1; /* 'query' or 'response' */ 15 | unsigned aa:1; /* 'authoritative answer' */ 16 | unsigned tc:1; /* 'truncation' */ 17 | unsigned rd:1; /* 'recursion desired' */ 18 | unsigned ra:1; /* 'recursion available' */ 19 | unsigned z:3; /* reserved */ 20 | unsigned opcode; 21 | unsigned rcode; /* response error code */ 22 | unsigned qdcount; /* query count */ 23 | unsigned ancount; /* answer count */ 24 | unsigned nscount; /* name-server/authority count */ 25 | unsigned arcount; /* additional record count */ 26 | struct { 27 | unsigned payload_size; 28 | unsigned version; 29 | unsigned z; 30 | } edns0; 31 | const unsigned char *req; 32 | unsigned req_length; 33 | 34 | /* the query name */ 35 | struct DomainPointer query_name; 36 | unsigned query_type; 37 | unsigned char query_name_buffer[256]; 38 | 39 | unsigned rr_count; 40 | unsigned short rr_offset[1024]; 41 | unsigned edns0_offset; 42 | }; 43 | 44 | 45 | void 46 | proto_dns_parse(struct DNS_Incoming *dns, const unsigned char px[], unsigned offset, unsigned max); 47 | 48 | unsigned 49 | dns_name_skip(const unsigned char px[], unsigned offset, unsigned max); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/proto-dns.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_DNS_H 2 | #define PROTO_DNS_H 3 | #include 4 | #include 5 | struct PreprocessedInfo; 6 | struct Output; 7 | 8 | unsigned handle_dns(struct Output *out, time_t timestamp, 9 | const unsigned char *px, unsigned length, struct PreprocessedInfo *parsed, uint64_t entropy); 10 | 11 | unsigned dns_set_cookie(unsigned char *px, size_t length, uint64_t seqno); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/proto-ftp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_FTP_H 2 | #define PROTO_FTP_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_ftp; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/proto-http.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_HTTP_H 2 | #define PROTO_HTTP_H 3 | #include "proto-banner1.h" 4 | #include "util-bool.h" 5 | 6 | extern struct ProtocolParserStream banner_http; 7 | 8 | 9 | /** 10 | * Called during configuration when processing a command-line option 11 | * like "--http-field " to add/change a field in the HTTP 12 | * header. 13 | */ 14 | size_t 15 | http_change_field(unsigned char **inout_header, size_t header_length, 16 | const char *field_name, 17 | const unsigned char *field_value, size_t field_value_len, 18 | int what); 19 | 20 | 21 | /** 22 | * Called during configuration when processing a command-line option 23 | * like "--http-url /foo.html". This replaces whatever the existing 24 | * URL is into the new one. 25 | * @param item 26 | * 0=method, 1=url, 2=version 27 | * @return 28 | * the new length of the header (expanded or shrunk) 29 | */ 30 | size_t 31 | http_change_requestline(unsigned char **inout_header, size_t header_length, 32 | const void *url, size_t url_length, int item); 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/proto-icmp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_ICMP_H 2 | #define PROTO_ICMP_H 3 | #include 4 | #include 5 | struct PreprocessedInfo; 6 | struct Output; 7 | 8 | void handle_icmp(struct Output *out, time_t timestamp, 9 | const unsigned char *px, unsigned length, 10 | struct PreprocessedInfo *parsed, 11 | uint64_t entropy); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/proto-imap4.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_IMAP4_H 2 | #define PROTO_IMAP4_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_imap4; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/proto-isakmp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_ISAKMP_H 2 | #define PROTO_ISAKMP_H 3 | #include 4 | #include 5 | #include 6 | struct Output; 7 | struct PreprocessedInfo; 8 | 9 | unsigned isakmp_parse(struct Output *out, time_t timestamp, 10 | const unsigned char *px, unsigned length, 11 | struct PreprocessedInfo *parsed, uint64_t entropy); 12 | 13 | unsigned isakmp_set_cookie(unsigned char *px, size_t length, uint64_t seqno); 14 | 15 | int 16 | proto_isakmp_selftest(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/proto-mc.c: -------------------------------------------------------------------------------- 1 | #include "proto-mc.h" 2 | #include "proto-banner1.h" 3 | #include "unusedparm.h" 4 | #include "masscan-app.h" 5 | #include "stack-tcp-api.h" 6 | #include "output.h" 7 | #include 8 | #include 9 | #include 10 | 11 | static unsigned char hand_shake_ptr[128]; 12 | 13 | static unsigned char * 14 | hand_shake(uint16_t port, const char* ip, size_t ip_len) 15 | { 16 | size_t tlen = 10+ip_len; 17 | unsigned char * ret = (unsigned char *)calloc(1,tlen); 18 | ret[0] = (unsigned char)(7+ip_len); 19 | ret[2] = 0xf7; 20 | ret[3] = 5; 21 | ret[4] = (unsigned char)ip_len; 22 | memcpy(ret+5,ip,ip_len); 23 | ret[tlen-5] = (unsigned char)(port>>8); 24 | ret[tlen-4] = (unsigned char)(port&0xff); 25 | ret[tlen-3] = 1; 26 | ret[tlen-2] = 1; 27 | ret[tlen-1] = 0; 28 | return ret; 29 | } 30 | 31 | static void * 32 | memstr(void * mem, size_t len, char * str) 33 | { 34 | size_t i; 35 | size_t stlen = strlen(str); 36 | if(len < stlen) 37 | return 0; 38 | for(i = 0; i < len-stlen; i++) { 39 | if(!memcmp((char*)mem+i,str,stlen)) 40 | return (char*)mem+i; 41 | } 42 | return 0; 43 | } 44 | 45 | /*************************************************************************** 46 | ***************************************************************************/ 47 | static void 48 | mc_parse( const struct Banner1 *banner1, 49 | void *banner1_private, 50 | struct StreamState *pstate, 51 | const unsigned char *px, size_t length, 52 | struct BannerOutput *banout, 53 | struct stack_handle_t *socket) 54 | { 55 | size_t i; 56 | struct MCSTUFF *mc = &pstate->sub.mc; 57 | UNUSEDPARM(banner1_private); 58 | UNUSEDPARM(banner1); 59 | for(i = 0; i < length; i++) { 60 | if(px[i] == '{') 61 | mc->brackcount++; 62 | if(px[i] == '}') 63 | mc->brackcount--; 64 | } 65 | if(mc->brackcount <= 0) 66 | tcpapi_close(socket); 67 | 68 | if((mc->imgstart&&mc->imgend) || mc->brackcount <= 0) { // we already found and removed image data 69 | banout_append(banout, PROTO_MC,px,length); 70 | } else { 71 | mc->banmem = realloc(mc->banmem,mc->totalLen+length+1); // expand to add new memory for added paket 72 | memcpy(mc->banmem+mc->totalLen,px,length); // copy in new packet 73 | mc->banmem[mc->totalLen] = 0; // add ending 0 for str 74 | mc->totalLen+=length; 75 | if(!mc->imgstart) { // dont search again if we found start 76 | mc->imgstart = (size_t)memstr(mc->banmem,mc->totalLen,"data:image/png;base64"); 77 | if(mc->imgstart) 78 | mc->imgstart-=(size_t)mc->banmem; 79 | } else { // we found start but not the end 80 | mc->imgend = (size_t)memchr(mc->banmem+mc->imgstart,'\"',mc->totalLen-mc->imgstart); 81 | if(mc->imgend){ // we found the end 82 | mc->imgend-=(size_t)mc->banmem; 83 | memcpy(mc->banmem+mc->imgstart,mc->banmem+mc->imgend,(mc->totalLen-mc->imgend)+1); // copy data after B64 84 | mc->totalLen=mc->imgstart+(mc->totalLen-mc->imgend); // shrink length to subtract B64 image 85 | banout_append(banout, PROTO_MC,mc->banmem,mc->totalLen); // print out banner minus image data 86 | free(mc->banmem); // we dont need to keep track of this any more. 87 | } 88 | } 89 | } 90 | } 91 | 92 | /*************************************************************************** 93 | ***************************************************************************/ 94 | static void * 95 | mc_init(struct Banner1 *banner1) 96 | { 97 | unsigned char * tmp = hand_shake(25565,"localhost",9); 98 | memcpy(hand_shake_ptr,tmp,tmp[0]+3); 99 | free(tmp); 100 | banner_mc.hello = hand_shake_ptr; 101 | banner_mc.hello_length = hand_shake_ptr[0]+3; 102 | banner1->payloads.tcp[25565] = (void*)&banner_mc; 103 | return 0; 104 | } 105 | 106 | /*************************************************************************** 107 | ***************************************************************************/ 108 | static int 109 | mc_selftest(void) 110 | { 111 | return 0; 112 | } 113 | 114 | /*************************************************************************** 115 | ***************************************************************************/ 116 | struct ProtocolParserStream banner_mc = { 117 | "mc", 25565, 0, 0, 0, 118 | mc_selftest, 119 | mc_init, 120 | mc_parse, 121 | }; 122 | -------------------------------------------------------------------------------- /src/proto-mc.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_MC_H 2 | #define PROTO_MC_H 3 | #include "proto-banner1.h" 4 | #include "util-bool.h" 5 | 6 | extern struct ProtocolParserStream banner_mc; 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/proto-memcached.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_MEMCACHED_H 2 | #define PROTO_MEMCACHED_H 3 | #include "proto-banner1.h" 4 | struct Output; 5 | struct PreprocessedInfo; 6 | 7 | /* 8 | * For sending TCP requests and parsing TCP responses. 9 | */ 10 | extern const struct ProtocolParserStream banner_memcached; 11 | 12 | /* 13 | * For parsing UDP responses 14 | */ 15 | unsigned 16 | memcached_udp_parse(struct Output *out, time_t timestamp, 17 | const unsigned char *px, unsigned length, 18 | struct PreprocessedInfo *parsed, 19 | uint64_t entropy 20 | ); 21 | 22 | /* 23 | * For creating UDP request 24 | */ 25 | unsigned 26 | memcached_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/proto-netbios.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_NETBIOS_H 2 | #define PROTO_NETBIOS_H 3 | #include 4 | #include 5 | struct PreprocessedInfo; 6 | struct Output; 7 | 8 | unsigned handle_nbtstat(struct Output *out, time_t timestamp, 9 | const unsigned char *px, unsigned length, 10 | struct PreprocessedInfo *parsed, 11 | uint64_t entropy); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/proto-ntlmssp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_NTLMSSP_H 2 | #define PROTO_NTLMSSP_H 3 | #include 4 | struct BannerOutput; 5 | 6 | struct NtlmsspDecode 7 | { 8 | unsigned length; 9 | unsigned offset; 10 | unsigned char *buf; 11 | }; 12 | 13 | void 14 | ntlmssp_decode_init(struct NtlmsspDecode *x, size_t length); 15 | 16 | void 17 | ntlmssp_cleanup(struct NtlmsspDecode *x); 18 | 19 | void 20 | ntlmssp_decode(struct NtlmsspDecode *x, 21 | const unsigned char *px, size_t length, 22 | struct BannerOutput *banout); 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /src/proto-ntp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_NTP_H 2 | #define PROTO_NTP_H 3 | #include 4 | #include 5 | struct Output; 6 | struct PreprocessedInfo; 7 | 8 | /** 9 | * Does a regression test. 10 | * @return 11 | * 0 if success, 1 if failure 12 | */ 13 | int ntp_selftest(void); 14 | 15 | /** 16 | * Sets a cookie on the packet, if possible. 17 | */ 18 | unsigned 19 | ntp_set_cookie(unsigned char *px, size_t length, uint64_t seqno); 20 | 21 | /** 22 | * Parse NTP responses looking for any "banner" information 23 | */ 24 | unsigned 25 | ntp_handle_response(struct Output *out, time_t timestamp, 26 | const unsigned char *px, unsigned length, 27 | struct PreprocessedInfo *parsed, 28 | uint64_t entropy); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/proto-oproto.c: -------------------------------------------------------------------------------- 1 | #include "proto-oproto.h" 2 | #include "unusedparm.h" 3 | 4 | void 5 | handle_oproto(struct Output *out, time_t timestamp, 6 | const unsigned char *px, unsigned length, 7 | struct PreprocessedInfo *parsed, 8 | uint64_t entropy) 9 | { 10 | UNUSEDPARM(entropy); 11 | UNUSEDPARM(parsed); 12 | UNUSEDPARM(length); 13 | UNUSEDPARM(px); 14 | UNUSEDPARM(timestamp); 15 | UNUSEDPARM(out); 16 | } 17 | -------------------------------------------------------------------------------- /src/proto-oproto.h: -------------------------------------------------------------------------------- 1 | /* 2 | Other IP protocol (not TCP, UDP, TCP, ICMP 3 | Specifically for scanning things like GRE. 4 | */ 5 | #ifndef PROTO_OPROTO_H 6 | #define PROTO_OPROTO_H 7 | #include 8 | #include 9 | struct Output; 10 | struct PreprocessedInfo; 11 | 12 | 13 | /** 14 | * Parse an incoming response. 15 | * @param entropy 16 | * The random seed, used in calculating syn-cookies. 17 | */ 18 | void 19 | handle_oproto(struct Output *out, time_t timestamp, 20 | const unsigned char *px, unsigned length, 21 | struct PreprocessedInfo *parsed, 22 | uint64_t entropy); 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /src/proto-pop3.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_POP3_H 2 | #define PROTO_POP3_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_pop3; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/proto-preprocess.h: -------------------------------------------------------------------------------- 1 | /* Copyright: (c) 2009-2010 by Robert David Graham */ 2 | #ifndef PREPROCESS_H 3 | #define PREPROCESS_H 4 | #include "massip-addr.h" 5 | 6 | 7 | enum { 8 | FOUND_NOTHING=0, 9 | FOUND_ETHERNET, 10 | FOUND_IPV4, 11 | FOUND_IPV6, 12 | FOUND_ICMP, 13 | FOUND_TCP, 14 | FOUND_UDP, 15 | FOUND_SCTP, 16 | FOUND_DNS, 17 | FOUND_IPV6_HOP, 18 | FOUND_8021Q, 19 | FOUND_MPLS, 20 | FOUND_WIFI_DATA, 21 | FOUND_WIFI, 22 | FOUND_RADIOTAP, 23 | FOUND_PRISM, 24 | FOUND_LLC, 25 | FOUND_ARP, 26 | FOUND_SLL, /* Linux SLL */ 27 | FOUND_OPROTO, /* some other IP protocol */ 28 | FOUND_IGMP, 29 | FOUND_NDPv6, 30 | }; 31 | struct PreprocessedInfo { 32 | const unsigned char *mac_src; 33 | const unsigned char *mac_dst; 34 | const unsigned char *mac_bss; 35 | unsigned ip_offset; /* 14 for normal Ethernet */ 36 | unsigned ip_version; /* 4 or 6 */ 37 | unsigned ip_protocol; /* 6 for TCP, 11 for UDP */ 38 | unsigned ip_length; /* length of total packet */ 39 | unsigned ip_ttl; 40 | const unsigned char *_ip_src; 41 | const unsigned char *_ip_dst; 42 | ipaddress src_ip; 43 | ipaddress dst_ip; 44 | unsigned transport_offset; /* 34 for normal Ethernet */ 45 | unsigned transport_length; 46 | union { 47 | unsigned port_src; 48 | unsigned opcode; 49 | }; 50 | unsigned port_dst; 51 | 52 | unsigned app_offset; /* start of TCP payload */ 53 | unsigned app_length; /* length of TCP payload */ 54 | 55 | int found; 56 | int found_offset; 57 | }; 58 | 59 | /** 60 | * @return 1 if useful stuff found, 0 otherwise 61 | */ 62 | unsigned 63 | preprocess_frame(const unsigned char *px, unsigned length, unsigned link_type, struct PreprocessedInfo *info); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/proto-sctp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_SCTP_H 2 | #define PROTO_SCTP_H 3 | #include 4 | #include 5 | 6 | struct PreprocessedInfo; 7 | struct Output; 8 | 9 | /** 10 | * Calculate the "CRC32c" checksum used in SCTP. This is a non-destructive 11 | * checksum that skips the checksum field itself. 12 | */ 13 | unsigned 14 | sctp_checksum(const void *vbuffer, size_t length); 15 | 16 | /** 17 | * Handle incoming SCTP response 18 | */ 19 | void 20 | handle_sctp(struct Output *out, time_t timestamp, 21 | const unsigned char *px, unsigned length, 22 | unsigned cookie, 23 | struct PreprocessedInfo *parsed, 24 | uint64_t entropy); 25 | 26 | int 27 | sctp_selftest(void); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/proto-smb.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_SMB_H 2 | #define PROTO_SMB_H 3 | #include "proto-banner1.h" 4 | 5 | extern struct ProtocolParserStream banner_smb0; 6 | extern struct ProtocolParserStream banner_smb1; 7 | 8 | /** 9 | * Called when command line parameter: 10 | * --hello smbv1 11 | * is set, in order to force negotiation down to SMBv1. This is because some machines 12 | * have faulty SMBv2 implementations. SMBv2, though, is the default negotiation 13 | * because Win10 disables SMBv1 by default. 14 | */ 15 | void smb_set_hello_v1(struct ProtocolParserStream *smb); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/proto-smtp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_SMTP_H 2 | #define PROTO_SMTP_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_smtp; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/proto-snmp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_SNMP_H 2 | #define PROTO_SNMP_H 3 | #include 4 | #include 5 | struct Output; 6 | struct PreprocessedInfo; 7 | 8 | /** 9 | * Need to call this on startup to compile the internal MIB. 10 | */ 11 | void snmp_init(void); 12 | 13 | /** 14 | * Does a regression test. 15 | * @return 16 | * 0 if success, 1 if failure 17 | */ 18 | int snmp_selftest(void); 19 | 20 | unsigned snmp_set_cookie(unsigned char *px, size_t length, uint64_t seqno); 21 | 22 | unsigned 23 | handle_snmp(struct Output *out, time_t timestamp, 24 | const unsigned char *px, unsigned length, 25 | struct PreprocessedInfo *parsed, 26 | uint64_t entropy); 27 | #endif 28 | -------------------------------------------------------------------------------- /src/proto-spnego.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_SPNEGO_H 2 | #define PROTO_SPNEGO_H 3 | 4 | #include "proto-x509.h" 5 | #include "proto-ntlmssp.h" 6 | 7 | struct SpnegoDecode 8 | { 9 | /* 10 | * ====== KLUDGE ALERT: there's no generic ASN.1 encoding, it's specific to 11 | * ====== x.509 parsing, so therefore we are just going to overload that 12 | * ====== a bit until we move the code out into it's own ASN.1 module 13 | */ 14 | struct CertDecode x509[1]; 15 | 16 | struct NtlmsspDecode ntlmssp; 17 | }; 18 | 19 | void 20 | spnego_decode_init(struct SpnegoDecode *x, size_t length); 21 | 22 | void 23 | spnego_decode(struct SpnegoDecode *x, 24 | const unsigned char *px, size_t length, 25 | struct BannerOutput *banout); 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /src/proto-ssh.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_SSH_H 2 | #define PROTO_SSH_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_ssh; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/proto-ssl.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_SSL_H 2 | #define PROTO_SSL_H 3 | #include "proto-banner1.h" 4 | 5 | extern struct ProtocolParserStream banner_ssl; 6 | extern struct ProtocolParserStream banner_ssl_12; 7 | 8 | extern const char *ssl_hello_heartbeat_template; 9 | extern const char *ssl_hello_ticketbleed_template; 10 | extern const char *ssl_hello_sslv3_template; 11 | 12 | /** 13 | * Parse the SSL Hello template to find its size 14 | */ 15 | unsigned ssl_hello_size(const void *templ); 16 | 17 | /** 18 | * Allocate memory and make a copy of the template, so that we can 19 | * rewrite some fields, such as setting the correct timestamp 20 | */ 21 | char *ssl_hello(const void *templ); 22 | 23 | /** 24 | * Add a cipher-spec. 25 | * There are many possible uses for this, but for now it's used for the POODLE 26 | * bug, appending TLS_FALLBACK_SCSV to the list. It may need to reallocate 27 | * the template. 28 | */ 29 | char *ssl_add_cipherspec(void *templ, unsigned cipher_spec, unsigned is_append); 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/proto-tcp-rdp.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PROTO_TCP_RDP_H 3 | #define PROTO_TCP_RDP_H 4 | #include "proto-banner1.h" 5 | 6 | extern const struct ProtocolParserStream banner_rdp; 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/proto-tcp-telnet.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_TELNET_H 2 | #define PROTO_TELNET_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_telnet; 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/proto-udp.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_UDP_H 2 | #define PROTO_UDP_H 3 | #include 4 | #include 5 | struct PreprocessedInfo; 6 | struct Output; 7 | 8 | /** 9 | * Parse an incoming UDP response. We parse the basics, then hand it off 10 | * to a protocol parser (SNMP, NetBIOS, NTP, etc.) 11 | * @param entropy 12 | * The random seed, used in calculating syn-cookies. 13 | */ 14 | void 15 | handle_udp(struct Output *out, time_t timestamp, 16 | const unsigned char *px, unsigned length, 17 | struct PreprocessedInfo *parsed, 18 | uint64_t entropy); 19 | 20 | /** 21 | * Default banner for UDP, consisting of the first 64 bytes, when it isn't 22 | * detected as the appropriate protocol 23 | */ 24 | unsigned 25 | default_udp_parse(struct Output *out, time_t timestamp, 26 | const unsigned char *px, unsigned length, 27 | struct PreprocessedInfo *parsed, 28 | uint64_t entropy); 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/proto-versioning.c: -------------------------------------------------------------------------------- 1 | /* 2 | SERVICE VERSIONING 3 | 4 | */ 5 | #include "proto-versioning.h" 6 | #include "proto-banner1.h" 7 | #include "smack.h" 8 | #include "unusedparm.h" 9 | #include "masscan-app.h" 10 | #include "output.h" 11 | #include "stack-tcp-api.h" 12 | #include "proto-preprocess.h" 13 | #include "proto-ssl.h" 14 | #include "proto-udp.h" 15 | #include "syn-cookie.h" 16 | #include "massip-port.h" 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | 23 | /*************************************************************************** 24 | ***************************************************************************/ 25 | static void 26 | versioning_tcp_parse( 27 | const struct Banner1 *banner1, 28 | void *banner1_private, 29 | struct StreamState *pstate, 30 | const unsigned char *px, size_t length, 31 | struct BannerOutput *banout, 32 | struct stack_handle_t *socket) 33 | { 34 | unsigned state = pstate->state; 35 | 36 | 37 | UNUSEDPARM(banner1_private); 38 | UNUSEDPARM(banner1); 39 | UNUSEDPARM(socket); 40 | UNUSEDPARM(px); 41 | UNUSEDPARM(length); 42 | UNUSEDPARM(banout); 43 | 44 | pstate->state = state; 45 | } 46 | 47 | /*************************************************************************** 48 | ***************************************************************************/ 49 | static void * 50 | versioning_init(struct Banner1 *b) 51 | { 52 | //b->memcached_responses = smack_create("memcached-responses", SMACK_CASE_INSENSITIVE); 53 | 54 | return b->http_fields; 55 | } 56 | 57 | 58 | /*************************************************************************** 59 | ***************************************************************************/ 60 | #if 0 61 | static unsigned 62 | versioning_udp_parse(struct Output *out, time_t timestamp, 63 | const unsigned char *px, unsigned length, 64 | struct PreprocessedInfo *parsed, 65 | uint64_t entropy 66 | ) 67 | { 68 | 69 | return default_udp_parse(out, timestamp, px, length, parsed, entropy); 70 | } 71 | #endif 72 | 73 | /**************************************************************************** 74 | ****************************************************************************/ 75 | #if 0 76 | static unsigned 77 | versioning_udp_set_cookie(unsigned char *px, size_t length, uint64_t seqno) 78 | { 79 | return 0; 80 | } 81 | #endif 82 | 83 | /*************************************************************************** 84 | ***************************************************************************/ 85 | static int 86 | versioning_selftest(void) 87 | { 88 | return 0; 89 | } 90 | 91 | /*************************************************************************** 92 | ***************************************************************************/ 93 | const struct ProtocolParserStream banner_versioning = { 94 | "versioning", 11211, "stats\r\n", 7, 0, 95 | versioning_selftest, 96 | versioning_init, 97 | versioning_tcp_parse, 98 | }; 99 | 100 | -------------------------------------------------------------------------------- /src/proto-versioning.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSIONING_H 2 | #define VERSIONING_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_versioning; 6 | 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /src/proto-vnc.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_VNC_H 2 | #define PROTO_VNC_H 3 | #include "proto-banner1.h" 4 | 5 | extern const struct ProtocolParserStream banner_vnc; 6 | 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/proto-x509.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_X509_H 2 | #define PROTO_X509_H 3 | #include 4 | #include 5 | struct BannerOutput; 6 | 7 | /**************************************************************************** 8 | * This stores the "state" of the X.509 certificate parser 9 | ****************************************************************************/ 10 | struct CertDecode { 11 | /** This is the master 'state' variable in the massive switch statement */ 12 | unsigned state; 13 | 14 | /** ASN.1 nests fields within fields. Therefore, as we parse down into 15 | * the structure, we push the parent length/state info on the stack, 16 | * and then when we exit a field, we pop it back off the stack. 17 | * NOTE: since space is at a premium, we have separate arrays 18 | * for the length/state, instead of an array of objects containing 19 | * both. */ 20 | struct { 21 | unsigned short remainings[9]; 22 | unsigned char states[9]; 23 | unsigned char depth; 24 | } stack; 25 | 26 | /** We catch some DER non-canonical encoding errors, but not all. Someday 27 | * we'll improve the parser to catch all of them */ 28 | unsigned is_der_failure:1; 29 | unsigned is_capture_subject:1; 30 | unsigned is_capture_issuer:1; 31 | 32 | 33 | 34 | /** Number of certificates we've processed */ 35 | unsigned char count; 36 | 37 | /** ??? */ 38 | time_t prev; 39 | 40 | /** This parser was originally written just to grab the "subect name" 41 | * of a certificate, i.e. "*.google.com" for Google's certificates. 42 | * However, there are many different types of subject names. Each 43 | * subject name comes in two parts, the first part being an OID 44 | * saying the type of subject, then the subject itself. We need to stash 45 | * the result of parsing the OID somewhere before parsing the subject 46 | */ 47 | struct { 48 | unsigned type; 49 | } subject; 50 | 51 | unsigned child_state; 52 | unsigned brother_state; 53 | 54 | /** 55 | * This union contains the intermediate/partial values as we are decoding 56 | * them. Since a packet may end with a field only partially decoded, 57 | * we have to stash that value someplace before the next bytes arive 58 | * that complete the decoding 59 | */ 60 | union { 61 | struct { 62 | unsigned short remaining; 63 | unsigned char length_of_length; 64 | } tag; 65 | uint64_t num; 66 | unsigned next_state; 67 | struct { 68 | uint64_t num; 69 | unsigned short state; 70 | unsigned char last_id; 71 | } oid; 72 | struct { 73 | unsigned state; 74 | unsigned year:7; 75 | unsigned month:4; 76 | unsigned day:5; 77 | unsigned hour:5; 78 | unsigned minute:6; 79 | unsigned second:6; 80 | } timestamp; 81 | } u; 82 | }; 83 | 84 | /** 85 | * Called before parsing the first fragment of an X.509 certificate 86 | */ 87 | void 88 | x509_decode_init(struct CertDecode *x, size_t length); 89 | 90 | /** 91 | * Called to decode the next fragment of an X.509 certificate. 92 | * Must call x509_decode_init() first. 93 | */ 94 | void 95 | x509_decode(struct CertDecode *x, 96 | const unsigned char *px, size_t length, 97 | struct BannerOutput *banout); 98 | 99 | /** 100 | * Called at program startup to initialize internal parsing structures 101 | * for certificates. Once called, it creates static read-only thread-safe 102 | * structures 103 | */ 104 | void 105 | x509_init(void); 106 | 107 | #endif 108 | 109 | -------------------------------------------------------------------------------- /src/proto-zeroaccess.h: -------------------------------------------------------------------------------- 1 | #ifndef PROTO_ZEROACCESS_H 2 | #define PROTO_ZEROACCESS_H 3 | #include 4 | #include 5 | struct PreprocessedInfo; 6 | struct Output; 7 | 8 | unsigned 9 | handle_zeroaccess( struct Output *out, time_t timestamp, 10 | const unsigned char *px, unsigned length, 11 | struct PreprocessedInfo *parsed, 12 | uint64_t entropy); 13 | 14 | extern const unsigned char zeroaccess_getL[]; 15 | #define zeroaccess_getL_length 16 16 | 17 | 18 | /** 19 | * Regression test this module. 20 | * @return 21 | * 0 on success, a positive integer otherwise. 22 | */ 23 | int 24 | zeroaccess_selftest(void); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/rawsock-adapter.h: -------------------------------------------------------------------------------- 1 | #ifndef RAWSOCK_ADAPTER_H 2 | #define RAWSOCK_ADAPTER_H 3 | 4 | struct Adapter 5 | { 6 | struct pcap *pcap; 7 | struct pcap_send_queue *sendq; 8 | struct __pfring *ring; 9 | unsigned is_packet_trace:1; /* is --packet-trace option set? */ 10 | unsigned is_vlan:1; 11 | unsigned vlan_id; 12 | double pt_start; 13 | int link_type; 14 | }; 15 | 16 | 17 | /** 18 | * Retrieve the datalink type of the adapter 19 | * 20 | * 1 = Ethernet 21 | * 12 = Raw IP (no datalink) 22 | */ 23 | int 24 | stack_if_datalink(struct Adapter *adapter); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/rawsock-pcapfile.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2007 by Errata Security, All Rights Reserved 2 | * Programmer(s): Robert David Graham [rdg] 3 | */ 4 | #ifndef __PCAPFILE_H 5 | #define __PCAPFILE_H 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | #include 10 | #include 11 | 12 | struct PcapFile; 13 | 14 | enum pcapfile_datalink_t { 15 | PCAPFILE_ETHERNET = 1, 16 | PCAPFILE_WIFi = 105, 17 | }; 18 | 19 | int pcapfile_datalink(struct PcapFile *handle); 20 | 21 | void pcapfile_writeframe( 22 | struct PcapFile *capfile, 23 | const void *buffer, 24 | unsigned buffer_size, 25 | unsigned original_length, 26 | unsigned time_sec, 27 | unsigned time_usec 28 | ); 29 | 30 | struct PcapFile *pcapfile_openread(const char *capfilename); 31 | struct PcapFile *pcapfile_openwrite(const char *capfilename, unsigned linktype); 32 | struct PcapFile *pcapfile_openappend(const char *capfilename, unsigned linktype); 33 | 34 | unsigned pcapfile_percentdone(struct PcapFile *handle, uint64_t *r_bytes_read); 35 | 36 | void pcapfile_get_timestamps(struct PcapFile *handle, time_t *start, time_t *end); 37 | 38 | /** 39 | * Set a "maximum" size for a file. When the current file fills up with data, 40 | * it will close that file and open a new one, then continue to write 41 | * from that point on in the new file. 42 | */ 43 | void pcapfile_set_max(struct PcapFile *capfile, unsigned max_megabytes, unsigned max_files); 44 | 45 | /** 46 | * Read a single frame from the file. 47 | * Returns 0 if failed to read (from error or end of file), and 48 | * returns 1 if successful. 49 | */ 50 | int pcapfile_readframe( 51 | struct PcapFile *capfile, 52 | unsigned *r_time_secs, 53 | unsigned *r_time_usecs, 54 | unsigned *r_original_length, 55 | unsigned *r_captured_length, 56 | unsigned char *buf, 57 | unsigned sizeof_buf 58 | ); 59 | 60 | 61 | void pcapfile_close(struct PcapFile *handle); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | #endif /*__PCAPFILE_H*/ 67 | -------------------------------------------------------------------------------- /src/read-service-probes.h: -------------------------------------------------------------------------------- 1 | /* 2 | Reads the 'nmap-service-probes' file. 3 | */ 4 | #ifndef READ_SERVICE_PROBES_H 5 | #define READ_SERVICE_PROBES_H 6 | #include 7 | #include "massip-rangesv4.h" 8 | 9 | /* 10 | Exclude 11 | Probe 12 | match [] 13 | softmatch 14 | ports 15 | sslports 16 | totalwaitms 17 | tcpwrappedms 18 | rarity 19 | fallback 20 | */ 21 | enum SvcP_RecordType { 22 | SvcP_Unknown, 23 | SvcP_Exclude, 24 | SvcP_Probe, 25 | SvcP_Match, 26 | SvcP_Softmatch, 27 | SvcP_Ports, 28 | SvcP_Sslports, 29 | SvcP_Totalwaitms, 30 | SvcP_Tcpwrappedms, 31 | SvcP_Rarity, 32 | SvcP_Fallback, 33 | }; 34 | 35 | enum SvcV_InfoType { 36 | SvcV_Unknown, 37 | SvcV_ProductName, 38 | SvcV_Version, 39 | SvcV_Info, 40 | SvcV_Hostname, 41 | SvcV_OperatingSystem, 42 | SvcV_DeviceType, 43 | SvcV_CpeName, 44 | }; 45 | 46 | struct ServiceVersionInfo { 47 | enum SvcV_InfoType type; 48 | char *value; 49 | struct ServiceVersionInfo *next; 50 | unsigned is_a:1; 51 | }; 52 | 53 | struct ServiceProbeFallback { 54 | char *name; 55 | struct ServiceProbeFallback *next; 56 | }; 57 | 58 | struct ServiceProbeMatch { 59 | struct ServiceProbeMatch *next; 60 | char *service; 61 | char *regex; 62 | size_t regex_length; 63 | struct ServiceVersionInfo *versioninfo; 64 | unsigned is_case_insensitive:1; 65 | unsigned is_include_newlines:1; 66 | unsigned is_softmatch:1; 67 | }; 68 | 69 | struct NmapServiceProbe { 70 | char *name; 71 | char *hellostring; 72 | size_t hellolength; 73 | unsigned protocol; 74 | unsigned totalwaitms; 75 | unsigned tcpwrappedms; 76 | unsigned rarity; 77 | struct RangeList ports; 78 | struct RangeList sslports; 79 | struct ServiceProbeMatch *match; 80 | struct ServiceProbeFallback *fallback; 81 | }; 82 | 83 | struct NmapServiceProbeList { 84 | struct NmapServiceProbe **list; 85 | struct RangeList exclude; 86 | unsigned count; 87 | unsigned max; 88 | const char *filename; 89 | unsigned line_number; 90 | }; 91 | 92 | 93 | struct NmapServiceProbeList * 94 | nmapserviceprobes_read_file(const char *filename); 95 | 96 | void 97 | nmapserviceprobes_free(struct NmapServiceProbeList *service_probes); 98 | 99 | int 100 | nmapserviceprobes_selftest(void); 101 | 102 | /** 103 | * Print to a file for testing purposes 104 | */ 105 | void 106 | nmapserviceprobes_print(const struct NmapServiceProbeList *list, FILE *fp); 107 | 108 | #endif 109 | 110 | -------------------------------------------------------------------------------- /src/scripting-masscan.c: -------------------------------------------------------------------------------- 1 | #include "masscan.h" 2 | #include "scripting.h" 3 | #include "stub-lua.h" 4 | #include "unusedparm.h" 5 | 6 | #define MASSCAN_CLASS "Masscan Class" 7 | 8 | struct MasscanWrapper 9 | { 10 | struct Masscan *masscan; 11 | }; 12 | 13 | /*************************************************************************** 14 | * "setconfig" function in Lua. 15 | * 16 | * Called to set a generic name=value parameter. Any configuration 17 | * option that can be set on the command-line, or from within a config 18 | * file, can be set via this function. 19 | ***************************************************************************/ 20 | static int mass_setconfig(struct lua_State *L) 21 | { 22 | struct MasscanWrapper *wrapper; 23 | struct Masscan *masscan; 24 | const char *name; 25 | const char *value; 26 | 27 | wrapper = luaL_checkudata(L, 1, MASSCAN_CLASS); 28 | masscan = wrapper->masscan; 29 | name = luaL_checkstring(L, 2); 30 | value = luaL_checkstring(L, 3); 31 | 32 | masscan_set_parameter(masscan, name, value); 33 | 34 | return 0; 35 | } 36 | 37 | /*************************************************************************** 38 | ***************************************************************************/ 39 | static int mass_gc(struct lua_State *L) 40 | { 41 | //struct MasscanWrapper *wrapper; 42 | //struct Masscan *masscan; 43 | 44 | UNUSEDPARM(L); 45 | 46 | //wrapper = luaL_checkudata(L, 1, MASSCAN_CLASS); 47 | //masscan = wrapper->masscan; 48 | 49 | /* I'm hot sure what I should do here for shutting down this object, 50 | * but I'm registering a garbage collection function anyway */ 51 | 52 | return 0; 53 | } 54 | 55 | 56 | /*************************************************************************** 57 | * This function creases the object called "Masscan" in the global 58 | * variable space of a Lua script. The script can then interact 59 | * with this object in order to setup the scan that it wants to 60 | * do. 61 | ***************************************************************************/ 62 | void scripting_masscan_init(struct Masscan *masscan) 63 | { 64 | struct MasscanWrapper *wrapper; 65 | struct lua_State *L = masscan->scripting.L; 66 | 67 | static const luaL_Reg my_methods[] = { 68 | {"setconfig", mass_setconfig}, 69 | {"__gc", mass_gc}, 70 | {NULL, NULL} 71 | }; 72 | 73 | /* 74 | * Lua: Create a class to wrap a 'socket' 75 | */ 76 | 77 | luaL_newmetatable(L, MASSCAN_CLASS); 78 | lua_pushvalue(L, -1); 79 | lua_setfield(L, -2, "__index"); 80 | luaL_setfuncs(L, my_methods, 0); 81 | lua_pop(L, 1); 82 | 83 | /* Lua: create a wrapper object and push it onto the stack */ 84 | wrapper = lua_newuserdata(L, sizeof(*wrapper)); 85 | memset(wrapper, 0, sizeof(*wrapper)); 86 | wrapper->masscan = masscan; 87 | 88 | /* Lua: set the class/type */ 89 | luaL_setmetatable(L, MASSCAN_CLASS); 90 | 91 | lua_setglobal(L, "Masscan"); 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/scripting.c: -------------------------------------------------------------------------------- 1 | #include "masscan.h" 2 | #include "scripting.h" 3 | #include "stub-lua.h" 4 | #include "util-logger.h" 5 | 6 | #include 7 | 8 | /*************************************************************************** 9 | ***************************************************************************/ 10 | void 11 | scripting_init(struct Masscan *masscan) 12 | { 13 | int version; 14 | struct lua_State *L; 15 | const char *filename = masscan->scripting.name; 16 | int x; 17 | 18 | 19 | if (filename == 0 || filename[0] == '\0') { 20 | LOG(0, "%s: no script specified, use --script option\n", "SCRIPTING"); 21 | exit(1); 22 | } 23 | 24 | /* Dynamically link the library */ 25 | stublua_init(); 26 | 27 | /* Test to see if the loading was successful */ 28 | version = (int)*lua_version(0); 29 | LOG(1, "Lua version = %d\n", version); 30 | if (version != 503 && version != 502) { 31 | LOG(0, "Unable to load Lua library\n"); 32 | exit(1); 33 | } 34 | 35 | /* 36 | * Create a Lua VM 37 | */ 38 | L = luaL_newstate(); 39 | luaL_openlibs(L); 40 | masscan->scripting.L = L; 41 | 42 | /* 43 | * TODO: Sandbox stuff 44 | */ 45 | /* We need to do a bunch of sandboxing here to prevent hostile or badly 46 | * written scripts from disrupting the system */ 47 | 48 | /* 49 | * Create the Masscan object 50 | */ 51 | scripting_masscan_init(masscan); 52 | 53 | /* 54 | * Load the script. This will verify the syntax. 55 | */ 56 | x = luaL_loadfile(L, filename); 57 | if (x != LUA_OK) { 58 | LOG(0, "%s error loading: %s: %s\n", "SCRIPTING:", filename, lua_tostring(L, -1)); 59 | lua_close(L); 60 | exit(1); 61 | } 62 | 63 | /* 64 | * Lua: Start running the script. At this stage, the "onConnection()" function doesn't 65 | * run. Instead, it's registered as a global function to be called later. 66 | */ 67 | LOG(1, "%s running script: %s\n", "SCRIPTING:", filename); 68 | x = lua_pcall(L, 0, 0, 0); 69 | if (x != LUA_OK) { 70 | LOG(0, "%s error running: %s: %s\n", "SCRIPTING:", filename, lua_tostring(L, -1)); 71 | lua_close(L); 72 | exit(1); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/scripting.h: -------------------------------------------------------------------------------- 1 | /* 2 | Masscan scripting subsystem 3 | */ 4 | #ifndef SCRIPTING_H 5 | #define SCRIPTING_H 6 | #include "proto-banner1.h" 7 | struct Masscan; 8 | 9 | extern const struct ProtocolParserStream banner_scripting; 10 | 11 | /** 12 | * Load the Lua scripting library and run the initialization 13 | * stage of all the specified scripts 14 | */ 15 | void scripting_init(struct Masscan *masscan); 16 | 17 | /** 18 | * Create the "Masscan" object within the scripting subsystem 19 | */ 20 | void scripting_masscan_init(struct Masscan *masscan); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/smackqueue.c: -------------------------------------------------------------------------------- 1 | #include "smackqueue.h" 2 | #include 3 | #include 4 | #include 5 | 6 | /**************************************************************************** 7 | * Build a queue so that we can do a breadth-first enumeration of the 8 | * sub-patterns 9 | ****************************************************************************/ 10 | struct QueueElement 11 | { 12 | unsigned m_data; 13 | struct QueueElement *m_next; 14 | }; 15 | struct Queue 16 | { 17 | struct QueueElement *m_head; 18 | struct QueueElement *m_tail; 19 | }; 20 | 21 | struct Queue * 22 | queue_create(void) 23 | { 24 | struct Queue *queue; 25 | queue = (struct Queue *)malloc(sizeof(*queue)); 26 | if (queue == NULL) { 27 | fprintf(stderr, "%s: out of memory error\n", "smack"); 28 | exit(1); 29 | } 30 | memset(queue, 0, sizeof(*queue)); 31 | return queue; 32 | } 33 | 34 | void 35 | queue_destroy(struct Queue * queue) 36 | { 37 | if (queue == NULL) 38 | return; 39 | while (queue_has_more_items(queue)) 40 | dequeue(queue); 41 | free(queue); 42 | } 43 | 44 | void 45 | enqueue(struct Queue *queue, unsigned data) 46 | { 47 | struct QueueElement *element; 48 | 49 | element = (struct QueueElement *)malloc(sizeof (struct QueueElement)); 50 | if (element == NULL) { 51 | fprintf(stderr, "%s: out of memory error\n", "smack"); 52 | exit(1); 53 | } 54 | 55 | if (queue->m_head == NULL) { 56 | /* If nothing in the queue, initialize the queue with the 57 | * first data */ 58 | queue->m_head = element; 59 | } else { 60 | /* Else, add the data to the tail of the queue */ 61 | queue->m_tail->m_next = element; 62 | } 63 | 64 | element->m_data = data; 65 | element->m_next = NULL; 66 | queue->m_tail = element; 67 | } 68 | 69 | unsigned 70 | dequeue(struct Queue *queue) 71 | { 72 | if (queue->m_head == NULL) 73 | return 0; 74 | else { 75 | struct QueueElement *element; 76 | unsigned result; 77 | 78 | element = queue->m_head; 79 | result = element->m_data; 80 | queue->m_head = element->m_next; 81 | 82 | free(element); 83 | return result; 84 | } 85 | } 86 | 87 | unsigned queue_has_more_items(struct Queue * queue) 88 | { 89 | return queue->m_head != NULL; 90 | } 91 | -------------------------------------------------------------------------------- /src/smackqueue.h: -------------------------------------------------------------------------------- 1 | #ifndef SMACKQUEUE_H 2 | #define SMACKQUEUE_H 3 | 4 | struct Queue * 5 | queue_create(void); 6 | 7 | 8 | void 9 | queue_destroy(struct Queue *queue); 10 | 11 | 12 | void 13 | enqueue(struct Queue *queue, unsigned data); 14 | 15 | 16 | unsigned 17 | dequeue(struct Queue *queue); 18 | 19 | 20 | unsigned 21 | queue_has_more_items(struct Queue *queue); 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/stack-arpv4.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_ARP_H 2 | #define STACK_ARP_H 3 | struct Adapter; 4 | #include "stack-queue.h" 5 | #include "massip-addr.h" 6 | 7 | /** 8 | * Response to an ARP request for our IP address. 9 | * 10 | * @param my_ip 11 | * My IP address 12 | * @param my_mac 13 | * My Ethernet MAC address that matches this IP address. 14 | * @param px 15 | * The incoming ARP request 16 | * @param length 17 | * The length of the incoming ARP request. 18 | * @param packet_buffers 19 | * Free packet buffers I can use to format the request 20 | * @param transmit_queue 21 | * I put the formatted response onto this queue for later 22 | * transmission by a transmit thread. 23 | */ 24 | int stack_arp_incoming_request(struct stack_t *stack, 25 | ipv4address_t my_ip, macaddress_t my_mac, 26 | const unsigned char *px, unsigned length); 27 | 28 | /** 29 | * Send an ARP request in order to resolve an IPv4 address into a 30 | * MAC address. Usually done in order to find the local router's 31 | * MAC address when given the IPv4 address of the router. 32 | */ 33 | int stack_arp_resolve(struct Adapter *adapter, 34 | ipv4address_t my_ipv4, macaddress_t my_mac_address, 35 | ipv4address_t your_ipv4, macaddress_t *your_mac_address); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/stack-if.c: -------------------------------------------------------------------------------- 1 | #include "rawsock.h" 2 | #include "rawsock-adapter.h" 3 | 4 | /*************************************************************************** 5 | ***************************************************************************/ 6 | int 7 | stack_if_datalink(struct Adapter *adapter) 8 | { 9 | if (adapter->ring) 10 | return 1; /* ethernet */ 11 | else { 12 | return adapter->link_type; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/stack-ndpv6.h: -------------------------------------------------------------------------------- 1 | /* 2 | IPv6 Neighbor Discovery Protocol 3 | 4 | This module is needed to talk to the local IPv6 router. 5 | It does two things: 6 | 7 | 1. find the local router, so that we can send packets to 8 | it 9 | 2. response to Neighbor Discovery Requests, to the router 10 | can find us 11 | */ 12 | #ifndef STACK_NDPV6_H 13 | #define STACK_NDPV6_H 14 | #include 15 | #include 16 | #include "stack-queue.h" 17 | #include "massip-addr.h" 18 | struct PreprocessedInfo; 19 | 20 | /** 21 | * Handle an incoming IPv6 neighbor notification request. We must send 22 | * back our MAC address. 23 | */ 24 | int 25 | stack_ndpv6_incoming_request(struct stack_t *stack, struct PreprocessedInfo *parsed, const unsigned char *px, size_t length); 26 | 27 | /** 28 | * Find the MAC address for the local router. 29 | */ 30 | int 31 | stack_ndpv6_resolve(struct Adapter *adapter, 32 | ipv6address my_ipv6, 33 | macaddress_t my_mac_address, 34 | macaddress_t *your_mac_address); 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /src/stack-queue.c: -------------------------------------------------------------------------------- 1 | #include "stack-queue.h" 2 | #include "pixie-timer.h" 3 | #include "rawsock.h" 4 | #include "util-malloc.h" 5 | #include 6 | #include 7 | 8 | struct PacketBuffer * 9 | stack_get_packetbuffer(struct stack_t *stack) 10 | { 11 | int err; 12 | struct PacketBuffer *response = NULL; 13 | 14 | for (err=1; err; ) { 15 | err = rte_ring_sc_dequeue(stack->packet_buffers, (void**)&response); 16 | if (err != 0) { 17 | /* Pause and wait for a buffer to become available */ 18 | pixie_usleep(1000); 19 | } 20 | } 21 | return response; 22 | } 23 | 24 | void 25 | stack_transmit_packetbuffer(struct stack_t *stack, struct PacketBuffer *response) 26 | { 27 | int err; 28 | for (err=1; err; ) { 29 | err = rte_ring_sp_enqueue(stack->transmit_queue, response); 30 | if (err) { 31 | fprintf(stderr, "[-] transmit queue full (should be impossible)\n"); 32 | pixie_usleep(1000); 33 | } 34 | } 35 | } 36 | 37 | /*************************************************************************** 38 | * The receive thread doesn't transmit packets. Instead, it queues them 39 | * up on the transmit thread. Every so often, the transmit thread needs 40 | * to flush this transmit queue and send everything. 41 | * 42 | * This is an inherent design issue trying to send things as batches rather 43 | * than individually. It increases latency, but increases performance. We 44 | * don't really care about latency. 45 | ***************************************************************************/ 46 | void 47 | stack_flush_packets( 48 | struct stack_t *stack, 49 | struct Adapter *adapter, 50 | uint64_t *packets_sent, 51 | uint64_t *batchsize) 52 | { 53 | /* 54 | * Send a batch of queued packets 55 | */ 56 | for ( ; (*batchsize); (*batchsize)--) { 57 | int err; 58 | struct PacketBuffer *p; 59 | 60 | /* 61 | * Get the next packet from the transmit queue. This packet was 62 | * put there by a receive thread, and will contain things like 63 | * an ACK or an HTTP request 64 | */ 65 | err = rte_ring_sc_dequeue(stack->transmit_queue, (void**)&p); 66 | if (err) { 67 | break; /* queue is empty, nothing to send */ 68 | } 69 | 70 | 71 | /* 72 | * Actually send the packet 73 | */ 74 | rawsock_send_packet(adapter, p->px, (unsigned)p->length, 1); 75 | 76 | /* 77 | * Now that we are done with the packet, put it on the free list 78 | * of buffers that the transmit thread can reuse 79 | */ 80 | for (err=1; err; ) { 81 | err = rte_ring_sp_enqueue(stack->packet_buffers, p); 82 | if (err) { 83 | fprintf(stderr, "[-] transmit queue full (should be impossible)\n"); 84 | pixie_usleep(10000); 85 | } 86 | } 87 | 88 | 89 | /* 90 | * Remember that we sent a packet, which will be used in 91 | * throttling. 92 | */ 93 | (*packets_sent)++; 94 | } 95 | 96 | } 97 | 98 | struct stack_t * 99 | stack_create(macaddress_t source_mac, struct stack_src_t *src) 100 | { 101 | struct stack_t *stack; 102 | size_t i; 103 | 104 | stack = CALLOC(1, sizeof(*stack)); 105 | stack->source_mac = source_mac; 106 | stack->src = src; 107 | 108 | /* 109 | * Allocate packet buffers for sending 110 | */ 111 | #define BUFFER_COUNT 16384 112 | stack->packet_buffers = rte_ring_create(BUFFER_COUNT, RING_F_SP_ENQ|RING_F_SC_DEQ); 113 | stack->transmit_queue = rte_ring_create(BUFFER_COUNT, RING_F_SP_ENQ|RING_F_SC_DEQ); 114 | for (i=0; ipacket_buffers, p); 120 | if (err) { 121 | /* I dunno why but I can't queue all 256 packets, just 255 */ 122 | fprintf(stderr, "[-] packet_buffers: enqueue: error %d\n", err); 123 | } 124 | } 125 | 126 | return stack; 127 | } 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /src/stack-queue.h: -------------------------------------------------------------------------------- 1 | #ifndef PACKET_QUEUE_H 2 | #define PACKET_QUEUE_H 3 | #include "rte-ring.h" 4 | #include "massip-addr.h" 5 | #include 6 | struct stack_src_t; 7 | struct Adapter; 8 | 9 | typedef struct rte_ring PACKET_QUEUE; 10 | 11 | struct PacketBuffer { 12 | size_t length; 13 | unsigned char px[2040]; 14 | }; 15 | 16 | struct stack_t { 17 | PACKET_QUEUE *packet_buffers; 18 | PACKET_QUEUE *transmit_queue; 19 | macaddress_t source_mac; 20 | struct stack_src_t *src; 21 | }; 22 | 23 | /** 24 | * Get a packet-buffer that we can use to create a packet before 25 | * sending 26 | */ 27 | struct PacketBuffer * 28 | stack_get_packetbuffer(struct stack_t *stack); 29 | 30 | /** 31 | * Queue up the packet for sending. This doesn't send the packet immediately, 32 | * but puts it into a queue to be sent later, when the throttler allows it 33 | * to be sent. 34 | */ 35 | void 36 | stack_transmit_packetbuffer(struct stack_t *stack, struct PacketBuffer *response); 37 | 38 | void 39 | stack_flush_packets( 40 | struct stack_t *stack, 41 | struct Adapter *adapter, 42 | uint64_t *packets_sent, 43 | uint64_t *batchsize); 44 | 45 | struct stack_t * 46 | stack_create(macaddress_t source_mac, struct stack_src_t *src); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/stack-src.c: -------------------------------------------------------------------------------- 1 | #include "stack-src.h" 2 | 3 | int is_myself(const struct stack_src_t *src, ipaddress ip, unsigned port) 4 | { 5 | return is_my_ip(src, ip) && is_my_port(src, port); 6 | } 7 | 8 | int is_my_ip(const struct stack_src_t *src, ipaddress ip) 9 | { 10 | switch (ip.version) { 11 | case 4: 12 | return src->ipv4.first <= ip.ipv4 && ip.ipv4 <= src->ipv4.last; 13 | case 6: 14 | return src->ipv6.first.hi == ip.ipv6.hi && src->ipv6.first.lo == ip.ipv6.lo; 15 | default: 16 | return 0; 17 | } 18 | } 19 | 20 | int is_my_port(const struct stack_src_t *src, unsigned port) 21 | { 22 | return src->port.first <= port && port <= src->port.last; 23 | } 24 | -------------------------------------------------------------------------------- /src/stack-src.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_SOURCE_H 2 | #define STACK_SOURCE_H 3 | #include "massip-addr.h" 4 | 5 | /** 6 | * These the source IP addresses that we'll be spoofing. IP addresses 7 | * and port numbers come from this list. 8 | */ 9 | struct stack_src_t 10 | { 11 | struct { 12 | unsigned first; 13 | unsigned last; 14 | unsigned range; 15 | } ipv4; 16 | struct { 17 | unsigned first; 18 | unsigned last; 19 | unsigned range; 20 | } port; 21 | 22 | struct { 23 | ipv6address first; 24 | ipv6address last; 25 | unsigned range; 26 | } ipv6; 27 | }; 28 | 29 | int is_myself(const struct stack_src_t *src, ipaddress ip, unsigned port); 30 | int is_my_ip(const struct stack_src_t *src, ipaddress ip); 31 | int is_my_port(const struct stack_src_t *src, unsigned ip); 32 | 33 | 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/stack-tcp-api.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_HANDLE_H 2 | #define STACK_HANDLE_H 3 | #include 4 | #include "util-bool.h" /* */ 5 | 6 | struct ProtocolParserStream; 7 | 8 | enum TCP__flags { 9 | TCP__static,/* it's static data, so the send function can point to it */ 10 | TCP__copy, /* the send function must copy the data */ 11 | TCP__adopt, /* the buffer was just allocated, so the send function can adopt the pointer */ 12 | TCP__close_fin /* close connection */ 13 | }; 14 | 15 | enum { 16 | SOCKERR_NONE=0, /* no error */ 17 | SOCKERR_EBADF=10, /* bad socket descriptor */ 18 | }; 19 | 20 | typedef struct stack_handle_t { 21 | void *tcpcon; 22 | void *tcb; 23 | unsigned secs; 24 | unsigned usecs; 25 | } stack_handle_t; 26 | 27 | 28 | 29 | /** 30 | * Set a new default timeout. 31 | */ 32 | int 33 | tcpapi_set_timeout(struct stack_handle_t *socket, 34 | unsigned secs, 35 | unsigned usecs 36 | ); 37 | 38 | /** 39 | * Change from the "send" state to the "receive" state. 40 | * Has no effect if in any state other than "send". 41 | * This is none-blocking, an event will be triggered 42 | * later that has the data. 43 | */ 44 | int 45 | tcpapi_recv(struct stack_handle_t *socket); 46 | 47 | int 48 | tcpapi_send(struct stack_handle_t *socket, 49 | const void *buf, size_t length, 50 | enum TCP__flags flags); 51 | 52 | /** 53 | * Re-connect to the target, same IP and port, creating a new connection 54 | * from a different port on this side. 55 | */ 56 | int 57 | tcpapi_reconnect(struct stack_handle_t *old_socket, 58 | struct ProtocolParserStream *new_stream, 59 | unsigned new_app_state); 60 | 61 | /** 62 | * The "app state" variable is stored opaquely in the `tcb` structure, so 63 | * to reset it, we need an access function. 64 | */ 65 | unsigned 66 | tcpapi_change_app_state(struct stack_handle_t *socket, unsigned new_app_state); 67 | 68 | 69 | /** Perform the sockets half-close function (calling `close()`). This 70 | * doesn't actually get rid of the socket, but only stops sending. 71 | * It sends a FIN packet to the other side, and transitions to the 72 | * TCP CLOSE-WAIT state. 73 | * The socket will continue to receive from the opposing side until they 74 | * give us a FIN packet. */ 75 | int 76 | tcpapi_close(struct stack_handle_t *socket); 77 | 78 | 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/stack-tcp-app.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_TCP_APP_H 2 | #define STACK_TCP_APP_H 3 | #include 4 | #include "util-bool.h" /* */ 5 | struct stack_handle_t; 6 | struct ProtocolParserStream; 7 | struct Banner1; 8 | 9 | 10 | enum App_Event { 11 | APP_CONNECTED, 12 | APP_RECV_TIMEOUT, 13 | APP_RECV_PAYLOAD, 14 | APP_SENDING, 15 | APP_SEND_SENT, 16 | APP_CLOSE /*FIN received */ 17 | }; 18 | 19 | /** 20 | * This is the interface between the underlying custom TCP/IP stack and 21 | * the rest of masscan. SCRIPTING will eventually go in here. 22 | */ 23 | unsigned 24 | application_event( struct stack_handle_t *socket, 25 | unsigned state, enum App_Event event, 26 | const struct ProtocolParserStream *stream, 27 | struct Banner1 *banner1, 28 | const void *payload, size_t payload_length 29 | ); 30 | 31 | void 32 | banner_set_sslhello(struct stack_handle_t *socket, bool is_true); 33 | 34 | void 35 | banner_set_small_window(struct stack_handle_t *socket, bool is_true); 36 | 37 | bool 38 | banner_is_heartbleed(const struct stack_handle_t *socket); 39 | 40 | void 41 | banner_flush(struct stack_handle_t *socket); 42 | 43 | size_t 44 | banner_parse( 45 | struct stack_handle_t *socket, 46 | const unsigned char *payload, 47 | size_t payload_length 48 | ); 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /src/stub-lua.c: -------------------------------------------------------------------------------- 1 | #define LUAAPI 2 | #include "stub-lua.h" 3 | 4 | #ifdef _MSC_VER 5 | #pragma warning(disable: 4133 4113 4047) 6 | #endif 7 | 8 | #if defined(WIN32) 9 | #define WIN32_LEAN_AND_MEAN 10 | #include 11 | #else 12 | #include 13 | #endif 14 | 15 | #if defined(__GNUC__) 16 | /* Disable MinGW warnings for Windows */ 17 | #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" 18 | #endif 19 | 20 | 21 | int stublua_init(void) 22 | { 23 | void *lib = NULL; 24 | 25 | { 26 | #if defined(__APPLE__) 27 | static const char *possible_names[] = { 28 | 29 | "liblua.5.3.5.dylib", 30 | "liblua.5.3.dylib", 31 | "liblua5.3.dylib", 32 | "liblua.dylib", 33 | 0 34 | }; 35 | #elif defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64) 36 | static const char *possible_names[] = { 37 | "lua53.dll", 38 | "lua.dll", 39 | 0 40 | }; 41 | #else 42 | static const char *possible_names[] = { 43 | "liblua5.3.so", 44 | "liblua5.3.so.0", 45 | "liblua5.3.so.0.0.0", 46 | 0 47 | }; 48 | #endif 49 | unsigned i; 50 | for (i=0; possible_names[i]; i++) { 51 | #if defined(WIN32) 52 | lib = LoadLibraryA(possible_names[i]); 53 | #else 54 | lib = dlopen(possible_names[i], RTLD_LAZY); 55 | #endif 56 | if (lib) { 57 | break; 58 | } else { 59 | ; 60 | } 61 | } 62 | 63 | if (lib == NULL) { 64 | fprintf(stderr, "liblua: failed to load Lua shared library\n"); 65 | fprintf(stderr, " HINT: you must install Lua library\n"); 66 | } 67 | } 68 | 69 | #if defined(WIN32) 70 | #define DOLINK(name) \ 71 | name = (void (*)())GetProcAddress(lib, #name); \ 72 | if (name == NULL) fprintf(stderr, "liblua: %s: failed\n", #name); 73 | #else 74 | #define DOLINK(name) \ 75 | name = dlsym(lib, #name); \ 76 | if (name == NULL) fprintf(stderr, "liblua: %s: failed\n", #name); 77 | #endif 78 | 79 | DOLINK(lua_version); 80 | 81 | 82 | DOLINK(lua_close) 83 | DOLINK(lua_getfield) 84 | DOLINK(lua_getglobal) 85 | DOLINK(lua_geti) 86 | DOLINK(lua_gettop) 87 | DOLINK(lua_isnumber); 88 | DOLINK(lua_isstring); 89 | DOLINK(lua_iscfunction); 90 | DOLINK(lua_isinteger); 91 | DOLINK(lua_isuserdata); 92 | DOLINK(lua_newthread) 93 | DOLINK(lua_newuserdata) 94 | DOLINK(lua_pcallk) 95 | DOLINK(lua_pushcclosure) 96 | DOLINK(lua_pushinteger) 97 | DOLINK(lua_pushlstring) 98 | DOLINK(lua_pushnumber) 99 | DOLINK(lua_pushstring) 100 | DOLINK(lua_pushvalue) 101 | DOLINK(lua_resume) 102 | DOLINK(lua_setfield) 103 | DOLINK(lua_setglobal) 104 | DOLINK(lua_seti) 105 | DOLINK(lua_settop) 106 | DOLINK(lua_toboolean) 107 | DOLINK(lua_tointegerx) 108 | DOLINK(lua_tolstring) 109 | DOLINK(lua_tonumberx) 110 | DOLINK(lua_type) 111 | DOLINK(lua_typename) 112 | DOLINK(lua_version) 113 | DOLINK(lua_xmove) 114 | DOLINK(lua_yieldk) 115 | 116 | DOLINK(luaL_checkinteger) 117 | DOLINK(luaL_checklstring) 118 | DOLINK(luaL_checkudata) 119 | DOLINK(luaL_len) 120 | DOLINK(luaL_loadbufferx) 121 | DOLINK(luaL_loadfilex) 122 | DOLINK(luaL_loadstring) 123 | DOLINK(luaL_newmetatable) 124 | DOLINK(luaL_newstate) 125 | DOLINK(luaL_openlibs) 126 | DOLINK(luaL_ref) 127 | DOLINK(luaL_setfuncs) 128 | DOLINK(luaL_setmetatable) 129 | DOLINK(luaL_unref) 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /src/stub-pcap-dlt.h: -------------------------------------------------------------------------------- 1 | #ifndef STUB_PCAP_DLT_H 2 | #define STUB_PCAP_DLT_H 3 | 4 | typedef enum { 5 | /* Packets are prefixed by an integer indicating 6 | * the protocol type in host-byte-order (4-bytes) 7 | * followed by the raw IPv4 or IPv6 header */ 8 | PCAP_DLT_NULL = 0, 9 | 10 | /* Ethernet */ 11 | PCAP_DLT_ETHERNET = 1, 12 | 13 | /* Packets are 'raw' on the network. The first byte 14 | * will be the first byte of the IPv4/IPv6 header */ 15 | PCAP_DLT_RAW = 12, 16 | } pcap_dlt_t; 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /src/stub-pfring.c: -------------------------------------------------------------------------------- 1 | /* 2 | PF_RING compatibility layer 3 | 4 | In order to avoid special build hassle, this code links to PF_RING at 5 | runtime instead compile-time. That means you can compile this code 6 | BEFORE installing and building PF_RING. 7 | 8 | */ 9 | #include "stub-pfring.h" 10 | #include "util-safefunc.h" 11 | #include "util-logger.h" 12 | 13 | struct PFRING PFRING; 14 | 15 | #if defined(__linux__) 16 | #include 17 | #endif 18 | 19 | /*************************************************************************** 20 | * This checks whether the "pf_ring" driver is installed. 21 | ***************************************************************************/ 22 | int 23 | PFRING_is_installed(void); 24 | 25 | int 26 | PFRING_is_installed(void) 27 | { 28 | #if defined(__linux__) 29 | FILE *fp; 30 | char line[256]; 31 | int found = 0; 32 | 33 | fp = fopen("/proc/modules", "rb"); 34 | if (fp == NULL) 35 | return 0; 36 | 37 | while (fgets(line, sizeof(line), fp)) { 38 | if (memcmp(line, "pf_ring ", 8) == 0) { 39 | found = 1; 40 | LOG(2, "pfring: found 'pf_ring' driver\n"); 41 | } 42 | if (memcmp(line, "ixgbe ", 6) == 0) { 43 | LOG(2, "pfring: found 'ixgbe' driver\n"); 44 | } 45 | if (memcmp(line, "e1000e ", 8) == 0) { 46 | LOG(2, "pfring: found 'e1000e' driver\n"); 47 | } 48 | } 49 | fclose(fp); 50 | return found; 51 | #else 52 | return 0; 53 | #endif 54 | } 55 | 56 | 57 | /*************************************************************************** 58 | ***************************************************************************/ 59 | int 60 | PFRING_init(void) 61 | { 62 | #if defined(__linux__) 63 | void *h; 64 | int err = 0; 65 | LOG(6, "pfring: initializing subsystem\n"); 66 | LOG(6, "pfring: looking for 'libpfring.so'\n"); 67 | h = dlopen("libpfring.so", RTLD_LAZY); 68 | if (h == NULL) { 69 | LOG(2, "pfring: error: dlopen('libpfring.so'): %s\n", strerror(errno)); 70 | return 0; 71 | } else 72 | LOG(2, "pfring: found 'libpfring.so'!\n"); 73 | 74 | #define LOADSYM(name) if ((PFRING.name = dlsym(h, "pfring_"#name)) == 0) {LOG(2, "pfring_%s: not found in 'libpfring.so': %s\n", #name, strerror(errno));err=1;} 75 | LOADSYM(open); 76 | LOADSYM(close); 77 | LOADSYM(enable_ring); 78 | LOADSYM(send); 79 | LOADSYM(recv); 80 | LOADSYM(poll); 81 | LOADSYM(version); 82 | LOADSYM(set_direction); 83 | LOADSYM(set_application_name); 84 | //LOADSYM(get_bound_device); 85 | 86 | if (err) { 87 | memset(&PFRING, 0, sizeof(PFRING)); 88 | LOG(2, "pfring: failed to load\n"); 89 | } else { 90 | LOG(2, "pfring: successfully loaded PF_RING API\n"); 91 | 92 | if (!PFRING_is_installed()) { 93 | LOG(0, "pfring: ERROR: 'pf_ring' driver module not found!!!!!\n"); 94 | } else 95 | LOG(2, "pfring: found 'pf_ring' driver module\n"); 96 | } 97 | 98 | #endif 99 | return 0; 100 | } 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/stub-pfring.h: -------------------------------------------------------------------------------- 1 | #ifndef RAWSOCK_PFRING_H 2 | #define RAWSOCK_PFRING_H 3 | #include 4 | #include 5 | 6 | /* 7 | * Various PF_RING defines 8 | */ 9 | struct __pfring; 10 | typedef struct __pfring pfring; 11 | 12 | typedef enum { 13 | rx_and_tx_direction = 0, 14 | rx_only_direction, 15 | tx_only_direction 16 | } packet_direction; 17 | struct pfring_pkthdr { 18 | struct xtimeval { 19 | long tv_sec; 20 | long tv_usec; 21 | } ts; 22 | unsigned caplen; 23 | unsigned len; 24 | /* only filled in if PF_RING_LONG_HEADER set */ 25 | unsigned char extended_hdr[512]; 26 | }; 27 | #define PF_RING_ERROR_GENERIC -1 28 | #define PF_RING_ERROR_INVALID_ARGUMENT -2 29 | #define PF_RING_ERROR_NO_PKT_AVAILABLE -3 30 | #define PF_RING_ERROR_NO_TX_SLOT_AVAILABLE -4 31 | #define PF_RING_ERROR_WRONG_CONFIGURATION -5 32 | #define PF_RING_ERROR_END_OF_DEMO_MODE -6 33 | #define PF_RING_ERROR_NOT_SUPPORTED -7 34 | #define PF_RING_ERROR_INVALID_LIB_VERSION -8 35 | #define PF_RING_ERROR_UNKNOWN_ADAPTER -9 36 | #define PF_RING_ERROR_NOT_ENOUGH_MEMORY -10 37 | #define PF_RING_ERROR_INVALID_STATUS -11 38 | #define PF_RING_DNA_SYMMETRIC_RSS 1 << 0 39 | #define PF_RING_REENTRANT 1 << 1 40 | #define PF_RING_LONG_HEADER 1 << 2 41 | #define PF_RING_PROMISC 1 << 3 42 | #define PF_RING_TIMESTAMP 1 << 4 43 | #define PF_RING_HW_TIMESTAMP 1 << 5 44 | #define PF_RING_RX_PACKET_BOUNCE 1 << 6 45 | #define PF_RING_DNA_FIXED_RSS_Q_0 1 << 7 46 | #define PF_RING_STRIP_HW_TIMESTAMP 1 << 8 47 | #define PF_RING_DO_NOT_PARSE 1 << 9 /* parsing already disabled in zero-copy */ 48 | #define PF_RING_DO_NOT_TIMESTAMP 1 << 10 /* sw timestamp already disabled in zero-copy */ 49 | 50 | /* 51 | * function prototypes 52 | */ 53 | typedef pfring*(*PFRING_OPEN)( 54 | const char *device_name, 55 | unsigned caplen, 56 | unsigned flags); 57 | typedef void (*PFRING_CLOSE)(pfring *ring); 58 | typedef int (*PFRING_ENABLE_RING)(pfring *ring); 59 | typedef int (*PFRING_SEND)( pfring *ring, 60 | const unsigned char *buffer, 61 | unsigned buffer_length, 62 | unsigned char flush_packet); 63 | typedef int (*PFRING_RECV)( pfring *ring, 64 | unsigned char** buffer, 65 | unsigned buffer_length, 66 | struct pfring_pkthdr *hdr, 67 | unsigned char wait_for_incoming_packet); 68 | typedef int (*PFRING_POLL)(pfring *ring, unsigned wait_duration); 69 | typedef int (*PFRING_VERSION)(pfring *ring, unsigned *version); 70 | typedef int (*PFRING_SET_DIRECTION)(pfring *ring, int direction); 71 | typedef int (*PFRING_SET_APPLICATION_NAME)(pfring *ring, char *name); 72 | typedef int (*PFRING_GET_BOUND_DEVICE)(pfring *ring, unsigned char mac_address[6]); 73 | 74 | /* 75 | * scoped object 76 | */ 77 | extern struct PFRING { 78 | PFRING_OPEN open; 79 | PFRING_CLOSE close; 80 | PFRING_ENABLE_RING enable_ring; 81 | PFRING_SEND send; 82 | PFRING_RECV recv; 83 | PFRING_POLL poll; 84 | PFRING_VERSION version; 85 | PFRING_SET_DIRECTION set_direction; 86 | PFRING_SET_APPLICATION_NAME set_application_name; 87 | PFRING_GET_BOUND_DEVICE get_bound_device; 88 | } PFRING; 89 | 90 | /* 91 | * call this to load the library 92 | */ 93 | int PFRING_init(void); 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/syn-cookie.c: -------------------------------------------------------------------------------- 1 | #include "syn-cookie.h" 2 | #include "pixie-timer.h" 3 | #include "util-safefunc.h" 4 | #include "crypto-siphash24.h" 5 | #include 6 | #include 7 | #include 8 | 9 | #if defined(_MSC_VER) 10 | #include 11 | #endif 12 | 13 | /*************************************************************************** 14 | * Go gather some entropy (aka. randmoness) to seed hashing with. 15 | * 16 | * NOTE: Mostly it's here to amuse cryptographers with its lulz. 17 | ***************************************************************************/ 18 | uint64_t 19 | get_entropy(void) 20 | { 21 | uint64_t entropy[2] = {0,0}; 22 | unsigned i; 23 | 24 | /* 25 | * Gather some random bits 26 | */ 27 | for (i=0; i<64; i++) { 28 | FILE *fp; 29 | entropy[0] += pixie_nanotime(); 30 | #if defined(_MSC_VER) 31 | entropy[0] ^= __rdtsc(); 32 | #endif 33 | time(0); 34 | fp = fopen("/", "r"); 35 | entropy[1] <<= 1; 36 | entropy[1] |= entropy[0]>>63; 37 | entropy[0] <<= 1; 38 | if (fp) { 39 | fclose(fp); 40 | } 41 | } 42 | 43 | entropy[0] ^= time(0); 44 | 45 | /* Always try to open this file, even on platforms like Windows 46 | * where it's not going to exist. */ 47 | { 48 | FILE *fp; 49 | 50 | fp = fopen("/dev/urandom", "r"); 51 | if (fp) { 52 | size_t x; 53 | uint64_t urand = 0; 54 | x = fread(&urand, 1, sizeof(urand), fp); 55 | entropy[0] ^= urand; 56 | entropy[0] ^= x; 57 | x = fread(&urand, 1, sizeof(urand), fp); 58 | entropy[1] ^= urand; 59 | entropy[1] ^= x; 60 | fclose(fp); 61 | } 62 | entropy[0] ^= pixie_nanotime(); 63 | } 64 | 65 | return entropy[0] ^ entropy[1]; 66 | } 67 | 68 | #if 0 69 | /*************************************************************************** 70 | * This implements the "murmur" hash function. 71 | ***************************************************************************/ 72 | static unsigned 73 | murmur(uint64_t entropy, ...) 74 | { 75 | /* reference: 76 | * http://en.wikipedia.org/wiki/MurmurHash 77 | */ 78 | static const unsigned c1 = 0xcc9e2d51; 79 | static const unsigned c2 = 0x1b873593; 80 | unsigned r1 = 15; 81 | unsigned r2 = 13; 82 | unsigned m = 5; 83 | unsigned n = 0xe6546b64; 84 | va_list key; 85 | unsigned len; 86 | 87 | unsigned hash = (unsigned)entropy; 88 | 89 | va_start(key, entropy); 90 | 91 | for (len=0; len<2; len++) { 92 | unsigned k = va_arg(key, unsigned); 93 | k = k * c1; 94 | k = (k << r1) | (k >> (32-r1)); 95 | k = k * c2; 96 | 97 | hash = hash ^ k; 98 | hash = (hash << r2) | (hash >> (32-r2)); 99 | hash = hash * m + n; 100 | } 101 | 102 | hash = hash ^ (len*4); 103 | 104 | hash = hash ^ (hash >> 16); 105 | hash = hash * 0x85ebca6b; 106 | hash = hash ^ (hash >> 13); 107 | hash = hash * 0xc2b2ae35; 108 | hash = hash ^ (hash >> 16); 109 | 110 | return hash; 111 | } 112 | #endif 113 | 114 | /*************************************************************************** 115 | ***************************************************************************/ 116 | uint64_t 117 | syn_cookie( ipaddress ip_them, unsigned port_them, 118 | ipaddress ip_me, unsigned port_me, 119 | uint64_t entropy) 120 | { 121 | switch (ip_them.version) { 122 | case 4: 123 | return syn_cookie_ipv4(ip_them.ipv4, port_them, ip_me.ipv4, port_me, entropy); 124 | case 6: 125 | return syn_cookie_ipv6(ip_them.ipv6, port_them, ip_me.ipv6, port_me, entropy); 126 | default: 127 | assert(!"unknown ip version"); 128 | return 0; 129 | } 130 | } 131 | 132 | /*************************************************************************** 133 | ***************************************************************************/ 134 | uint64_t 135 | syn_cookie_ipv4( unsigned ip_them, unsigned port_them, 136 | unsigned ip_me, unsigned port_me, 137 | uint64_t entropy) 138 | { 139 | unsigned data[4]; 140 | uint64_t x[2]; 141 | 142 | x[0] = entropy; 143 | x[1] = entropy; 144 | 145 | data[0] = ip_them; 146 | data[1] = port_them; 147 | data[2] = ip_me; 148 | data[3] = port_me; 149 | return siphash24(data, sizeof(data), x); 150 | } 151 | 152 | /*************************************************************************** 153 | ***************************************************************************/ 154 | uint64_t 155 | syn_cookie_ipv6( ipv6address ip_them, unsigned port_them, 156 | ipv6address ip_me, unsigned port_me, 157 | uint64_t entropy) 158 | { 159 | uint64_t data[5]; 160 | uint64_t x[2]; 161 | 162 | x[0] = entropy; 163 | x[1] = entropy; 164 | 165 | data[0] = ip_them.hi; 166 | data[1] = ip_them.lo; 167 | data[2] = ip_me.hi; 168 | data[3] = ip_me.lo; 169 | data[4] = port_them<<16ULL | port_me; 170 | return siphash24(data, sizeof(data), x); 171 | } 172 | -------------------------------------------------------------------------------- /src/syn-cookie.h: -------------------------------------------------------------------------------- 1 | #ifndef SYN_COOKIE_H 2 | #define SYN_COOKIE_H 3 | #include 4 | #include "massip-addr.h" 5 | 6 | /** 7 | * Create a hash of the src/dst IP/port combination. This allows us to match 8 | * incoming responses with their original requests 9 | */ 10 | uint64_t 11 | syn_cookie_ipv4( unsigned ip_dst, unsigned port_dst, 12 | unsigned ip_src, unsigned port_src, 13 | uint64_t entropy); 14 | 15 | uint64_t 16 | syn_cookie( ipaddress ip_dst, unsigned port_dst, 17 | ipaddress ip_src, unsigned port_src, 18 | uint64_t entropy); 19 | 20 | uint64_t 21 | syn_cookie_ipv6( ipv6address ip_dst, unsigned port_dst, 22 | ipv6address ip_src, unsigned port_src, 23 | uint64_t entropy); 24 | 25 | 26 | /** 27 | * Called on startup to set a secret key 28 | */ 29 | uint64_t get_entropy(void); 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/templ-nmap-payloads.h: -------------------------------------------------------------------------------- 1 | /* 2 | Parses the "nmap-payloads" file. 3 | */ 4 | #ifndef TEMPL_NMAP_PAYLOADS_H 5 | #define TEMPL_NMAP_PAYLOADS_H 6 | #include 7 | struct PayloadsUDP; 8 | struct RangeList; 9 | 10 | typedef unsigned 11 | (*payloads_datagram_add_cb)(struct PayloadsUDP *payloads, 12 | const unsigned char *buf, size_t length, 13 | struct RangeList *ports, unsigned source_port 14 | ); 15 | 16 | void 17 | read_nmap_payloads(FILE *fp, const char *filename, 18 | struct PayloadsUDP *payloads, 19 | payloads_datagram_add_cb add_payload 20 | ); 21 | 22 | int 23 | templ_nmap_selftest(void); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/templ-opts.h: -------------------------------------------------------------------------------- 1 | #ifndef TEMPL_OPTS_H 2 | #define TEMPL_OPTS_H 3 | #include "massip-addr.h" 4 | 5 | #ifdef _MSC_VER 6 | #pragma warning(disable:4214) 7 | #endif 8 | 9 | /** 10 | * This tells us whether we should add, remove, or leave default 11 | * a field in the packet headers. 12 | * FIXME: not all of these are supported 13 | */ 14 | typedef enum {Default, Add, Remove} addremove_t; 15 | 16 | struct TemplateOptions { 17 | struct { 18 | addremove_t is_badsum:4; /* intentionally bad checksum */ 19 | addremove_t is_tsecho:4; /* enable timestamp echo */ 20 | addremove_t is_tsreply:4; /* enable timestamp echo */ 21 | addremove_t is_flags:4; 22 | addremove_t is_ackno:4; 23 | addremove_t is_seqno:4; 24 | addremove_t is_win:4; 25 | addremove_t is_mss:4; 26 | addremove_t is_sackok:4; 27 | addremove_t is_wscale:4; 28 | unsigned flags; 29 | unsigned ackno; 30 | unsigned seqno; 31 | unsigned win; 32 | unsigned mss; 33 | unsigned sackok; 34 | unsigned wscale; 35 | unsigned tsecho; 36 | unsigned tsreply; 37 | } tcp; 38 | 39 | struct { 40 | addremove_t is_badsum:4; /* intentionally bad checksum */ 41 | } udp; 42 | 43 | struct { 44 | addremove_t is_sender_mac:4; 45 | addremove_t is_sender_ip:4; 46 | addremove_t is_target_mac:4; 47 | addremove_t is_target_ip:4; 48 | macaddress_t sender_mac; 49 | ipaddress sender_ip; 50 | macaddress_t target_mac; 51 | ipaddress target_ip; 52 | } arp; 53 | 54 | struct { 55 | addremove_t is_badsum:4; /* intentionally bad checksum */ 56 | addremove_t is_tos:4; 57 | addremove_t is_ipid:4; 58 | addremove_t is_df:4; 59 | addremove_t is_mf:4; 60 | addremove_t is_ttl:4; 61 | 62 | unsigned tos; 63 | unsigned ipid; 64 | unsigned ttl; 65 | 66 | } ipv4; 67 | }; 68 | 69 | #endif 70 | 71 | -------------------------------------------------------------------------------- /src/templ-payloads.h: -------------------------------------------------------------------------------- 1 | #ifndef TEMPL_PAYLOADS_H 2 | #define TEMPL_PAYLOADS_H 3 | #include 4 | #include 5 | struct MassIP; 6 | 7 | /** 8 | * Regression test this module. 9 | * @return 10 | * 0 on success, or positive integer on failure. 11 | */ 12 | int 13 | templ_payloads_selftest(void); 14 | 15 | /** 16 | * Create this module. Must be matched with the 'destroy()' function on exit 17 | */ 18 | struct PayloadsUDP * 19 | payloads_udp_create(void); 20 | 21 | struct PayloadsUDP * 22 | payloads_oproto_create(void); 23 | 24 | /** 25 | * Free the resources of an object created with a matching call to 26 | * 'payloads_create()' 27 | */ 28 | void 29 | payloads_udp_destroy(struct PayloadsUDP *payloads); 30 | 31 | void 32 | payloads_oproto_destroy(struct PayloadsUDP *payloads); 33 | 34 | /** 35 | * Read payloads from an "nmap-payloads" formatted file. The caller is 36 | * responsible for opening/closing the file, but should passing the 37 | * filename so that we can print helpful error messages. 38 | */ 39 | void 40 | payloads_udp_readfile(FILE *fp, const char *filename, 41 | struct PayloadsUDP *payloads); 42 | 43 | /** 44 | * Read payloads from a libpcap formatted file. 45 | */ 46 | void 47 | payloads_read_pcap(const char *filename, struct PayloadsUDP *payloads, struct PayloadsUDP *oproto_payloads); 48 | 49 | /** 50 | * Called to remove any payloads that aren't be used in the scan. This makes 51 | * lookups faster when generating packets. 52 | */ 53 | void 54 | payloads_udp_trim(struct PayloadsUDP *payloads, const struct MassIP *targets); 55 | 56 | void 57 | payloads_oproto_trim(struct PayloadsUDP *payloads, const struct MassIP *targets); 58 | 59 | 60 | /** 61 | * The port scanner creates a "cookie" for every packet that it sends, which 62 | * will be a 64-bit value, whose low-order bits will be trimmed to fit whatever 63 | * size is available. For TCP, this becomes the 32-bit seqno of the SYN packet. 64 | * For UDP protocols, however, each application layer protocol will be 65 | * different. For example, SNMP can use a 32-bit transaction ID, whereas DNS 66 | * can use only a 16-bit transaction ID. 67 | */ 68 | typedef unsigned (*SET_COOKIE)(unsigned char *px, size_t length, 69 | uint64_t seqno); 70 | 71 | 72 | /** 73 | * Given a UDP port number, return the payload we have that is associated 74 | * with that port number. 75 | * @param payloads 76 | * A table full over payloads. 77 | * @param port 78 | * The input port number. 79 | * @param px 80 | * The returned payload bytes. 81 | * @param length 82 | * The returned count of payload bytes. 83 | * @param source_port 84 | * The returned port that should be used when sending packets. 85 | * @param xsum 86 | * The returned partial checksum of the payload bytes, so that it 87 | * doesn't need to be recalculated for every packet. 88 | * @param set_cookie 89 | * The returned function that will set the "cookie" field in the 90 | * packet for each transmission 91 | */ 92 | int 93 | payloads_udp_lookup( 94 | const struct PayloadsUDP *payloads, 95 | unsigned port, 96 | const unsigned char **px, 97 | unsigned *length, 98 | unsigned *source_port, 99 | uint64_t *xsum, 100 | SET_COOKIE *set_cookie); 101 | 102 | int 103 | payloads_oproto_lookup( 104 | const struct PayloadsUDP *payloads, 105 | unsigned port, 106 | const unsigned char **px, 107 | unsigned *length, 108 | unsigned *source_port, 109 | uint64_t *xsum, 110 | SET_COOKIE *set_cookie); 111 | 112 | 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /src/templ-tcp-hdr.h: -------------------------------------------------------------------------------- 1 | #ifndef TEMPL_TCP_H 2 | #define TEMPL_TCP_H 3 | #include "util-bool.h" /* */ 4 | #include 5 | struct TemplateOptions; 6 | 7 | /** 8 | * Called during configuration, to apply all the various changes the 9 | * user asked for on the command-line, such as optioms like: 10 | * --tcp-mss 1460 11 | * --tcp-sackperm 12 | * --tcp-wscale 3 13 | */ 14 | void 15 | templ_tcp_apply_options(unsigned char **inout_buf, size_t *inout_length, 16 | const struct TemplateOptions *templ_opts); 17 | 18 | /** 19 | * Conduct a selftest of all the functions that manipulate the TCP 20 | * header template. 21 | */ 22 | int 23 | templ_tcp_selftest(void); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/unusedparm.h: -------------------------------------------------------------------------------- 1 | #ifndef UNUSEDPARM 2 | #if defined(_MSC_VER) 3 | #define UNUSEDPARM(x) x 4 | #elif defined(__GNUC__) 5 | #define UNUSEDPARM(x) (void) x 6 | #endif 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /src/util-bool.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_BOOL_H 2 | #define UTIL_BOOL_H 3 | 4 | #if _MSC_VER && _MSC_VER < 1800 5 | typedef enum {false=0, true=1} bool; 6 | #else 7 | #include 8 | #endif 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /src/util-checksum.h: -------------------------------------------------------------------------------- 1 | /* 2 | Calculates Internet checksums for protocols like TCP/IP. 3 | 4 | Author: Robert David Graham 5 | Copyright: 2020 6 | License: The MIT License (MIT) 7 | Dependencies: none 8 | */ 9 | #ifndef UTIL_CHECKSUM_H 10 | #define UTIL_CHECKSUM_H 11 | #include 12 | 13 | /** 14 | * Calculate a checksum for IPv4 packets. 15 | * @param ip_src 16 | * The source IPv4 address, represented a standard way, 17 | * as a 32-bit integer in host byte order. 18 | * @param ip_dst 19 | * The destination IPv4 address, represented as a 32-bit integer in host byte order. 20 | * @param ip_proto 21 | * A value of 6 for TCP or 17 for UDP. 22 | * @param payload_length 23 | * The length of the IP packet payload, meaning, everything after the IPv4 header. 24 | * In other words, it's the "total length" field of the IP packet minus the 25 | * length of the IP header. 26 | * @param payload 27 | * A pointer to the aforementioned payload (a pointer to the first byte past the 28 | * IP header). Note that the calculation skips the checksum field, so the payload 29 | * we use is everything but the 2 bytes in the checksum field. Thus, due to the 30 | * quirkiness of Internet protocols, the result of this calculation should end 31 | * up equally the value of the checksum field. 32 | * @return 33 | * the calculated checksum, which should equal the checksum found in the payload 34 | */ 35 | unsigned 36 | checksum_ipv4(unsigned ip_src, unsigned ip_dst, unsigned ip_proto, size_t payload_length, const void *payload); 37 | 38 | unsigned 39 | checksum_ipv6(const unsigned char *ip_src, const unsigned char *ip_dst, unsigned ip_proto, size_t payload_length, const void *payload); 40 | 41 | 42 | /** 43 | * Simple unit tests. 44 | * @return 45 | * 1 if failure, 0 if success 46 | */ 47 | int checksum_selftest(void); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/util-errormsg.c: -------------------------------------------------------------------------------- 1 | #include "util-errormsg.h" 2 | #include "crypto-siphash24.h" 3 | #include "massip-addr.h" 4 | #include 5 | #include 6 | 7 | #ifdef _MSC_VER 8 | #pragma warning(disable: 4204) 9 | #endif 10 | 11 | 12 | static unsigned long long _entropy; 13 | 14 | void errmsg_init(unsigned long long in_entropy) { 15 | _entropy = in_entropy; 16 | } 17 | 18 | static void 19 | _errmsg(const char *fmt, va_list marker) 20 | { 21 | fprintf(stderr, "[-] ERR: "); 22 | vfprintf(stderr, fmt, marker); 23 | fflush(stderr); 24 | } 25 | 26 | static void 27 | _errmsgip(ipaddress ip, unsigned port, const char *fmt, va_list marker) 28 | { 29 | ipaddress_formatted_t fmted = ipaddress_fmt(ip); 30 | 31 | fprintf(stderr, "[-] %s:%u: ", fmted.string, port); 32 | vfprintf(stderr, fmt, marker); 33 | fflush(stderr); 34 | } 35 | 36 | /*************************************************************************** 37 | * Prints the message if the global "verbosity" flag exceeds this level. 38 | ***************************************************************************/ 39 | void 40 | ERRMSG(const char *fmt, ...) 41 | { 42 | va_list marker; 43 | size_t index; 44 | uint64_t key[2] = {_entropy, _entropy}; 45 | static size_t _table[1024] = {0}; 46 | 47 | /* Hash the address of the format string */ 48 | index = (size_t)siphash24(fmt, sizeof(fmt), key); 49 | index %= 1024; 50 | 51 | /* Filter out this error if we've seen it before */ 52 | if (_table[index] == (size_t)fmt) 53 | return; 54 | else 55 | _table[index] = (size_t)fmt; 56 | 57 | 58 | va_start(marker, fmt); 59 | _errmsg(fmt, marker); 60 | va_end(marker); 61 | } 62 | 63 | void 64 | ERRMSGip(ipaddress ip, unsigned port, const char *fmt, ...) 65 | { 66 | va_list marker; 67 | size_t index; 68 | uint64_t key[2] = {_entropy, _entropy}; 69 | static size_t _table[1024] = {0}; 70 | 71 | /* Hash the address of the format string */ 72 | index = (size_t)siphash24(fmt, sizeof(fmt), key); 73 | index %= 1024; 74 | 75 | /* Filter out this error if we've seen it before */ 76 | if (_table[index] == (size_t)fmt) 77 | return; 78 | else 79 | _table[index] = (size_t)fmt; 80 | 81 | 82 | va_start(marker, fmt); 83 | _errmsgip(ip, port, fmt, marker); 84 | va_end(marker); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/util-errormsg.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_ERRORMSG_H 2 | #define UTIL_ERRORMSG_H 3 | #include "massip-addr.h" 4 | 5 | void errmsg_init(unsigned long long entropy); 6 | 7 | /** 8 | * Prints an error message only once 9 | */ 10 | void 11 | ERRMSG(const char *fmt, ...); 12 | 13 | void 14 | ERRMSGip(ipaddress ip, unsigned port, const char *fmt, ...); 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/util-extract.c: -------------------------------------------------------------------------------- 1 | #include "util-extract.h" 2 | 3 | 4 | unsigned char 5 | e_next_byte(struct ebuf_t *ebuf) { 6 | if (ebuf->offset + 1 > ebuf->max) 7 | return -1; 8 | 9 | return ebuf->buf[ebuf->offset++]; 10 | } 11 | 12 | unsigned short 13 | e_next_short16(struct ebuf_t *ebuf, int endian) { 14 | const unsigned char *buf = ebuf->buf; 15 | size_t offset = ebuf->offset; 16 | unsigned short result; 17 | 18 | if (ebuf->offset + 2 > ebuf->max) 19 | return -1; 20 | 21 | if (endian == EBUF_BE) { 22 | result = buf[offset+0]<<8 | buf[offset+1]; 23 | } else { 24 | result = buf[offset+1]<<8 | buf[offset+0]; 25 | } 26 | ebuf->offset += 2; 27 | return result; 28 | } 29 | unsigned e_next_int32(struct ebuf_t *ebuf, int endian) { 30 | const unsigned char *buf = ebuf->buf; 31 | size_t offset = ebuf->offset; 32 | unsigned result; 33 | 34 | if (ebuf->offset + 4 > ebuf->max) 35 | return -1; 36 | 37 | if (endian == EBUF_BE) { 38 | result = buf[offset+0]<<24 | buf[offset+1] << 16 39 | | buf[offset+2]<<8 | buf[offset+3] << 0; 40 | } else { 41 | result = buf[offset+3]<<24 | buf[offset+2] << 16 42 | | buf[offset+1]<<8 | buf[offset+0] << 0; 43 | } 44 | ebuf->offset += 4; 45 | return result; 46 | } 47 | unsigned long long 48 | e_next_long64(struct ebuf_t *ebuf, int endian) { 49 | const unsigned char *buf = ebuf->buf; 50 | size_t offset = ebuf->offset; 51 | unsigned long long hi; 52 | unsigned long long lo; 53 | 54 | if (ebuf->offset + 8 > ebuf->max) 55 | return -1ll; 56 | 57 | if (endian == EBUF_BE) { 58 | hi = buf[offset+0]<<24 | buf[offset+1] << 16 59 | | buf[offset+2]<<8 | buf[offset+3] << 0; 60 | lo = buf[offset+4]<<24 | buf[offset+5] << 16 61 | | buf[offset+6]<<8 | buf[offset+7] << 0; 62 | } else { 63 | lo = buf[offset+3]<<24 | buf[offset+2] << 16 64 | | buf[offset+1]<<8 | buf[offset+0] << 0; 65 | hi = buf[offset+7]<<24 | buf[offset+6] << 16 66 | | buf[offset+5]<<8 | buf[offset+4] << 0; 67 | } 68 | ebuf->offset += 8; 69 | return hi<<32ull | lo; 70 | 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/util-extract.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_EXTRACT_H 2 | #define UTIL_EXTRACT_H 3 | #include 4 | 5 | struct ebuf_t { 6 | const unsigned char *buf; 7 | size_t offset; 8 | size_t max; 9 | }; 10 | 11 | enum { 12 | EBUF_BE, 13 | EBUG_LE, 14 | }; 15 | 16 | unsigned char e_next_byte(struct ebuf_t *ebuf); 17 | unsigned short e_next_short16(struct ebuf_t *ebuf, int endian); 18 | unsigned e_next_int32(struct ebuf_t *ebuf, int endian); 19 | unsigned long long e_next_long64(struct ebuf_t *ebuf, int endian); 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/util-logger.c: -------------------------------------------------------------------------------- 1 | /* 2 | log messages to console, depending on verbose level 3 | 4 | Use -d to get more verbose output. The more -v you add, the 5 | more verbose the output becomes. 6 | 7 | Details about the running of the program go to . 8 | Details about scan results go to , so that they can easily 9 | be redirected to a file. 10 | */ 11 | #include "util-logger.h" 12 | #include "util-safefunc.h" 13 | #include 14 | #include 15 | 16 | static int global_debug_level = 0; /* yea! a global variable!! */ 17 | void LOG_add_level(int x) 18 | { 19 | global_debug_level += x; 20 | } 21 | 22 | /*************************************************************************** 23 | ***************************************************************************/ 24 | static void 25 | vLOG(int level, const char *fmt, va_list marker) 26 | { 27 | if (level <= global_debug_level) { 28 | vfprintf(stderr, fmt, marker); 29 | fflush(stderr); 30 | } 31 | } 32 | 33 | 34 | /*************************************************************************** 35 | * Prints the message if the global "verbosity" flag exceeds this level. 36 | ***************************************************************************/ 37 | void 38 | LOG(int level, const char *fmt, ...) 39 | { 40 | va_list marker; 41 | 42 | va_start(marker, fmt); 43 | vLOG(level, fmt, marker); 44 | va_end(marker); 45 | } 46 | 47 | /*************************************************************************** 48 | ***************************************************************************/ 49 | static void 50 | vLOGnet(unsigned port_me, ipaddress ip_them, const char *fmt, va_list marker) 51 | { 52 | char sz_ip[64]; 53 | ipaddress_formatted_t fmt1 = ipaddress_fmt(ip_them); 54 | 55 | snprintf(sz_ip, sizeof(sz_ip), "%s", fmt1.string); 56 | fprintf(stderr, "%u:%s: ", port_me, sz_ip); 57 | vfprintf(stderr, fmt, marker); 58 | fflush(stderr); 59 | } 60 | void 61 | LOGnet(unsigned port_me, ipaddress ip_them, const char *fmt, ...) 62 | { 63 | va_list marker; 64 | 65 | va_start(marker, fmt); 66 | vLOGnet(port_me, ip_them, fmt, marker); 67 | va_end(marker); 68 | } 69 | 70 | 71 | 72 | /*************************************************************************** 73 | ***************************************************************************/ 74 | static void 75 | vLOGip(int level, ipaddress ip, unsigned port, const char *fmt, va_list marker) 76 | { 77 | if (level <= global_debug_level) { 78 | char sz_ip[64]; 79 | ipaddress_formatted_t fmt1 = ipaddress_fmt(ip); 80 | 81 | snprintf(sz_ip, sizeof(sz_ip), "%s:%u: ", fmt1.string, port); 82 | fprintf(stderr, "%s ", sz_ip); 83 | vfprintf(stderr, fmt, marker); 84 | fflush(stderr); 85 | } 86 | } 87 | void 88 | LOGip(int level, ipaddress ip, unsigned port, const char *fmt, ...) 89 | { 90 | va_list marker; 91 | 92 | va_start(marker, fmt); 93 | vLOGip(level, ip, port, fmt, marker); 94 | va_end(marker); 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/util-logger.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_LOGGER_H 2 | #define UTIL_LOGGER_H 3 | #include "massip-addr.h" 4 | 5 | void LOG(int level, const char *fmt, ...); 6 | void LOGip(int level, ipaddress ip, unsigned port, const char *fmt, ...); 7 | void LOGnet(unsigned port_me, ipaddress ip_them, const char *fmt, ...); 8 | 9 | 10 | void LOG_add_level(int level); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/util-malloc.c: -------------------------------------------------------------------------------- 1 | #include "util-malloc.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAXNUM ((size_t)1 << (sizeof(size_t)*4)) 8 | 9 | /*************************************************************************** 10 | ***************************************************************************/ 11 | void * 12 | REALLOCARRAY(void *p, size_t count, size_t size) 13 | { 14 | if (count >= MAXNUM || size >= MAXNUM) { 15 | if (size != 0 && count >= SIZE_MAX/size) { 16 | fprintf(stderr, "[-] alloc too large, aborting\n"); 17 | abort(); 18 | } 19 | } 20 | 21 | p = realloc(p, count * size); 22 | if (p == NULL && count * size != 0) { 23 | fprintf(stderr, "[-] out of memory, aborting\n"); 24 | abort(); 25 | } 26 | 27 | return p; 28 | } 29 | 30 | /*************************************************************************** 31 | ***************************************************************************/ 32 | void * 33 | CALLOC(size_t count, size_t size) 34 | { 35 | void *p; 36 | 37 | if (count >= MAXNUM || size >= MAXNUM) { 38 | if (size != 0 && count >= SIZE_MAX/size) { 39 | fprintf(stderr, "[-] alloc too large, aborting\n"); 40 | abort(); 41 | } 42 | } 43 | 44 | p = calloc(count, size); 45 | if (p == NULL && count * size != 0) { 46 | fprintf(stderr, "[-] out of memory, aborting\n"); 47 | abort(); 48 | } 49 | 50 | return p; 51 | } 52 | 53 | /*************************************************************************** 54 | * Wrap the standard 'malloc()' function. 55 | * - never returns a NULL pointer, aborts program instead 56 | * - if size is zero, still returns a valid pointer to one byte 57 | ***************************************************************************/ 58 | void * 59 | MALLOC(size_t size) 60 | { 61 | void *p; 62 | 63 | /* If 'size' is zero, then the behavior of 'malloc()' is undefined. 64 | * I'm not sure which behavior would be best, to either always abort 65 | * or always succeed. I'm choosing "always succeed" by bumping the 66 | * length by one byte */ 67 | if (size == 0) 68 | size = 1; 69 | 70 | /* Do the original allocation */ 71 | p = malloc(size); 72 | 73 | /* Abort the program if we've run out of memory */ 74 | if (p == NULL) { 75 | fprintf(stderr, "[-] out of memory, aborting\n"); 76 | abort(); 77 | } 78 | 79 | /* At this point, we've either succeeded or aborted the program, 80 | * so this value is guaranteed to never be NULL */ 81 | return p; 82 | } 83 | 84 | /*************************************************************************** 85 | ***************************************************************************/ 86 | void * 87 | REALLOC(void *p, size_t size) 88 | { 89 | p = realloc(p, size); 90 | 91 | if (p == NULL) { 92 | fprintf(stderr, "[-] out of memory, aborting\n"); 93 | abort(); 94 | } 95 | 96 | return p; 97 | } 98 | 99 | /*************************************************************************** 100 | ***************************************************************************/ 101 | char * 102 | STRDUP(const char *str) 103 | { 104 | #if defined(WIN32) 105 | char *p = _strdup(str); 106 | #else 107 | char *p = strdup(str); 108 | #endif 109 | 110 | if (p == NULL && str != NULL) { 111 | fprintf(stderr, "[-] out of memory, aborting\n"); 112 | abort(); 113 | } 114 | 115 | return p; 116 | } 117 | 118 | 119 | -------------------------------------------------------------------------------- /src/util-malloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Wrappers around the malloc()/heap functions to `abort()` the program in 3 | case of running out of memory. 4 | 5 | Also, defines a REALLOCARRAY() function that checks for integer 6 | overflow before trying to allocate memory. 7 | */ 8 | #ifndef UTIL_MALLOC_H 9 | #define UTIL_MALLOC_H 10 | #include 11 | #include 12 | 13 | void * 14 | REALLOCARRAY(void *p, size_t count, size_t size); 15 | 16 | void * 17 | CALLOC(size_t count, size_t size); 18 | 19 | void * 20 | MALLOC(size_t size); 21 | 22 | void * 23 | REALLOC(void *p, size_t size); 24 | 25 | char * 26 | STRDUP(const char *str); 27 | 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/util-safefunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | safe C library functions 3 | 4 | This upgrades unsafe C functions like "strcpy()" to safer equivalents, 5 | like "safe_strcpy()". 6 | 7 | NOTE: This is for maintaining a policy of "no unsafe functions" 8 | */ 9 | #include "util-safefunc.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /** 16 | * Case-insensitive memcmp() 17 | */ 18 | #ifdef __GNUC__ 19 | int 20 | memcasecmp(const void *lhs, const void *rhs, size_t length) 21 | { 22 | int i; 23 | for (i=0; i= sizeof_dst) { 52 | dst[0] = 0; 53 | return; 54 | } else 55 | dst[i] = src[i]; 56 | } 57 | if (i >= sizeof_dst) { 58 | dst[0] = 0; 59 | return ; 60 | } else 61 | dst[i] = src[i]; 62 | 63 | return; 64 | } 65 | 66 | 67 | 68 | int 69 | safe_localtime(struct tm* _tm, const time_t *time) 70 | { 71 | struct tm *x; 72 | 73 | x = localtime(time); 74 | if (x == NULL) { 75 | memset(_tm, 0, sizeof(*_tm)); 76 | return -1; 77 | } 78 | memcpy(_tm, x, sizeof(*_tm)); 79 | 80 | return 0; 81 | } 82 | 83 | 84 | int 85 | safe_gmtime(struct tm* _tm, const time_t *time) 86 | { 87 | struct tm *x; 88 | 89 | x = gmtime(time); 90 | if (x == NULL) { 91 | memset(_tm, 0, sizeof(*_tm)); 92 | return -1; 93 | } 94 | memcpy(_tm, x, sizeof(*_tm)); 95 | 96 | return 0; 97 | } 98 | 99 | 100 | -------------------------------------------------------------------------------- /src/util-safefunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | safe "string" functions 3 | 4 | This is for the "safe" clib functions, where things like "strcpy()" is 5 | replaced with a safer version of the function, like "safe_strcpy()". 6 | 7 | NOTE: I tried to based these on Microosft's `..._s()` functions proposed 8 | in Annex K, but it's become too hard trying to deal with both my own 9 | version and existing versions. Therefore, I've changed this code to 10 | use names not used by others. 11 | 12 | Reference: 13 | http://msdn.microsoft.com/en-us/library/bb288454.aspx 14 | */ 15 | #ifndef UTIL_SAFEFUNC_H 16 | #define UTIL_SAFEFUNC_H 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef _MSC_VER 25 | #pragma warning(disable: 4996) 26 | #endif 27 | 28 | #undef strcpy 29 | #define strcpy STRCPY_FUNCTION_IS_BAD 30 | 31 | /*#undef strncpy 32 | #define strncpy STRNCPY_FUNCTION_IS_BAD*/ 33 | 34 | #undef strcat 35 | #define strcat STRCAT_FUNCTION_IS_BAD 36 | 37 | #undef strncat 38 | #define strncat STRNCAT_FUNCTION_IS_BAD 39 | 40 | #undef sprintf 41 | #define sprintf SPRINTF_FUNCTION_IS_BAD 42 | 43 | #undef vsprintf 44 | #define vsprintf VSPRINTF_FUNCTION_IS_BAD 45 | 46 | #undef strtok 47 | #define strtok STRTOK_FUNCTION_IS_BAD 48 | 49 | #undef gets 50 | #define gets GETS_FUNCTION_IS_BAD 51 | 52 | #undef scanf 53 | #define scanf SCANF_FUNCTION_IS_BAD 54 | 55 | #undef sscanf 56 | #define sscanf SSCANF_FUNCTION_IS_BAD 57 | 58 | #undef itoa 59 | #define itoa ITOA_FUNCTION_IS_BAD 60 | 61 | /** 62 | * A bounds checking version of strcpy, like `strcpy_s()` on Windows or 63 | * `strlcpy()` in glibc. 64 | */ 65 | void safe_strcpy(char *dst, size_t sizeof_dst, const char *src); 66 | int safe_localtime(struct tm* _tm, const time_t *time); 67 | int safe_gmtime(struct tm* _tm, const time_t *time); 68 | 69 | 70 | #if defined(_MSC_VER) && (_MSC_VER >= 1900) 71 | /*Visual Studio 2015 and 2017*/ 72 | # include 73 | # include 74 | # define strcasecmp _stricmp 75 | # define memcasecmp _memicmp 76 | # ifndef PRIu64 77 | # define PRIu64 "llu" 78 | # define PRId64 "lld" 79 | # define PRIx64 "llx" 80 | # endif 81 | 82 | #elif defined(_MSC_VER) && (_MSC_VER == 1600) 83 | /*Visual Studio 2010*/ 84 | # include 85 | # include 86 | #pragma warning(disable: 4996) 87 | #define snprintf _snprintf 88 | # define strcasecmp _stricmp 89 | # define memcasecmp _memicmp 90 | # ifndef PRIu64 91 | # define PRIu64 "llu" 92 | # define PRId64 "lld" 93 | # define PRIx64 "llx" 94 | # endif 95 | 96 | 97 | #elif defined(_MSC_VER) && (_MSC_VER == 1200) 98 | /* Visual Studio 6.0 */ 99 | # define snprintf _snprintf 100 | # define strcasecmp _stricmp 101 | # define memcasecmp _memicmp 102 | # define vsnprintf _vsnprintf 103 | 104 | #elif defined(__GNUC__) && (__GNUC__ >= 4) 105 | #include 106 | int memcasecmp(const void *lhs, const void *rhs, size_t length);; 107 | 108 | #else 109 | # warning unknown compiler 110 | #endif 111 | 112 | 113 | 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /src/vulncheck-heartbleed.c: -------------------------------------------------------------------------------- 1 | #include "proto-ssl.h" 2 | 3 | static const char 4 | ssl_hello_ticketbleed_templatex[] = 5 | "\x16\x03\x01\x01\x64\x01\x00\x01\x60\x03\x03\x13\xd4\xf7\xa8\xac" 6 | "\xdd\xc2\x20\xc5\xcc\xdb\xa4\x8d\xb3\xf3\xb5\xd3\x45\x1b\x53\x8d" 7 | "\x18\x70\xa2\xd9\x97\xaa\x63\xdd\xff\xdc\x68\x10\xff\x6f\xbf\xbc" 8 | "\x1b\xea\x36\x01\x56\x76\x24\x94\x2e\x30\x34\x81\x00\x1a\xc0\x2f" 9 | "\xc0\x2b\xc0\x11\xc0\x07\xc0\x13\xc0\x09\xc0\x14\xc0\x0a\x00\x05" 10 | "\x00\x2f\x00\x35\xc0\x12\x00\x0a\x01\x00\x01\x0d\x00\x00\x00\x15" 11 | "\x00\x13\x00\x00\x10\x77\x77\x77\x2e\x61\x6e\x63\x65\x73\x74\x72" 12 | "\x79\x2e\x63\x6f\x6d\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x0a" 13 | "\x00\x08\x00\x06\x00\x17\x00\x18\x00\x19\x00\x0b\x00\x02\x01\x00" 14 | "\x00\x23\x00\xc2\x58\x11\x74\xac\xcd\xf0\x07\xee\x52\x64\xcb\x41" 15 | "\xed\x72\xf7\x06\xaa\xc1\x1c\xf1\xa5\xf5\x63\x42\x3c\xea\x55\xb7" 16 | "\xde\xce\x8f\xec\x00\x00\x7e\x6e\xed\xf2\x28\x45\x1f\xcc\xc8\x08" 17 | "\x08\x2e\x23\x97\xda\x33\x7b\xaa\x53\x86\x95\x55\x58\xcf\x27\xce" 18 | "\x6a\x66\x81\xb8\xf8\x2f\x13\xa2\xc9\xcc\x9a\x93\x1b\x87\x57\x97" 19 | "\xe0\xec\x64\x96\x75\x01\x82\x79\x17\xe9\xb5\xa4\x5e\xba\xbe\xfe" 20 | "\xac\x86\x3c\xa4\x7c\xc3\x66\x16\x7e\x72\x86\xc5\xa9\x64\x3f\x0c" 21 | "\xd2\xae\xa0\xe6\xa1\xc0\x14\xdd\x8c\x41\x2c\xbd\xa9\x2a\xaa\x1c" 22 | "\x47\xa8\x5f\x3d\x26\xa8\xd8\x19\xa6\x2b\x3e\x1e\x85\x75\x0e\x73" 23 | "\x8e\xb1\x34\x15\x91\x2e\xeb\xb0\x24\x45\xb3\xc1\xa3\x27\x3d\xd6" 24 | "\x21\x3e\xad\xc8\x25\x4c\x75\x09\x95\x3c\x33\x3c\xc4\x35\xb8\xea" 25 | "\x17\x3a\x3b\x91\x9d\x60\x36\x70\x57\xe5\x62\x37\x27\xb2\x1a\xb5" 26 | "\xca\xf6\x4c\x8c\xb0\x07\x00\x0d\x00\x0a\x00\x08\x04\x01\x04\x03" 27 | "\x02\x01\x02\x03\xff\x01\x00\x01\x00"; 28 | 29 | const char * 30 | ssl_hello_ticketbleed_template = ssl_hello_ticketbleed_templatex; 31 | 32 | static const char 33 | ssl_hello_heartbeat_templatex[] = 34 | "\x16" /* type = handshake */ 35 | "\x03\x02" /* version = 3.2 (TLS/1.1) */ 36 | "\x00\xdc" /* length = 220 */ 37 | "\x01" /* type = client hello */ 38 | "\x00\x00\xd8" /* length = 216 */ 39 | "\x03\x02" /* version = 3.2 (TLS/1.1) */ 40 | "\x53\x43\x5b\x90" /* gm time = April 7 */ 41 | /*000F*/ "\x9d" 42 | /*0010*/ "\x9b\x72\x0b\xbc\x0c\xbc\x2b\x92\xa8\x48\x97\xcf\xbd\x39\x04\xcc" 43 | /*0020*/ "\x16\x0a\x85\x03\x90\x9f\x77\x04\x33\xd4\xde" 44 | 45 | "\x00" /* session id length = 0 */ 46 | /* session id */ 47 | "\x00\x66" /* cipher suites length = 102 */ 48 | /*002e*/ "\xc0\x14" 49 | /*0030*/ "\xc0\x0a\xc0\x22\xc0\x21\x00\x39\x00\x38\x00\x88\x00\x87\xc0\x0f" 50 | /*0040*/ "\xc0\x05\x00\x35\x00\x84\xc0\x12\xc0\x08\xc0\x1c\xc0\x1b\x00\x16" 51 | /*0050*/ "\x00\x13\xc0\x0d\xc0\x03\x00\x0a\xc0\x13\xc0\x09\xc0\x1f\xc0\x1e" 52 | /*0060*/ "\x00\x33\x00\x32\x00\x9a\x00\x99\x00\x45\x00\x44\xc0\x0e\xc0\x04" 53 | /*0070*/ "\x00\x2f\x00\x96\x00\x41\xc0\x11\xc0\x07\xc0\x0c\xc0\x02\x00\x05" 54 | /*0080*/ "\x00\x04\x00\x15\x00\x12\x00\x09\x00\x14\x00\x11\x00\x08\x00\x06" 55 | /*0090*/ "\x00\x03\x00\xff" 56 | "\x01" /* compression methods = 1 */ 57 | "\x00" /* nul compression */ 58 | "\x00\x49" /* extensions length */ 59 | "\x00\x0b\x00\x04\x03\x00\x01\x02" 60 | /*00a0*/ 61 | "\x00\x0a\x00\x34\x00\x32\x00\x0e\x00\x0d\x00\x19\x00\x0b\x00\x0c" 62 | /*00b0*/ "\x00\x18\x00\x09\x00\x0a\x00\x16\x00\x17\x00\x08\x00\x06\x00\x07" 63 | /*00c0*/ "\x00\x14\x00\x15\x00\x04\x00\x05\x00\x12\x00\x13\x00\x01\x00\x02" 64 | /*00d0*/ "\x00\x03\x00\x0f\x00\x10\x00\x11" 65 | "\x00\x23\x00\x00" 66 | "\x00\x0f\x00\x01\x01"; 67 | 68 | const char * 69 | ssl_hello_heartbeat_template = ssl_hello_heartbeat_templatex; 70 | 71 | -------------------------------------------------------------------------------- /src/vulncheck-ntp-monlist.c: -------------------------------------------------------------------------------- 1 | #include "vulncheck.h" 2 | #include "templ-pkt.h" 3 | #include "unusedparm.h" 4 | 5 | 6 | /***************************************************************************** 7 | *****************************************************************************/ 8 | static void 9 | set_target(struct TemplatePacket *tmpl, 10 | unsigned ip_them, unsigned port_them, 11 | unsigned ip_me, unsigned port_me, 12 | unsigned seqno, 13 | unsigned char *px, size_t sizeof_px, 14 | size_t *r_length) 15 | { 16 | unsigned offset_tcp = tmpl->ipv4.offset_tcp; 17 | unsigned offset_ip = tmpl->ipv4.offset_ip; 18 | unsigned offset_app = tmpl->ipv4.offset_app; 19 | unsigned tmpl_length= tmpl->ipv4.length; 20 | unsigned xsum; 21 | 22 | UNUSEDPARM(r_length); 23 | UNUSEDPARM(sizeof_px); 24 | UNUSEDPARM(seqno); 25 | UNUSEDPARM(ip_me); 26 | UNUSEDPARM(ip_them); 27 | 28 | px[offset_tcp+ 0] = (unsigned char)(port_me >> 8); 29 | px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF); 30 | px[offset_tcp+ 2] = (unsigned char)(port_them >> 8); 31 | px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF); 32 | px[offset_tcp+ 4] = (unsigned char)((tmpl_length - offset_app + 8)>>8); 33 | px[offset_tcp+ 5] = (unsigned char)((tmpl_length - offset_app + 8)&0xFF); 34 | 35 | px[offset_tcp+6] = (unsigned char)(0); 36 | px[offset_tcp+7] = (unsigned char)(0); 37 | xsum = udp_checksum2(px, offset_ip, offset_tcp, tmpl_length - offset_tcp); 38 | xsum = ~xsum; 39 | px[offset_tcp+6] = (unsigned char)(xsum >> 8); 40 | px[offset_tcp+7] = (unsigned char)(xsum >> 0); 41 | } 42 | 43 | /***************************************************************************** 44 | *****************************************************************************/ 45 | static unsigned char packet_template[] = 46 | "\0\1\2\3\4\5" /* Ethernet: destination */ 47 | "\6\7\x8\x9\xa\xb" /* Ethernet: source */ 48 | "\x08\x00" /* Ethernet type: IPv4 */ 49 | "\x45" /* IP type */ 50 | "\x00" 51 | "\x00\x4c" /* total length = 28 bytes */ 52 | "\x00\x00" /* identification */ 53 | "\x00\x00" /* fragmentation flags */ 54 | "\xFF\x11" /* TTL=255, proto=UDP */ 55 | "\xFF\xFF" /* checksum */ 56 | "\0\0\0\0" /* source address */ 57 | "\0\0\0\0" /* destination address */ 58 | 59 | "\xfe\xdc" /* source port */ 60 | "\x00\x00" /* destination port */ 61 | "\x00\x38" /* length */ 62 | "\x00\x00" /* checksum */ 63 | 64 | "\x17\x00\x03\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 65 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 66 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 67 | 68 | ; 69 | 70 | /***************************************************************************** 71 | *****************************************************************************/ 72 | struct MassVulnCheck vuln_ntp_monlist = { 73 | "ntp-monlist", /* name of this vuln, matches command-line name */ 74 | "U:123", /* default ports this vuln check should target */ 75 | packet_template, 76 | sizeof(packet_template)-1, 77 | set_target 78 | 79 | }; 80 | -------------------------------------------------------------------------------- /src/vulncheck-sslv3.c: -------------------------------------------------------------------------------- 1 | #include "proto-ssl.h" 2 | 3 | #define TLS_FALLBACK_SCSV 0x5600 4 | #define inappropriate_fallback 86 5 | 6 | static const char sslv3_hello[] = 7 | "\x16\x03\x00\x00\x43" 8 | "\x01\x00\x00\x3f\x03\x00" 9 | "\x00\x07\x06\x30" /* gmtime */ 10 | "\x16" 11 | "\x79\xa4\xc3\xf0\xa9\xbe\x26\xf5\x1c\x36\xad\xff\x65\x0b\x9e\x2a" 12 | "\x8e\xef\x58\x1c\x16\x44\x12\x35\x93\x36\xb9" 13 | "\x00" /* session id length = 0 */ 14 | "\x00\x18" /* cipher suites length = 24 */ 15 | "\x00\x39" 16 | "\x00\x38\x00\x35\x00\x33\x00\x32\x00\x04\x00\x05\x00\x2f\x00\x16" 17 | "\x00\x13\xfe\xff\x00\x0a\x01\x00"; 18 | 19 | const char * 20 | ssl_hello_sslv3_template = sslv3_hello; 21 | 22 | -------------------------------------------------------------------------------- /src/vulncheck.c: -------------------------------------------------------------------------------- 1 | #include "vulncheck.h" 2 | #include "util-safefunc.h" 3 | 4 | extern struct MassVulnCheck vuln_ntp_monlist; 5 | 6 | 7 | struct MassVulnCheck * 8 | vulncheck_lookup(const char *name) 9 | { 10 | if (strcmp(name, vuln_ntp_monlist.name) == 0) 11 | return &vuln_ntp_monlist; 12 | return 0; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/vulncheck.h: -------------------------------------------------------------------------------- 1 | #ifndef VULNCHECK_H 2 | #define VULNCHECK_H 3 | #include 4 | struct TemplatePacket; 5 | 6 | struct MassVulnCheck 7 | { 8 | const char *name; 9 | 10 | /** 11 | * A list of default port ranges that should be used in case that none 12 | * are specified. 13 | */ 14 | const char *ports; 15 | 16 | /** 17 | * The hello packet template 18 | */ 19 | const unsigned char *packet; 20 | 21 | /** 22 | * The hello packet template length 23 | */ 24 | unsigned packet_length; 25 | 26 | 27 | /** 28 | * Called to change the template based upon the target 29 | */ 30 | void (*set_target)(struct TemplatePacket *tmpl, 31 | unsigned ip_them, unsigned port_them, 32 | unsigned ip_me, unsigned port_me, 33 | unsigned seqno, 34 | unsigned char *px, size_t sizeof_px, 35 | size_t *r_length); 36 | 37 | /** 38 | * Called at startup to change the template according to options 39 | */ 40 | void (*init)(struct TemplatePacket *tmpl); 41 | }; 42 | 43 | /** 44 | * Lookup the vuln based on the name 45 | * @param name 46 | * The name of the vuln to check. 47 | * @return 48 | * The desired vuln check if found, NULL if the vuln check doesn't exist 49 | */ 50 | struct MassVulnCheck * 51 | vulncheck_lookup(const char *name); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/xring.h: -------------------------------------------------------------------------------- 1 | #ifndef XRING_H 2 | #define XRING_H 3 | 4 | 5 | int xring_selftest(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /tmp/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | 5 | -------------------------------------------------------------------------------- /vs10/.gitignore: -------------------------------------------------------------------------------- 1 | masscan.opensdf 2 | masscan.suo 3 | tmp/Debug 4 | tmp/Release 5 | masscan.sdf 6 | masscan.vcxproj.user 7 | tmp 8 | ipch 9 | 10 | -------------------------------------------------------------------------------- /vs10/masscan.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "masscan", "masscan.vcxproj", "{C88D7583-254F-4BE6-A9B9-89A5BB52E679}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|Win32.Build.0 = Debug|Win32 16 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|x64.ActiveCfg = Debug|x64 17 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Debug|x64.Build.0 = Debug|x64 18 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|Win32.ActiveCfg = Release|Win32 19 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|Win32.Build.0 = Release|Win32 20 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|x64.ActiveCfg = Release|x64 21 | {C88D7583-254F-4BE6-A9B9-89A5BB52E679}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /xcode4/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | -------------------------------------------------------------------------------- /xcode4/masscan.xcodeproj/.gitignore: -------------------------------------------------------------------------------- 1 | project.xcworkspace 2 | xcuserdata 3 | 4 | --------------------------------------------------------------------------------