Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

improve IP cloaking with a salt #52

Open
wants to merge 1 commit into from

7 participants

@anarcat

We have had this new ip_cloaking.c lying around here we wanted to discuss.

We still have to test this, and it's probably not backwards-compatible (so bans will fail), but it's a start of a better default host mangling.

Comments?

@WubTheCaptain

I don't see why to do this since IPs can be uncloaked by attackers anyway. In my opinion regarding that, this isn't really going to bring more security.

@skyhighwings

Having a configurable salt in etc/ircd.conf might be a nice addition, so that your user's IPs are not all immediately known if (when) someone releases a charybdis-family hostmask un-cloaking brute-forcing tool.

Additionally, @WubTheCaptain, with that logic, there's no point in including any IP cloaking at all. It's acknowledged, by this point, that ircd host-cloaking will always be susceptible to being brute-forced if *@real-ip-mask-goes-here matches against cloaked users.

@kaniini
Collaborator

Having a configurable salt in etc/ircd.conf might be a nice addition, so that your user's IPs are not all immediately known if (when) someone releases a charybdis-family hostmask un-cloaking brute-forcing tool.

ChanServ UNBAN on any modern services can do it using CIDR masks -- apparently some moron felt this to be so important that he gave a 50 minute talk about it last year at DerbyCon.

@Elizafox

Having rewritten the host cloaking 4 years ago, I can say this is a conscious design decision.

Here are the reasons:
1) Host cloaking is security theatre. IP's can be retrieved from DCC or figured out using atheme's ChanServ UNBAN feature with quiets. In addition, it's relatively trivial to dupe users into visiting a site to get their IP.

The only reason it exists at all is to stop the casual DDoS kiddie from attacking you. It is not there to provide 100% security.

2) The salt would have to be consistent across the network, or surprises will pop up. A lot of networks will wind up mis-configuring things. Without ENCAP hackery, it would be impossible to ensure the salt remains the same.

3) The hash used at present - FNV - is not cryptographically secure. This is not a bug - cryptographic hashes are slow. Balls slow. Your granny can walk to the store faster than the HMAC can be computed (okay, I kid, but you get the idea). On a huge network, this is computationally intensive, and the ircd is single-threaded. You just made botting a hell of a lot more effective for a bit of "security."

In short, this isn't worth the time, and is of dubious value in increasing security.

@micah
@kaniini
Collaborator

The modified module could be included as an extension, i.e. extensions/ip_cloaking_hmac.so. Making the new behaviour the default would be considered a regression by most users I would think.

@Argure

I've had https://gist.github.com/Argure/7254056 lying around for a while. See #79

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 4, 2014
  1. improve IP cloaking with a salt, first draft

    Antoine Beaupré authored
This page is out of date. Refresh to see the latest.
Showing with 31 additions and 85 deletions.
  1. +31 −85 extensions/ip_cloaking.c
View
116 extensions/ip_cloaking.c
@@ -3,8 +3,10 @@
* ip_cloaking.c: provide user hostname cloaking
*
* Written originally by nenolod, altered to use FNV by Elizabeth in 2008
+ * altered some more by groente
*/
+#include <openssl/hmac.h>
#include "stdinc.h"
#include "modules.h"
#include "hook.h"
@@ -16,6 +18,15 @@
#include "s_user.h"
#include "s_serv.h"
#include "numeric.h"
+#include "newconf.h"
+
+char *secretsalt = "32qwnqoWI@DpMd&w";
+
+static void
+conf_set_secretsalt(void *data)
+{
+ secretsalt = rb_strdup(data);
+}
static int
_modinit(void)
@@ -24,6 +35,9 @@ _modinit(void)
user_modes['h'] = find_umode_slot();
construct_umodebuf();
+ add_top_conf("cloaking", NULL, NULL, NULL);
+ add_conf_item("cloaking", "secretsalt", CF_QSTRING, conf_set_secretsalt);
+
return 0;
}
@@ -33,6 +47,10 @@ _moddeinit(void)
/* disable the umode and remove it from the available list */
user_modes['h'] = 0;
construct_umodebuf();
+
+ add_top_conf("cloaking", NULL, NULL, NULL);
+ add_conf_item("cloaking", "secretsalt", CF_QSTRING, conf_set_secretsalt);
+
}
static void check_umode_change(void *data);
@@ -72,92 +90,23 @@ distribute_hostchange(struct Client *client_p, char *newhost)
}
static void
-do_host_cloak_ip(const char *inbuf, char *outbuf)
-{
- /* None of the characters in this table can be valid in an IP */
- char chartable[] = "ghijklmnopqrstuvwxyz";
- char *tptr;
- uint32_t accum = fnv_hash((const unsigned char*) inbuf, 32);
- int sepcount = 0;
- int totalcount = 0;
- int ipv6 = 0;
-
- rb_strlcpy(outbuf, inbuf, HOSTLEN + 1);
-
- if (strchr(outbuf, ':'))
- {
- ipv6 = 1;
-
- /* Damn you IPv6...
- * We count the number of colons so we can calculate how much
- * of the host to cloak. This is because some hostmasks may not
- * have as many octets as we'd like.
- *
- * We have to do this ahead of time because doing this during
- * the actual cloaking would get ugly
- */
- for (tptr = outbuf; *tptr != '\0'; tptr++)
- if (*tptr == ':')
- totalcount++;
- }
- else if (!strchr(outbuf, '.'))
- return;
-
- for (tptr = outbuf; *tptr != '\0'; tptr++)
- {
- if (*tptr == ':' || *tptr == '.')
- {
- sepcount++;
- continue;
- }
-
- if (ipv6 && sepcount < totalcount / 2)
- continue;
-
- if (!ipv6 && sepcount < 2)
- continue;
-
- *tptr = chartable[(*tptr + accum) % 20];
- accum = (accum << 1) | (accum >> 31);
- }
-}
-
-static void
-do_host_cloak_host(const char *inbuf, char *outbuf)
+do_host_cloak(const char *inbuf, char *outbuf)
{
- char b26_alphabet[] = "abcdefghijklmnopqrstuvwxyz";
- char *tptr;
- uint32_t accum = fnv_hash((const unsigned char*) inbuf, 32);
-
- rb_strlcpy(outbuf, inbuf, HOSTLEN + 1);
-
- /* pass 1: scramble first section of hostname using base26
- * alphabet toasted against the FNV hash of the string.
- *
- * numbers are not changed at this time, only letters.
- */
- for (tptr = outbuf; *tptr != '\0'; tptr++)
- {
- if (*tptr == '.')
- break;
+ unsigned char *hash;
+ char buf[3];
+ char output[HOSTLEN+1];
+ int i;
- if (isdigit(*tptr) || *tptr == '-')
- continue;
+ hash = HMAC(EVP_sha256(), secretsalt, strlen(secretsalt), (unsigned char*)inbuf, strlen(inbuf), NULL, NULL);
- *tptr = b26_alphabet[(*tptr + accum) % 26];
+ output[0]=0;
- /* Rotate one bit to avoid all digits being turned odd or even */
- accum = (accum << 1) | (accum >> 31);
- }
+ for (i = 0; i < 32; i++) {
+ sprintf(buf, "%.2x", hash[i]);
+ strcat(output,buf);
+ }
- /* pass 2: scramble each number in the address */
- for (tptr = outbuf; *tptr != '\0'; tptr++)
- {
- if (isdigit(*tptr))
- *tptr = '0' + (*tptr + accum) % 10;
-
- accum = (accum << 1) | (accum >> 31);
- }
+ rb_strlcpy(outbuf,output,HOSTLEN+1);
}
static void
@@ -209,10 +158,7 @@ check_new_user(void *vdata)
return;
}
source_p->localClient->mangledhost = rb_malloc(HOSTLEN + 1);
- if (!irccmp(source_p->orighost, source_p->sockhost))
- do_host_cloak_ip(source_p->orighost, source_p->localClient->mangledhost);
- else
- do_host_cloak_host(source_p->orighost, source_p->localClient->mangledhost);
+ do_host_cloak(source_p->orighost, source_p->localClient->mangledhost);
if (IsDynSpoof(source_p))
source_p->umodes &= ~user_modes['h'];
if (source_p->umodes & user_modes['h'])
Something went wrong with that request. Please try again.