progress
This commit is contained in:
parent
6b2e4b4373
commit
87eb2c34d9
312
src/main.c
312
src/main.c
@ -24,7 +24,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||||||
#include <sys/stat.h> // library für is_directory: Unterscheidung zwischen Dateien und Ordnern
|
#include <sys/stat.h> // library für is_directory: Unterscheidung zwischen Dateien und Ordnern
|
||||||
#include <time.h> // um aktuelle Zeit zu generieren
|
#include <time.h> // um aktuelle Zeit zu generieren
|
||||||
#include "gzunpack.h"
|
#include "gzunpack.h"
|
||||||
#include "suspicious_detection.h"
|
|
||||||
|
|
||||||
#define INITIAL_ENTRIES 1000 // globale Variable zur initialen Speicherallokation in allocate_initial_memory(). Wird falls nötig um GROWTH_FACTOR erweitert
|
#define INITIAL_ENTRIES 1000 // globale Variable zur initialen Speicherallokation in allocate_initial_memory(). Wird falls nötig um GROWTH_FACTOR erweitert
|
||||||
#define GROWTH_FACTOR 1.1 // wird in mem_expand_dynamically() genutzt, um den Speicher zu vergrößern
|
#define GROWTH_FACTOR 1.1 // wird in mem_expand_dynamically() genutzt, um den Speicher zu vergrößern
|
||||||
@ -332,6 +331,48 @@ int is_log_file(char* filename) {
|
|||||||
return 0; // false, wenn nichts zutrifft
|
return 0; // false, wenn nichts zutrifft
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Funktion zum suchen eines Suchbegriffs innerhalb eines Strings (lowercase)
|
||||||
|
int search_in_string(char* raw_string, char* search_string) {
|
||||||
|
char raw_string_lower[512]; // Puffer zum Speichern des zu durchsuchenden Strings
|
||||||
|
char search_string_lower[256]; // Puffer zum Speichern des Suchbegriffs
|
||||||
|
|
||||||
|
// Konvertierung des Datensatzes zu Kleinbuchstaben
|
||||||
|
int i = 0;
|
||||||
|
// für jeden Buchstaben innerhalb des Datensatzes Verschiebung innerhalb des ASCII-Alphabets um 32
|
||||||
|
while (raw_string[i] && i < 511) {
|
||||||
|
if (raw_string[i] >= 'A' && raw_string[i] <= 'Z') {
|
||||||
|
raw_string_lower[i] = raw_string[i] + 32; // Verschiebung im ASCII-Alphabet
|
||||||
|
} else {
|
||||||
|
raw_string_lower[i] = raw_string[i]; // alles was kein Buchstabe ist, wird beibehalten
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
raw_string_lower[i] = '\0'; // Nullterminator anfügen
|
||||||
|
|
||||||
|
// gleiche Methode mit dem Suchbegriff
|
||||||
|
i = 0;
|
||||||
|
while (search_string[i] && i < 255) {
|
||||||
|
if (search_string[i] >= 'A' && search_string[i] <= 'Z') {
|
||||||
|
search_string_lower[i] = search_string[i] + 32; // Verschiebung im ASCII-Alphabet
|
||||||
|
} else {
|
||||||
|
search_string_lower[i] = search_string[i]; // nicht-Buchstaben beibehalten
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
search_string_lower[i] = '\0'; // Nullterminator anfügen
|
||||||
|
|
||||||
|
// strstr()-Vergleich - gibt NULL zurück wenn nichts gefunden
|
||||||
|
char* result = strstr(raw_string_lower, search_string_lower);
|
||||||
|
|
||||||
|
// Einfache Rückgabe: 1 wenn gefunden, 0 wenn nicht gefunden
|
||||||
|
if (result != NULL) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fügt eine Annotation zu einem bestimmten Eintrag hinzu
|
// Fügt eine Annotation zu einem bestimmten Eintrag hinzu
|
||||||
void annotate_entry(int index, char* annotation_string) {
|
void annotate_entry(int index, char* annotation_string) {
|
||||||
if (index >= 0 && index < total_entries) {
|
if (index >= 0 && index < total_entries) {
|
||||||
@ -342,24 +383,240 @@ void annotate_entry(int index, char* annotation_string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Muster hier KI-generiert.
|
|
||||||
|
|
||||||
|
// TRANSPARENZ: Diese Funktion ist KI-generiert
|
||||||
void annotate_suspicious_entries(struct log_entry* dataset) {
|
void annotate_suspicious_entries(struct log_entry* dataset) {
|
||||||
printf("DEBUG: Prüfe %d Einträge auf verdächtige Muster...\n", total_entries);
|
printf("DEBUG: Prüfe %d Einträge auf verdächtige Muster...\n", total_entries);
|
||||||
|
|
||||||
for (int i=0; i< total_entries; i++){
|
for (int i = 0; i < total_entries; i++) {
|
||||||
|
// Initialisierung der Annotation falls noch nicht gesetzt
|
||||||
if (all_entries[i].annotation[0] == '\0') {
|
if (all_entries[i].annotation[0] == '\0') {
|
||||||
all_entries[i].annotation[0] = '\0';
|
all_entries[i].annotation[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prüfmuster: Sehr lange Requests
|
int is_suspicious = 0; // Flag um zu verfolgen ob bereits annotiert
|
||||||
|
|
||||||
|
// 1. PAYLOAD-GRÖßE: Sehr lange Requests (bereits vorhanden, aber verbessert)
|
||||||
int url_length = strlen(all_entries[i].url_path);
|
int url_length = strlen(all_entries[i].url_path);
|
||||||
if (url_length>SUSPICIOUS_REQUEST_LEN_THRESHOLD){
|
if (url_length > SUSPICIOUS_REQUEST_LEN_THRESHOLD) {
|
||||||
//printf("DEBUG: URL: %s\nLänge: %d\nmax_länge: %d\n", all_entries[i].url_path, url_length, SUSPICIOUS_REQUEST_LEN_THRESHOLD);
|
|
||||||
annotate_entry(i, "Long Payload");
|
annotate_entry(i, "Long Payload");
|
||||||
suspicious_patterns_count++;
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. PFAD-BASIERTE ANGRIFFE: Häufige Angriffsziele und sensible Pfade
|
||||||
|
if (!is_suspicious) {
|
||||||
|
// Git-Repository Zugriffe (häufig bei Recon)
|
||||||
|
if (search_in_string(all_entries[i].url_path, ".git/") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "/.git")) {
|
||||||
|
annotate_entry(i, "Git Access");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
// Environment-Dateien (kritische Konfigurationsdateien)
|
||||||
|
else if (search_in_string(all_entries[i].url_path, ".env") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".config") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "config.php")) {
|
||||||
|
annotate_entry(i, "Config Access");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
// WordPress Admin-Bereiche (häufig attackiert)
|
||||||
|
else if (search_in_string(all_entries[i].url_path, "wp-admin") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "wp-login") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "wp-config")) {
|
||||||
|
annotate_entry(i, "WP Attack");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
// Database Management Tools
|
||||||
|
else if (search_in_string(all_entries[i].url_path, "phpmyadmin") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "phpMyAdmin") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "adminer")) {
|
||||||
|
annotate_entry(i, "DB Tool Access");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
// Admin/Management Interfaces
|
||||||
|
else if (search_in_string(all_entries[i].url_path, "/admin") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "/manager") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "/console")) {
|
||||||
|
annotate_entry(i, "Admin Access");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. DIRECTORY TRAVERSAL: Pfad-Traversal Versuche
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (search_in_string(all_entries[i].url_path, "../") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "..\\") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "%2e%2e%2f") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "%2e%2e%5c")) {
|
||||||
|
annotate_entry(i, "Path Traversal");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. SQL INJECTION: SQL-Keywords in URLs
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (search_in_string(all_entries[i].url_path, "select%20") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "union%20") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "insert%20") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "delete%20") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "drop%20") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "' or ") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "' and ") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "1=1") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "1' or '1'='1")) {
|
||||||
|
annotate_entry(i, "SQL Injection");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. XSS ATTEMPTS: Cross-Site-Scripting Versuche
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (search_in_string(all_entries[i].url_path, "<script") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "%3cscript") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "javascript:") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "onerror=") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "onload=") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "alert(")) {
|
||||||
|
annotate_entry(i, "XSS Attempt");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. BACKUP/SENSITIVE FILE ACCESS: Backup-Dateien und sensible Extensions
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (search_in_string(all_entries[i].url_path, ".bak") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".old") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".backup") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".sql") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".log") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".key") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".pem")) {
|
||||||
|
annotate_entry(i, "Sensitive File");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. BOT/SCANNER DETECTION: Verdächtige User-Agents
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (search_in_string(all_entries[i].user_agent, "nmap") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "sqlmap") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "nikto") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "dirb") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "gobuster") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "whatweb") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "masscan") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "python-requests") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "curl/") ||
|
||||||
|
search_in_string(all_entries[i].user_agent, "wget/")) {
|
||||||
|
annotate_entry(i, "Scanner/Bot");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. EXCESSIVE URL ENCODING: Verdächtig hohe Anzahl von URL-Encoding
|
||||||
|
if (!is_suspicious) {
|
||||||
|
char *url = all_entries[i].url_path;
|
||||||
|
int encoding_count = 0;
|
||||||
|
char *pos = url;
|
||||||
|
while ((pos = strstr(pos, "%")) != NULL) {
|
||||||
|
encoding_count++;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
// Wenn mehr als 10 URL-Encodings in einer URL, verdächtig
|
||||||
|
if (encoding_count > 10) {
|
||||||
|
annotate_entry(i, "Heavy Encoding");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. ATYPICAL HTTP METHODS: Ungewöhnliche oder fehlerhafte HTTP-Methoden
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (strcmp(all_entries[i].request_method, "ATYPICAL") == 0) {
|
||||||
|
annotate_entry(i, "Malformed Request");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
// Seltene aber potentiell gefährliche HTTP-Methoden
|
||||||
|
else if (strcmp(all_entries[i].request_method, "PROPFIND") == 0 ||
|
||||||
|
strcmp(all_entries[i].request_method, "MKCOL") == 0 ||
|
||||||
|
strcmp(all_entries[i].request_method, "COPY") == 0 ||
|
||||||
|
strcmp(all_entries[i].request_method, "MOVE") == 0 ||
|
||||||
|
strcmp(all_entries[i].request_method, "LOCK") == 0) {
|
||||||
|
annotate_entry(i, "Rare Method");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. STATUS CODE ANOMALIES: Verdächtige Status-Code Muster
|
||||||
|
if (!is_suspicious) {
|
||||||
|
// 403 auf sensible Pfade könnte Angriffserkennung bedeuten
|
||||||
|
if (all_entries[i].status_code == 403 &&
|
||||||
|
(search_in_string(all_entries[i].url_path, "admin") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".git") ||
|
||||||
|
search_in_string(all_entries[i].url_path, ".env"))) {
|
||||||
|
annotate_entry(i, "Blocked Access");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
// 429 Too Many Requests - Rate Limiting aktiviert
|
||||||
|
else if (all_entries[i].status_code == 429) {
|
||||||
|
annotate_entry(i, "Rate Limited");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. CREDENTIAL STUFFING: Wiederholte Login-Versuche mit verschiedenen Credentials
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if ((search_in_string(all_entries[i].url_path, "login") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "signin") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "auth")) &&
|
||||||
|
(all_entries[i].status_code == 401 || all_entries[i].status_code == 403)) {
|
||||||
|
annotate_entry(i, "Failed Auth");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12. SHELL/WEBSHELL ACCESS: Verdächtige Shell-bezogene Pfade
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (search_in_string(all_entries[i].url_path, ".php?") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "shell") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "backdoor") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "cmd=") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "exec=") ||
|
||||||
|
search_in_string(all_entries[i].url_path, "system=")) {
|
||||||
|
annotate_entry(i, "Shell Access");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 13. API ABUSE: Verdächtige API-Zugriffe
|
||||||
|
if (!is_suspicious) {
|
||||||
|
if (search_in_string(all_entries[i].url_path, "/api/") &&
|
||||||
|
(all_entries[i].status_code >= 400 && all_entries[i].status_code < 500)) {
|
||||||
|
annotate_entry(i, "API Error");
|
||||||
|
suspicious_patterns_count++;
|
||||||
|
is_suspicious = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("DEBUG: Analyse abgeschlossen. %d verdächtige Muster erkannt.\n", suspicious_patterns_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -714,52 +971,13 @@ void load_log_file(char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("INFO: Erfolgreich %d Einträge insgesamt geladen.\n", total_entries);
|
printf("INFO: Erfolgreich %d Einträge insgesamt geladen.\n", total_entries);
|
||||||
|
// die aufgerufene Funktion ist KI-generiert und annotiert verdächtige Requests automatisch.
|
||||||
|
// TODO
|
||||||
annotate_suspicious_entries(all_entries);
|
annotate_suspicious_entries(all_entries);
|
||||||
printf("DEBUG: Aktueller Speicherverbrauch: %lu Bytes für %d Einträge\n",
|
printf("DEBUG: Aktueller Speicherverbrauch: %lu Bytes für %d Einträge\n",
|
||||||
(unsigned long)(max_entries * sizeof(struct log_entry)), max_entries);
|
(unsigned long)(max_entries * sizeof(struct log_entry)), max_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funktion zum suchen eines Suchbegriffs innerhalb eines Strings (lowercase)
|
|
||||||
int search_in_string(char* raw_string, char* search_string) {
|
|
||||||
char raw_string_lower[512]; // Puffer zum Speichern des zu durchsuchenden Strings
|
|
||||||
char search_string_lower[256]; // Puffer zum Speichern des Suchbegriffs
|
|
||||||
|
|
||||||
// Konvertierung des Datensatzes zu Kleinbuchstaben
|
|
||||||
int i = 0;
|
|
||||||
// für jeden Buchstaben innerhalb des Datensatzes Verschiebung innerhalb des ASCII-Alphabets um 32
|
|
||||||
while (raw_string[i] && i < 511) {
|
|
||||||
if (raw_string[i] >= 'A' && raw_string[i] <= 'Z') {
|
|
||||||
raw_string_lower[i] = raw_string[i] + 32; // Verschiebung im ASCII-Alphabet
|
|
||||||
} else {
|
|
||||||
raw_string_lower[i] = raw_string[i]; // alles was kein Buchstabe ist, wird beibehalten
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
raw_string_lower[i] = '\0'; // Nullterminator anfügen
|
|
||||||
|
|
||||||
// gleiche Methode mit dem Suchbegriff
|
|
||||||
i = 0;
|
|
||||||
while (search_string[i] && i < 255) {
|
|
||||||
if (search_string[i] >= 'A' && search_string[i] <= 'Z') {
|
|
||||||
search_string_lower[i] = search_string[i] + 32; // Verschiebung im ASCII-Alphabet
|
|
||||||
} else {
|
|
||||||
search_string_lower[i] = search_string[i]; // nicht-Buchstaben beibehalten
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
search_string_lower[i] = '\0'; // Nullterminator anfügen
|
|
||||||
|
|
||||||
// strstr()-Vergleich - gibt NULL zurück wenn nichts gefunden
|
|
||||||
char* result = strstr(raw_string_lower, search_string_lower);
|
|
||||||
|
|
||||||
// Einfache Rückgabe: 1 wenn gefunden, 0 wenn nicht gefunden
|
|
||||||
if (result != NULL) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filterfunktion für den User-Agent. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück
|
// Filterfunktion für den User-Agent. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück
|
||||||
int user_agent_matches(char* user_agent) {
|
int user_agent_matches(char* user_agent) {
|
||||||
if (filters.user_agent_count == 0) return 1;
|
if (filters.user_agent_count == 0) return 1;
|
||||||
|
@ -1,259 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2025 Mario Stöckl (mstoeck3@hs-mittweida.de).
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TRANSPARENZ
|
|
||||||
// Diese Funktion ist KI-generiert
|
|
||||||
|
|
||||||
|
|
||||||
#include "suspicious_detection.h"
|
|
||||||
|
|
||||||
// Main suspicious activity detection function
|
|
||||||
// Parameters made explicit to avoid global variable dependencies
|
|
||||||
void annotate_suspicious_entries(struct log_entry* dataset,
|
|
||||||
struct log_entry* all_entries,
|
|
||||||
int total_entries,
|
|
||||||
int* suspicious_patterns_count,
|
|
||||||
int suspicious_request_len_threshold) {
|
|
||||||
|
|
||||||
printf("DEBUG: Prüfe %d Einträge auf verdächtige Muster...\n", total_entries);
|
|
||||||
|
|
||||||
for (int i = 0; i < total_entries; i++) {
|
|
||||||
// Initialisierung der Annotation falls noch nicht gesetzt
|
|
||||||
if (all_entries[i].annotation[0] == '\0') {
|
|
||||||
all_entries[i].annotation[0] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_suspicious = 0; // Flag um zu verfolgen ob bereits annotiert
|
|
||||||
|
|
||||||
// 1. PAYLOAD-GRÖßE: Sehr lange Requests
|
|
||||||
int url_length = strlen(all_entries[i].url_path);
|
|
||||||
if (url_length > suspicious_request_len_threshold) {
|
|
||||||
annotate_entry(i, "Long Payload", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. PFAD-BASIERTE ANGRIFFE: Häufige Angriffsziele und sensible Pfade
|
|
||||||
if (!is_suspicious) {
|
|
||||||
// Git-Repository Zugriffe (häufig bei Recon)
|
|
||||||
if (search_in_string(all_entries[i].url_path, ".git/") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "/.git")) {
|
|
||||||
annotate_entry(i, "Git Access", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
// Environment-Dateien (kritische Konfigurationsdateien)
|
|
||||||
else if (search_in_string(all_entries[i].url_path, ".env") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".config") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "config.php")) {
|
|
||||||
annotate_entry(i, "Config Access", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
// WordPress Admin-Bereiche (häufig attackiert)
|
|
||||||
else if (search_in_string(all_entries[i].url_path, "wp-admin") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "wp-login") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "wp-config")) {
|
|
||||||
annotate_entry(i, "WP Attack", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
// Database Management Tools
|
|
||||||
else if (search_in_string(all_entries[i].url_path, "phpmyadmin") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "phpMyAdmin") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "adminer")) {
|
|
||||||
annotate_entry(i, "DB Tool Access", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
// Admin/Management Interfaces
|
|
||||||
else if (search_in_string(all_entries[i].url_path, "/admin") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "/manager") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "/console")) {
|
|
||||||
annotate_entry(i, "Admin Access", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. DIRECTORY TRAVERSAL: Pfad-Traversal Versuche
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (search_in_string(all_entries[i].url_path, "../") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "..\\") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "%2e%2e%2f") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "%2e%2e%5c")) {
|
|
||||||
annotate_entry(i, "Path Traversal", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. SQL INJECTION: SQL-Keywords in URLs
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (search_in_string(all_entries[i].url_path, "select%20") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "union%20") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "insert%20") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "delete%20") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "drop%20") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "' or ") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "' and ") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "1=1") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "1' or '1'='1")) {
|
|
||||||
annotate_entry(i, "SQL Injection", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. XSS ATTEMPTS: Cross-Site-Scripting Versuche
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (search_in_string(all_entries[i].url_path, "<script") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "%3cscript") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "javascript:") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "onerror=") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "onload=") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "alert(")) {
|
|
||||||
annotate_entry(i, "XSS Attempt", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. BACKUP/SENSITIVE FILE ACCESS: Backup-Dateien und sensible Extensions
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (search_in_string(all_entries[i].url_path, ".bak") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".old") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".backup") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".sql") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".log") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".key") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".pem")) {
|
|
||||||
annotate_entry(i, "Sensitive File", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. BOT/SCANNER DETECTION: Verdächtige User-Agents
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (search_in_string(all_entries[i].user_agent, "nmap") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "sqlmap") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "nikto") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "dirb") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "gobuster") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "whatweb") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "masscan") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "python-requests") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "curl/") ||
|
|
||||||
search_in_string(all_entries[i].user_agent, "wget/")) {
|
|
||||||
annotate_entry(i, "Scanner/Bot", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. EXCESSIVE URL ENCODING: Verdächtig hohe Anzahl von URL-Encoding
|
|
||||||
if (!is_suspicious) {
|
|
||||||
char *url = all_entries[i].url_path;
|
|
||||||
int encoding_count = 0;
|
|
||||||
char *pos = url;
|
|
||||||
while ((pos = strstr(pos, "%")) != NULL) {
|
|
||||||
encoding_count++;
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
// Wenn mehr als 10 URL-Encodings in einer URL, verdächtig
|
|
||||||
if (encoding_count > 10) {
|
|
||||||
annotate_entry(i, "Heavy Encoding", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 9. ATYPICAL HTTP METHODS: Ungewöhnliche oder fehlerhafte HTTP-Methoden
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (strcmp(all_entries[i].request_method, "ATYPICAL") == 0) {
|
|
||||||
annotate_entry(i, "Malformed Request", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
// Seltene aber potentiell gefährliche HTTP-Methoden
|
|
||||||
else if (strcmp(all_entries[i].request_method, "PROPFIND") == 0 ||
|
|
||||||
strcmp(all_entries[i].request_method, "MKCOL") == 0 ||
|
|
||||||
strcmp(all_entries[i].request_method, "COPY") == 0 ||
|
|
||||||
strcmp(all_entries[i].request_method, "MOVE") == 0 ||
|
|
||||||
strcmp(all_entries[i].request_method, "LOCK") == 0) {
|
|
||||||
annotate_entry(i, "Rare Method", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10. STATUS CODE ANOMALIES: Verdächtige Status-Code Muster
|
|
||||||
if (!is_suspicious) {
|
|
||||||
// 403 auf sensible Pfade könnte Angriffserkennung bedeuten
|
|
||||||
if (all_entries[i].status_code == 403 &&
|
|
||||||
(search_in_string(all_entries[i].url_path, "admin") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".git") ||
|
|
||||||
search_in_string(all_entries[i].url_path, ".env"))) {
|
|
||||||
annotate_entry(i, "Blocked Access", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
// 429 Too Many Requests - Rate Limiting aktiviert
|
|
||||||
else if (all_entries[i].status_code == 429) {
|
|
||||||
annotate_entry(i, "Rate Limited", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 11. CREDENTIAL STUFFING: Wiederholte Login-Versuche mit verschiedenen Credentials
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if ((search_in_string(all_entries[i].url_path, "login") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "signin") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "auth")) &&
|
|
||||||
(all_entries[i].status_code == 401 || all_entries[i].status_code == 403)) {
|
|
||||||
annotate_entry(i, "Failed Auth", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 12. SHELL/WEBSHELL ACCESS: Verdächtige Shell-bezogene Pfade
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (search_in_string(all_entries[i].url_path, ".php?") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "shell") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "backdoor") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "cmd=") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "exec=") ||
|
|
||||||
search_in_string(all_entries[i].url_path, "system=")) {
|
|
||||||
annotate_entry(i, "Shell Access", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 13. API ABUSE: Verdächtige API-Zugriffe
|
|
||||||
if (!is_suspicious) {
|
|
||||||
if (search_in_string(all_entries[i].url_path, "/api/") &&
|
|
||||||
(all_entries[i].status_code >= 400 && all_entries[i].status_code < 500)) {
|
|
||||||
annotate_entry(i, "API Error", all_entries);
|
|
||||||
(*suspicious_patterns_count)++;
|
|
||||||
is_suspicious = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("DEBUG: Analyse abgeschlossen. %d verdächtige Muster erkannt.\n", *suspicious_patterns_count);
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2025 Mario Stöckl (mstoeck3@hs-mittweida.de).
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TRANSPARENZ
|
|
||||||
// Diese Funktion ist KI-generiert
|
|
||||||
|
|
||||||
#ifndef SUSPICIOUS_DETECTION_H
|
|
||||||
#define SUSPICIOUS_DETECTION_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// Forward declaration of the log_entry struct
|
|
||||||
// (The full definition should be in main.c or a shared header)
|
|
||||||
struct log_entry;
|
|
||||||
|
|
||||||
// Function declarations
|
|
||||||
void annotate_suspicious_entries(struct log_entry* dataset,
|
|
||||||
struct log_entry* all_entries,
|
|
||||||
int total_entries,
|
|
||||||
int* suspicious_patterns_count,
|
|
||||||
int suspicious_request_len_threshold);
|
|
||||||
|
|
||||||
// Helper function declarations that need to be available
|
|
||||||
void annotate_entry(int index, char* annotation_string,
|
|
||||||
struct log_entry* entries);
|
|
||||||
int search_in_string(char* raw_string, char* search_string);
|
|
||||||
|
|
||||||
#endif // SUSPICIOUS_DETECTION_H
|
|
Loading…
x
Reference in New Issue
Block a user