0

Hydra's output using hydra -L ~/Documents/wordlists/Aliases.txt -P ~/Documents/wordlists/shortlist.txt -M servers.txt ssh -t 4 -V

sharp67 is a user in PAM and aaron1 is not.

[ATTEMPT] target 172.xx.x.12 - login "sharp67" - pass "aaaaaaaz" - 26 of 390364 [child 1]
[ATTEMPT] target 172.xx.x.34 - login "sharp67" - pass "aaaaaaaz" - 26 of 390364 [child 3]
[ATTEMPT] target 172.xx.x.40 - login "sharp67" - pass "aaaaaaay" - 25 of 390364 [child 12]
[ATTEMPT] target 172.xx.x.12 - login "aaron1" - pass "aaaaaaaa" - 27 of 390364 [child 13]
[ATTEMPT] target 172.xx.x.40 - login "sharp67" - pass "aaaaaaaz" - 26 of 390364 [child 18]
[ATTEMPT] target 172.xx.x.12 - login "aaron1" - pass "aaaaaaab" - 28 of 390364 [child 19]
[ATTEMPT] target 172.xx.x.40 - login "aaron1" - pass "aaaaaaaa" - 27 of 390364 [child 0]
[ATTEMPT] target 172.xx.x.34 - login "aaron1" - pass "aaaaaaaa" - 27 of 390364 [child 15]
[ATTEMPT] target 172.xx.x.33 - login "sharp67" - pass "aaaaaaaz" - 26 of 390364 [child 14]
[ATTEMPT] target 172.xx.x.40 - login "aaron1" - pass "aaaaaaab" - 28 of 390364 [child 6]
[ATTEMPT] target brotest-01.xxxxxx.edu- login "sharp67" - pass "aaaaaaay" - 25 of 390364 [child 16]
[ATTEMPT] target 172.xx.x.33 - login "aaron1" - pass "aaaaaaaa" - 27 of 390364 [child 8]
[ATTEMPT] target 172.xx.x.34 - login "aaron1" - pass "aaaaaaab" - 28 of 390364 [child 9]
[ATTEMPT] target 172.xx.x.33 - login "aaron1" - pass "aaaaaaab" - 28 of 390364 [child 20]
[ATTEMPT] target brotest-01.xxxxx.edu - login "sharp67" - pass "aaaaaaaz" - 26 of 390364 [child 22]
[ATTEMPT] target brotest-01.xxxxx.edu - login "aaron1" - pass "aaaaaaaa" - 27 of 390364 [child 10]

Below is a snippet from notice.log the Syslog::Password_Guessing was an attempt to circumvent my current issue. Syslog::Password_Guessing contains code copied straight from /usr/local/bro/share/bro/policy/protocols/ssh/detect-bruteforcing.bro and simply logs if AUTH_PRIV is noticed more than once in the syslog.log. However, while it works, it does not use the correct orig_h IP. It uses the local ip rather than my IP as seen in the default SSH::Password_Guessing.

#fields ts      uid     id.orig_h       id.orig_p       id.resp_h       id.resp_p       fuid    file_mime_type  file_desc       proto   note    msg     sub     src     dst     p       n       peer_descr      actions suppress_for    dropped remote_location.country_code    remote_location.region  remote_location.city    remote_location.latitude        remote_location.longitude

1533049771.315720    -    -    -    -    -    -    -    -    -    Syslog::Password_Guessing    172.xx.x.34 appears to be guessing SSH passwords (seen in 6 connections).    Syslog Sampled servers:  128.xxx.xxx.xx, 128.xxx.xxx.xx, 128.xxx.xxx.xx, 128.xxx.xxx.xx, 128.xxx.xxx.xx   172.xx.x.34    -    -    -    worker-4-13    Notice::ACTION_LOG    3600.000000    F    -    -    -    -    -
1533050443.932235    -    -    -    -    -    -    -    -    -    SSH::Password_Guessing    10.xxx.xx.81 appears to be guessing SSH passwords (seen in 6 connections).    Sampled servers:  172.xx.x.34, 172.xx.x.34, 172.xx.x.34, 172.xx.x.33, 172.xx.x.33    10.xxx.xx.81    --    -    worker-0-1    Notice::ACTION_LOG    3600.000000    F    -    -    -    -    -

Currently, the default SSH::Password_Guessing does not work unless the user receives a PAM error of user unknown.

/var/logs/secure from brotest-01 while using sharp67

Jul 31 11:20:38 brotest-01 sshd[40996]: Failed password for sharp67 from 10.186.13.81 port 39590 ssh2
Jul 31 11:20:38 brotest-01 sshd[40996]: error: maximum authentication attempts exceeded for sharp67 from 10.xxx.xx.81 port 39590 ssh2 [preauth]
Jul 31 11:20:38 brotest-01 sshd[40996]: Disconnecting: Too many authentication failures [preauth]
Jul 31 11:20:38 brotest-01 sshd[40997]: Failed password for sharp67 from 10.xxx.xx.81 port 39602 ssh2
Jul 31 11:20:38 brotest-01 sshd[40997]: error: maximum authentication attempts exceeded for sharp67 from 10.xxx.xx.81 port 39602 ssh2 [preauth]
Jul 31 11:20:38 brotest-01 sshd[40997]: Disconnecting: Too many authentication failures [preauth] 

And here is the /var/log/secure on brotest-01 for aaron1

Jul 31 11:21:06 brotest-01 sshd[41008]: pam_unix(sshd:auth): check pass; user unknown
Jul 31 11:21:08 brotest-01 sshd[41007]: Failed password for invalid user aaron1 from 10.xxx.xx.81 port 39664 ssh2
Jul 31 11:21:08 brotest-01 sshd[41007]: error: maximum authentication attempts exceeded for invalid user aaron1 from 10.xxx.xx.81 port 39664 ssh2 [preauth]
Jul 31 11:21:08 brotest-01 sshd[41007]: Disconnecting: Too many authentication failures [preauth]

In the ssh.log if the user does not exist in PAM, the auth_success field will almost instantly change from - to F while if the user exists, the auth_success field will stay as - for much longer, which I believe is why it fails to generate the SSH::Password_Guessing.

I'm really at a loss as to why this is occurring. Is it a problem with PAM? Does PAM drop the connection which then doesn't allow Bro to log it as a failed SSH attempt? Do I need to stop PAM from dropping the connection or should I find a way to use the SSH connection's IP instead of the IP which generates the syslog? Any help or input would be greatly appreciated, Thank you.

[EDIT]: Below are the changes I've made to `/usr/local/bro/share/bro/base/protocols/syslog/main.bro

##! Core script support for logging syslog messages.  This script represents 
##! one syslog message as one logged record.

@load ./consts
@load base/protocols/ssh

module Syslog;

export {
        redef enum Log::ID += { LOG };

        ## The record type which contains the fields of the syslog log.
        type Info: record {
                ## Timestamp when the syslog message was seen.
                ts:        time            &log;
                ## Unique ID for the connection.
                uid:       string          &log;
                ## The connection's 4-tuple of endpoint addresses/ports.
                id:        conn_id         &log;
                ## Protocol over which the message was seen.
                proto:     transport_proto &log;
                ## Syslog facility for the message.
                facility:  string          &log;
                ## Syslog severity for the message.
                severity:  string          &log;
                ## The plain text message.
                message:   string          &log;
        };
}

redef record connection += {
        syslog: Info &optional;
};

const ports = { 514/udp };
redef likely_server_ports += { ports };

event bro_init() &priority=5
        {
        Log::create_stream(Syslog::LOG, [$columns=Info, $path="syslog"]);
        Analyzer::register_for_ports(Analyzer::ANALYZER_SYSLOG, ports);
        }
# Added
module SSH;
event ssh_fail()
        {
        local c: SSH::Info;
        local t: record {
                ts:              time         &log;
                uid:             string       &log;
                id:              conn_id      &log;
                version:         count        &log;
                auth_success:    bool         &log &optional;
                auth_attempts:   count        &log &optional;
                direction:       Direction    &log &optional;
                client:          string       &log &optional;
                server:          string       &log &optional;
                cipher_alg:      string       &log &optional;
                mac_alg:         string       &log &optional;
                compression_alg: string       &log &optional;
                kex_alg:         string       &log &optional;
                host_key_alg:    string       &log &optional;
                host_key:        string       &log &optional;
        };
        local p: connection;
        #event log_ssh(c);
        event ssh_auth_failed(p);
        return;
        }


module Syslog;

event syslog_message(c: connection, facility: count, severity: count, msg: string) &priority=5
        {
        local info: Info;
        info$ts=network_time();
        info$uid=c$uid;
        info$id=c$id;
        info$proto=get_port_transport_proto(c$id$resp_p);
        info$facility=facility_codes[facility];
        info$severity=severity_codes[severity];
        info$message=msg;

        #if (info$facility=="AUTHPRIV" && info$severity=="ERR"){
        #       event ssh_fail();
        #}
        c$syslog = info;
        }

# Added  
const logCount= 0&redef;
function logUp(i: count): count
        {
        local Up = i+1;
        return Up;
        }

event syslog_message(c: connection, facility: count, severity: count, msg: string) &priority=-5
        {
        local info: Info;
        #local logCount = 0;
        Log::write(Syslog::LOG, c$syslog);
        # More Changes below
        if (info$facility=="AUTHPRIV" && info$severity=="ERR"){
                event ssh_fail();
        }
        #Log::write(Syslog::LOG, c$syslog);
        }
David Hoelzer
  • 15,862
  • 4
  • 48
  • 67
  • I would suggest switching focus to what is going on in the network traffic and what Bro is doing. The brute-forcing detector is driven by the SumStats framework, here using the `ssh_auth_successful` and `ssh_auth_failed` events. You could try adding the `dump-events` script to your Bro invocation, to get a trace of the events thrown. If this looks different for the PAM/non-PAM connections, you've narrowed down the problem: Bro is seeing differing activity. – Christian Aug 01 '18 at 23:34
  • @Christian I added the changes I've made to bro/base/protocols/syslog. In the past 24hrs I have now opened bro up to view all campus traffic and even after bruteforcing every system we have with both users who exist and users who don't and using proxychains, I still see none of the attempts. In neither the ssh.log, syslog.log, nor notice.log – Jacob Sharp Aug 02 '18 at 14:49
  • @Christian another note: The main thing in notice is `CaptureLoss::Too_Much_Loss` usually above or around 65% and port scans. – Jacob Sharp Aug 02 '18 at 14:51
  • Oh that's helpful — you definitely want to get loss down first. Try to isolate a setting where loss isn't a problem. You could record a pcap, since tcpdump can probably keep up with greater traffic loads than Bro, and then verify correct operation with that pcap. At loss that high, I fear Bro won't be able to make much sense of any payloads... – Christian Aug 02 '18 at 19:11
  • @Christian Sorry I was on vacation. We determined the loss to be due to firewall settings. Yet it still doesn't log SSH attacks that directly target any of our worker nodes – Jacob Sharp Aug 09 '18 at 18:12
  • No problem Jacob ... well, I would still try to capture a pcap of the traffic and then work from that pcap repeatedly, not live traffic. You can then inspect the various logs and start digging in — tweak event handlers etc. It's tricky to give more advice without actually looking at the traffic, I'm afraid. You could try the Bro [user list](http://mailman.icsi.berkeley.edu/mailman/listinfo/bro) for more input, particularly if you have traffic you can share. – Christian Aug 15 '18 at 01:02

0 Answers0