├── CMakeLists.txt
├── LICENSE
├── README.md
├── bin
└── .gitignore
├── build.sh
├── data
├── afl-http.pcap
├── exclude.conf
└── flush_all.pcap
├── 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-blackrock2.c
├── event-timeout.c
├── event-timeout.h
├── in-binary.c
├── in-binary.h
├── in-filter.c
├── in-filter.h
├── in-report.c
├── in-report.h
├── logger.c
├── logger.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-interactive.c
├── proto-interactive.h
├── proto-memcached.c
├── proto-memcached.h
├── proto-minecraft.cpp
├── proto-minecraft.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-tcp.c
├── proto-tcp.h
├── proto-udp.c
├── proto-udp.h
├── proto-vnc.c
├── proto-vnc.h
├── proto-x509.c
├── proto-x509.h
├── proto-zeroaccess.c
├── proto-zeroaccess.h
├── rand-blackrock.c
├── rand-blackrock.h
├── rand-lcg.c
├── rand-lcg.h
├── rand-primegen.c
├── rand-primegen.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
├── siphash24.c
├── siphash24.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
├── string_s.c
├── string_s.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-payloads.c
├── templ-payloads.h
├── templ-pkt.c
├── templ-pkt.h
├── unusedparm.h
├── util-bool.h
├── util-checksum.c
├── util-checksum.h
├── util-malloc.c
├── util-malloc.h
├── versioning.c
├── versioning.h
├── vulncheck-heartbleed.c
├── vulncheck-ntp-monlist.c
├── vulncheck-sslv3.c
├── vulncheck.c
├── vulncheck.h
├── xring.c
└── xring.h
└── videlicet.db
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.18)
2 | project(masscan)
3 |
4 | set(CMAKE_C_COMPILER /usr/bin/clang)
5 | set(CMAKE_CXX_COMPILER /usr/bin/clang++)
6 |
7 | set(CMAKE_CXX_STANDARD 20)
8 |
9 | if(NOT CMAKE_BUILD_TYPE)
10 | set(CMAKE_BUILD_TYPE Release)
11 | endif()
12 |
13 | set(BASE_FLAGS "-g3 -Wall -fvisibility=hidden -fvisibility-inlines-hidden")
14 | set(DEBUG_FLAGS "-Og")
15 | set(RELEASE_FLAGS "-O3 -Ofast -funroll-loops -fno-signed-zeros -fno-trapping-math -march=native -mtune=native -flto=full")
16 |
17 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BASE_FLAGS}")
18 | set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEBUG_FLAGS}")
19 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} ${RELEASE_FLAGS}")
20 |
21 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_FLAGS} -Wextra -fno-rtti")
22 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_FLAGS}")
23 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${RELEASE_FLAGS} -fforce-emit-vtables -fstrict-vtable-pointers -fwhole-program-vtables")
24 |
25 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-v,--build-id=none,--exclude-libs,ALL,--icf=all,--gc-sections -fuse-ld=gold -lm -lrt -ldl -lpthread -lsqlite3")
26 |
27 | file(GLOB SRC CONFIGURE_DEPENDS "src/*.h" "src/*.cpp" "src/*.c")
28 |
29 | add_executable(${PROJECT_NAME} ${SRC})
30 | add_custom_command(
31 | TARGET ${PROJECT_NAME} POST_BUILD
32 | COMMAND ${CMAKE_OBJCOPY} ARGS --only-keep-debug ${PROJECT_NAME} ${PROJECT_NAME}.dbg
33 | COMMAND ${CMAKE_STRIP} ARGS --strip-all ${PROJECT_NAME}
34 | COMMAND ${CMAKE_OBJCOPY} ARGS --add-gnu-debuglink=${PROJECT_NAME}.dbg ${PROJECT_NAME}
35 | )
36 |
37 | find_package(SQLite3 REQUIRED)
38 | include_directories(${SQLite3_INCLUDE_DIRS})
39 | target_link_libraries(${PROJECT_NAME} ${SQLite3_LIBRARIES})
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Robert David Graham
2 |
3 | You can use, redistribute, and/or modify
4 | this code under the terms of the GNU Affero General Public License
5 | version 3.
6 |
7 | This program is distributed in the hope that it will be useful,
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 | GNU Affero General Public License for more details.
11 |
12 | You should have received a copy of the GNU Affero General Public License
13 | along with this program. If not, see .
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ServerScanner
2 | Based off of Masscan, and modified by Footsiefat.
3 |
4 | ### Advantages
5 | * Faster than Copenheimer
6 | * Made to be efficient, and no API calls.
7 | ^^ It only pings the minecraft server and writes it to the Database.
8 |
9 | ### Caveats
10 | * Writes to Sqlite Database synchronously, both are bad.
11 |
12 | Contributing makes a difference, thanks in advance.
13 |
--------------------------------------------------------------------------------
/bin/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | cd bin || exit
2 | cmake .. || cd .. || exit
3 | make || cd .. || exit
4 | cd .. || exit
--------------------------------------------------------------------------------
/data/afl-http.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/The-Ether-Project/ServerScanner/6a370de9c06aa8d59c23c11cb473e7e586ea263a/data/afl-http.pcap
--------------------------------------------------------------------------------
/data/flush_all.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/The-Ether-Project/ServerScanner/6a370de9c06aa8d59c23c11cb473e7e586ea263a/data/flush_all.pcap
--------------------------------------------------------------------------------
/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 tranmission 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 decidate 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 exlude 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/event-timeout.h:
--------------------------------------------------------------------------------
1 | #ifndef EVENT_TIMEOUT_H
2 | #define EVENT_TIMEOUT_H
3 | #include
4 | #include
5 | #include /* offsetof*/
6 | #if defined(_MSC_VER)
7 | #undef inline
8 | #define inline _inline
9 | #endif
10 | struct Timeouts;
11 |
12 |
13 |
14 |
15 | /***************************************************************************
16 | ***************************************************************************/
17 | struct TimeoutEntry {
18 | /**
19 | * In units of 1/16384 of a second. We use power-of-two units here
20 | * to make the "modulus" operation a simple binary "and".
21 | * See the TICKS_FROM_TV() macro for getting the timestamp from
22 | * the current time.
23 | */
24 | uint64_t timestamp;
25 |
26 | /** we build a doubly-linked list */
27 | struct TimeoutEntry *next;
28 | struct TimeoutEntry **prev;
29 |
30 | /** The timeout entry is never allocated by itself, but instead
31 | * lives inside another data structure. This stores the value of
32 | * 'offsetof()', so given a pointer to this structure, we can find
33 | * the original structure that contains it */
34 | unsigned offset;
35 | };
36 |
37 | /***************************************************************************
38 | ***************************************************************************/
39 | static inline void
40 | timeout_unlink(struct TimeoutEntry *entry)
41 | {
42 | if (entry->prev == 0 && entry->next == 0)
43 | return;
44 | *(entry->prev) = entry->next;
45 | if (entry->next)
46 | entry->next->prev = entry->prev;
47 | entry->next = 0;
48 | entry->prev = 0;
49 | entry->timestamp = 0;
50 | }
51 |
52 | /***************************************************************************
53 | ***************************************************************************/
54 | static inline void
55 | timeout_init(struct TimeoutEntry *entry)
56 | {
57 | entry->next = 0;
58 | entry->prev = 0;
59 | }
60 |
61 | /**
62 | * Create a timeout subsystem.
63 | * @param timestamp_now
64 | * The current timestamp indicating "now" when the thing starts.
65 | * This should be 'time(0) * TICKS_PER_SECOND'.
66 | */
67 | struct Timeouts *
68 | timeouts_create(uint64_t timestamp_now);
69 |
70 | /**
71 | * Insert the timeout 'entry' into the future location in the timeout
72 | * ring, as determined by the timestamp.
73 | * @param timeouts
74 | * A ring of timeouts, with each slot corresponding to a specific
75 | * time in the future.
76 | * @param entry
77 | * The entry that we are going to insert into the ring. If it's
78 | * already in the ring, it'll be removed from the old location
79 | * first before inserting into the new location.
80 | * @param offset
81 | * The 'entry' field above is part of an existing structure. This
82 | * tells the offset_of() from the beginning of that structure.
83 | * In other words, this tells us the pointer to the object that
84 | * that is the subject of the timeout.
85 | * @param timestamp_expires
86 | * When this timeout will expire. This is in terms of internal
87 | * ticks, which in units of TICKS_PER_SECOND.
88 | */
89 | void
90 | timeouts_add(struct Timeouts *timeouts, struct TimeoutEntry *entry,
91 | size_t offset, uint64_t timestamp_expires);
92 |
93 | /**
94 | * Remove an object from the timestamp system that is older than than
95 | * the specified timestamp. This function must be called repeatedly
96 | * until it returns NULL to remove all the objects that are older
97 | * than the given timestamp.
98 | * @param timeouts
99 | * A ring of timeouts. We'll walk the ring until we've caught
100 | * up with the current time.
101 | * @param timestamp_now
102 | * Usually, this timestmap will be "now", the current time,
103 | * and anything older than this will be aged out.
104 | * @return
105 | * an object older than the specified timestamp, or NULL
106 | * if there are no more objects to be found
107 | */
108 | void *
109 | timeouts_remove(struct Timeouts *timeouts, uint64_t timestamp_now);
110 |
111 | /*
112 | * This macros convert a normal "timeval" structure into the timestamp
113 | * that we use for timeouts. The timeval structure probably will come
114 | * from the packets that we are capturing.
115 | */
116 | #define TICKS_PER_SECOND (16384ULL)
117 | #define TICKS_FROM_SECS(secs) ((secs)*16384ULL)
118 | #define TICKS_FROM_USECS(usecs) ((usecs)/16384ULL)
119 | #define TICKS_FROM_TV(secs,usecs) (TICKS_FROM_SECS(secs)+TICKS_FROM_USECS(usecs))
120 |
121 | #endif
122 |
--------------------------------------------------------------------------------
/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 | read_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/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 "logger.h"
12 | #include "string_s.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 | vLOGip(int level, ipaddress ip, unsigned port, const char *fmt, va_list marker)
51 | {
52 | if (level <= global_debug_level) {
53 | char sz_ip[64];
54 | ipaddress_formatted_t fmt1 = ipaddress_fmt(ip);
55 |
56 | sprintf_s(sz_ip, sizeof(sz_ip), "%s", fmt1.string);
57 | fprintf(stderr, "%-15s:%5u: ", sz_ip, port);
58 | vfprintf(stderr, fmt, marker);
59 | fflush(stderr);
60 | }
61 | }
62 |
63 |
64 | /***************************************************************************
65 | ***************************************************************************/
66 | void
67 | LOGip(int level, ipaddress ip, unsigned port, const char *fmt, ...)
68 | {
69 | va_list marker;
70 |
71 | va_start(marker, fmt);
72 | vLOGip(level, ip, port, fmt, marker);
73 | va_end(marker);
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/src/logger.h:
--------------------------------------------------------------------------------
1 | #ifndef LOGGER_H
2 | #define 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 |
8 | void LOG_add_level(int level);
9 |
10 | #endif
11 |
--------------------------------------------------------------------------------
/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 "logger.h"
3 | #include "rand-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 "string_s.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 | sprintf_s(from, sizeof(from), "[%s]:%u", fmt.string, parsed.port_src);
39 |
40 | fmt = ipaddress_fmt(parsed.dst_ip);
41 | sprintf_s(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:strcpy_s(sz_type, sizeof(sz_type), "request"); break;
50 | case 2:strcpy_s(sz_type, sizeof(sz_type), "response"); break;
51 | default: sprintf_s(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: strcpy_s(sz_type, sizeof(sz_type), "NULL"); break;
69 | case 0x01: strcpy_s(sz_type, sizeof(sz_type), "FIN"); break;
70 | case 0x11: strcpy_s(sz_type, sizeof(sz_type), "FIN-ACK"); break;
71 | case 0x19: strcpy_s(sz_type, sizeof(sz_type), "FIN-ACK-PSH"); break;
72 | case 0x02: strcpy_s(sz_type, sizeof(sz_type), "SYN"); break;
73 | case 0x12: strcpy_s(sz_type, sizeof(sz_type), "SYN-ACK"); break;
74 | case 0x04: strcpy_s(sz_type, sizeof(sz_type), "RST"); break;
75 | case 0x14: strcpy_s(sz_type, sizeof(sz_type), "RST-ACK"); break;
76 | case 0x15: strcpy_s(sz_type, sizeof(sz_type), "RST-FIN-ACK"); break;
77 | case 0x10: strcpy_s(sz_type, sizeof(sz_type), "ACK"); break;
78 | case 0x18: strcpy_s(sz_type, sizeof(sz_type), "ACK-PSH"); break;
79 | default:
80 | sprintf_s(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 | struct Range range = list4->list[i];
59 | fprintf(fp, "%u.%u.%u.%u",
60 | (range.begin>>24)&0xFF,
61 | (range.begin>>16)&0xFF,
62 | (range.begin>> 8)&0xFF,
63 | (range.begin>> 0)&0xFF
64 | );
65 | if (range.begin != range.end) {
66 | unsigned cidr_bits = count_cidr_bits(range);
67 |
68 | if (cidr_bits) {
69 | fprintf(fp, "/%u", cidr_bits);
70 | } else {
71 | fprintf(fp, "-%u.%u.%u.%u",
72 | (range.end>>24)&0xFF,
73 | (range.end>>16)&0xFF,
74 | (range.end>> 8)&0xFF,
75 | (range.end>> 0)&0xFF
76 | );
77 | }
78 | }
79 | fprintf(fp, "\n");
80 | }
81 |
82 | for (i=0; icount; i++) {
83 | struct Range6 range = list6->list[i];
84 | ipaddress_formatted_t fmt = ipv6address_fmt(range.begin);
85 | fprintf(fp, "%s", fmt.string);
86 | if (!ipv6address_is_equal(range.begin, range.end)) {
87 | unsigned cidr_bits = count_cidr6_bits(range);
88 | if (cidr_bits) {
89 | fprintf(fp, "/%u", cidr_bits);
90 | } else {
91 | fmt = ipv6address_fmt(range.end);
92 | fprintf(fp, "-%s", fmt.string);
93 | }
94 | }
95 | fprintf(fp, "\n");
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/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.c:
--------------------------------------------------------------------------------
1 | #include "masscan-app.h"
2 | #include "string_s.h"
3 |
4 | /******************************************************************************
5 | * When outputting results, we call this function to print out the type of
6 | * banner that we've collected
7 | ******************************************************************************/
8 | const char *
9 | masscan_app_to_string(enum ApplicationProtocol proto)
10 | {
11 | static char tmp[64];
12 |
13 | switch (proto) {
14 | case PROTO_NONE: return "unknown";
15 | case PROTO_HEUR: return "unknown";
16 | case PROTO_SSH1: return "ssh";
17 | case PROTO_SSH2: return "ssh";
18 | case PROTO_HTTP: return "http";
19 | case PROTO_FTP: return "ftp";
20 | case PROTO_DNS_VERSIONBIND: return "dns-ver";
21 | case PROTO_SNMP: return "snmp";
22 | case PROTO_NBTSTAT: return "nbtstat";
23 | case PROTO_SSL3: return "ssl";
24 | case PROTO_SMB: return "smb";
25 | case PROTO_SMTP: return "smtp";
26 | case PROTO_POP3: return "pop";
27 | case PROTO_IMAP4: return "imap";
28 | case PROTO_UDP_ZEROACCESS: return "zeroaccess";
29 | case PROTO_X509_CERT: return "X509";
30 | case PROTO_HTML_TITLE: return "title";
31 | case PROTO_HTML_FULL: return "html";
32 | case PROTO_NTP: return "ntp";
33 | case PROTO_VULN: return "vuln";
34 | case PROTO_HEARTBLEED: return "heartbleed";
35 | case PROTO_TICKETBLEED: return "ticketbleed";
36 | case PROTO_VNC_RFB: return "vnc";
37 | case PROTO_SAFE: return "safe";
38 | case PROTO_MEMCACHED: return "memcached";
39 | case PROTO_SCRIPTING: return "scripting";
40 | case PROTO_VERSIONING: return "versioning";
41 | case PROTO_COAP: return "coap";
42 | case PROTO_TELNET: return "telnet";
43 | case PROTO_RDP: return "rdp";
44 | case PROTO_HTTP_SERVER: return "http.server";
45 | case PROTO_MINECRAFT: return "minecraft";
46 |
47 | default:
48 | sprintf_s(tmp, sizeof(tmp), "(%u)", proto);
49 | return tmp;
50 | }
51 | }
52 |
53 | /******************************************************************************
54 | ******************************************************************************/
55 | enum ApplicationProtocol
56 | masscan_string_to_app(const char *str)
57 | {
58 | const static struct {
59 | const char *name;
60 | enum ApplicationProtocol value;
61 | } list[] = {
62 | {"ssh1", PROTO_SSH1},
63 | {"ssh2", PROTO_SSH2},
64 | {"ssh", PROTO_SSH2},
65 | {"http", PROTO_HTTP},
66 | {"ftp", PROTO_FTP},
67 | {"dns-ver", PROTO_DNS_VERSIONBIND},
68 | {"snmp", PROTO_SNMP},
69 | {"ssh2", PROTO_SSH2},
70 | {"nbtstat", PROTO_NBTSTAT},
71 | {"ssl", PROTO_SSL3},
72 | {"smtp", PROTO_SMTP},
73 | {"smb", PROTO_SMB},
74 | {"pop", PROTO_POP3},
75 | {"imap", PROTO_IMAP4},
76 | {"x509", PROTO_X509_CERT},
77 | {"zeroaccess", PROTO_UDP_ZEROACCESS},
78 | {"title", PROTO_HTML_TITLE},
79 | {"html", PROTO_HTML_FULL},
80 | {"ntp", PROTO_NTP},
81 | {"vuln", PROTO_VULN},
82 | {"heartbleed", PROTO_HEARTBLEED},
83 | {"ticketbleed", PROTO_TICKETBLEED},
84 | {"vnc", PROTO_VNC_RFB},
85 | {"safe", PROTO_SAFE},
86 | {"memcached", PROTO_MEMCACHED},
87 | {"scripting", PROTO_SCRIPTING},
88 | {"versioning", PROTO_VERSIONING},
89 | {"coap", PROTO_COAP},
90 | {"telnet", PROTO_TELNET},
91 | {"rdp", PROTO_RDP},
92 | {"http.server", PROTO_HTTP_SERVER},
93 | {"minecraft", PROTO_MINECRAFT},
94 | {0,0}
95 | };
96 | size_t i;
97 |
98 | for (i=0; list[i].name; i++) {
99 | if (strcmp(str, list[i].name) == 0)
100 | return list[i].value;
101 | }
102 | return 0;
103 | }
104 |
--------------------------------------------------------------------------------
/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, /* simple network management protocol, udp/161 */
17 | PROTO_NBTSTAT, /* netbios, udp/137 */
18 | PROTO_SSL3,
19 | PROTO_SMB, /* SMB tcp/139 and tcp/445 */
20 | PROTO_SMTP,
21 | PROTO_POP3,
22 | PROTO_IMAP4,
23 | PROTO_UDP_ZEROACCESS,
24 | PROTO_X509_CERT,
25 | PROTO_HTML_TITLE,
26 | PROTO_HTML_FULL,
27 | PROTO_NTP, /* network time protocol, udp/123 */
28 | PROTO_VULN,
29 | PROTO_HEARTBLEED,
30 | PROTO_TICKETBLEED,
31 | PROTO_VNC_RFB,
32 | PROTO_SAFE,
33 | PROTO_MEMCACHED,
34 | PROTO_SCRIPTING,
35 | PROTO_VERSIONING,
36 | PROTO_COAP, /* constrained app proto, udp/5683, RFC7252 */
37 | PROTO_TELNET,
38 | PROTO_MINECRAFT,
39 | PROTO_RDP, /* Microsoft Remote Desktop Protocol tcp/3389 */
40 | PROTO_HTTP_SERVER, /* HTTP "Server:" field */
41 |
42 | PROTO_end_of_list /* must be last one */
43 | };
44 |
45 | const char *
46 | masscan_app_to_string(enum ApplicationProtocol proto);
47 |
48 | enum ApplicationProtocol
49 | masscan_string_to_app(const char *str);
50 |
51 | #endif
52 |
--------------------------------------------------------------------------------
/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.2"
4 |
5 | #endif
6 |
7 |
--------------------------------------------------------------------------------
/src/massip-addr.h:
--------------------------------------------------------------------------------
1 | /*
2 | Simple module for handling addresses (IPv6, IPv4, MAC).
3 | Also implements a 128-bit type for dealing with addresses.
4 |
5 | This is the module that almost all the other code depends
6 | upon, because everything else deals with the IP address
7 | types defined here.
8 |
9 | */
10 | #ifndef MASSIP_ADDR_H
11 | #define MASSIP_ADDR_H
12 | #include
13 | #include
14 |
15 | #if defined(_MSC_VER) && !defined(inline)
16 | #define inline __inline
17 | #endif
18 | #if defined(_MSC_VER)
19 | #pragma warning(disable: 4201)
20 | #endif
21 |
22 | /**
23 | * An IPv6 address is represented as two 64-bit integers instead of a single
24 | * 128-bit integer. This is because currently (year 2020) most compilers
25 | * do not support the `uint128_t` type, but all relevant ones do support
26 | * the `uint64_t` type.
27 | */
28 | struct ipv6address {uint64_t hi; uint64_t lo;};
29 | typedef struct ipv6address ipv6address;
30 | typedef struct ipv6address ipv6address_t;
31 |
32 | /**
33 | * IPv4 addresses are represented simply with an integer.
34 | */
35 | typedef unsigned ipv4address;
36 | typedef ipv4address ipv4address_t;
37 |
38 | /**
39 | * MAC address (layer 2). Since we have canonical types for IPv4/IPv6
40 | * addresses, we may as well have a canonical type for MAC addresses,
41 | * too.
42 | */
43 | struct macaddress_t {unsigned char addr[6];};
44 | typedef struct macaddress_t macaddress_t;
45 |
46 | /**
47 | * In many cases we need to do arithmetic on IPv6 addresses, treating
48 | * them as a large 128-bit integer. Thus, we declare our own 128-bit
49 | * integer type (and some accompanying math functions). But it's
50 | * still just the same as a 128-bit integer.
51 | */
52 | typedef ipv6address massint128_t;
53 |
54 |
55 | /**
56 | * Most of the code in this project is agnostic to the version of IP
57 | * addresses (IPv4 or IPv6). Therefore, we represent them as a union
58 | * distinguished by a version number. The `version` is an integer
59 | * with a value of either 4 or 6.
60 | */
61 | struct ipaddress {
62 | union {
63 | unsigned ipv4;
64 | ipv6address ipv6;
65 | };
66 | unsigned char version;
67 | };
68 | typedef struct ipaddress ipaddress;
69 |
70 | static inline int ipv6address_is_zero(ipv6address_t a) {
71 | return a.hi == 0 && a.lo == 0;
72 | }
73 | #define massint128_is_zero ipv6address_is_zero
74 |
75 | static inline int ipv6address_is_invalid(ipv6address_t a) {
76 | return a.hi == ~0ULL && a.lo == ~0ULL;
77 | }
78 | static inline int ipv6address_is_equal(ipv6address_t a, ipv6address_t b) {
79 | return a.hi == b.hi && a.lo == b.lo;
80 | }
81 | static inline int ipv6address_is_lessthan(ipv6address_t a, ipv6address_t b) {
82 | return (a.hi == b.hi)?(a.lo < b.lo):(a.hi < b.hi);
83 | }
84 |
85 | int ipv6address_is_equal_prefixed(ipv6address_t lhs, ipv6address_t rhs, unsigned prefix);
86 |
87 |
88 | static inline ipv6address ipv6address_from_bytes(const unsigned char *buf) {
89 | ipv6address addr;
90 | addr.hi = (uint64_t)buf[ 0] << 56
91 | | (uint64_t)buf[ 1] << 48
92 | | (uint64_t)buf[ 2] << 40
93 | | (uint64_t)buf[ 3] << 32
94 | | (uint64_t)buf[ 4] << 24
95 | | (uint64_t)buf[ 5] << 16
96 | | (uint64_t)buf[ 6] << 8
97 | | (uint64_t)buf[ 7] << 0;
98 | addr.lo = (uint64_t)buf[ 8] << 56
99 | | (uint64_t)buf[ 9] << 48
100 | | (uint64_t)buf[10] << 40
101 | | (uint64_t)buf[11] << 32
102 | | (uint64_t)buf[12] << 24
103 | | (uint64_t)buf[13] << 16
104 | | (uint64_t)buf[14] << 8
105 | | (uint64_t)buf[15] << 0;
106 | return addr;
107 | }
108 | static inline macaddress_t macaddress_from_bytes(const void *vbuf)
109 | {
110 | const unsigned char *buf = (const unsigned char *)vbuf;
111 | macaddress_t result;
112 | result.addr[0] = buf[0];
113 | result.addr[1] = buf[1];
114 | result.addr[2] = buf[2];
115 | result.addr[3] = buf[3];
116 | result.addr[4] = buf[4];
117 | result.addr[5] = buf[5];
118 | return result;
119 | }
120 | static inline int macaddress_is_zero(macaddress_t mac)
121 | {
122 | return mac.addr[0] == 0
123 | && mac.addr[1] == 0
124 | && mac.addr[2] == 0
125 | && mac.addr[3] == 0
126 | && mac.addr[4] == 0
127 | && mac.addr[5] == 0;
128 | }
129 | static inline int macaddress_is_equal(macaddress_t lhs, macaddress_t rhs)
130 | {
131 | return lhs.addr[0] == rhs.addr[0]
132 | && lhs.addr[1] == rhs.addr[1]
133 | && lhs.addr[2] == rhs.addr[2]
134 | && lhs.addr[3] == rhs.addr[3]
135 | && lhs.addr[4] == rhs.addr[4]
136 | && lhs.addr[5] == rhs.addr[5];
137 | }
138 |
139 | /**
140 | * Return a buffer with the formatted address
141 | */
142 | typedef struct ipaddress_formatted {
143 | char string[48];
144 | } ipaddress_formatted_t;
145 |
146 | struct ipaddress_formatted ipv6address_fmt(ipv6address a);
147 | struct ipaddress_formatted ipv4address_fmt(ipv4address a);
148 | struct ipaddress_formatted ipaddress_fmt(ipaddress a);
149 | struct ipaddress_formatted macaddress_fmt(macaddress_t a);
150 |
151 | unsigned massint128_bitcount(massint128_t num);
152 |
153 | /**
154 | * @return 0 on success, 1 on failure
155 | */
156 | int ipv6address_selftest(void);
157 |
158 | #endif
159 |
--------------------------------------------------------------------------------
/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 "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 "string_s.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[2] = "\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[4096];
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/out-xml.c:
--------------------------------------------------------------------------------
1 | #include "output.h"
2 | #include "masscan-app.h"
3 | #include "masscan-status.h"
4 | #include "string_s.h"
5 |
6 |
7 |
8 | /****************************************************************************
9 | ****************************************************************************/
10 | static void
11 | xml_out_open(struct Output *out, FILE *fp)
12 | {
13 | //const struct Masscan *masscan = out->masscan;
14 |
15 | fprintf(fp, "\r\n");
16 | fprintf(fp, "\r\n");
17 | if (out->xml.stylesheet && out->xml.stylesheet[0]) {
18 | fprintf(fp, "\r\n",
19 | out->xml.stylesheet);
20 | }
21 | fprintf(fp, "\r\n",
22 | "masscan",
23 | (unsigned)time(0),
24 | "1.0-BETA",
25 | "1.03" /* xml output version I copied from their site */
26 | );
27 | fprintf(fp, "\r\n",
28 | "syn", "tcp" );
29 | }
30 |
31 |
32 | /****************************************************************************
33 | ****************************************************************************/
34 | static void
35 | xml_out_close(struct Output *out, FILE *fp)
36 | {
37 | char buffer[256];
38 | time_t now = time(0);
39 | struct tm tm;
40 |
41 | if (out->is_gmt)
42 | gmtime_s(&tm, &now);
43 | else
44 | localtime_s(&tm, &now);
45 | strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
46 |
47 | fprintf(fp,
48 | "\r\n"
49 | "\r\n"
50 | "\r\n"
51 | "\r\n"
52 | "\r\n",
53 | (unsigned)now, /* time */
54 | buffer, /* timestr */
55 | (unsigned)(now - out->rotate.last), /* elapsed */
56 | out->counts.tcp.open,
57 | out->counts.tcp.closed,
58 | out->counts.tcp.open + out->counts.tcp.closed
59 | );
60 |
61 | }
62 |
63 | /****************************************************************************
64 | ****************************************************************************/
65 | static void
66 | xml_out_status(struct Output *out, FILE *fp, time_t timestamp, int status,
67 | ipaddress ip, unsigned ip_proto, unsigned port, unsigned reason, unsigned ttl)
68 | {
69 | char reason_buffer[128];
70 | ipaddress_formatted_t fmt = ipaddress_fmt(ip);
71 |
72 | UNUSEDPARM(out);
73 | fprintf(fp, ""
74 | ""
75 | ""
76 | ""
77 | ""
78 | ""
79 | ""
80 | ""
81 | "\r\n",
82 | (unsigned)timestamp,
83 | fmt.string,
84 | name_from_ip_proto(ip_proto),
85 | port,
86 | status_string(status),
87 | reason_string(reason, reason_buffer, sizeof(reason_buffer)),
88 | ttl
89 | );
90 | }
91 |
92 | /****************************************************************************
93 | ****************************************************************************/
94 | static void
95 | xml_out_banner(struct Output *out, FILE *fp, time_t timestamp,
96 | ipaddress ip, unsigned ip_proto, unsigned port,
97 | enum ApplicationProtocol proto,
98 | unsigned ttl,
99 | const unsigned char *px, unsigned length)
100 | {
101 | char banner_buffer[4096];
102 | const char *reason;
103 | ipaddress_formatted_t fmt = ipaddress_fmt(ip);
104 |
105 | switch (proto) {
106 | case 6: reason = "syn-ack"; break;
107 | default: reason = "response"; break;
108 | }
109 |
110 | UNUSEDPARM(out);
111 |
112 | fprintf(fp, ""
113 | ""
114 | ""
115 | ""
116 | ""
117 | ""
118 | ""
119 | ""
120 | ""
121 | "\r\n",
122 | (unsigned)timestamp,
123 | fmt.string,
124 | name_from_ip_proto(ip_proto),
125 | port,
126 | reason, ttl,
127 | masscan_app_to_string(proto),
128 | normalize_string(px, length, banner_buffer, sizeof(banner_buffer))
129 | );
130 | }
131 |
132 | /****************************************************************************
133 | ****************************************************************************/
134 | const struct OutputType xml_output = {
135 | "xml",
136 | 0,
137 | xml_out_open,
138 | xml_out_close,
139 | xml_out_status,
140 | xml_out_banner
141 | };
142 |
143 |
--------------------------------------------------------------------------------
/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 "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 | /**
63 | * Append a single character to the banner.
64 | */
65 | void
66 | banout_append_char(struct BannerOutput *banout, unsigned proto, int c);
67 |
68 | /**
69 | * Append an integer, with hex digits, with the specified number of
70 | * digits
71 | */
72 | void
73 | banout_append_hexint(struct BannerOutput *banout, unsigned proto, unsigned long long number, int digits);
74 |
75 | void
76 | banout_append_unicode(struct BannerOutput *banout, unsigned proto, unsigned c);
77 |
78 | /**
79 | * Select a specific string (of the specified protocol).
80 | * The "banner output" can have multiple protocol objects associated
81 | * with it, such as an SSL protocol object and an X.509 certificate.
82 | * Thus, instead of just grabbing the string, we need to grab the
83 | * specific protocol instead.
84 | */
85 | const unsigned char *
86 | banout_string(const struct BannerOutput *banout, unsigned proto);
87 |
88 | /**
89 | * Get the length of a specific string of the specified protocol.
90 | * This is the matching function to banout_string.
91 | */
92 | unsigned
93 | banout_string_length(const struct BannerOutput *banout, unsigned proto);
94 |
95 |
96 | /**
97 | * Prepare to start calling banout_append_base64()
98 | */
99 | void
100 | banout_init_base64(struct BannerBase64 *base64);
101 |
102 | /**
103 | * Converts the string to BASE64 and appends it to the banner.
104 | * Since this can be called iteratively as new input arrives,
105 | * a call to banout_init_base64() must be called before the first fragment,
106 | * and a call to banout_finalize_base64() must be called after the last
107 | * fragment
108 | */
109 | void
110 | banout_append_base64(struct BannerOutput *banout, unsigned proto,
111 | const void *px, size_t length,
112 | struct BannerBase64 *base64);
113 |
114 | /**
115 | * Finish encoding the BASE64 string, appending the '==' things on the
116 | * end if necessary
117 | */
118 | void
119 | banout_finalize_base64(struct BannerOutput *banout, unsigned proto,
120 | struct BannerBase64 *base64);
121 |
122 | /**
123 | * Compares a banner string to a fixed string. This is primarily used
124 | * in the "self-test" feature in order to compare parsed banners from
125 | * expected banners.
126 | */
127 | unsigned
128 | banout_is_equal(const struct BannerOutput *banout, unsigned proto,
129 | const char *string);
130 |
131 | unsigned
132 | banout_is_contains(const struct BannerOutput *banout, unsigned proto,
133 | const char *string);
134 |
135 | /**
136 | * Do the typical unit/regression test, for this module.
137 | */
138 | int
139 | banout_selftest(void);
140 |
141 | #endif
142 |
--------------------------------------------------------------------------------
/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-interactive.c:
--------------------------------------------------------------------------------
1 | #include "proto-interactive.h"
2 | #include "unusedparm.h"
3 | #include "util-malloc.h"
4 | #include
5 |
6 | /*
7 | * TODO: we need to track the memory used for this better than with malloc(), such
8 | * as using a preallocated array of packet buffers. But for now, I'm just using
9 | * malloc() 'cause I'm a lazy programmer.
10 | */
11 | unsigned char *
12 | tcp_transmit_alloc(struct InteractiveData *more, size_t length)
13 | {
14 | /* Note using this parameter yet, but in the future, we are going to have
15 | * memory pools instead of heap malloc(), which will use this parameter */
16 | UNUSEDPARM(more);
17 |
18 | return MALLOC(length);
19 | }
20 |
21 | void
22 | tcp_close(struct InteractiveData *more)
23 | {
24 | if (more == NULL)
25 | return;
26 | more->is_closing = 1;
27 | }
28 |
29 | /*
30 | * This doesn't actually transmit right now. Instead, marks the payload as ready
31 | * to transmit, which will be transmitted later
32 | */
33 | void
34 | tcp_transmit(struct InteractiveData *more, const void *payload, size_t length, unsigned flags)
35 | {
36 | more->m_payload = payload;
37 | more->m_length = (unsigned)length;
38 |
39 | if (flags & TCPTRAN_DYNAMIC)
40 | more->is_payload_dynamic = 1;
41 | }
42 |
--------------------------------------------------------------------------------
/src/proto-interactive.h:
--------------------------------------------------------------------------------
1 | #ifndef PROTO_INTERACTIVE_H
2 | #define PROTO_INTERACTIVE_H
3 | #include
4 |
5 | struct InteractiveData {
6 | const void *m_payload;
7 | unsigned m_length;
8 | unsigned is_payload_dynamic:1;
9 | unsigned is_closing:1;
10 | };
11 | enum {
12 | TCPTRAN_DYNAMIC = 0x0001,
13 | };
14 |
15 | /**
16 | * Called to 'transmit' TCP packet payload.
17 | */
18 | void
19 | tcp_transmit(struct InteractiveData *more, const void *data, size_t length, unsigned flags);
20 |
21 | /**
22 | * Called to close the connection
23 | */
24 | void
25 | tcp_close(struct InteractiveData *more);
26 |
27 | /**
28 | * Called to allocate a TCP buffer.
29 | */
30 | unsigned char *
31 | tcp_transmit_alloc(struct InteractiveData *more, size_t length);
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/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-minecraft.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include "massip-addr.c"
11 |
12 | extern "C"
13 | {
14 | void banout_end(struct BannerOutput *banout, unsigned proto);
15 | void banout_append_unicode(struct BannerOutput *banout, unsigned proto, unsigned c);
16 | void banout_append(struct BannerOutput *banout, unsigned proto, const void *px, size_t length);
17 | void tcp_close(struct InteractiveData *more);
18 | }
19 |
20 | #include "proto-minecraft.h"
21 | #include "proto-interactive.h"
22 |
23 | #define MC_PROTO_MAX_PACKET_SIZE 1024
24 |
25 | uint64_t timeSinceEpochMillisec()
26 | {
27 | using namespace std::chrono;
28 | return duration_cast(system_clock::now().time_since_epoch()).count();
29 | }
30 |
31 | static void minecraft_parse([[maybe_unused]] const struct Banner1 *banner1,
32 | [[maybe_unused]] void *banner1_private,
33 | [[maybe_unused]] struct ProtocolState *pstate,
34 | const unsigned char *px, size_t length,
35 | struct BannerOutput *banout,
36 | struct InteractiveData *more,
37 | ipaddress ip_them,
38 | unsigned short port_them)
39 | {
40 | if (length > MC_PROTO_MAX_PACKET_SIZE)
41 | {
42 | tcp_close(more);
43 | return;
44 | }
45 |
46 | std::string read_data;
47 | for (size_t i = 0; i < length; i++)
48 | {
49 | read_data.append(reinterpret_cast(&px[i]), 1);
50 | }
51 | std::vector process_string;
52 | std::string temp_data;
53 | for (size_t t = 8; t < read_data.size(); t += 2)
54 | {
55 | char &i = read_data[t];
56 | char &i2 = read_data[t - 2];
57 | if ((int)i > 0 && i2 != '\xa7')
58 | {
59 | temp_data += read_data[t];
60 | }
61 | else if ((int)i == 0 && t != 8)
62 | {
63 | process_string.push_back(temp_data);
64 | temp_data = "";
65 | }
66 | }
67 | if (!temp_data.empty())
68 | {
69 | process_string.push_back(temp_data);
70 | }
71 | if (process_string.size() >= 4)
72 | {
73 | sqlite3 *db;
74 | int rc;
75 |
76 | /* Open database */
77 | rc = sqlite3_open("videlicet.db", &db);
78 |
79 | if (rc)
80 | {
81 | fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
82 | }
83 |
84 | std::string serverVersion = process_string[1];
85 | std::string motd = process_string[2];
86 | int playerCount = -1;
87 | int maxPlayers = -1;
88 |
89 | try
90 | {
91 | playerCount = stoi(process_string[3]);
92 | maxPlayers = stoi(process_string[4]);
93 | }
94 | catch (const std::invalid_argument)
95 | {
96 | // FAILED TO CONVERT PLAYER COUNT TO INT
97 | }
98 |
99 | struct ipaddress_formatted fmt;
100 | fmt = ipaddress_fmt(ip_them);
101 |
102 | std::string mainString;
103 | mainString = "INSERT INTO BASIC_PINGS (TIMESTAMP,IP,PORT,VERSION,MOTD,PLAYERS_ONLINE,MAX_PLAYERS) VALUES (?,?,?,?,?,?,?)";
104 |
105 | sqlite3_stmt *statement;
106 | sqlite3_prepare_v2(db, mainString.c_str(), -1, &statement, NULL);
107 |
108 | sqlite3_bind_int64(statement, 1, timeSinceEpochMillisec());
109 | sqlite3_bind_text(statement, 2, fmt.string, sizeof(fmt), SQLITE_TRANSIENT);
110 | sqlite3_bind_int(statement, 3, port_them);
111 | sqlite3_bind_text(statement, 4, serverVersion.c_str(), serverVersion.size(), SQLITE_TRANSIENT);
112 | sqlite3_bind_text(statement, 5, motd.c_str(), motd.size(), SQLITE_TRANSIENT);
113 | sqlite3_bind_int(statement, 6, playerCount);
114 | sqlite3_bind_int(statement, 7, maxPlayers);
115 |
116 | sqlite3_step(statement);
117 | sqlite3_finalize(statement);
118 | sqlite3_close(db);
119 | }
120 | else
121 | {
122 | banout_append(banout, PROTO_MINECRAFT, "PARSING ERROR:", AUTO_LEN);
123 | banout_append(banout, PROTO_MINECRAFT, px, length);
124 | }
125 | banout_end(banout, PROTO_MINECRAFT);
126 | tcp_close(more);
127 | }
128 |
129 | static void *minecraft_init([[maybe_unused]] struct Banner1 *banner1)
130 | {
131 | return nullptr;
132 | }
133 |
134 | static int minecraft_selftest()
135 | {
136 | return 0;
137 | }
138 |
139 | const struct ProtocolParserStream banner_minecraft = {
140 | "minecraft", 25565, "\xFE\x01", 2, 0,
141 | minecraft_selftest,
142 | minecraft_init,
143 | minecraft_parse,
144 | nullptr,
145 | nullptr,
146 | nullptr};
147 |
--------------------------------------------------------------------------------
/src/proto-minecraft.h:
--------------------------------------------------------------------------------
1 | #ifndef PROTO_MINECRAFT_H
2 | #define PROTO_MINECRAFT_H
3 | #include "proto-banner1.h"
4 |
5 | extern const struct ProtocolParserStream banner_minecraft;
6 |
7 | #endif
--------------------------------------------------------------------------------
/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.c:
--------------------------------------------------------------------------------
1 | #include "proto-ssh.h"
2 | #include "proto-banner1.h"
3 | #include "unusedparm.h"
4 | #include "masscan-app.h"
5 | #include "proto-interactive.h"
6 | #include
7 |
8 |
9 | /***************************************************************************
10 | ***************************************************************************/
11 | static void
12 | ssh_parse( const struct Banner1 *banner1,
13 | void *banner1_private,
14 | struct ProtocolState *pstate,
15 | const unsigned char *px, size_t length,
16 | struct BannerOutput *banout,
17 | struct InteractiveData *more)
18 | {
19 | unsigned state = pstate->state;
20 | unsigned i;
21 |
22 | UNUSEDPARM(banner1_private);
23 | UNUSEDPARM(banner1);
24 | UNUSEDPARM(more);
25 |
26 | for (i=0; istate = state;
43 | }
44 |
45 | /***************************************************************************
46 | ***************************************************************************/
47 | static void *
48 | ssh_init(struct Banner1 *banner1)
49 | {
50 | UNUSEDPARM(banner1);
51 | return 0;
52 | }
53 |
54 |
55 | /***************************************************************************
56 | ***************************************************************************/
57 | static int
58 | ssh_selftest(void)
59 | {
60 | return 0;
61 | }
62 |
63 | /***************************************************************************
64 | ***************************************************************************/
65 | const struct ProtocolParserStream banner_ssh = {
66 | "ssh", 22, 0, 0, 0,
67 | ssh_selftest,
68 | ssh_init,
69 | ssh_parse,
70 | };
71 |
--------------------------------------------------------------------------------
/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 |
7 | extern const char *ssl_hello_heartbeat_template;
8 | extern const char *ssl_hello_ticketbleed_template;
9 | extern const char *ssl_hello_sslv3_template;
10 |
11 | /**
12 | * Parse the SSL Hello template to find its size
13 | */
14 | unsigned ssl_hello_size(const void *templ);
15 |
16 | /**
17 | * Allocate memory and make a copy of the template, so that we can
18 | * rewrite some fields, such as setting the correct timestamp
19 | */
20 | char *ssl_hello(const void *templ);
21 |
22 | /**
23 | * Add a cipher-spec.
24 | * There are many possible uses for this, but for now it's used for the POODLE
25 | * bug, appending TLS_FALLBACK_SCSV to the list. It may need to reallocate
26 | * the template.
27 | */
28 | char *ssl_add_cipherspec(void *templ, unsigned cipher_spec, unsigned is_append);
29 |
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/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.c:
--------------------------------------------------------------------------------
1 | #include "proto-udp.h"
2 | #include "proto-coap.h"
3 | #include "proto-dns.h"
4 | #include "proto-netbios.h"
5 | #include "proto-snmp.h"
6 | #include "proto-memcached.h"
7 | #include "proto-ntp.h"
8 | #include "proto-zeroaccess.h"
9 | #include "proto-preprocess.h"
10 | #include "syn-cookie.h"
11 | #include "logger.h"
12 | #include "output.h"
13 | #include "masscan-status.h"
14 | #include "unusedparm.h"
15 |
16 |
17 | /****************************************************************************
18 | * When the "--banner" command-line option is selected, this will
19 | * will take up to 64 bytes of a response and display it. Other UDP
20 | * protocol parsers may also default to this function when they detect
21 | * a response is not the protocol they expect. For example, if a response
22 | * to port 161 obviously isn't ASN.1 formatted, the SNMP parser will
23 | * call this function instead. In such cases, the protocool identifier will
24 | * be [unknown] rather than [snmp].
25 | ****************************************************************************/
26 | unsigned
27 | default_udp_parse(struct Output *out, time_t timestamp,
28 | const unsigned char *px, unsigned length,
29 | struct PreprocessedInfo *parsed,
30 | uint64_t entropy)
31 | {
32 | ipaddress ip_them = parsed->src_ip;
33 | unsigned port_them = parsed->port_src;
34 |
35 | UNUSEDPARM(entropy);
36 |
37 |
38 | if (length > 64)
39 | length = 64;
40 |
41 | output_report_banner(
42 | out, timestamp,
43 | ip_them, 17, port_them,
44 | PROTO_NONE,
45 | parsed->ip_ttl,
46 | px, length);
47 |
48 | return 0;
49 | }
50 |
51 | /****************************************************************************
52 | ****************************************************************************/
53 | void
54 | handle_udp(struct Output *out, time_t timestamp,
55 | const unsigned char *px, unsigned length,
56 | struct PreprocessedInfo *parsed, uint64_t entropy)
57 | {
58 | ipaddress ip_them = parsed->src_ip;
59 | unsigned port_them = parsed->port_src;
60 | unsigned status = 0;
61 |
62 |
63 | switch (port_them) {
64 | case 53: /* DNS - Domain Name System (amplifier) */
65 | status = handle_dns(out, timestamp, px, length, parsed, entropy);
66 | break;
67 | case 123: /* NTP - Network Time Protocol (amplifier) */
68 | status = ntp_handle_response(out, timestamp, px, length, parsed, entropy);
69 | break;
70 | case 137: /* NetBIOS (amplifier) */
71 | status = handle_nbtstat(out, timestamp, px, length, parsed, entropy);
72 | break;
73 | case 161: /* SNMP - Simple Network Managment Protocol (amplifier) */
74 | status = handle_snmp(out, timestamp, px, length, parsed, entropy);
75 | break;
76 | case 5683:
77 | status = coap_handle_response(out, timestamp, px + parsed->app_offset, parsed->app_length, parsed, entropy);
78 | break;
79 | case 11211: /* memcached (amplifier) */
80 | px += parsed->app_offset;
81 | length = parsed->app_length;
82 | status = memcached_udp_parse(out, timestamp, px, length, parsed, entropy);
83 | break;
84 | case 16464:
85 | case 16465:
86 | case 16470:
87 | case 16471:
88 | status = handle_zeroaccess(out, timestamp, px, length, parsed, entropy);
89 | break;
90 | default:
91 | px += parsed->app_offset;
92 | length = parsed->app_length;
93 | status = default_udp_parse(out, timestamp, px, length, parsed, entropy);
94 | break;
95 | }
96 |
97 | if (status == 0)
98 | output_report_status(
99 | out,
100 | timestamp,
101 | PortStatus_Open,
102 | ip_them,
103 | 17, /* ip proto = udp */
104 | port_them,
105 | 0,
106 | 0,
107 | parsed->mac_src);
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/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-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/rand-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/rand-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/rand-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/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 "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/siphash24.h:
--------------------------------------------------------------------------------
1 | #ifndef SIPHASH24_H
2 | #define 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/smack.h:
--------------------------------------------------------------------------------
1 | #ifndef _SMACK_H
2 | #define _SMACK_H
3 | #include
4 |
5 | #define SMACK_NOT_FOUND ((size_t)(~0))
6 |
7 | /**
8 | * "Anchor" flags are specified only for patterns that must
9 | * match at the start of input, at the end, or both.
10 | * These are equivalent to the regex specifiers "^" and "$"
11 | * respectively.
12 | */
13 | enum {
14 | SMACK_ANCHOR_BEGIN = 0x01,
15 | SMACK_ANCHOR_END = 0x02,
16 | SMACK_SNMP_HACK = 0x04,
17 | SMACK_WILDCARDS = 0x08,
18 | };
19 |
20 | enum {
21 | SMACK_CASE_SENSITIVE = 0,
22 | SMACK_CASE_INSENSITIVE = 1,
23 | };
24 |
25 |
26 | /**
27 | * This is the function that will be called whenever SMACK
28 | * finds a pattern.
29 | */
30 | typedef int (*FOUND_CALLBACK)(size_t id, int offset, void *data);
31 |
32 |
33 | /**
34 | * Create the Aho-Corasick search object. After creation, you can start
35 | * adding patterns, but you cannot use it for searching until you've
36 | * compiled the patterns.
37 | */
38 | struct SMACK *
39 | smack_create(const char *name, unsigned nocase);
40 |
41 |
42 | /**
43 | * Cleans up and frees an object created with smack_create().
44 | */
45 | void
46 | smack_destroy(struct SMACK *smack);
47 |
48 |
49 | /**
50 | * Registers a pattern with the search engine. The 'smack' object
51 | * must have been created with 'smack_create()', but you must not
52 | * have yet called 'smack_compile()' to compile the patterns. The
53 | * "id" field can contain a pointer (size_t is 64-bit on 64-bit
54 | * systems).
55 | */
56 | void
57 | smack_add_pattern( struct SMACK * smack,
58 | const void * pattern,
59 | unsigned pattern_length,
60 | size_t id,
61 | unsigned flags);
62 |
63 | /**
64 | * You call this function after you have registered all the patterns
65 | * using 'smack_add_pattern()' in order to compile the state-machine.
66 | * Don't use the state-machine with 'smack_search()' until you have
67 | * compiled all the patterns with this function.
68 | */
69 | void
70 | smack_compile(struct SMACK *smack);
71 |
72 |
73 | /**
74 | * Run the state-machine, searching for the compiled patterns within
75 | * a block of data/text. This can only be called after "smack_compile()"
76 | * has created the state-machine.
77 | *
78 | * If the input is fragmented, this function can be called repeatedly
79 | * for each fragment. Patterns that cross fragments will still be
80 | * detected.
81 | *
82 | * The caller must initialize "*state" to zero "0" before running this
83 | * function on the first fragment, but must thereafter leave it
84 | * unchanged between fragments. (If the caller resets the *state variable
85 | * to zero between each fragment, then patterns that cross fragment
86 | * boundaries cannot be detected).
87 | */
88 | unsigned
89 | smack_search( struct SMACK * smack,
90 | const void * px,
91 | unsigned length,
92 | FOUND_CALLBACK cb_found,
93 | void * cb_data,
94 | unsigned * state);
95 |
96 | size_t
97 | smack_search_next( struct SMACK * smack,
98 | unsigned * state,
99 | const void * px,
100 | unsigned * offset,
101 | unsigned length
102 | );
103 |
104 | /**
105 | * Called to terminate a search (after multiple calls to `smack_search_next()`.
106 | * This triggers any patterns that SMACK_ANCHOR_END attribute on them.
107 | * If more than one pattern can match at the end of the search text, then
108 | * this should be called multiple times until SMACK_NOT_FOUND is
109 | * returned.
110 | * @return The 'id' field of a pattenr registered with the SMACK_ANCHOR_END
111 | * attribute if that was found in the searched buffer, or SMACK_NOT_FOUND.
112 | */
113 | size_t
114 | smack_search_next_end( struct SMACK * smack,
115 | unsigned * state
116 | );
117 |
118 | #define smack_search_start(state) (*(state)) = 0
119 |
120 | /**
121 | * If there are multiple matches at the current state, returns the next
122 | * one. Otherwise, returns NOT_FOUND. Used with "smack_search_next()".
123 | */
124 | size_t
125 | smack_next_match( struct SMACK * smack,
126 | unsigned * state);
127 |
128 | /**
129 | * Call this after search is done. This is not generally necessary.
130 | * It's only purpose is to detect patterns that have the
131 | * SMACK_ANCHOR_END flag set. If no pattern has that flag, then
132 | * this function will do nothing.
133 | */
134 | unsigned
135 | smack_search_end( struct SMACK * smack,
136 | FOUND_CALLBACK cb_found,
137 | void * cb_data,
138 | unsigned * state);
139 |
140 |
141 |
142 | /**
143 | * Runs a regression test on the module to make sure it's compiled
144 | * correctly for the current platform.
145 | *
146 | * @return
147 | * zero if regression test succeeds, non-zero on failure
148 | */
149 | int
150 | smack_selftest(void);
151 |
152 | int
153 | smack_benchmark(void);
154 |
155 | #endif /*_SMACK_H*/
156 |
--------------------------------------------------------------------------------
/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/string_s.c:
--------------------------------------------------------------------------------
1 | /*
2 | safe C library functions
3 |
4 | This upgrades unsafe C functions like "strcpy()" to safer equivalents,
5 | like "strcpy_s()".
6 |
7 | NOTE: This is for maintaining a policy of "no unsafe functions"
8 | */
9 | #include "string_s.h"
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | /**
16 | * fopen_s
17 | */
18 | #if !defined(WIN32) || _MSC_VER == 1200
19 | errno_t fopen_s(FILE **pFile, const char *filename, const char *mode)
20 | {
21 | if (pFile == NULL || filename == NULL || mode == NULL)
22 | return EINVAL;
23 | *pFile = fopen(filename, mode);
24 | if (*pFile != NULL)
25 | return 0;
26 | else
27 | return errno;
28 | }
29 | #endif
30 |
31 | /**
32 | * Case-insensitive memcmp()
33 | */
34 | #ifdef __GNUC__
35 | int
36 | memcasecmp(const void *lhs, const void *rhs, int length)
37 | {
38 | int i;
39 | for (i=0; i= sizeof_dst) {
68 | dst[0] = 0;
69 | return ERANGE;
70 | } else
71 | dst[i] = src[i];
72 | }
73 | if (i >= sizeof_dst) {
74 | dst[0] = 0;
75 | return ERANGE;
76 | } else
77 | dst[i] = src[i];
78 |
79 | return 0;
80 | }
81 | #endif
82 |
83 | #ifdef __GNUC__
84 |
85 | errno_t localtime_s(struct tm* _tm, const time_t *time)
86 | {
87 | struct tm *x;
88 |
89 | x = localtime(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 | errno_t gmtime_s(struct tm* _tm, const time_t *time)
99 | {
100 | struct tm *x;
101 |
102 | x = gmtime(time);
103 | if (x == NULL) {
104 | memset(_tm, 0, sizeof(*_tm));
105 | return -1;
106 | }
107 | memcpy(_tm, x, sizeof(*_tm));
108 |
109 | return 0;
110 | }
111 | #endif
112 |
113 |
114 | /*
115 | * I don't understand why Microsoft says this function is unsafe, so
116 | * do it anyway
117 | */
118 | const char *strerror_x(int x)
119 | {
120 | #ifdef _MSC_VER
121 | #pragma warning(disable: 4996)
122 | #endif
123 | #undef strerror
124 | return strerror(x);
125 | }
126 |
--------------------------------------------------------------------------------
/src/string_s.h:
--------------------------------------------------------------------------------
1 | /*
2 | safe "string" functions, like Microsoft's
3 |
4 | This is for the "safe" clib functions, where things like "strcpy()" is
5 | replaced with a safer version of the function, like "strcpy_s()". Since
6 | these things are non-standard, compilers deal with them differently.
7 |
8 | Reference:
9 | http://msdn.microsoft.com/en-us/library/bb288454.aspx
10 | */
11 | #ifndef STRCPY_S
12 | #define STRCPY_S
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #undef strcpy
21 | #define strcpy STRCPY_FUNCTION_IS_BAD
22 |
23 | #undef strncpy
24 | #define strncpy STRNCPY_FUNCTION_IS_BAD
25 |
26 | #undef strcat
27 | #define strcat STRCAT_FUNCTION_IS_BAD
28 |
29 | #undef strncat
30 | #define strncat STRNCAT_FUNCTION_IS_BAD
31 |
32 | #undef sprintf
33 | #define sprintf SPRINTF_FUNCTION_IS_BAD
34 |
35 | #undef vsprintf
36 | #define vsprintf VSPRINTF_FUNCTION_IS_BAD
37 |
38 | #undef strtok
39 | #define strtok STRTOK_FUNCTION_IS_BAD
40 |
41 | #undef gets
42 | #define gets GETS_FUNCTION_IS_BAD
43 |
44 | #undef scanf
45 | #define scanf SCANF_FUNCTION_IS_BAD
46 |
47 | #undef sscanf
48 | #define sscanf SSCANF_FUNCTION_IS_BAD
49 |
50 | #undef itoa
51 | #define itoa ITOA_FUNCTION_IS_BAD
52 |
53 | #undef strerror
54 | #define strerror STRERROR_FUNCTION_IS_BAD
55 |
56 | const char *strerror_x(int x);
57 |
58 | #if defined(_MSC_VER) && (_MSC_VER >= 1900)
59 | /*Visual Studio 2015 and 2017*/
60 | # include
61 | # include
62 | # define strcasecmp _stricmp
63 | # define memcasecmp _memicmp
64 | # ifndef PRIu64
65 | # define PRIu64 "llu"
66 | # define PRId64 "lld"
67 | # define PRIx64 "llx"
68 | # endif
69 |
70 | #elif defined(_MSC_VER) && (_MSC_VER == 1600)
71 | /*Visual Studio 2010*/
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 |
83 | #elif defined(_MSC_VER) && (_MSC_VER == 1200)
84 | /* Visual Studio 6.0 */
85 | # define sprintf_s _snprintf
86 | # define strcasecmp _stricmp
87 | # define memcasecmp _memicmp
88 | # define vsprintf_s _vsnprintf
89 | typedef int errno_t;
90 | errno_t fopen_s(FILE **fp, const char *filename, const char *mode);
91 |
92 | #elif defined(__GNUC__) && (__GNUC__ >= 4)
93 | #include
94 | /* GCC 4 */
95 | # define sprintf_s snprintf
96 | # define vsprintf_s vsnprintf
97 | int memcasecmp(const void *lhs, const void *rhs, int length);
98 | typedef int errno_t;
99 | #if !defined(WIN32) /* mingw */
100 | errno_t fopen_s(FILE **fp, const char *filename, const char *mode);
101 | errno_t strcpy_s(char *dst, size_t sizeof_dst, const char *src);
102 | errno_t localtime_s(struct tm* _tm, const time_t *time);
103 | errno_t gmtime_s(struct tm* _tm, const time_t *time);
104 | #endif
105 | #undef strerror
106 |
107 | #else
108 | # warning unknown compiler
109 | #endif
110 |
111 |
112 |
113 |
114 | #endif
115 |
--------------------------------------------------------------------------------
/src/stub-lua.c:
--------------------------------------------------------------------------------
1 | #define LUAAPI
2 | #include "stub-lua.h"
3 |
4 | #if defined(WIN32)
5 | #define WIN32_LEAN_AND_MEAN
6 | #include
7 | #pragma warning(disable: 4133 4113 4047)
8 | #else
9 | #include
10 | #endif
11 |
12 | #if defined(__GNUC__)
13 | /* Disable MinGW warnings for Windows */
14 | #pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
15 | #endif
16 |
17 |
18 | int stublua_init(void)
19 | {
20 | void *lib = NULL;
21 |
22 | {
23 | #if defined(__APPLE__)
24 | static const char *possible_names[] = {
25 |
26 | "liblua.5.3.5.dylib",
27 | "liblua.5.3.dylib",
28 | "liblua5.3.dylib",
29 | "liblua.dylib",
30 | 0
31 | };
32 | #elif defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)
33 | static const char *possible_names[] = {
34 | "lua53.dll",
35 | "lua.dll",
36 | 0
37 | };
38 | #else
39 | static const char *possible_names[] = {
40 | "liblua5.3.so",
41 | "liblua5.3.so.0",
42 | "liblua5.3.so.0.0.0",
43 | 0
44 | };
45 | #endif
46 | unsigned i;
47 | for (i=0; possible_names[i]; i++) {
48 | #if defined(WIN32)
49 | lib = LoadLibraryA(possible_names[i]);
50 | #else
51 | lib = dlopen(possible_names[i], RTLD_LAZY);
52 | #endif
53 | if (lib) {
54 | break;
55 | } else {
56 | ;
57 | }
58 | }
59 |
60 | if (lib == NULL) {
61 | fprintf(stderr, "liblua: failed to load Lua shared library\n");
62 | fprintf(stderr, " HINT: you must install Lua library\n");
63 | }
64 | }
65 |
66 | #if defined(WIN32)
67 | #define DOLINK(name) \
68 | name = (void (*)())GetProcAddress(lib, #name); \
69 | if (name == NULL) fprintf(stderr, "liblua: %s: failed\n", #name);
70 | #else
71 | #define DOLINK(name) \
72 | name = dlsym(lib, #name); \
73 | if (name == NULL) fprintf(stderr, "liblua: %s: failed\n", #name);
74 | #endif
75 |
76 | DOLINK(lua_version);
77 |
78 |
79 | DOLINK(lua_close)
80 | DOLINK(lua_getfield)
81 | DOLINK(lua_getglobal)
82 | DOLINK(lua_geti)
83 | DOLINK(lua_gettop)
84 | DOLINK(lua_isnumber);
85 | DOLINK(lua_isstring);
86 | DOLINK(lua_iscfunction);
87 | DOLINK(lua_isinteger);
88 | DOLINK(lua_isuserdata);
89 | DOLINK(lua_newthread)
90 | DOLINK(lua_newuserdata)
91 | DOLINK(lua_pcallk)
92 | DOLINK(lua_pushcclosure)
93 | DOLINK(lua_pushinteger)
94 | DOLINK(lua_pushlstring)
95 | DOLINK(lua_pushnumber)
96 | DOLINK(lua_pushstring)
97 | DOLINK(lua_pushvalue)
98 | DOLINK(lua_resume)
99 | DOLINK(lua_setfield)
100 | DOLINK(lua_setglobal)
101 | DOLINK(lua_seti)
102 | DOLINK(lua_settop)
103 | DOLINK(lua_toboolean)
104 | DOLINK(lua_tointegerx)
105 | DOLINK(lua_tolstring)
106 | DOLINK(lua_tonumberx)
107 | DOLINK(lua_type)
108 | DOLINK(lua_typename)
109 | DOLINK(lua_version)
110 | DOLINK(lua_xmove)
111 | DOLINK(lua_yieldk)
112 |
113 | DOLINK(luaL_checkinteger)
114 | DOLINK(luaL_checklstring)
115 | DOLINK(luaL_checkudata)
116 | DOLINK(luaL_len)
117 | DOLINK(luaL_loadbufferx)
118 | DOLINK(luaL_loadfilex)
119 | DOLINK(luaL_loadstring)
120 | DOLINK(luaL_newmetatable)
121 | DOLINK(luaL_newstate)
122 | DOLINK(luaL_openlibs)
123 | DOLINK(luaL_ref)
124 | DOLINK(luaL_setfuncs)
125 | DOLINK(luaL_setmetatable)
126 | DOLINK(luaL_unref)
127 |
128 | return 0;
129 | }
130 |
--------------------------------------------------------------------------------
/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 "string_s.h"
11 | #include "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 | int err;
31 | char line[256];
32 | int found = 0;
33 |
34 | err = fopen_s(&fp, "/proc/modules", "rb");
35 | if (err)
36 | return 0;
37 |
38 | while (fgets(line, sizeof(line), fp)) {
39 | if (memcmp(line, "pf_ring ", 8) == 0) {
40 | found = 1;
41 | LOG(2, "pfring: found 'pf_ring' driver\n");
42 | }
43 | if (memcmp(line, "ixgbe ", 6) == 0) {
44 | LOG(2, "pfring: found 'ixgbe' driver\n");
45 | }
46 | if (memcmp(line, "e1000e ", 8) == 0) {
47 | LOG(2, "pfring: found 'e1000e' driver\n");
48 | }
49 | }
50 | fclose(fp);
51 | return found;
52 | #else
53 | return 0;
54 | #endif
55 | }
56 |
57 |
58 | /***************************************************************************
59 | ***************************************************************************/
60 | int
61 | PFRING_init(void)
62 | {
63 | #if defined(__linux__)
64 | void *h;
65 | int err = 0;
66 | LOG(6, "pfring: initializing subsystem\n");
67 | LOG(6, "pfring: looking for 'libpfring.so'\n");
68 | h = dlopen("libpfring.so", RTLD_LAZY);
69 | if (h == NULL) {
70 | LOG(2, "pfring: error: dlopen('libpfring.so'): %s\n", strerror_x(errno));
71 | return 0;
72 | } else
73 | LOG(2, "pfring: found 'libpfring.so'!\n");
74 |
75 | #define LOADSYM(name) if ((PFRING.name = dlsym(h, "pfring_"#name)) == 0) {LOG(2, "pfring_%s: not found in 'libpfring.so': %s\n", #name, strerror_x(errno));err=1;}
76 | LOADSYM(open);
77 | LOADSYM(close);
78 | LOADSYM(enable_ring);
79 | LOADSYM(send);
80 | LOADSYM(recv);
81 | LOADSYM(poll);
82 | LOADSYM(version);
83 | LOADSYM(set_direction);
84 | LOADSYM(set_application_name);
85 | //LOADSYM(get_bound_device);
86 |
87 | if (err) {
88 | memset(&PFRING, 0, sizeof(PFRING));
89 | LOG(2, "pfring: failed to load\n");
90 | } else {
91 | LOG(2, "pfring: successfully loaded PF_RING API\n");
92 |
93 | if (!PFRING_is_installed()) {
94 | LOG(0, "pfring: ERROR: 'pf_ring' driver module not found!!!!!\n");
95 | } else
96 | LOG(2, "pfring: found 'pf_ring' driver module\n");
97 | }
98 |
99 | #endif
100 | return 0;
101 | }
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/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 "string_s.h"
4 | #include "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 | int err;
24 |
25 | /*
26 | * Gather some random bits
27 | */
28 | for (i=0; i<64; i++) {
29 | FILE *fp;
30 | entropy[0] += pixie_nanotime();
31 | #if defined(_MSC_VER)
32 | entropy[0] ^= __rdtsc();
33 | #endif
34 | time(0);
35 | err = fopen_s(&fp, "/", "r");
36 | entropy[1] <<= 1;
37 | entropy[1] |= entropy[0]>>63;
38 | entropy[0] <<= 1;
39 | if (err == 0 && fp) {
40 | fclose(fp);
41 | }
42 | }
43 |
44 | entropy[0] ^= time(0);
45 |
46 | #if defined(__linux__)
47 | {
48 | FILE *fp;
49 |
50 | err = fopen_s(&fp, "/dev/urandom", "r");
51 | if (err == 0 && fp) {
52 | int 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 | #endif
65 |
66 | return entropy[0] ^ entropy[1];
67 | }
68 |
69 | #if 0
70 | /***************************************************************************
71 | * This implements the "murmur" hash function.
72 | ***************************************************************************/
73 | static unsigned
74 | murmur(uint64_t entropy, ...)
75 | {
76 | /* reference:
77 | * http://en.wikipedia.org/wiki/MurmurHash
78 | */
79 | static const unsigned c1 = 0xcc9e2d51;
80 | static const unsigned c2 = 0x1b873593;
81 | unsigned r1 = 15;
82 | unsigned r2 = 13;
83 | unsigned m = 5;
84 | unsigned n = 0xe6546b64;
85 | va_list key;
86 | unsigned len;
87 |
88 | unsigned hash = (unsigned)entropy;
89 |
90 | va_start(key, entropy);
91 |
92 | for (len=0; len<2; len++) {
93 | unsigned k = va_arg(key, unsigned);
94 | k = k * c1;
95 | k = (k << r1) | (k >> (32-r1));
96 | k = k * c2;
97 |
98 | hash = hash ^ k;
99 | hash = (hash << r2) | (hash >> (32-r2));
100 | hash = hash * m + n;
101 | }
102 |
103 | hash = hash ^ (len*4);
104 |
105 | hash = hash ^ (hash >> 16);
106 | hash = hash * 0x85ebca6b;
107 | hash = hash ^ (hash >> 13);
108 | hash = hash * 0xc2b2ae35;
109 | hash = hash ^ (hash >> 16);
110 |
111 | return hash;
112 | }
113 | #endif
114 |
115 | /***************************************************************************
116 | ***************************************************************************/
117 | uint64_t
118 | syn_cookie( ipaddress ip_them, unsigned port_them,
119 | ipaddress ip_me, unsigned port_me,
120 | uint64_t entropy)
121 | {
122 | switch (ip_them.version) {
123 | case 4:
124 | return syn_cookie_ipv4(ip_them.ipv4, port_them, ip_me.ipv4, port_me, entropy);
125 | case 6:
126 | return syn_cookie_ipv6(ip_them.ipv6, port_them, ip_me.ipv6, port_me, entropy);
127 | default:
128 | assert(!"unknown ip version");
129 | return 0;
130 | }
131 | }
132 |
133 | /***************************************************************************
134 | ***************************************************************************/
135 | uint64_t
136 | syn_cookie_ipv4( unsigned ip_them, unsigned port_them,
137 | unsigned ip_me, unsigned port_me,
138 | uint64_t entropy)
139 | {
140 | unsigned data[4];
141 | uint64_t x[2];
142 |
143 | x[0] = entropy;
144 | x[1] = entropy;
145 |
146 | data[0] = ip_them;
147 | data[1] = port_them;
148 | data[2] = ip_me;
149 | data[3] = port_me;
150 | return siphash24(data, sizeof(data), x);
151 | }
152 |
153 | /***************************************************************************
154 | ***************************************************************************/
155 | uint64_t
156 | syn_cookie_ipv6( ipv6address ip_them, unsigned port_them,
157 | ipv6address ip_me, unsigned port_me,
158 | uint64_t entropy)
159 | {
160 | uint64_t data[5];
161 | uint64_t x[2];
162 |
163 | x[0] = entropy;
164 | x[1] = entropy;
165 |
166 | data[0] = ip_them.hi;
167 | data[1] = ip_them.lo;
168 | data[2] = ip_me.hi;
169 | data[3] = ip_me.lo;
170 | data[4] = port_them<<16ULL | port_me;
171 | return siphash24(data, sizeof(data), x);
172 | }
173 |
--------------------------------------------------------------------------------
/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-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 | payloads_udp_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/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 |
--------------------------------------------------------------------------------
/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-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/versioning.c:
--------------------------------------------------------------------------------
1 | /*
2 | SERVICE VERSIONING
3 |
4 | */
5 | #include "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 "proto-interactive.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 ProtocolState *pstate,
30 | const unsigned char *px, size_t length,
31 | struct BannerOutput *banout,
32 | struct InteractiveData *more)
33 | {
34 | unsigned state = pstate->state;
35 |
36 |
37 | UNUSEDPARM(banner1_private);
38 | UNUSEDPARM(banner1);
39 | UNUSEDPARM(more);
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/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/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 "string_s.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 |
--------------------------------------------------------------------------------
/videlicet.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/The-Ether-Project/ServerScanner/6a370de9c06aa8d59c23c11cb473e7e586ea263a/videlicet.db
--------------------------------------------------------------------------------