Sample Applications - zmap/zmap GitHub Wiki

ZMap is designed for initiating contact with a large number of hosts and finding ones that respond positively. However, we realize that many users will want to perform follow-up processing, such as performing an application level handshake. For example, users who perform a TCP SYN scan on port 80 might want to perform a simple GET request and users who scan port 443 may be interested in completing a TLS handshake.

Banner Grab

We have included a sample application, banner-grab, with ZMap that enables users to receive messages from listening TCP servers. Banner-grab connects to the provided servers, optionally sends a message, and prints out the first message received from the server. This tool can be used to fetch banners such as HTTP server responses to specific commands, telnet login prompts, or SSH server strings.

This example finds 1000 servers listening on port 80, and sends a simple GET request to each, storing their base-64 encoded responses in http-banners.out

$ zmap -p 80 -N 1000 -B 10M -o - | ./banner-grab-tcp -p 80 -c 500 -d ./http-req > out For more details on using banner-grab, see the README file in examples/banner-grab.

Heads Up! ZMap and banner-grab can have significant performance and accuracy impact on one another if run simultaneously (as in the example). Make sure not to let ZMap saturate banner-grab-tcp's concurrent connections, otherwise banner-grab will fall behind reading stdin, causing ZMap to block on writing stdout. We recommend using a slower scanning rate with ZMap, and increasing the concurrency of banner-grab-tcp to no more than 3000 (Note that > 1000 concurrent connections requires you to use ulimit -SHn 100000 and ulimit -HHn 100000 to increase the maximum file descriptors per process). These parameters will of course be dependent on your server performance, and hit-rate; we encourage developers to experiment with small samples before running a large scan.

Forge Socket

We have also included a form of banner-grab, called forge-socket, that reuses the SYN-ACK sent from the server for the connection that ultimately fetches the banner. In banner-grab-tcp, ZMap sends a SYN to each server, and listening servers respond with a SYN+ACK. The ZMap host's kernel receives this, and sends a RST, as no active connection is associated with that packet. The banner-grab program must then create a new TCP connection to the same server to fetch data from it.

In forge-socket, we utilize a kernel module by the same name, that allows us to create a connection with arbitrary TCP parameters. This enables us to suppress the kernel's RST packet, and instead create a socket that will reuse the SYN+ACK's parameters, and send and receive data through this socket as we would any normally connected socket.

To use forge-socket, you will need the forge-socket kernel module, available from github. You should git clone [email protected]:ewust/forge_socket.git in the ZMap root source directory, and then cd into the forge_socket directory, and run make. Install the kernel module with insmod forge_socket.ko as root.

You must also tell the kernel not to send RST packets. An easy way to disable RST packets system wide is to use iptables. iptables -A OUTPUT -p tcp -m tcp --tcp-flags RST,RST RST,RST -j DROP as root will do this, though you may also add an optional --dport X to limit this to the port (X) you are scanning. To remove this after your scan completes, you can run iptables -D OUTPUT -p tcp -m tcp --tcp-flags RST,RST RST,RST -j DROP as root.

Now you should be able to build the forge-socket ZMap example program. To run it, you must use the extended_file ZMap output module:

$ zmap -p 80 -N 1000 -B 10M -O extended_file -o - | \
    ./forge-socket -c 500 -d ./http-req > ./http-banners.out

See the README in examples/forge-socket for more details.