Script voor verzending waarschuwingsmail na hackpogingen*

Pagina: 1
Acties:

Acties:
  • +1 Henk 'm!

  • SPT
  • Registratie: Januari 2007
  • Laatst online: 06-10 19:21
Agelopen weekend heb ik me verdiept in mogelijkheden om na hackpogingen die afkomstig zijn van een bepaald IP een geautomatiseerde waarschuwingsmail te sturen naar de ISP of het hostingbedrijf waar dat IP onder valt. Hoewel er geen database of iets dergelijks lijkt te bestaan waarin de abuse email adressen staan (zie mijn vraag in dit topic), blijkt het in de praktijk veelal toch mogelijk om iets te doen via reverse mapping. Bijvoorbeeld mijn eigen ip resolvt naar ... .adsl.xs4all.nl. abuse@xs4all.nl is het abuse email adres van xs4all, en na een kleine check blijkt dat dit heel vaak zo werkt.

Ik ben nu dan ook begonnen met het maken van een script dat na een aantal hack/brute-force pogingen geheel geautomatiseerd een waarschuwing mailt naar de provider. Het bevindt zich nog in een beginfase, dus ik ben zeer geïnteresseerd in opmerkingen/toevoegingen. Andere mensen zijn er uiteraard vrij in om de onderstaande code zelf te gebruiken.

Script
De basis van mijn script is fail2ban, dat weer gebaseerd is op iptables. Fail2ban detecteerd een aantal soorten inbraakpogingen, en voegt gedurende één uur in iptables een firewall regel toe die het verkeer van een bepaalde combi van ip en netwerkprotocol blokkeerd. Via crontab voer ik elke nacht een shell script uit, dat een aantal stappen uitvoerd.
(1) Kijk of alle gebande ip's nog in iptables staan (na rebooten wordt iptables gereset).
(2) Indien ip's ontbreken, voeg ze weer toe.
(3) Controleer in /var/log/fail2ban.log of er nog niet geblokkeerde ip's zijn die minstens 2x geblokkeerd zijn door fail2ban
(4) Als dat het geval is: controleer of het ip adres uit Nederland komt (anders geen blokkade).
(5) Controleer in /var/log/auth.log of vanaf het ip ooit succesvol is ingelogd (anders geen blokkade).
(6) Zend indien mogelijk een waarschuwingsmail.
(7) Voeg het ip toe aan de lijst met permanent geblokkeerde ip's, en aan iptables.

Commentaar op het script is uiteraard zeer welkom.

Het script ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/bin/sh

#Check whether all the IP's from ban_list.txt are still banned in iptables
RESULT=`cat ban_list.txt | grep "ALL: " | cut -d " " -f2`
for IP in $RESULT;
    do
    IPTABLES=`iptables -n -L | grep "DROP       all  --  $IP"`
        if [ -z "$IPTABLES" ]
        then
            iptables -A INPUT -s "$IP" -j DROP
        fi
    done

#Then we check whether new IP's have to be banned
RESULT=`cat /var/log/fail2ban.log* | grep "Ban" | cut -d " " -f7`

for IP in $RESULT;
    do
    #First we check whether we have alreadly processed a potentially duplicate IP
    CHECK=`echo "$FINISHED" | grep "$IP"`
    if [ ! -z "$CHECK" ]
    then
        continue
    fi

    #Count how many bans a user has had, if it's more than two he gets banned if he has never logged in
    COUNT=`echo "$RESULT" | grep "$IP" | wc -l`
    if [ ! $COUNT -le 1 ];
    then
        #Check if user is already banned
        BANNED=`cat ban_list.txt | grep "$IP"`
        if [ -z "$BANNED" ]
        then
        #Check country
        COUNTRY=`./country "$IP"`
        if [ "$COUNTRY" = "NL" ]
        then 
        continue
        fi

            #Check if user has ever succesfully loged on to the system
            SUCCESS=`cat /var/log/auth.log | grep "Accepted password" | grep "$IP"`
            if [ -z "$SUCCESS" ]
            then
        #Send a warning mail
        HOST=`host "$IP"`
        RES=`echo "$HOST" | grep "not found"`
        if [ -z "$RES" ]
        then
            MAIL1=`echo "$HOST" | rev | cut -d "." -f3 | rev`
            MAIL2=`echo "$HOST" | rev | cut -d "." -f2 | rev`
            MAIL="abuse@$MAIL1.$MAIL2"

            MAILIP=`host "$MAIL1.$MAIL2" | grep "mail is handled by" | rev | cut -d " " -f1 | tail -n 1 | rev`
            if [ ! -z "$MAILIP" ]
            then
                    MAILIP=`host "$MAILIP" | grep "has address" | rev | cut -d " " -f1 | rev`
                    if [ ! -z "$MAILIP" ]
                        then
                            LOGS=`cat /var/log/auth.log* | grep "$IP"`
                            ./abusemail "$MAILIP" "$MAIL1.$MAIL2" "$MAIL" "$IP" "$LOGS"
                    fi
                fi
        fi
        # Ban the user
                echo "ALL: $IP" >> ban_list.txt
                iptables -A INPUT -s "$IP" -j DROP
                echo "IP $IP is banned"
            fi
        fi
    fi
    FINISHED="$FINISHED\n$IP"
    done
exit


Zoals te zien is maakt het shell script gebruik van twee externe programma's om het land op te zoeken waar het ip vandaan komt, en om de waarschuwingsmail te versturen. Deze zal ik nu kort bespreken.

Herkomstland ip
Maxmind's Geo IP database is een gratis beschikbare database waarin per ip range het herkomstland staat. Deze database wordt regelmatig geupdate. Hoewel je deze database bijvoorbeeld in een MySQL database kunt importeren, maak ik voor dit doel gebruik van een eenvoudig programma dat ik zelf heb geschreven. Ik gebruik dit programma overigens ook voor mijn website, waar ik via PHP een Nederlandstalige welkomsttekst aanbied aan bezoekers uit Nederland, en een engelstalige tekst aan mensen uit het buitenland, en waarbij sommige functionaliteiten (zoals de zichtbaarheid van mijn email adres) alleen beschikbaar zijn voor mensen uit westerse landen. Als jullie bugs of kwetsbaarheden vinden hoor ik het graag.

De broncode is als volgt. Aangezien deze geen externe libraries nodig heeft kan er eenvoudig een executable van worden gemaakt.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#define BUFSIZE 1024

FILE *fildes;
unsigned char data[BUFSIZE+128];

int search(int pos, uint32_t addr)
{
    int i = 0, j;
    uint32_t lower_addr = 0;
    char buf[128];
    
    fseek(fildes, pos, SEEK_SET);
    fread(data, 1, BUFSIZE, fildes);
    
    // Eerste adres
    while (data[i++] != '\n');
    i++;
    j = i;
    while (data[j++] != '"');
    strncpy(buf, &data[i], j - i - 1);
    buf[j - i - 1] = '\0';
    lower_addr = inet_addr(buf);
    lower_addr = htonl(lower_addr);
    if (lower_addr > addr) return 1;
    return 0;
}

int checkout(int pos, uint32_t addr)
{
    int i = 0, j;
    uint32_t lower_addr = 0xffffffff, upper_addr = 0;
    char buf[128];
    
    fseek(fildes, pos, SEEK_SET);
    fread(data, 1, BUFSIZE, fildes);
    while (i < BUFSIZE & addr > upper_addr)
    {
        // Eerste adres
        while (i < BUFSIZE & i < BUFSIZE & data[i++] != '\n');

        i++;
        j = i;

        while (j < BUFSIZE & data[j++] != '"');
        strncpy(buf, &data[i], j - i - 1);
        buf[j - i - 1] = '\0';
        lower_addr = inet_addr(buf);
        lower_addr = htonl(lower_addr);
        while (i < BUFSIZE & data[i++] != ',');

        // Tweede adres
        while (i < BUFSIZE & data[i++] != '"');
        j = i;
        while (j < BUFSIZE & data[j++] != '"');
        strncpy(buf, &data[i], j - i - 1);
        buf[j - i - 1] = '\0';

        upper_addr = inet_addr(buf);
        upper_addr = htonl(upper_addr);
    }
    while (i < BUFSIZE & data[i++] != ',');
    while (i < BUFSIZE & data[i++] != ',');
    while (i < BUFSIZE & data[i++] != ',');

    i++;
    buf[0] = data[i++]; buf[1] = data[i++]; buf[2] = '\0';
    printf("%s", buf);
    return 0;
}

int main(int argc, char *argv[])
{
    int pos = 0, searchsize = 1000000;
    uint32_t addr = 0;
    
    if (argc != 2)
    {
        printf("Error");
        return 0;
    }
    addr = inet_addr(argv[1]);
    if (addr == INADDR_NONE | addr == EAFNOSUPPORT | addr == ENOSPC)
    {
        printf("Error");
        return 0;
    }
    addr = htonl(addr);
    
    fildes = fopen("GeoIPCountryWhois.csv", "r");
    if(!fildes)
    {
        printf("Error");
        return 0;
    }
    fseek(fildes, 0L, SEEK_END);
    int len = ftell(fildes);

    while (pos < len)
    {
        if (search(pos, addr) == 1) break;
        pos += searchsize;
    }
    pos -= searchsize;
    searchsize /= 10;
    pos += searchsize;
    while (pos < len)
    {
        if (search(pos, addr) == 1) break;
        pos += searchsize;
    }
    pos -= searchsize;
    searchsize /= 10;
    pos += searchsize;
    while (pos < len)
    {
        if (search(pos, addr) == 1) break;
        pos += searchsize;
    }
    pos -= searchsize;
    searchsize /= 10;
    pos += searchsize;
    while (pos < len)
    {
        if (search(pos, addr) == 1) break;
        pos += searchsize;
    }
    pos -= searchsize;
    checkout(pos, addr);
    fclose(fildes);
    return 0;
}


Versturen waarschuwings mail
Ook het versturen van de waarschuwingsmail verloopt zoals gezegd via een simpel programmatje. Dat zit itt. het bovenstaande programma echter extreem ad-hoc inelkaar. De versie die hieronder staat is een test versie, die de waarschuwingsmail naar mijn eigen email adres stuurt. Door deze regels te vervangen door de uitgeschakelde versies die zich baseren op argv[1], argv[2] en argv[3] gaat de mail naar het juiste adres.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <sys/types.h>
#include <sys/socket.h> 
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>


#define PORT_NR 25
#define ERROR -1
#define NOT_FOUND -1

int sockfd;


int main(int argc, char *argv[])
{
    if (argc < 6) return -1;
    int sockfd, len, result;
    struct sockaddr_in address;
    
    time_t t;
    struct tm *tstruct;
        
    // Create a socket for the client
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    // Set a timeout interval
    struct timeval tv;
    tv.tv_sec = 30;  /* 30 Secs Timeout */  
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval));   
    
    // Name the socket
    address.sin_family = AF_INET;
//  address.sin_addr.s_addr = inet_addr(argv[1]);
    address.sin_addr.s_addr = inet_addr("192.168.1.11");
    address.sin_port = htons(PORT_NR);
    len = sizeof(address);
    
    if (strlen(argv[4]) > 3000) return -1;
    
    // Connect your socket to the server&#8217;s socket
    result = connect(sockfd, (struct sockaddr *)&address, len);
    if(result == -1)
    { 
        printf("Could not connect!\n");
        return 0;
    }
    
    char *helo, *rcptto, *message, *from;
    helo = malloc(32 + strlen(argv[2]));
    rcptto = malloc(32 + strlen(argv[3]));
    from = malloc(1024);
    message = malloc(4096);
//    sprintf(helo, "HELO %s\n", argv[2]);
    sprintf(helo, "HELO %s\n", "eigen_domein.net");
//    sprintf(rcptto, "RCPT TO: %s\n", argv[3]);
    sprintf(rcptto, "RCPT TO: %s\n", "mail@eigen_domein.net");
    sprintf(from, "From: noreply@noreply.net\nSubject: Abuse from ip %s\n\n", argv[4]);
    sprintf(message, "THIS MESSAGE WAS AUTOMATICALLY GENERATED\n\nDear Mr./Mrs.,\n\nI have noticed several attacks on my system, originating from the following ip-address:\n\n%s\n\nThis ip-address seems to be owned by your company. Relevant log entries have been included at the bottom of this mail.\n\nI would like to kindly ask you to undertake the necessary steps to stop this.\n\nThank you in advance.\n\nBest regards,\nRaspberry Pi\n\n%s\n.\n", argv[4], argv[5]);
    send(sockfd, helo, strlen(helo),0);
    send(sockfd,"MAIL FROM: noreply@noreply.net\n",strlen("MAIL FROM: noreply@noreply.net\n"),0);
    send(sockfd, rcptto,strlen(rcptto),0);
    send(sockfd,"DATA\n",strlen("DATA\n"),0);
    send(sockfd, from,strlen(from),0);
    send(sockfd, message,strlen(message),0);
    
    close(sockfd);
    return 0;
}

Acties:
  • 0 Henk 'm!

  • iisschots
  • Registratie: November 2002
  • Laatst online: 12-10 17:38
titel aangepast

Hackerspace in Friesland | www.frack.nl | Bezig met opzetten, help mee!


Acties:
  • 0 Henk 'm!

  • Brahiewahiewa
  • Registratie: Oktober 2001
  • Laatst online: 30-09-2022

Brahiewahiewa

boelkloedig

Knap stukje script; daar niet van. Maar ik vrees dat 't effect is dat (de beheerders van) ISP's voornamelijk tijd gaan steken in 't automagisch doorzetten van jouw mail naar dev0. Tijd, die ze ook aan het veiliger maken van hun netwerk hadden kunnen besteden.

QnJhaGlld2FoaWV3YQ==


Acties:
  • 0 Henk 'm!

  • SPT
  • Registratie: Januari 2007
  • Laatst online: 06-10 19:21
Brahiewahiewa schreef op dinsdag 05 februari 2013 @ 14:46:
Knap stukje script; daar niet van. Maar ik vrees dat 't effect is dat (de beheerders van) ISP's voornamelijk tijd gaan steken in 't automagisch doorzetten van jouw mail naar dev0. Tijd, die ze ook aan het veiliger maken van hun netwerk hadden kunnen besteden.
Als sommige van hun klanten zombie machines zijn, en ze meldingen daarover negeren, denk ik niet dat tijd besteden aan het veiliger maken van hun netwerk veel prioriteit heeft. Ik zou het eerlijk gezegd behoorlijk asociaal vinden, en betwijfel of alle bedrijven zo te werk gaan. Het zou ze trouwens ook juridische problemen op kunnen leveren: telecom bedrijven zijn alleen uitgesloten van aansprakelijkheid voor het faciliteren van verboden activiteiten indien ze daarvan niet op de hoogte zijn.

[ Voor 14% gewijzigd door SPT op 05-02-2013 15:56 ]


Acties:
  • 0 Henk 'm!

  • Brahiewahiewa
  • Registratie: Oktober 2001
  • Laatst online: 30-09-2022

Brahiewahiewa

boelkloedig

Nou, voor ISP's zou 't betekenen dat er constant zo'n 10% van hun klandizie afgesloten is. De ellende die dat geeft (helpdesk calls, mensen die hun abonnementsgeld terug eisen, mensen die willen weten hoe ze 't oplossen) daar zou ik persoonlijk niet aan beginnen (maar ik ben ook geen ISP).

Tel daarbij op de know-how die ze daarvoor nodig hebben en dus moeten inhuren of salariëren, dan heb je denk ik wel een idee van 't kostenplaatje. E vergeet niet dat 't crisis is

QnJhaGlld2FoaWV3YQ==


Acties:
  • 0 Henk 'm!

  • Jheroun
  • Registratie: April 2002
  • Niet online
Reactie zal een beetje van de ISP afhangen. Veel ISP's hebben gewoon een abusedesk waar echt wel iets met dergelijke gegevens gedaan kan worden. Als je ze echter bv iedere dag mailt kom je al gauw in een spambox terecht denk ik.

Ze zullen zeker niet grootschalig klanten af gaan sluiten maar als een ISP van een bepaald IP ziet dat die heel vaak langskomt (en daar zal een abusedesk ook allerlei scripting voor hebben) kunnen ze dit soort info wel meenemen.

Veel zal afhangen van wat jouw definitie van hack is. Is een regelmatige connect op een poort ook een hackpoging of niet? Als je connect en inlogpogingen ziet op een poort lijkt me dat wat anders dan een willekeurige portscan die langskomt.

Acties:
  • 0 Henk 'm!

  • SPT
  • Registratie: Januari 2007
  • Laatst online: 06-10 19:21
Dingen als poortscannen en verbindingen maken en verbreken beschouw ik niet als hack, het gaat in de praktijk nagenoeg uitsluitend om het bruteforcen op ssh en mail. Meestal worden er dan woordenboek aanvallen uitgevoerd onder standaard login namen als root en admin. Dat is natuurlijk totaal kansloos, en vroeger had ik dan ook helemaal geen beveiliging daartegen. Omdat me echter laatst bij toeval opviel dat met nanaf één ip al een week lang bezig was permanent te brute-forcen, zodat mijn log gigantisch lang begon te worden, heb ik fail2ban geïnstalleerd. Het email script is eigenlijk uitsluitend bedoeld om de andere kant te helpen, voor mijzelf maakt het niets uit.
Pagina: 1