Closed Frky closed 8 months ago
This looks really good. I'd like to see this integrated. Right now I'm going through a phase of accepting the 40+ outstanding pull requests, so I don't have time to look at something this complex.
They way I'd intended to solve this was a little different, maybe a linked-list of protocols to iterate over rather than an array. I'm going to have to look at your design more.
I agree, a linked list would be way nicer. I will adapt my PR.
Also, one problem I encountered using this multi-protocols feature is that once we have multiple probes for one port, it is then needed to have a way in the output file (XML/bin/etc.) to know which probe led to which answer. I have an other draft PR (not pushed yet) to add an option --output-probes
which adds a field probe=...
in the output file. @p-l- has prepared an update of Ivre to support this, but it could break other tools parsing masscan
output (although without the --output-probes
flag the output would not change). What did you have in mind for that?
I have vastly changed the TCP stack in the latest push. It now makes this much easier. To find all the changes, such search for reconnect
in the code. I integrated your first proposal from the IVRE branch, and then rewrote most of it.
First of all, a new SYN-cookie isn't needed, so I removed all those parts. Once a new port is selected, a new SYN-cookie is generated automatically. I now default to using 16 source ports, so there should always be a source port available.
I cleaned up the TCP state-machine, so that when you do a "send" of the SYN rather than a "xmit". This means it's been queued up in the TCB, and if it doesn't get a reply, it'll resend the SYN a few times.
I'm setting this up to integrate Lua scripting, so that scripts can likewise open a new TCP connection whenever they like.
I'm going to close this pull request since I've completely redone the TCP stack in the last week. Also, request has actually been accepted, since I pulled it down from the IVRE fork, but it doesn't have anything you've added in the last week.
Go search for "reconnect", especially the _do_reconnect()
function.
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):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:
next
in theProtocolParserStream
struct, we can already link several protocols in one port (see code):ProtocolState
state, calledtry_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 settry_next
to1
(true
) when it parses an SSL alert (see diff):SYN
packet in the sending queue when the fieldtry_next
of the protocol state is set to1
(see diff):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 withentropy + 1
as a key instead ofentropy
. 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: