@load site @load ssh @load irc @load http-request @load ftp @load dpd @load site redef local_nets += { 192.168.0.0/16, }; module Fingerprint; export { # Define a NOTICE type for our alert. redef enum Notice += { FingerprintFound }; } # We track a state-machine for each host. type state: enum { expect_http, expect_ftp_exec, expect_ftp_zip, expect_irc, found }; global hosts: table[addr] of state; event protocol_confirmation(c: connection, atype: count, aid: count) { local orig = c$id$orig_h; local resp = c$id$resp_h; # For (1), we check for an incoming SSH on port 2222. if ( is_local_addr(resp) && resp !in hosts ) { if ( c$id$resp_p == 2222/tcp && atype == ANALYZER_SSH ) hosts[resp] = expect_http; } # For (4), we check for an outgoing IRC connection. if ( orig in hosts && hosts[orig] == expect_irc ) { if ( atype == ANALYZER_IRC ) { # Found it! NOTICE([$note=FingerprintFound, $src=orig, $msg=fmt("%s matches FooBar CERT's fingerprint", orig)]); hosts[orig] = found; } } } event http_request(c: connection, method: string, original_URI: string, unescaped_URI: string, version: string) { local orig = c$id$orig_h; # For (2), we check for an HTTP request for "download.html" if ( orig in hosts && hosts[orig] == expect_http && "download.html" in unescaped_URI ) hosts[orig] = expect_ftp_exec; } event file_transferred(c: connection, prefix: string, descr: string, mime_type: string) { local orig = c$id$orig_h; if ( orig !in hosts ) return; # For (3a), we check for an FTP transfer of an executable. if ( hosts[orig] == expect_ftp_exec ) { if ( "executable" in descr ) hosts[orig] = expect_ftp_zip; } else if ( hosts[orig] == expect_ftp_zip ) { if ( "x-zip" in mime_type ) hosts[orig] = expect_irc; } } # If we don't have libmagic, we can alternatively check the # requested file names but that's less reliable. # #event ftp_request(c: connection, command: string, arg: string) # { # local orig = c$id$orig_h; # # if ( orig !in hosts ) # return; # # if ( command != "RETR" ) # return; # # # For (3a), we check for an FTP transfer of an executable. # if ( hosts[orig] == expect_ftp_exec ) # { # if ( /\.[eE][xX][eE]$/ in arg ) # hosts[orig] = expect_ftp_zip; # } # # else if ( hosts[orig] == expect_ftp_zip ) # { # if ( /\.[zZ][iI][pP]$/ in arg ) # hosts[orig] = expect_irc; # } # }