progress
This commit is contained in:
		
							parent
							
								
									80504583a4
								
							
						
					
					
						commit
						d3b949949c
					
				
							
								
								
									
										417
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										417
									
								
								src/main.c
									
									
									
									
									
								
							@ -384,7 +384,7 @@ int search_in_string(char* raw_string, char* search_string) {
 | 
			
		||||
// https://stackoverflow.com/questions/5901181/c-string-append
 | 
			
		||||
void annotate_entry(int index, char* annotation_string) {
 | 
			
		||||
    if (index >= 0 && index < total_entries) {
 | 
			
		||||
        if (all_entries[index].annotation== NULL){
 | 
			
		||||
        if (all_entries[index].annotation[0] == '\0'){
 | 
			
		||||
            strncpy(all_entries[index].annotation, annotation_string, sizeof(all_entries[index].annotation) - 1);
 | 
			
		||||
            all_entries[index].annotation[sizeof(all_entries[index].annotation) - 1] = '\0';
 | 
			
		||||
            all_entries[index].annotated_flag = 1;
 | 
			
		||||
@ -392,8 +392,9 @@ void annotate_entry(int index, char* annotation_string) {
 | 
			
		||||
            char * new_str ;
 | 
			
		||||
            if((new_str = malloc(strlen(all_entries[index].annotation)+strlen(",")+strlen(annotation_string)+1)) != NULL){
 | 
			
		||||
                new_str[0] = '\0';   // ensures the memory is an empty string
 | 
			
		||||
                strcat(new_str,",");
 | 
			
		||||
                strcat(new_str,annotation_string);
 | 
			
		||||
                strcat(new_str, all_entries[index].annotation);
 | 
			
		||||
                strcat(new_str, ",");
 | 
			
		||||
                strcat(new_str, annotation_string);
 | 
			
		||||
                strncpy(all_entries[index].annotation, new_str, sizeof(all_entries[index].annotation) - 1);
 | 
			
		||||
                all_entries[index].annotation[sizeof(all_entries[index].annotation) - 1] = '\0';
 | 
			
		||||
                free(new_str);
 | 
			
		||||
@ -415,224 +416,183 @@ void annotate_suspicious_entries(struct log_entry* dataset) {
 | 
			
		||||
            all_entries[i].annotation[0] = '\0';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int is_suspicious = 0; // Flag um zu verfolgen ob bereits annotiert
 | 
			
		||||
        
 | 
			
		||||
        // 1. PAYLOAD-GRÖßE: Sehr lange Requests (bereits vorhanden, aber verbessert)
 | 
			
		||||
        // 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");
 | 
			
		||||
            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;
 | 
			
		||||
            }
 | 
			
		||||
        // 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++;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Environment-Dateien (kritische Konfigurationsdateien)
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // WordPress Admin-Bereiche (häufig attackiert)
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Database Management Tools
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Admin/Management Interfaces
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        if (strcmp(all_entries[i].request_method, "ATYPICAL") == 0) {
 | 
			
		||||
            annotate_entry(i, "Malformed Request");
 | 
			
		||||
            suspicious_patterns_count++;
 | 
			
		||||
        }
 | 
			
		||||
        // 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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        // 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++;
 | 
			
		||||
        }
 | 
			
		||||
        // 429 Too Many Requests - Rate Limiting aktiviert
 | 
			
		||||
        if (all_entries[i].status_code == 429) {
 | 
			
		||||
            annotate_entry(i, "Rate Limited");
 | 
			
		||||
            suspicious_patterns_count++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            }
 | 
			
		||||
        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++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@ -1382,8 +1342,20 @@ void format_iso8601_time(struct simple_time time, char* buffer, int buffer_size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//Export in Timesketch-kompatiblem Format
 | 
			
		||||
void write_csv_field(FILE* file, const char* field) {
 | 
			
		||||
    fprintf(file, "\"");
 | 
			
		||||
    for (const char* p = field; *p; p++) {
 | 
			
		||||
        if (*p == '"') {
 | 
			
		||||
            fprintf(file, "\"\"");
 | 
			
		||||
        } else {
 | 
			
		||||
            fprintf(file, "%c", *p);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fprintf(file, "\"");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void export_filtered_entries(char *filepath) {
 | 
			
		||||
    //90 chars + delimiter
 | 
			
		||||
    // 90 chars +delimiter
 | 
			
		||||
    char filename[91];
 | 
			
		||||
    if (filepath == NULL) {
 | 
			
		||||
        printf("Dateiname für Timesketch-Export eingeben (ohne .csv): ");
 | 
			
		||||
@ -1396,7 +1368,7 @@ void export_filtered_entries(char *filepath) {
 | 
			
		||||
        strncpy(filename, filepath, sizeof(filename) - 1);
 | 
			
		||||
        filename[sizeof(filename) - 1] = '\0';
 | 
			
		||||
    }
 | 
			
		||||
    // Dateiendung
 | 
			
		||||
    
 | 
			
		||||
    strcat(filename, ".csv");
 | 
			
		||||
    printf("\nINFO: Schreibe Datei %s...\n", filename);
 | 
			
		||||
    FILE* file = fopen(filename, "w");
 | 
			
		||||
@ -1415,44 +1387,56 @@ void export_filtered_entries(char *filepath) {
 | 
			
		||||
        if (passes_filter(i)) {
 | 
			
		||||
            format_iso8601_time(all_entries[i].time, iso_datetime, sizeof(iso_datetime));
 | 
			
		||||
            
 | 
			
		||||
            // https://stackoverflow.com/questions/5901181/c-string-append
 | 
			
		||||
            // https://www.quora.com/How-can-we-count-the-number-of-special-characters-in-a-string-in-the-C-language-using-fgets
 | 
			
		||||
            char* tag_str;
 | 
			
		||||
            int num_delimiters = 0;
 | 
			
		||||
            int c=0;
 | 
			
		||||
            while(all_entries[i].annotation[c]!='\0'){
 | 
			
		||||
                num_delimiters++;
 | 
			
		||||
            }
 | 
			
		||||
            if (tag_str=malloc(sizeof(all_entries[i].annotation)+sizeof("[  ]")+(sizeof(','))*num_delimiters)+1)!=NULL){
 | 
			
		||||
                tag_str[0] = '\0';
 | 
			
		||||
            // Tags werden von Timesketch in diesem Format erwartet: [ "tag1","tag2" ]
 | 
			
		||||
            char tag_str[256] = "";
 | 
			
		||||
            if (strlen(all_entries[i].annotation) > 0) {
 | 
			
		||||
                // Create a working copy for strtok (it modifies the string)
 | 
			
		||||
                char annotation_copy[64];
 | 
			
		||||
                strncpy(annotation_copy, all_entries[i].annotation, sizeof(annotation_copy) - 1);
 | 
			
		||||
                annotation_copy[sizeof(annotation_copy) - 1] = '\0';
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                char* token = strtok(all_entries[i].annotation, ",");
 | 
			
		||||
                if (!token) return;
 | 
			
		||||
                strcat(tag_str, "[ ");
 | 
			
		||||
                for (i=0;i<num_delimiters;i++){
 | 
			
		||||
                // https://stackoverflow.com/questions/5901181/c-string-append
 | 
			
		||||
                // https://www.quora.com/How-can-we-count-the-number-of-special-characters-in-a-string-in-the-C-language-using-fgets
 | 
			
		||||
                char* token = strtok(annotation_copy, ",");
 | 
			
		||||
                int first = 1;
 | 
			
		||||
                while (token != NULL) {
 | 
			
		||||
                    if (!first) {
 | 
			
		||||
                        strcat(tag_str, ",");
 | 
			
		||||
                    }
 | 
			
		||||
                    strcat(tag_str, "\"");
 | 
			
		||||
                    strcat(tag_str, strtok(NULL, ","));
 | 
			
		||||
                    strcat(tag_str, '"');
 | 
			
		||||
                    strncat(tag_str, token, sizeof(tag_str) - strlen(tag_str) - 3);
 | 
			
		||||
                    strcat(tag_str, "\"");
 | 
			
		||||
                    first = 0;
 | 
			
		||||
                    token = strtok(NULL, ",");
 | 
			
		||||
                }
 | 
			
		||||
                strcat(tag_str, " ]");
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            fprintf(file, "\"%s\",\"%s\",\"HTTP Access Log\",\"%s\",\"%s\",\"%s\",%d,%d,\"%s\",\"%s\",\"%s\"\n",
 | 
			
		||||
                iso_datetime, // datetime
 | 
			
		||||
                all_entries[i].source_file, // message
 | 
			
		||||
                all_entries[i].ip_address,
 | 
			
		||||
                all_entries[i].request_method,
 | 
			
		||||
                all_entries[i].url_path,
 | 
			
		||||
                all_entries[i].status_code,
 | 
			
		||||
                all_entries[i].bytes_sent,
 | 
			
		||||
                all_entries[i].user_agent,
 | 
			
		||||
                all_entries[i].parsing_timestamp,
 | 
			
		||||
                tag_str
 | 
			
		||||
                //all_entries[i].annotation // tag
 | 
			
		||||
            );
 | 
			
		||||
            free(tag_str);
 | 
			
		||||
            tag_str=NULL;
 | 
			
		||||
            // Write CSV row with proper escaping
 | 
			
		||||
            write_csv_field(file, iso_datetime);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, all_entries[i].source_file);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, "HTTP Access Log");
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, all_entries[i].ip_address);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, all_entries[i].request_method);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, all_entries[i].url_path);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            fprintf(file, "%d", all_entries[i].status_code);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            fprintf(file, "%d", all_entries[i].bytes_sent);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, all_entries[i].user_agent);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, all_entries[i].parsing_timestamp);
 | 
			
		||||
            fprintf(file, ",");
 | 
			
		||||
            write_csv_field(file, tag_str);
 | 
			
		||||
            fprintf(file, "\n");
 | 
			
		||||
            
 | 
			
		||||
            exported_count++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -3033,8 +3017,8 @@ void print_help(char* binary) {
 | 
			
		||||
    printf("  0.0.0.0 - - [31/Aug/2025:00:11:42 +0000] \"GET /.git/config HTTP/1.1\" 400 255 \"-\" \"Mozilla/5.0\" \"-\"\n");
 | 
			
		||||
 | 
			
		||||
    printf("\nCSV-Export (Timesketch-kompatibel):\n");
 | 
			
		||||
    printf("  Spalten: datetime, timestamp_desc, ip_address, method, url_path, status_code,\n");
 | 
			
		||||
    printf("           bytes_sent, user_agent, source_file, parsing_timestamp, annotation\n");
 | 
			
		||||
    printf("  Spalten: datetime, message timestamp_desc, ip_address, method, url_path, status_code,\n");
 | 
			
		||||
    printf("           bytes_sent, user_agent, source_file, parsing_timestamp, tag\n");
 | 
			
		||||
 | 
			
		||||
    printf("\nAnnotationen:\n");
 | 
			
		||||
    printf("  - Automatische Erkennung verdächtiger Muster (z.B. 'Long Payload')\n");
 | 
			
		||||
@ -3045,7 +3029,6 @@ void print_help(char* binary) {
 | 
			
		||||
    printf("  - Parser erwartet das obige Standardformat. Abweichungen können zum Abbruch führen.\n");
 | 
			
		||||
    printf("  - Zeitzone aus dem Log wird gelesen, aber intern als einfache Felder verarbeitet.\n");
 | 
			
		||||
    printf("  - ATYPICAL-Methode: für fehlerhafte/binäre Requests innerhalb der \"request\"-Spalte.\n");
 | 
			
		||||
    printf("  - Komplexe Zeitraum-Filter sind vollständig über Kommandozeile verfügbar.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[]) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user