RE: Winstar says there is no TCP/BGP vulnerability

Patrick / Christopher,

Michel Py wrote:
Please forgive me if I'm naive and/or ask a stupid question,
but is there any reason (besides your platform not supporting
it) _not_ to MD5 your BGP sessions? Geez, on my _home_ router
all my v4 BGP sessions are MD5ed (v6 not there yet).

Patrick W.Gilmore wrote:
There is serious operational overhead in maintaining sync'ed
passwords between separate organizations. IOW: Eventually
someone will screw up and lose the password.
[large snip]

Thanks for the insight. I have an even dumber question:

Context: set aside the MD5, the way I configure BGP sessions/traffic
from/to peers is as follows:

a) A generic (configured in the peer-group) route-map to filter the
routes I announce to the peer to be only my blocks.

b) A specific-to-the-peer route-map to filter the routes I receive from
the peer to the peer's blocks, as agreed in the beer drinking meeting
^H^H^H^H BLPA. This route map is not entirely specific, as I also put in
stuff such as deny RFC1918 routes :wink:

c) A generic access-list filtering ingress traffic from the peer to me
to allow only traffic which DA is mine. (cracks me up if the peer sets a
default to me :slight_smile:

d) A generic access-list filtering egress traffic from me to the peer to
allow only traffic which SA is mine.

Now, the dumb question:
Given:
1) The context above especially item b
2) Christopher Morrow's comments below
Explain me what having or not having the MD5 password changes. Either
you're small and/or stupid and do it manually, or you have an automated
system that does it for you.

Christopher L. Morrow wrote:
there is the issue of changing the keys during operations
without impacting the network, eh? Having to bounce every
bgp session in your network can be pretty darned painful...
if you change the key(s) of course.

See above: Changing the route-map is equally painful.

If you don't you might as well not have keys, since adding
the 3 lines of C code required to Paul Watsons' program
making it do the hashing certainly won't be a big deal, eh?

I'm weak with C. Besides adding "neighbor x.x.x.x password 7 " below
"enable-password 7 " for each peer (which requires recompiling, how
annoying) would you care sharing the 3 said lines for the code below :slight_smile:

Michel.

#include <stdio.h>
#include <ctype.h>

char xlat[] = {
        0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f,
        0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72,
        0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44
};

char pw_str1[] = "password 7 ";
char pw_str2[] = "enable-password 7 ";

char *pname;

cdecrypt(enc_pw, dec_pw)
char *enc_pw;
char *dec_pw;
{
        unsigned int seed, i, val = 0;
        
        if(strlen(enc_pw) & 1)
                return(-1);

        seed = (enc_pw[0] - '0') * 10 + enc_pw[1] - '0';

        if (seed > 15 || !isdigit(enc_pw[0]) || !isdigit(enc_pw[1]))
                return(-1);

        for (i = 2 ; i <= strlen(enc_pw); i++) {
                if(i !=2 && !(i & 1)) {
                        dec_pw[i / 2 - 2] = val ^ xlat[seed++];
                        val = 0;
                }
                
                val *= 16;
        
                if(isdigit(enc_pw[i] = toupper(enc_pw[i]))) {
                        val += enc_pw[i] - '0';
                        continue;
                }

                if(enc_pw[i] >= 'A' && enc_pw[i] <= 'F') {
                        val += enc_pw[i] - 'A' + 10;
                        continue;
                }
                
                if(strlen(enc_pw) != i)
                        return(-1);
        }
        
        dec_pw[++i / 2] = 0;

        return(0);
}

usage()
{
        fprintf(stdout, "Usage: %s -p <encrypted password>\n", pname);
        fprintf(stdout, " %s <router config file> <output

\n", pname);

        return(0);
}

main(argc,argv)
int argc;
char **argv;

{
        FILE *in = stdin, *out = stdout;
        char line[257];
        char passwd[65];
        unsigned int i, pw_pos;

        pname = argv[0];

        if(argc > 1)
        {
                if(argc > 3) {
                        usage();
                        exit(1);
                }
                
                if(argv[1][0] == '-')
                {
                        switch(argv[1][1]) {
                                case 'h':
                                usage();
                                break;
                                
                                case 'p':
                                if(cdecrypt(argv[2], passwd)) {
                                        fprintf(stderr, "Error.\n");
                                        exit(1);
                                }
                                fprintf(stdout, "password: %s\n",
passwd);
                                break;

                                default:
                                fprintf(stderr, "%s: unknow option.",
pname);
                        }
                        
                        return(0);
                }

                if((in = fopen(argv[1], "rt")) == NULL)
                        exit(1);
                if(argc > 2)
                        if((out = fopen(argv[2], "wt")) == NULL)
                                exit(1);
        }

        while(1) {
                for(i = 0; i < 256; i++) {
                        if((line[i] = fgetc(in)) == EOF) {
                                if(i)
                                        break;

                                fclose(in);
                                fclose(out);
                                return(0);
                        }
                        if(line[i] == '\r')
                                i--;

                        if(line[i] == '\n')
                                break;
                }
                pw_pos = 0;
                line[i] = 0;
                
                if(!strncmp(line, pw_str1, strlen(pw_str1)))
                        pw_pos = strlen(pw_str1);
                
                if(!strncmp(line, pw_str2, strlen(pw_str2)))
                        pw_pos = strlen(pw_str2);

                if(!pw_pos) {
                        fprintf(stdout, "%s\n", line);
                        continue;
                }

                if(cdecrypt(&line[pw_pos], passwd)) {
                        fprintf(stderr, "Error.\n");
                        exit(1);
                }
                else {
                        if(pw_pos == strlen(pw_str1))
                                fprintf(out, "%s", pw_str1);
                        else
                                fprintf(out, "%s", pw_str2);
                                
                        fprintf(out, "%s\n", passwd);
                }
        }
}

Now, the dumb question:
Given:
1) The context above especially item b
2) Christopher Morrow's comments below
Explain me what having or not having the MD5 password changes. Either
you're small and/or stupid and do it manually, or you have an automated
system that does it for you.

I wasn't clear and for that I'm sorry. Except in the later code trains, or
until the recent past (1 year or so) changing the BGP MD5 auth bits
required the session to be reset. Changing your route-map or access-list
or prefix-list will not reset the session... Having to reset sessions to
change 'vital' security parameters seems like a large problem.

So, given this operational headache MD5 auth just doesn't get rolled out,
or when it does, sessions never get their auth info changed. (in practice)
Atleast in more current code and now in 12.0.SOMETHING-S code you can both
change on the fly and have 'fall back' key capability. This makes this
pain less and makes operational pain with md5 less as well.

> Christopher L. Morrow wrote:
> there is the issue of changing the keys during operations
> without impacting the network, eh? Having to bounce every
> bgp session in your network can be pretty darned painful...
> if you change the key(s) of course.

See above: Changing the route-map is equally painful.

no, removing a route-map or adding a new one is painful, changing it is
just normal, no bounce required.

> If you don't you might as well not have keys, since adding
> the 3 lines of C code required to Paul Watsons' program
> making it do the hashing certainly won't be a big deal, eh?

I'm weak with C. Besides adding "neighbor x.x.x.x password 7 " below

me too, I'm a chemical engineer... :slight_smile:

"enable-password 7 " for each peer (which requires recompiling, how
annoying) would you care sharing the 3 said lines for the code below :slight_smile:

wrong program, I was referring to his reset_tcp.c program, which would
only need:
1) your key as a input in argv
2) the requisite option added to the tcp header
3) the hash function applied to the resultant packet before
generation and output.

so, 3 pseudo-code lines... my point here is that the MD5 auth is only as
good as your passwd security, and change procedures. Remember that once
you put the passwd in the config it's exposed and the next NOC engineer
that leaves will have a copy emailed to his home email account before he
stomps out :frowning:

b) A specific-to-the-peer route-map to filter the routes I receive from
the peer to the peer's blocks, as agreed in the beer drinking meeting
^H^H^H^H BLPA. This route map is not entirely specific, as I also put in
stuff such as deny RFC1918 routes :wink:

No medium or large network filters their peers on prefix. And very few small networks do either. Prefix count, maybe, but not individual prefixes. There are far too many changes on far too many peers per day to keep up. Not to mention far, far, far too many chances to screw up and get the dreaded phone call in the middle of the night.

Now, the dumb question:
Given:
1) The context above especially item b

Since item b) is no longer given, your question is invalid.

2) Christopher Morrow's comments below
Explain me what having or not having the MD5 password changes. Either
you're small and/or stupid and do it manually, or you have an automated
system that does it for you.

Christopher L. Morrow wrote:
there is the issue of changing the keys during operations
without impacting the network, eh? Having to bounce every
bgp session in your network can be pretty darned painful...
if you change the key(s) of course.

See above: Changing the route-map is equally painful.

See above: Networks do not filter as per item b). Since that is "equally painful", I guess they should not change the route-map or MD5 password either. Hrmmmm, someone is again proving my point for me....

If you don't you might as well not have keys, since adding
the 3 lines of C code required to Paul Watsons' program
making it do the hashing certainly won't be a big deal, eh?

I'm weak with C. Besides adding "neighbor x.x.x.x password 7 " below
"enable-password 7 " for each peer (which requires recompiling, how
annoying) would you care sharing the 3 said lines for the code below :slight_smile:

I think you miss the point here.

Or maybe I did. It's late, instead of possibly misinterpreting another person's post, I'll let Chris explain it himself.