Skip to content
This repository has been archived by the owner on Dec 30, 2018. It is now read-only.
/ Mini-Nmap Public archive
forked from sipian/Mini-Nmap

Project repository for CS3543: Computer Networks offered in Spring 2018

Notifications You must be signed in to change notification settings

vishwakftw/Mini-Nmap

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mini-Nmap

Objective and Motivation


Nmap has been a very-effective tool for network discovery and security analysis for about 20 years now. The goal of the project was to implement certain network discovery techniques which are available in Nmap. A full implementation of Nmap would take quite a long time of development, hence in this project, we have decided to stick with certain techniques that are popularly used.

The motivation of the project was to get an idea of how such network discovery tools are implemented, and to objectively see how hard implementing a suite like Nmap would actually be.

Project Specifications


The size of the project stands at around 2000 lines of code written in C++ and Python. The tools implemented as a part of the project are:

  • Host discovery utility

  • Port scanning techniques: SYN, FIN, NULL, XMAS and Decoy scan

  • A TCP sniffer

  • ARP Poisoner (with ARP Doctor)

A full documentation of the code is available to be auto-generated for user convenience. This is discussed later.

Code Structure, Design Decisions and Tools used


Code Structure and Organization


The code is organized in the following manner:

  • ping.h/.cpp consists of ICMP ping preliminaries required for the host discovery.

  • discover.h/.cpp consists of code required for host discovery using ICMP messages.

  • packet.h/.cpp consists of code which enables socket creation, packet processing (e.g., checksum calculation), layer-wise packet assembly.

  • scan.h/.cpp consists of code required for scanning techniques.

  • sniff.h/.cpp consists of code required for the TCP sniffing utility

  • error.h/.cpp consists of error handling utilities.

  • logger.h/.cpp consists of logging utilities.

  • arpPoison.py is a Python module consists of code required for a Man-in-the-Middle Attack using ARP poisoning.

What happens in each of the files above?


discover.h/.cpp

The main host discovery takes place with the discover_host() function. The algorithm followed by the function is as follows:

  • Get CIDR string and validate CIDR
  • IPaddr, Mask = CIDR_string
  • Get list of IPaddrs using IPaddr and Mask
  • Populate a Queue with requests
  • active = Empty Set
  • Open request and get the IPaddr. Ping the IPaddr and await reply
    • If IPaddr replies
      • add IPaddr to active.
    • Else
      • If non-zero trials for the request left, add to the queue. Otherwise, don’t.
  • Return active
packet.h/.cpp

This a utility file. This helps create socket descriptors, assemble packets at a header level (TCP, IP), and calculate checksums.

The source code has been adapted and modified to requirements based on other code available online (Linux kernel). These links are available in the references and the function descriptions.

ping.h/.cpp

This is a utility file to handle ICMP packets. This file consists of functions to create sockets, assemble ICMP packets, and handling sending and receiving of ping messages.

scan.h/.cpp

Here is where the port scanning techniques take place. The most important function is scan. Here, too, we follow a round robin approach with requests, hence the algorithm is very similar to that specified above. Instead of CIDR, we will instead have a user specified range of ports, and instead of pinging we would be sending specialized packets pertaining to each technique. We have incorporated parallelism by chunking the ports to be scanned evenly across multiple threads. The scanning techniques are briefly explained below:

  • In SYN scanning, the attacking client attempts to set up a TCP/IP connection with a server at every possible port. This is done by sending a SYN (synchronization) packet, to mimic initiating a three-way handshake, to every port on the server. If the server responds with a SYN/ACK (synchronization acknowledged) packet from a particular port, it means the port is open. If the server responds with a RST (reset) packet from a particular port, it means the port is closed.

  • In FIN scanning, the specifications of RFC 793 are exploited. RFC 793 states that: “Traffic to a closed port should always return RST” and “If neither of the SYN or RST bits is set then drop the segment and return”. Now, if you send a packet with a FIN bit set to 1, then for closed ports you will receive a RST, but for open ports / filtered ports you will not receive anything. Thus, if there is no firewall, then there is a good chance that timeout indicates activity of the port.

  • Both these work in the same way as FIN Scan, thereby exploiting the specifications of RFC 793.

  • To prevent a filtering of the attacker’s side, there is a utility called Decoy Scan. This sends spoofed packets mimicking random IP address to the victim IP address, thus making it hard to pinpoint the attacker.

sniff.h/.cpp

This is a sniffing utility. Sent and Received packets are analyzed in a process_packet function. This sniffer only analyzes TCP packets, since most of our scans are designed to work with the TCP header.

arpPoison.py

This has two key functions - poisoner and doctor. poisoner will tell the victim that the MAC address of the gateway is its own, and will tell the gateway that the victims’s MAC address is its own. Now packets inbound to the victim from anywhere will be intercepted by the attacker. Messages from the victim to the gateway, will be intercepted by the attacker as well.

To revert the changes made, the “doctor” broadcasts messages as the gateway and victim asking for the MAC addresses of the victim and gateway respectively, thus restoring the ARP tables.

This is a simple man-in-the-middle attack, which is why we decided to add it in this suite. The network library ScaPy was used for this module alone. The main file will execute the attack for a given duration, after which the attacked reprises the role of a “doctor” and reverts the changes

Design Decisions


Certain design decisions were made as a part of the project. We chose C++ over Python, despite the huge module support from Python, since we believed that C++ was closer to the Linux Network API than Python, thus leaving room for less error. We have also made use of threads for parallel port scanning, and Python’s threading module is not as efficient as C++, which is also another reason to migrate to C++.

However, for the ARP poisoning tool, we decided to go with Python instead of C++, since it would require dealing with the link-layer packets, which could cause a lot of pointer manipulation, which is tedious and error-prone.

We have also effectively modularized our code, so that the utilities designed could also be used for other purposes than their intended usage as well. For example, we have a ICMP message sender which can be used in place of the iputils utility ping.

In the host discovery and port scanning techniques, we have decided to use a Round-robin technique. Here, we create a queue of “requests”, and these “requests” are processed in a round-robin fashion. If a “request” is successfully completed or has run out of trials, then we remove it from the queue. Other alternatives were to wait until a reply arrived for a given request - which is susceptible to timeouts. This round-robin scheme allows us to pipeline the process as well.

We have also made use of raw sockets (specified using SOCK_RAW). This helps us modify the properties of the socket to our will (for example: sending spoofed packets), which is why we decided to use them over traditional stream or datagram sockets. Using raw sockets, we were able to populate the header appropriately as per requirements (for TCP, IP, and ICMP).

Tools used


We have made use of OpenStack. Using this, we have created a private subnet, which behaves as the test-bed for our tools.

We have also made use of tcpdump and WireShark for monitoring the network traffic during the time of the attack.

For specifying input to the executable, we have used a JSON (Javascript Object Notation) parser designed by Niels Lohmann. The file json.h is code for the aforementioned parser.

The documentation in generated using Doxygen.

Scope for improvement


We had a working prototype a firewall, which will be able to detect port-scanners. We were able to test it completely, which is why we haven’t submitted it as a part of the project.

Furthermore, we also would like improve this by adding an OS fingerprinting technique, wherein specifics of the networking APIs of multiple OSes are exploited to possibly find of the OS operating at each port.

Please note that an illustrated version of this document is available in main.pdf

About

Project repository for CS3543: Computer Networks offered in Spring 2018

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 95.1%
  • TeX 3.5%
  • Other 1.4%