Mitigating classic NMDC CTM DOS attacks

Bug #1419478 reported by eMTee
256
This bug affects 1 person
Affects Status Importance Assigned to Milestone
DC++
Fix Released
Critical
Unassigned

Bug Description

Proposal and discussion log from the public hub : http://pastebin.com/dMY5eaRP

eMTee (realprogger)
Changed in dcplusplus:
importance: Undecided → High
Fredrik Ullner (ullner)
Changed in dcplusplus:
status: New → Confirmed
Revision history for this message
Gabberworld (gabberworld) wrote :

That Error thing is only for temporary fix for the hubsofts.

Revision history for this message
Fredrik Ullner (ullner) wrote :

Just pasting the text here so pastebin don't just remove it.

Revision history for this message
Fredrik Ullner (ullner) wrote :
Download full text (22.8 KiB)

[2015-01-14 16:05] [16:05:57] <[Apex]RoLex> mornings
[2015-01-14 16:06] [16:06:26] <[Apex]RoLex> i have a new feature for dc in general that i would to discuss
[2015-01-14 16:06] [16:06:37] <[Apex]RoLex> flylinkdc++ and verlihub already supports this
[2015-01-14 16:07] [16:07:09] <[Apex]RoLex> ptokax will support this when dc++ will support this, talked to ppk couple of minutes ago
[2015-01-14 16:07] [16:07:33] <[Apex]RoLex> its related to ctm ddos that some still suffer from
...
[2015-01-14 16:10] [16:10:58] <[Apex]RoLex> it is very little tweaking, it uses already existing commands, only one new parameter needs to be added into dc++
[2015-01-14 16:11] [16:11:47] <[Apex]RoLex>

HUB1 = exploited hub that allows to send fake CTM
HUB2 = attacked hub
HUB2.ADDR = address of attacked hub

DC1 = a bot that sends bad CTM requests to HUB1
DC2 = regular user on HUB1

DC1 -> HUB1 $ConnectToMe DC2 HUB2.ADDR|
HUB1 -> DC2 $ConnectToMe DC2 HUB2.ADDR|

DC2 doesnt find HUB2.ADDR in his blacklist and continues to process CTM request

DC2 -> HUB2 socket_connect(HUB2.ADDR) + $MyNick DC2|$Lock ABC|
HUB2 -> DC2 $Error CTM2HUB|

DC2 adds HUB2.ADDR in his blacklist and closes connection

DC1 -> HUB1 $ConnectToMe DC2 HUB2.ADDR|
HUB1 -> DC2 $ConnectToMe DC2 HUB2.ADDR|

DC2 finds HUB2.ADDR in blacklist and ignores CTM request
...
[2015-01-14 16:13] [16:13:04] <[Apex]RoLex> why $Error CTM2HUB is useful:

1. clients that supports CTM2HUB will blacklist the address
2. clients that dont support CTM2HUB will close the connection immediately (client closes connection on any $Error according to dc++ source code)
...
[2015-01-14 16:14] [16:14:57] <[Apex]RoLex> as i said earlier, verlihub and flylinkdc++ already support this scheme, and we made alot of testing, everything works great
...
[2015-01-14 16:30] [16:30:03] <Yorhel> The $Error is probably not even necessary, if a client receives a $Lock instead of $MyNick first it can infer that it's likely not connected to another client and block the IP
[2015-01-14 16:30] [16:30:16] <Yorhel> But having the $Error makes it explicit, so either way works
[2015-01-14 16:30] [16:30:28] <Yorhel> Overall idea seems good
[2015-01-14 16:33] [16:33:17] <[Apex]RoLex> thats what another person told me too, when first command is $Lock, its most likely a hub. but i was little bit agains that because: $Lock is a valid client-client command too, and according to dc++ source code $Lock and $MyNick doesnt have any specific order = $MyNick must not necessarily be received first, $Lock could be received first too
[2015-01-14 16:33] [16:33:28] <[Apex]RoLex> thats why i chose $Error
[2015-01-14 16:33] [16:33:36] <Yorhel> Okay, makes sense
[2015-01-14 16:33] [16:33:57] <[Apex]RoLex> also with using $Error hub has a chance to read the Ref= part (atleast first time)
...
[2015-01-14 19:07] [19:07:59] <Pretorian> Rolex: Seems easier/better to fix the state machine when getting $Lock as first command.
[2015-01-14 19:09] [19:09:04] <Pretorian> $Error is also, as far as I know, a basic text. I'm not aware of any other command that sends a special identifier for a particular error.
[2015-01-14 19:15] [19:15:52] <Pretorian> A very clude way of managing $Erro...

Revision history for this message
Fredrik Ullner (ullner) wrote :
Revision history for this message
Fredrik Ullner (ullner) wrote :

I have not tested this, I have simply attempted to adapt Pimenov's code with poy's comments (it does compile).

Changed in dcplusplus:
importance: High → Critical
Revision history for this message
Gabberworld (gabberworld) wrote :

i test that in Ynhub and in non DC++ client

Revision history for this message
Gabberworld (gabberworld) wrote :

i think there is problem, you should block hub who send you to the attacked hub, i make some more tests later

Revision history for this message
Gabberworld (gabberworld) wrote :

one thing what you could add that code is check if there not coming in the chat messages, threat them too as error CTM2HUB messages

poy (poy)
information type: Public → Public Security
Revision history for this message
poy (poy) wrote :

thanks; renamed some variables to be more protocol-agnostic (in preparation of tackling bug 1435038) and applied in rev 552709a7d491.

not tested!

Changed in dcplusplus:
status: Confirmed → Fix Committed
Revision history for this message
Gabberworld (gabberworld) wrote :

yeah, tested that code and it actualy works for webpages too

if (aError.compare(0, 7, "CTM2HUB", 7 == 0)) <-- 7 == 0 i think because of that it works for webpages too

weird

Revision history for this message
Gabberworld (gabberworld) wrote :

one thing i dont like is the

+ if(cc_blocked)
+ {
+ LogManager::getInstance()->message(str(F_("Blocked a C-C connection to a hub ('%1%:%2%'; request from '%3%')") % aServer % aPort % aHubUrl));
+ return true;
+ }

is there possible add that it not show that many messages in log? some count or something like that

Revision history for this message
Gabberworld (gabberworld) wrote :

if (aError.compare(0, 7, "CTM2HUB") == 0) maybe you should use something like that ?

Revision history for this message
poy (poy) wrote :

yeah good catch; fixed.
in lack of a more evolved solution, the log messages will have to do for now.

Revision history for this message
Gabberworld (gabberworld) wrote :

UserConnection.cpp

 } else if(aLine[0] == '<') {

  fire(UserConnectionListener::ProtocolError(), this, _("CTM2HUB"));

  return;

 } else if(!isSet(FLAG_NMDC)) {

  fire(UserConnectionListener::ProtocolError(), this, _("Invalid data"));

  return;

 }

helps some old hubsofts who dont have the CTM2HUB command, also helps some webpages who send message back

Revision history for this message
Gabberworld (gabberworld) wrote :

for line 69

Revision history for this message
poy (poy) wrote :

that could be a possibility but goes outside the scope of this thread; needs more analysis. can you open another one about it?

Revision history for this message
poy (poy) wrote :

attaching a test; DC++ successfully avoids sending any data to a hub that has answered with a "CTM2HUB" error.

Revision history for this message
poy (poy) wrote :

Fixed in DC++ 0.851.

Changed in dcplusplus:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.