Digging into Antecursor

Note

It’s recommended to understand the Antecursor Project before reading the following.

This page provides information about how Antecursor works behind the scenes.

Overview and architectures

Functional architecture

Being autonomous, the Antecursor system discovers by itself the black box environment where it is placed. Like a Man-in-the-Middle, the Antecursor system listens to the data flow passing through, pretending to be the target computer it is plugged to.

_images/functional_architecture.png

Logical architecture

In an Antecursor running environment, you can distinguish 4 actors:

  • The Antecursor system itself, which interacts with the 3 others as described below.

  • The target computer (or secretary computer) that covers the Antecursor system identity and which is part of the corporate network

  • The corporate network that the Antecursor system process according to its configured mode

  • The GSM or Wi-Fi Network that can give orders to the Antecursor system and exfiltrate the data collected, outside the corporate network

_images/logical_architecture.png

Physical architecture

The Antecursor system is composed of a Raspberry Pi 3 as its core component, with a micro SD card as storage.

To connect the network and the secretary computer, 2 RJ45 cables are required: network on the integrated Raspberry Pi 3 Ethernet port (potentially PoE) and secretary with a USB adapter. For exfiltration to be available, a GSM module is required, or the integrated WiFi controller can be used.

To charge the Antecursor system, it is Power over Ethernet compatible (on the integrated Raspberry Pi 3 Ethernet port), or use a power bank, or the local power supply.

_images/physical_architecture.png

System configuration

System initialization

When the Antecursor system is first plugged between the network and the target computer (or secretary computer), it follows the next steps.

First is spoofing the MAC address of the target computer to fool the network:

_images/spoofing.png

Network configuration

sequenceDiagram participant Target Computer participant Antecursor participant Corporate Network Antecursor->>Target Computer: Ethernet port connection Antecursor->>Corporate Network: Ethernet port connection Antecursor->>Target Computer: Ethernet port activation Note over Antecursor, Target Computer: ARP exchange<br/>(target computer's MAC address<br/>is recorded) Target Computer->>+Antecursor: DHCP Discover Antecursor-->>-Target Computer: DHCP Offer Target Computer->>+Antecursor: DHCP Request Antecursor-->>-Target Computer: DHCP ACK Note over Antecursor, Target Computer: The Antecursor is visible to the<br/>target computer as a generic<br/>network router (with DHCP, DNS,<br/>routing services) Note over Antecursor: Post-lease hook<br/>script (each time we<br/>get client) Antecursor->>Antecursor: MAC address changing (target spoofing) Antecursor->>Corporate Network: Ethernet port activation Antecursor->>+Corporate Network: DHCP Discover Corporate Network-->>-Antecursor: DHCP Offer Antecursor->>+Corporate Network: DHCP Request Corporate Network-->>-Antecursor: DHCP ACK Note over Antecursor, Corporate Network: The Antecursor is visible to the<br/>corporate network as the original<br/>target computer Antecursor->>Antecursor: DHCPd configuration update (DNS, domain, etc.) Target Computer->>+Antecursor: DNS Request Antecursor->>+Corporate Network: DNS Request (forwarding) Corporate Network->>-Antecursor: DNS Response Antecursor->>-Target Computer: DNS Response Target Computer->>+Antecursor: Any TCP/UDP packet Note over Antecursor, Corporate Network: Basic routing using NAT

At the end of the process, the routing tables are like:

  • for the target computer:

IP address

MAC address

Interface

Description

dynamic

@MAC A

eth0

Connected to the Antecursor system

  • for the Antecursor system:

IP address

MAC address

Interface

Description

192.168.0.1

@MAC B

eth0

Connected to the Target Computer

dynamic

@MAC A (spoofed from target computer)

eth1

Connected to the Corporate Network

System scripts

Sniffer

Description

This tool aims to sniff and capture useful data on a given interface. It stores everything in the SQLite Database that is intended to be processed by the other modules.

It is able to map the network and determine the network topology from the data collected. The Sniffer may be run in stealthy-mode-doc since it just passively grabs the data passing through.

From the requests flow, the script stores every:

  • IP Addresses from any protocol

  • Ports from any protocol

  • Credentials from specific protocols such as FTP, HTTP, SNMP

  • Other output specified in the database documentation below

Note

The credential gathering is inspired by net-creds.

In recon mode, the Sniffer will automatically start a nmap scan when a DHCP request is discovered..

It can also receive commands, see Change config on the fly in the user guide part.

Usage

usage: main.py [-h] -d DATABASE [-i INTERFACE] [-p PCAP] [-t TIME] [-a]
               [-o OUTPUT] [-m {stealthy,recon,exploitation}]

    )
   (_)
  /___\                Antecursor Project
 |  |  |    https://gitlab.com/Antecursor/antecursor
 |__|__|

optional arguments:
  -h, --help            show this help message and exit
  -d DATABASE, --database DATABASE
                        The SQLite file where the database will be stored
  -i INTERFACE, --interface INTERFACE
                        The interface used for sniffing
  -p PCAP, --pcap PCAP  Specify a PCAP as data input
  -t TIME, --time TIME  The time to wait before ending the sniffer
  -a, --append          Append the data to an existing database
  -o OUTPUT, --output OUTPUT
                        Specify a PCAP file to write data
  -m {stealthy,recon,exploitation}, --mode {stealthy,recon,exploitation}
                        Mode to be used by sniffer

Example:

python main.py -i [INTERFACE] -d [OUTPUT_DATABASE]

SQLite Database

The database is generated by the system scripts when the Antecursor system is in its running phase.

It can be exfiltrated and viewed using the web interface.

Architecture

_images/database_diagram.png

Web interface

The web interface comes with many views to visualize the database. It’s used after the database was exfiltrated as a client-only web interface.

It is written in JS, using JQuery and Bootstrap 4 for the view.

Below is an insight of the web interface model.

_images/web_interface_model.png

API Reference

API modules

class src.sniffer.Sniffer(interface, database, pcap=None, output_pcap=None, mode='stealthy')[source]

Class used to sniff the network and saving into the database

analyse(packet)[source]

Analyse the packet for useful informations before storing it

Parameters

packet – packet to analyse

capture()[source]

Launch the sniffing process.

run()[source]

Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

store_packet(packet)[source]

Callback function that will store all packet received by the capture.

Parameters

packet – packet to process

class src.credential_harvester.CredentialEngine[source]

Class that will parse data to find credentials into it. The processor engine is in part inspired by (https://github.com/DanMcInerney/net-creds/blob/master/net-creds.py)

assemble_tcp_packet(src, dst, pkt)[source]

This function will be used to assemble TCP packet in order to keep the full trame data together. It keep it’s data in a dict if there is too much data, it split it in order to keep a good cpu usage.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • pkt – the pkt itself

Returns

the assembled packet

find_ftp(src, dst, pkt)[source]

This function will try to find FTP credentials in the data given.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • pkt – the pkt itself

Returns

True if the credentials were stored, None otherwise

find_http_auth(src, dst, pkt)[source]

This function will extract uris and password and cookies from web communication in http. This use known ids.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • pkt – the pkt itself

Returns

True if credentials were found and stored in the database, False otherwise

find_irc(src, dst, pkt)[source]

This function ill try to find IRC creedntials in the data given

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • pkt – the pkt itself

Returns

True if credentials were found and stored in the database, False otherwise

find_kerberos(src, dst, pkt)[source]

Finding kerberos tokens in UDP.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • pkt – the pkt itself

find_mail_auth(src, dst, pkt)[source]

This function will try to find plain IMAP POP and SMTP authentication and extract the credentials.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • pkt – the pkt itself

Returns

True if credentials were found and stored in the database, None otherwise

find_telnet(src, dst, pkt)[source]

This function ill try to find IRC creedntials in the data given.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • pkt – the pkt itself

Returns

True if credentials were found and stored in the database, False otherwise

parse_snmp(src, dst, snmp_layer)[source]

Check if there is a commmunity string in the packet.

The community string is used as a password for SNMP protocols. There is 3 types of community string :

  • Read-Only: you can retrieve read only informations

  • Read-Write: you can retrieve and write informations

  • Traps: sort of alarms

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • snmp_layer – the packet itself

process(pkt)[source]

The function that will do all the step to process the packet :param packet: the packet to process :return: tuple containing the found information

store_credentials(src, dst, type, data)[source]

Store credentials if they don’t already exist in the previous credentials found.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • type – type of credentials

  • data – data to store

Returns

True

store_http_request(src, dst, method, host, uri, cookies_result=None, params_get_result=None, params_post_result=None)[source]

Store HTTP Requests if they don’t already exists in the previous requests found.

Parameters
  • src – sender of the packet

  • dst – receiver of the packet

  • type – type of credentials

  • data – data to store

Returns

True if the request was added to the database, False otherwise

class src.database.DHCPInstance[source]

Representation of a DHCP Request

class src.database.DataBase(database_path=None, keep=False)[source]

The SQLite database.

close()[source]

Close the connection to database

create_table_scheme()[source]

Function that will create the according relational database for the current database.

insert_credentials(src, dest, type, infos)[source]

Insert found credentials into the database.

Parameters
  • src – (ip,port) of the source

  • dst – (ip,port) of the receiver

  • infos – (type of credential, … )

insert_dhcp(dhcp_instance)[source]

Store DHCP informations

Parameters

dhcp_instance – instance of class DHCPInstance containing the dhcp info to store

insert_http_request(src, dst, method, host, url, cookies=None, get_params=None, post_params=None)[source]

Store HTTP data into the sqlite database.

Parameters
  • src – (ip,port) of the sender

  • dst – (ip,port) of the receiver

  • method – method of the http request

  • host – host of the http request

  • url – url of the http request

  • cookies – cookies of the http request (default=None)

  • get_params – get parameters of the http request (default=None)

  • post_params – post parameters of the httprequest (default=None)

insert_ip(ip_address)[source]

Function that will insert an ip into the table.

Parameters

ip_address – the ip to insert

insert_port(ip_address, port_number, protocol)[source]

Function that will insert a port for an associated ip.

Parameters
  • ip_address – the ip_adress

  • port_number – the port to insert

  • protocol – the protocol to insert

class src.network_mapper.NetworkMapper[source]

Class that will map the network according to the packet it receives

process_dhcp_packet(packet)[source]

This will process the dhcp packet in order to retrieve useful infomrmations to map the network successfully.

Parameters

packet – scapy packet containing the dhcp request