diff --git a/.gitignore b/.gitignore index c6597e4..6d2d5e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,4 @@ -# CakePHP 3 - /vendor/* -/config/app.php - -/tmp/cache/models/* -!/tmp/cache/models/empty -/tmp/cache/persistent/* -!/tmp/cache/persistent/empty -/tmp/cache/views/* -!/tmp/cache/views/empty -/tmp/sessions/* -!/tmp/sessions/empty -/tmp/tests/* -!/tmp/tests/empty - -/logs/* -!/logs/empty - -# CakePHP 2 - -/app/tmp/* -/app/Config/core.php -/app/Config/database.php -/vendors/* +composer.lock +composer.phar +GeoLite2-City.mmdb \ No newline at end of file diff --git a/LICENSE b/LICENSE index 52dcd8e..9a966a7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Andrea Santaniello +Copyright (c) 2022 Andrea Santaniello / Monocul.us Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..bdcb887 --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "geoip2/geoip2": "~2.0" + } +} diff --git a/config.php b/config.php new file mode 100644 index 0000000..5993ea5 --- /dev/null +++ b/config.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/naughtylist.php b/naughtylist.php new file mode 100644 index 0000000..6aba22a --- /dev/null +++ b/naughtylist.php @@ -0,0 +1,166 @@ + $name, + 'protocol' => $protocol, + 'port' => $port, + 'ip' => $ip, + 'key' => REMOTESECRET + ]; + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); + $response = curl_exec($ch); + curl_close($ch); +} + +function updateReport($db, $report_id) +{ + $QUERY = "UPDATE naughtylist set count=count+1 where id = :id"; + + $db->prepare($QUERY)->execute( + [ + 'id' => $report_id + ] + ); +} + +function addReport($db, $geoip, $name, $protocol, $port, $ip) +{ + $QUERY = "INSERT INTO naughtylist VALUES (:id, :name, :protocol, :port, :ip, :count, :longitude, :latitude, :countrycode, :geo)"; + $geoipRecord = $geoip->city($ip); + + $db->prepare($QUERY)->execute( + ['id' => 0, + 'name' => $name, + 'protocol' => $protocol, + 'port' => intval($port), + 'ip' => $ip, + 'count' => 1, + 'longitude' => $geoipRecord->location->longitude, + 'latitude' => $geoipRecord->location->latitude, + 'countrycode' => $geoipRecord->country->isoCode, + 'geo' => $geoipRecord->mostSpecificSubdivision->name . " " . $geoipRecord->city->name + ] + ); + +} + +function reportExists($db, $name, $protocol, $port, $ip) +{ + $QUERY = "SELECT id FROM naughtylist WHERE name = :name AND protocol = :protocol AND port = :port AND ip = :ip LIMIT 1"; + + $stmt = $db->prepare($QUERY); + $stmt->execute( + ['name' => $name, + 'protocol' => $protocol, + 'port' => intval($port), + 'ip' => $ip + ] + ); + if(!$stmt) { return -1; } + return $stmt->fetchColumn(); +} + +function honeypot($name, $protocol, $port) +{ + /* Credits to https://stackoverflow.com/a/13646848 */ + /* This DOES NOT resolve VPNs. Only transparent HTTP proxy */ + if(array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) { + if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')>0) { + $addr = explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']); + $ip = trim($addr[0]); + } else { + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } + } + else { + $ip = $_SERVER['REMOTE_ADDR']; + } + + if(LOCALDB) { + $db = new PDO(MYSQL_PDO, MYSQL_USERNAME, MYSQL_PASSWORD); + $geoip = new Reader(PATH_GEOIPDB); + + $report = reportExists($db, $name, $protocol, $port, $ip); + + if($report != -1) + { + updateReport($db, $report); + } else { + addReport($db, $geoip, $name, $protocol, $port, $ip); + } + } else { + sendReport($name, $protocol, $port, $ip); + } +} + +function serve() +{ + if(LOCALDB) { + $db = new PDO(MYSQL_PDO, MYSQL_USERNAME, MYSQL_PASSWORD); + $geoip = new Reader(PATH_GEOIPDB); + } + /* Running from console */ + if(isset($_SERVER["argv"][1]) && isset($_SERVER["argv"][2]) && isset($_SERVER["argv"][3]) && isset($_SERVER["argv"][4])) + { + $name = $_SERVER["argv"][1]; + $protocol = $_SERVER["argv"][2]; + $port = $_SERVER["argv"][3]; + $ip = $_SERVER["argv"][4]; + if(LOCALDB) + { + $report = reportExists($db, $name, $protocol, $port, $ip); + + if($report != -1) + { + updateReport($db, $report); + } else { + addReport($db, $geoip, $name, $protocol, $port, $ip); + } + } else { + sendReport($name, $protocol, $port, $ip); + } + /* Remote query */ + } elseif (isset($_POST['name']) && isset($_POST['protocol']) && isset($_POST['port']) && isset($_POST['ip']) && isset($_POST['key']) && LOCALDB) { + $name = $_POST['name']; + $protocol = $_POST['protocol']; + $port = $_POST['port']; + $ip = $_POST['ip']; + + if($_POST['key'] != REMOTESECRET) {die(0);} + $report = reportExists($db, $name, $protocol, $port, $ip); + if($report != -1) + { + updateReport($db, $report); + echo json_encode(["status" => "updated"]); + } else { + addReport($db, $geoip, $name, $protocol, $port, $ip); + echo json_encode(["status" => "added"]); + } + } + +} + +if(!defined("HONEYPOT")) +{ + serve(); +} +