Jul 2
Logging incorrect SSH passwords
When I decided to set up this server, I wanted to do something about the inevitable hordes of SSH brute force attempts that I knew would be coming. I decided against changing the SSH port and, instead, thought I would take advantage of it. I need to beef up my résumé and thought that a published paper on SSH brute force attempts might be a good way to do so. But first, I’d need to be able to collect more information than was normally given.
In /var/log/auth.log, a normal entry for a failed login looks like this:
Jul 1 11:39:36 www sshd[18479]: User root not allowed because account is locked
Jul 1 11:39:36 www sshd[18479]: error: Could not get shadow information for NOUSER
Jul 1 11:39:36 www sshd[18479]: Failed password for invalid user root from 211.40.52.80 port 59701 ssh2
This last line provides us with a fair bit of information, namely the user, ip address, port, and time of the failed login. However, I wanted to see if I could get more information than this. What I really wanted to see was the password they were attempting to use while logging into the server.
Since most SSH brute force attempts are from PCs infected with bots, I really wanted to know how sophisticated these bots were, what kinds of passwords were they guessing. However, as I soon found out, SSH has no built-in option to record passwords, incorrect or otherwise. I asked around to see if there was a patch I could apply that would record passwords without having to reinstall, but none existed that I could find. I figured my only way was to download and edit the source by hand, then reinstall from scratch, foregoing any updates that might be released by Ubuntu. As I was in the process of sifting through the source, someone pointed me to an instance where someone had already done the exact same thing. I followed the link in the comments pointing to a version for linux (this was BSD-specific) and applied it to the 5.0p1 version, hoping it would work. After about 30 minutes of configuring/compiling/installing, I tested it out. It worked great! Now I’ve got a file steadily building up with username/password combinations from brute force attempts. Once I get above 10,000 I’ll start graphing them and look through the commonalities. So far, the most used username is ‘root’ (go figure) with 641 attempts, followed by ‘test’ and ‘admin’ with 42 and 33 attempts respectably. The passwords used most often is ‘123456′, ‘1234′, and ‘password’ with 88, 61, and 36 attempts respectably.
Once I get enough data to graph, and do so, I’ll link to a dynamic page with a constant watch on the number of username/password attempts.
For those wishing to do the same, it works in OpenSSH 5.0p1. The file to edit is auth-passwd.c. The following is the patch taken from monkeyhouse.org:
--- auth-passwd.c
+++ auth-passwd.c.new
@@ -40,11 +40,13 @@
#include <sys/types.h>
+#include <time.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+#include <sys/stat.h>
#include "packet.h"
#include "buffer.h"
#include "log.h"
@@ -125,6 +129,14 @@
result = sys_auth_passwd(authctxt, password);
if (authctxt->force_pwchange)
disable_forwarding();
+ if(!result)
+ {
+ FILE *garp;
+ garp = fopen("/var/log/sshd_logged", "a");
+ chmod("/var/log/sshd_logged", 0600);
+ fprintf(garp,"%i:%.100s:%.100s:%.200s\n",
+ time(NULL),authctxt->user,password,get_remote_ipaddr());
+ fclose(garp);
+ }
return (result && ok);
}
Currently, this logs every incorrect password into a file ’sshd_logged’ readable/writeable only by root. What I hope to do in the near future is allow it to be configureable from the sshd_config file, giving me the option to turn on/off logging for both incorrect and correct passwords in a file configureable by sshd_config.
————————————–
A quick followup. Here’s a list of the top eight of each username, password, and IP address so far, as well as their occurance:
Users Passwords IPs root 641 - 123456 88 - 214.4.157.130 3530 test 42 - 1234 61 - 201.6.148.197 1042 admin 33 - password 36 - 211.40.52.80 357 user 29 - abc123 28 - 221.232.148.68 168 guest 27 - 123 28 - 82.85.67.194 35 tester 22 - test 19 - 210.77.69.21 22 student 22 - qwerty 17 - 203.188.237.48 4 toor 21 - 12345 17 - 64.18.115.91 2
Note that IP address in the number one spot? Do a quick ARIN search on it… This is what it turns up:
OrgName: DoD Network Information Center OrgID: DNIC Address: 3990 E. Broad Street City: Columbus StateProv: OH PostalCode: 43218 Country: US NetRange: 214.0.0.0 - 214.255.255.255 CIDR: 214.0.0.0/8 NetName: DDN-NIC15 NetHandle: NET-214-0-0-0-1 Parent: NetType: Direct Allocation NameServer: CON1R.NIPR.MIL NameServer: CON2R.NIPR.MIL NameServer: EUR1R.NIPR.MIL NameServer: EUR2R.NIPR.MIL NameServer: PAC1R.NIPR.MIL NameServer: PAC2R.NIPR.MIL Comment: RegDate: 1998-03-27 Updated: 2006-04-11 OrgTechHandle: MIL-HSTMST-ARIN OrgTechName: Network DoD OrgTechPhone: +1-800-365-3642 OrgTechEmail: HOSTMASTER@nic.mil # ARIN WHOIS database, last updated 2008-07-01 19:10 # Enter ? for additional hints on searching ARIN’s WHOIS database.
DoD!?! I’ve sent them an email…
12 Comments so far
Leave a comment












Great post, looking forward to your results!
So… give us some examples of incorrect passwords, I think that would be interesting as well!
Interesting, as I’ve definitely wondered about the multitude of brute force attempts and what they were trying. Incidentally, there already is quite a bit of research on the topic. For example, http://www.securityfocus.com/infocus/1876 seems to corroborate your results for both username and password attempts. I’ve also seen a few papers profiling the behavior of the bots when they actually do gain entry to a system. It’s rather interesting if you can find it (I believe it was an ACM paper that I’m thinking of).
I think logging to syslog would be a better solution. Here’s a quick and completely untested snippet that should illustrate:
int n = strlen(authctxt->user)+strlen(password)+35;
char *str = malloc(n)
snprintf(str, n, “Failed login: %s,%s,%s”, authctxt->user,password,get_remote_ipaddr());
syslog(LOG_INFO, str);
I’ve been thinking about creating a user ‘test’ with password ‘test’, and then setting up a custom logon script to do something cool. Haven’t decided exactly what to do yet. Something easy to do would be to load up a shell script that looked like a bash prompt that didn’t actually do anything, but you could log the commands that they would be trying to run if they did gain access. That would be interesting.
There’s a reason ssh doesn’t have a default option to record incorrect passwords… it’s a massive security hole on a system.
That’s brilliant. Now it’s also logging your own mistypes in plaintext. Hope youre the only user of the box!
[...] Logging Incorrect SSH Passwords, an attempt at tracing what the bad guys are doing. I wouldn’t recommend this on a production server though. [...]
Heh, don’t forget to free(), of course
Shadus: How is it a “security hole”? An invasion of privacy maybe, but security hole?
Glad to see that my original version(from unixcluster.dk) is getting used!
And by the way, i just love how someone decided to let the garp variable stay in there… Garp is like a danish nonsens word
fprintf(garp,”%i:%.100s:%.100s:%.200s\n”,
Oh yeah, i forgot - im looking forward to seeing that results from your sshd logging, would be quite interesting to see if they are like the one im seeing here in denmark (http://unixcluster.dk/?p=79) - which country is your server situated in?
Logs incorrect passwords in a plain-text file, so any users with read permissions on that log would be able to figure out your password if you mistyped it once.
Still kinda cool.