Skip to content

Option: Don't fail on duplicate knocks#72

Open
escitalopram wants to merge 5 commits intojvinet:masterfrom
escitalopram:f-ignore-duplicate-knocks
Open

Option: Don't fail on duplicate knocks#72
escitalopram wants to merge 5 commits intojvinet:masterfrom
escitalopram:f-ignore-duplicate-knocks

Conversation

@escitalopram
Copy link

This adds the AllowDuplicates configuration directive. If specified, knockd will ignore duplicates of packets that already matched the knock sequence. This allows for browser-based knocking.

To be used when you can't control the amount of e.g. SYN
packets sent, e.g. browser often send multiple SYN packets.
Always on right now, configuration follows
via options config section and add docs
Copy link
Owner

@jvinet jvinet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple stylistic inconsistencies to address, and then we can merge. Thank you for the contribution!

src/knockd.c Outdated
* may be duplicated (e.g. if a browser always sends 2 SYN-packets)
*/
int already_matched(knocker_t * attempt, unsigned short dport, uint8_t proto) {
if (o_duplicate) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In an effort to maintain consistency in code style, could you please adjust this function's style to match the rest of the file?

  • Please remove the space between if or for, and its opening parenthesis, eg, if(o_duplicate) {
  • In the function signature, please remove the space between the asterisk and the type, eg, int already_matched(knocker_t* attempt, ...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that there is a pcap filter that seems to filter out only ports that are mentioned in knock sequences. Doesn't this reduce the difficulty to guess the sequence significantly in general?

When combined with this new feature, though, you are basically bound to crack a port sequence just by repeatedly portscanning a few times, given the right circumstances. So this request can't be merged in its current form because it's a gaping security hole.

Do you think it is viable if I just disable the port filtering when this feature is active?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're speaking of the generate_pcap_filter() function, I presume? We ask pcap to only give us packets that we care about (ie, ports within one or more of our sequences), because it is infeasible to examine every TCP/UDP packet moving through the system. If we do that, your CPU will jump to 100% under realistic levels of network traffic, so we pretty much have to let the filter do its work.

Doesn't this reduce the difficulty to guess the sequence significantly in general?

Hmm, I don't see how, but I could be missing something. Does a portscan reveal something about the ports in the knock sequence? In my local tests with nmap, I cannot see anything notable, but maybe you do?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't see how, but I could be missing something. Does a portscan reveal something about the ports in the knock sequence

No, what I meant was that it could make brute-forcing the sequence way easier. Theoretically, as soon as an attacker has knocked the first port, there are 65534 ports that will reset the sequence, when knocked, excluding the port next in sequence and 0, if there is no filtering. With the filter, only (number of ports mentioned-1) will reset the sequence while the others are ignored.

Regarding the CPU problem: Maybe we could go the other way around and just exclude a lot of well-known ports that potentially have lots of traffic, and make that port list also configurable for people using the odd port? Then still almost any wrongly knocked port will reset the sequence and the cpu usage will be reasonably low. Then we could also automatically refuse knock sequences from the config, if they contain any of those potential high-traffic ports.

Copy link
Contributor

@TDFKAOlli TDFKAOlli Apr 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhmm, I might be wrong, but only the ports you added as your own sequence are added to the pcap filter. As such knockd only sees the ports you set (lets say 3 ports) and only those can reset the sequence.

Anyhow from the view of an attacker:
First I need to know you use knockd. It is not visible from the outside in a port scan. (Or I could do one port scan and then a second to see if an additional port is now open).
Then even if I know, I don't know in which order to knock your ports or what kind of packets I have to use. Port scans usually run from port 1 to x (e.g. 65535). So increasing order.

Simple example:
You use port 1001, 1002 and 1003 and all three TCP with Syn.. well bad choice I think. According to my understanding this means the port scan in increasing order will touch all your ports and open the door.
But assume you use UDP, then nothing happens. And as an attacker I can't even see the difference between the two (only from doing a port scan again and seeing that another port has opened).

Just using a different order already make it very difficult. Lets say you use port 1001, 1003 and 1002. Now an increasing port scan would not work. 1-1000 is ignored because knockd doesn't see them. 1001 is stage 1 but then comes 1002 and this would be out-of-order and cancel the sequence. Next port 1003 is then also out-of-order because a new sequence is started and 1001 is expected. The rest up to 65535 is irrelevant.
Now of course I could port-scan so that 1001 is first touched, then 1003 and then 1002. But without knowledge of your sequence how should I come to this conclusion? I could only try all kind of combinations and orders of 3 (or more?) ports with all combination of UDP, TCP and syn, fin, etc. packets. And you always have to do another full scan to just see if your previous scan had any effect on another port to be open now. I guess that makes it save in the end (if you select a proper sequence).

Maybe there is a mistake in my understanding? If not, then in my understanding allowing knocking one port again doesn't weaken the security of it. How should that help an attacker in the given examples above?

Copy link
Author

@escitalopram escitalopram Apr 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, maybe I'm overreacting, because I've had a security contractor discover a (admittedly bad) knock sequence a few years ago. So if @jvinet has no problems with this merge request, I guess I'm okay with it too.

For my personal paranoia I can still add a few dozen ports to some NOOP-sequences in my config.

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.

4 participants