what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

scandetd.c

scandetd.c
Posted Aug 17, 1999
Authored by Michal Suszycki

Scandetd is a port scan detection daemon that waits for incoming tcp connections and tries to recognize port scans. If tripped, scandetd sends email to root@127.0.0.1 with the time, attacking host, number of connections made, port of the first and last connections. Easy on system resources; for Linux; initial release. 6k.

tags | root, tcp
systems | linux, unix
SHA-256 | 305219b79f012a5152846430f4c566386f23c156aa8d040e810ccddc4f3c7a6d

scandetd.c

Change Mirror Download
/*
* Scandetd is daemon which tries to recognize port scanning.
* If it happens daemon sends e-mail to root@localhost (by default)
* with following informations:
*
* time
* host
* how many connetctions was made
* port of first connection and port of last connection
*
* compile: gcc scandetd.c -o scandetd
*
* author: Michal Suszycki mike@wizard.ae.krakow.pl
*
* You can change few define's and variables below this comment to tune
* scandetd to your needs.
*
* If you have some problems with compiling try to
* change 2 lines:
* #include <netinet/ip.h> to #include <linux/ip.h>
* #include <netinet/tcp.h> to #include <linux/tcp.h>
*
* This code was based on IpLogger Package by Mike Edulla (medulla@infosoc.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
//#include <netinet/ip.h>
#include <linux/ip.h>
//#include <netinet/tcp.h>
#include <linux/tcp.h>
#include <time.h>
#include <signal.h>
#include <string.h>

extern int errno;


/* how many hosts should I remember. If your server is heavily loaded it's
good idea to increase this number a little bit
*/
#define HOW_MANY 6

/* how many connections should I recognize as scanning? */
#define SCAN 25

/* uncomment this to enable printing to log files scan warnings (using syslogd) */
//#define DOSYSLOG

/* uncoment this if you want to log every connection attempt (using syslogd) */
//#defind LOGCON

/* here you can define special port you want to ignore:
if 'scanning' started and ended on the same port and this port is equal
to NOPORT then 'scanning' will be ignored. If you notice for example that
your server get a lot of fast connections (from one host) to www port you
can define NOPORT to 80 so there will be no false warnings
*/
#define NOPORT 80

/*
If next connection arrived right after the previous one we have to count it.
Default time is 1 second.
*/
#define SEC 1

/* We use this port for sending mail */
#define MAILPORT 25

/* we send mail to <user@host>: */
char *mail_to = "<root@localhost>";

/* IP of the machine which sends our mail */
char *mail_host = "127.0.0.1";

/* mail will be send from host: */
char *from_host = "localhost";


/* ----------- end of user's configuration ---------------- */

#ifndef NOFILE
#define NOFILE 1024
#endif


char *hostlookup(int i)
{
static char buff[256];
struct in_addr ia;
struct hostent *he;
ia.s_addr = i;

if (!(he = gethostbyaddr((char *)&ia, sizeof ia, AF_INET)))
strncpy(buff,inet_ntoa(ia),sizeof buff);
else
strncpy(buff,he->h_name,sizeof buff);
return buff;
}

char *servlookup(unsigned short port)
{
struct servent *se;
static char buff[256];

se=getservbyport(port, "tcp");
if(se == NULL) sprintf(buff, "port %d", ntohs(port));
else sprintf(buff, "%s", se->s_name);
return buff;
}



struct ippkt{
struct iphdr ip;
struct tcphdr tcp;
} pkt;

struct host{
unsigned int from;
time_t t;
time_t start;
unsigned short low_port;
unsigned short hi_port;
int count;
} hosts[HOW_MANY];

void demonize()
{
int fd, f;

if (getppid() != 1){
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
f = fork();
if (f < 0)
exit(-1);

if (f > 0)
exit (0);

/* child process */
setpgrp();
for (fd = 0 ; fd < NOFILE; fd++) close(fd);
chdir("/");
umask(0);
return;
}
}


void init()
{
int i;
time_t now;
now = time(NULL);
for (i = 0; i < HOW_MANY; i++)
hosts[i].t = now;
}

int allocate(int *p, unsigned int addr)
{
int i, v = 0;
time_t tmp = hosts[0].t;
for( i = 0; i < HOW_MANY; i++){
if (hosts[i].t <= tmp) {
tmp = hosts[i].t;
v = i;
}
if (hosts[i].from == addr){
*p = 1;
return i;
}
}
*p = 0;
return v;
}

// only for debugging
void show(int a)
{
int i;

for (i = 0; i < HOW_MANY; i++){
printf("Host %s, time %ld, count=%d, l=%d,",
hostlookup(hosts[i].from),hosts[i].t, hosts[i].count,
ntohs(hosts[i].low_port));
printf("hi = %d\n",ntohs(hosts[i].hi_port));
}
exit (0);
}

void no_zombie(int i)
{
wait(NULL);
}

int send_mail(struct host *bad)
{
static struct sockaddr_in sa;
int s, i, low, high;
char buf[1024], combuf[256];

char *comm[] = { "HELO ", from_host,
"MAIL FROM: SCANDETD@", from_host,
"RCPT TO:" , mail_to,
"DATA" , " "
};

i = fork();

if (i < 0) return -1;
if (!i) return 0;

low = ntohs(bad->low_port);
high = ntohs(bad->hi_port);
sprintf(buf,"%sPossible port scanning from %s,\n"
"I counted %d connections.\nFirst connection was made on %d port and the last one on %d port.\r\n.\r\n",
ctime(&bad->start),hostlookup(bad->from),bad->count, low, high);


sa.sin_port = htons(MAILPORT);
sa.sin_family = AF_INET;
if ((sa.sin_addr.s_addr = inet_addr(mail_host)) == -1)
exit (-1);

bzero(&sa.sin_zero, 8);
if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0)
exit (-1);

if (connect(s,(struct sockaddr *) &sa, sizeof (struct sockaddr)) < 0)
exit (-1);

for (i = 0; i < 8 ; i += 2){
sprintf(combuf,"%s%s\n",comm[i],comm[i+1]);
if (write(s,combuf,strlen(combuf)) < 0 ){
close(s);
exit(-1);
}
sleep(1);
}
if (write(s,buf,strlen(buf)) < 0) exit(-1);
sleep(1);
if (write(s,"QUIT\n",5) < 0) exit (-1);

close(s);
exit(0);
}


void main(int argc, char **argv)
{
int s, index, was;
time_t now;

demonize();

init();
s = socket(AF_INET, SOCK_RAW, 6);

#ifdef DOSYSLOG
openlog("scandetd", 0, LOG_LOCAL2);
syslog(LOG_NOTICE,"scandetd started and ready");
#endif
// signal(SIGINT,show);

/* to avoid zombies */
signal(SIGCHLD,no_zombie);

while(1){
read(s, (struct ippkt*) &pkt, sizeof(pkt));
now = time(NULL);

if (pkt.tcp.syn == 1 && pkt.tcp.ack == 0){

#ifdef LOGCON
syslog(LOG_NOTICE,"%s connecion attempt from %s",
servlookup(pkt.tcp.dest),
hostlookup(pkt.ip.saddr)
);
#endif
index = allocate(&was,pkt.ip.saddr);

if (!was){
if (hosts[index].count >= SCAN
#ifdef NOPORT
&& hosts[index].low_port != htons(NOPORT)
&& hosts[index].hi_port != htons(NOPORT)
#endif
){
send_mail(&hosts[index]);
#ifdef DOSYSLOG
syslog(LOG_NOTICE,"Possible port scanning from %s",
hostlookup(hosts[index].from));
#endif
}
hosts[index].from = pkt.ip.saddr;
hosts[index].low_port = pkt.tcp.dest;
hosts[index].hi_port = pkt.tcp.dest;
hosts[index].count = 1;
hosts[index].t = now;
hosts[index].start = now;
continue;
}

/* if this connection was right after previous we must count it */
else if (now - SEC <= hosts[index].t){
hosts[index].count++;
hosts[index].hi_port = pkt.tcp.dest;

}
hosts[index].t = now;
}
}
}

Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    8 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    11 Files
  • 23
    Apr 23rd
    68 Files
  • 24
    Apr 24th
    23 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close