Ein Honeypot für Angreifer aus dem Web und ein Verfahren für eine whitelist

Angriffen auf Webserver geht zumeist ein mehr oder weniger automatisiertes Herumprobieren voraus, mit welchem die Angreifer nach verwundbarer Software suchen. Das kann man nutzen um solche Angriffe abzuwehren.

Ich selbst benutze auf meinem Server ein kleines, selbst geschriebenes Skript und die Datei .htaccess um solche Angriffe zu erkennen und die Angreifer vorsorglich zu sperren. Um bestimmte Dienste auszunehmen arbeite ich dabei mit einer whitelist. Kommen solche vermeintlichen Angriffsvorberitungen von einer bestimmten Adresse, oder einem bestimmten Adressbereich, dann wird derjenige, der den Abruf tätigt (das kann auch ein Robot oder Bot sein) darauf hingewiesen,eine Sperrung erfolgt aber nicht.

Geschrieben ist dies in PHP für den Apache Webserver auf Linux. Bitte seien Sie vorsichtig, Sie könnten sich selbst aussperren, wenn Sie sich selbst nicht in die whitelist aufgenommen haben. Im Übrigen können Sie sich per E-Mail informieren lassen, wenn eine IP gesperrt wird.


1. Die Datei " ___honeypot.php":

<?php
/*
      Konfiguration
*/
define ('FS_ROOT', '/srv/www/vhosts/');
# oder_ define ('FS_ROOT', $_SERVER['DOCUMENT_ROOT']);

define ('INFOMAIL', 'Vorname Name <mailexample.org>');
# oder: define ('INFOMAIL', FALSE);

# Whitelist-Datei
define ('FTX_IP_LIST_FILE',FS_ROOT.'___honeypot_whitlelist.txt');

#Array mit Subdomains oder virtuellen Domains in Unterverzeichnissen,
#in denen ebenfalls gesperrt werden soll:
$arDirs=array(
    'fastix.de',
    'fastix.org'
);

$GLOBALS['FTX_LIST_FILTER'] = new IPFilter(FTX_getListArray(FTX_IP_LIST_FILE));

$addr=str_replace (array('"', '\'', '`','\\'),'',$_SERVER['REMOTE_ADDR']);

if (FTX_checkIp($addr)) {
    header('HTTP-ERROR: 404');
    header('HTTP/1.1: 404');
    print '404 - NOT FOUND';
    exit;
}

$regUri=str_replace(array('"',"'",'`',"\n","\r",'|'),'',$_SERVER['REQUEST_URI']);
$serverName=str_replace(array('"',"'",'`',"\n","\r",'|'),'',$_SERVER['SERVER_NAME']);

foreach ($arDirs as $dir) {
    $file=FS_ROOT.$dir.'/.htaccess';
    $sys='echo "#'.date('Y-m-d H:i:s').'" >>'.$file;
    $dummy=system($sys);
    $sys= 'echo "deny from '.$addr.'" >> '.$file;
    $dummy=system($sys);
}
if (INFOMAIL) {
    mb_send_mail (
      INFOMAIL,
      'Blockierter Zugriff auf Webserver -> htaccess',
      $serverName . $regUri . ' - ' . $addr . ' (wurde in .htaccess eingetragen).'
    );
}

header('HTTP-ERROR: 404');
header('HTTP/1.1: 404');
die ('
<h1>Fine!</h1>
<ul>
	<li>You have tried to access "'.htmlentities($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).'".</li>
	<li>But this server has a admin was is not a f***** script-kiddy.</li>
	<li>You are blocked now. Try to reload, then cry!</li>
</ul>
<hr />
<h1>Toll!</h1>
<ul>
	<li>Sie haben versucht "'.htmlentities($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).'" aufzurufen.</li>
	<li>Aber der Administrator dieses Servers ist kein verf****** Script-kiddy.</li>
	<li>Sie werden jetzt blockiert. Um sich zu ärgern versuchen Sie es mit einem Reload!</li>
</ul>
');

####################################################################################
#                                       WHITELIST                                  #
####################################################################################

function FTX_checkIp ($ip, $listet=TRUE, $notListet=FALSE) {
    if ( $GLOBALS['FTX_LIST_FILTER'] -> check($ip)) {
        return($listet);
    }
    return $notListet;
}

function FTX_getListArray($listFile) {
    $arList=array();
    $ar=array();
    $ar_lenght=0;
    $str='';
    $i=0;
    if ($listFile) {
        $ar=file($listFile);
        $ar_lenght=count($ar);
        if ($ar_lenght) {
            for ($i=0; $i<$ar_lenght; $i++) {
                $str=strtolower(trim($ar[$i]));
                if ( '' != $str && '#' != $str{0} ) {
                     if ( false !== strpos($str,'#') ) {
                          $str=substr($str, 0, strpos($str,'#'));
                     }
                     $arList[]=trim($str);
                }
            }
        }
    }
    return ($arList);
}

function ip_or_mask_to_bin($ip_m) {
    $a=explode('.',$ip_m);
    if (4==count ($a)) {
    for ($i=0; $i<4; $i++) {
        if (0 > $a[$i] || 255 < $a[$i]) {
            die("Fehler in ". __FILE__ .", function 'ip_to_bin': keine gültige IP-Adresse oder Netzwerkmaske übergeben: '$ip_m'\n");
        }
    }
    return   str_pad(decbin($a[0]), 8, '0', STR_PAD_LEFT)
            .str_pad(decbin($a[1]), 8, '0', STR_PAD_LEFT)
            .str_pad(decbin($a[2]), 8, '0', STR_PAD_LEFT)
            .str_pad(decbin($a[3]), 8, '0', STR_PAD_LEFT);
    }
    if (1==count($a)) {
        if (0 > $ip_m && 32 < $ip_m) {
            die("Fehler in ". __FILE__ .", function 'ip_to_bin': keine gültige IP-Adresse oder Netzwerkmaske übergeben: '$ip_m'\n");
        }
        return str_repeat ( '1' , $a[0] ).str_repeat ( '0' , 32-$a[0] );
    }
    die("Fehler in ". __FILE__ .", function 'ip_to_bin': keine gültige IP-Adresse oder Netzwerkmaske übergeben: '$ip_m'\n");
}

class IPFilter  {
    private static $_IP_TYPE_SINGLE = 'single';
    private static $_IP_TYPE_WILDCARD = 'wildcard';
    private static $_IP_TYPE_MASK = 'mask';
    private static $_IP_TYPE_SECTION = 'section';
    private $_allowed_ips = array();

    public function __construct($allowed_ips)  {
        $this -> _allowed_ips = $allowed_ips;
    }

    public function check($ip, $allowed_ips = null)   {
        $allowed_ips = $allowed_ips ? $allowed_ips : $this->_allowed_ips;

        foreach($allowed_ips as $allowed_ip)  {
            $type = $this -> _judge_ip_type($allowed_ip);
            $sub_rst = call_user_func(array($this,'_sub_checker_' . $type), $allowed_ip, $ip);

            if ($sub_rst)  {
                return true;
            }
        }

        return false;
    }

    private function _judge_ip_type($ip)
    {
        if (strpos($ip, '*'))  {
            return self :: $_IP_TYPE_WILDCARD;
        }

        if (strpos($ip, '/'))  {
            return self :: $_IP_TYPE_MASK;
        }

        if (strpos($ip, '-')) {
            return self :: $_IP_TYPE_SECTION;
        }

        if (ip2long($ip)) {
            return self :: $_IP_TYPE_SINGLE;
        }

        return false;
    }

    private function _sub_checker_single($allowed_ip, $ip)  {
        return (ip2long($allowed_ip) == ip2long($ip));
    }

    private function _sub_checker_wildcard($allowed_ip, $ip) {
        $allowed_ip_arr = explode('.', $allowed_ip);
        $ip_arr = explode('.', $ip);
        for($i = 0;$i < count($allowed_ip_arr);$i++)
        {
            if ($allowed_ip_arr[$i] == '*') {
                return TRUE;
            }  else  {
                if (FALSE == ($allowed_ip_arr[$i] == $ip_arr[$i]))  {
                    return FALSE;
                }
            }
        }
    }

    private function _sub_checker_mask($allowed_ip, $ip)    {
        list($allowed_ip, $allowed_ip_mask) = explode('/', $allowed_ip);
        $allowed_ip_bin        = ip_or_mask_to_bin($allowed_ip);
        $allowed_ip_mask_bin    = ip_or_mask_to_bin($allowed_ip_mask);
        $ip_bin            = ip_or_mask_to_bin($ip);
        $network_bin='';
        $broadcast_bin='';
        for ($i=0; $i<32; $i++) {
                if ( '1'==$allowed_ip_bin{$i} && '1'==$allowed_ip_mask_bin{$i} ) {
                        $network_bin.='1';
                } else {
                        $network_bin.='0';
                }
                if ( '0'==$allowed_ip_mask_bin{$i} || ( '1'==$allowed_ip_bin{$i} && '1'==$allowed_ip_mask_bin{$i} ) ) {
                        $broadcast_bin.='1';
                } else {
                        $broadcast_bin.='0';
                }
        }
        return (bindec($ip_bin) >= bindec($network_bin) && bindec($ip_bin) <= bindec($broadcast_bin));
    }

    private function _sub_checker_section($allowed_ip, $ip)
    {
        list($begin, $end) = explode('-', $allowed_ip);
        $begin = ip2long(trim($begin));
        $end = ip2long(trim($end));
        $ip = ip2long($ip);
        return ($ip >= $begin && $ip <= $end);
    }
}
?>

 

Die Datei mit den "whitelist"-Einträgen:

Dies sind IP-Adressen in folgenden Formen:

192.168.10.10                   # Einzelne IP-Adresse
192.168.10.1 - 192.168.10.10    # Bereich von - bis
192.168.10.1/255.255.255.0      # IP-Adresse und Netzwerkmaske
192.168.10.1/24                 # IP-Adresse und Netzwerkmaske

 

2. Beispiel der Datei "___honeypot_whitlelist.txt"

# Dieser Server:
81.28.232.70
127.0.0.1

#Google:
66.249.64.1/19
216.239.32.0-216.239.63.255
64.68.80.0 - 64.68.87.255
66.102.0.0 - 66.102.15.255
64.233.160.0 - 64.233.191.255
66.249.64.0 - 66.249.95.255
72.14.192.0 - 72.14.255.255
209.85.128.0 - 209.85.255.255
198.108.100.192 - 198.108.100.207
173.194.0.0 - 173.194.255.255
216.33.229.144 - 216.33.229.151
216.33.229.160 - 216.33.229.167
209.185.108.128 - 209.185.108.255
70.32.128.0 - 70.32.159.255
216.109.75.80 - 216.109.75.95
64.68.88.0 - 64.68.95.255
64.68.64.64 - 64.68.64.127
64.41.221.192 - 64.41.221.207
74.125.0.0 - 74.125.255.255

 

Hinzu kommen Einträge in der Datei .htaccess oder der Serverkonfiguration, mit denen sichergestellt wird, dass bei einem Angriffsversuch auch das Skript (Programm) "___honeypot.php" ausgeführt wird:

 

3. Einträge in Datei ".htaccess"

###
# Rules for Honeypot
###

# Dirs
RewriteRule   ^admin/(.*)$         ./___honeypot.php [L]
RewriteRule   ^admin$              ./___honeypot.php [L]
RewriteRule   ^wp-admin/(.*)$      ./___honeypot.php [L]
RewriteRule   ^wp-admin$           ./___honeypot.php [L]
RewriteRule   ^noxdir/(.*)$        ./___honeypot.php [L]
RewriteRule   ^noxdir$             ./___honeypot.php [L]
RewriteRule   ^phpMyAdmin/(.*)$    ./___honeypot.php [L]
RewriteRule   ^phpMyAdmin$         ./___honeypot.php [L]
RewriteRule   ^phpmyadmin/(.*)$    ./___honeypot.php [L]
RewriteRule   ^phpmyadmin$         ./___honeypot.php [L]
RewriteRule   ^pma/(.*)$           ./___honeypot.php [L]
RewriteRule   ^pma$                ./___honeypot.php [L]
RewriteRule   ^PMA/(.*)$           ./___honeypot.php [L]
RewriteRule   ^PMA$                ./___honeypot.php [L]
RewriteRule   ^xampp/(.*)$         ./___honeypot.php [L]
RewriteRule   ^xampp$              ./___honeypot.php [L]
RewriteRule   ^vhcs2/(.*)$         ./___honeypot.php [L]
RewriteRule   ^vhcs$               ./___honeypot.php [L]
RewriteRule   ^mysql/(.*)$         ./___honeypot.php [L]
RewriteRule   ^mysql$              ./___honeypot.php [L]
RewriteRule   ^myadmin/(.*)$       ./___honeypot.php [L]
RewriteRule   ^myadmin$            ./___honeypot.php [L]
RewriteRule   ^mysqldumper/(.*)$   ./___honeypot.php [L]
RewriteRule   ^mysqldumper$        ./___honeypot.php [L]
RewriteRule   ^db/(.*)$            ./___honeypot.php [L]
RewriteRule   ^db$                 ./___honeypot.php [L]
RewriteRule   ^mysqldump/(.*)$     ./___honeypot.php [L]
RewriteRule   ^mysqldump$          ./___honeypot.php [L]
RewriteRule   ^msd/(.*)$           ./___honeypot.php [L]
RewriteRule   ^msd$                ./___honeypot.php [L]
RewriteRule   ^backup/(.*)$        ./___honeypot.php [L]
RewriteRule   ^backup$             ./___honeypot.php [L]
RewriteRule   ^dmpr/(.*)$          ./___honeypot.php [L]
RewriteRule   ^dmpr$               ./___honeypot.php [L]
RewriteRule   ^websql/(.*)$        ./___honeypot.php [L]
RewriteRule   ^websql$             ./___honeypot.php [L]
RewriteRule   ^sqlweb/(.*)$        ./___honeypot.php [L]
RewriteRule   ^sqlweb$             ./___honeypot.php [L]
RewriteRule   ^sqlmanager/(.*)$    ./___honeypot.php [L]
RewriteRule   ^sqlmanager$         ./___honeypot.php [L]
RewriteRule   ^mysqlmanager/(.*)$  ./___honeypot.php [L]
RewriteRule   ^mysqlmanager$       ./___honeypot.php [L]
RewriteRule   ^typo3/(.*)$         ./___honeypot.php [L]
RewriteRule   ^typo3$              ./___honeypot.php [L]
RewriteRule   ^horde/(.*)$         ./___honeypot.php [L]
RewriteRule   ^horde$              ./___honeypot.php [L]

#Files
RewriteRule   proxyheader.php(.*)$ ./___honeypot.php [L]
RewriteRule   judge.php(.*)$       ./___honeypot.php [L]
RewriteRule   ip.php(.*)$          ./___honeypot.php [L]
RewriteRule   proxy-1.php(.*)$     ./___honeypot.php [L]
RewriteRule   uploadify.php(.*)$   ./___honeypot.php [L]

 

Den Honeypot habe ich auf Grund meiner Erfahrungen mit ähnlichen Versuchen just eines großen und ziemlich unverschämt agierenden Mitbewerbers programmiert und eingerichtet. Natürlich muss womöglich Einiges an Ihre Gegebenheiten angepasst werden. Dabei helfe ich jedoch gern und günstig.


Weitere Informationen in diesem Bereich: