Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple protocols on one port: example with TLS1.1 & TLS1.2 #681

Closed
wants to merge 3 commits into from

Conversation

Frky
Copy link
Collaborator

@Frky Frky commented Aug 19, 2022

This PR aims to add the possibility to retry with another protocol when the first one failed. The implemented example is for TLS: if we have an alert when trying TLS 1.1, we want to retry on the same host, port with TLS 1.2.

The result is that the x509 certificate of a server that only supports TLS1.2 will now be successfully grabbed by masscanned (while before it would not have been):

$ sudo ./bin/masscan --banners -p443 -n $targetip
[+] resolving router 192.168.1.1 with ARP (may take some time)...
Starting masscan 1.3.2 (http://bit.ly/14GZzcT) at 2022-08-18 17:33:30 GMT
Initiating SYN Stealth Scan
Scanning 1 hosts [1 port/host]
Discovered open port 443/tcp on [...]                                  
Discovered open port 443/tcp on [...]                                  
Banner on port 443/tcp on [...]: [ssl] TLS/1.2 cipher:0xc030, [...]
Banner on port 443/tcp on [...]: [X509] MIIEPjCCAyagAwIB[...]
Banner on port 443/tcp on [...]: [X509] MIIFLTCCBBWgAwIB[...]
Banner on port 443/tcp on [...]: [X509] MIIHUDCCBjigAwIB[...]
Banner on port 443/tcp on [...]: [ssl]  ALERT(0x0246) 

However, I am not 100% confident this PR does not have important drawbacks on the performances or even if it breaks things, so any review/testing/feedback/suggestion is welcome.

Here is an overview on how it is implemented:

  • using the already existing (but unused?) field next in the ProtocolParserStream struct, we can already link several protocols in one port (see code):
    /* When multiple items are registered for a port. When one
     * connection is closed, the next will be opened.*/
    struct ProtocolParserStream *next;
  • we add a field in the ProtocolState state, called try_next, which is set by a protocol parser when it fails (this tells that the next one should be tried) -- for instance, the TLS 1.1 parsing function set try_next to 1 (true) when it parses an SSL alert (see diff):
  • in the receiving thread, we add a new SYN packet in the sending queue when the field try_next of the protocol state is set to 1 (see diff):
                if (tcb->banner1_state.try_next) {
                    /* create a new TCP SYN packet in the sending queue */
                    [...]
                    stack_transmit_packetbuffer(tcpcon->stack, response);
                }
  • because the transmitting and receiving threads are stateless (to avoid locks), we use the syn-cookie to distinguish the first from the second attempt (to know which protocol to test when we receive the SYN-ACK from the server). What we suggest here is to compute the syn-cookie of the second attempt with entropy + 1 as a key instead of entropy. Of course, this implies to try both keys when we receive a packet, but this allows for the receiving thread to know the index of the protocol to try in the linked-list of protocols:
            /* compute all possible cookies for other protocols */
            for (unsigned int i = 0; i < MAX_ITER; i++)
                cookie[i] = syn_cookie(ip_them, port_them, ip_me, port_me, entropy + i) & 0xFFFFFFFF;

            [...]

                /* check seqno against all possible cookies */
                for (iter = 0; iter < MAX_ITER; iter++) {
                    if (cookie[iter] == seqno_me-1)
                       break;

            [...]

                if (tcb == NULL) {
                    tcb = tcpcon_create_tcb(tcpcon,
                                    ip_me, ip_them,
                                    port_me, port_them,
                                    seqno_me, seqno_them+1,
                                    parsed.ip_ttl, iter);

@Frky
Copy link
Collaborator Author

Frky commented Aug 9, 2023

Reopened at #728.

@Frky Frky closed this Aug 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant