SSH Password Logging

So, i’m alive.  I know I don’t post as often as I should.  And I know you probably feel left out, alone, bereft.  Fear not, I am back.

Logging Attempted Passwords With SSH

Anyway, remember that post I made of ssh attempts way back when?  Well, I got bored.  I decided it wasn’t enough to see the usernames attempted, I needed to see the passwords attempted as well.  My first thought was to use one of the honeypot ssh servers that exist and simply run the real ssh on another port.  I didn’t like that approach.  For one thing,  I don’t want the attacker to actually make it in, not even to a fake environment.

I decided the best way to go about it was to use the existing openssh server I have running.  Even there, there are options.  I can modify the openssh server source to log the password it receives.  Or, I can create a PAM module to record the password that it attempts to authenticate.  The biggest problem here is, i’m not a programmer.  I haven’t the slightest idea how to write a PAM module.  Curiously, nobody has written any PAM modules specifically to record usernames and passwords.  It’s almost like they’re worried about security or something.  I decided to just modify openssh since it already has the username and password stored in memory and the ability to log.  Should be easy, right?

I learned a lot.  I’ve never really looked at professionally produced, competent source code before.  Its interesting how well written, and complicated, the code is.  Especially without an IDE.  I first had to find the method it used to log to syslog.  I had to figure out how to use it.  I then needed to find where in the code I could insert a call to that method to log the variables I wanted.  That I was able to figure out.  Some google searches showed that while not many have tried to do this, a few have.  I was able to at least determine where I needed to insert the code.  The source file “auth-passwd.c” is the place.  Anywhere else, I discovered, the password has been sanitized and is no longer available.  I needed to get to a place where the password still existed in memory and that point is right when it gets authenticated.

 How to do it

Option 1: Be lazy and use my pre-compiled .deb.

Ok, so you don’t feel like following my wonderful instructions and compiling the source yourself.  No worries, i’ve uploaded the deb package created and included it here.  I don’t believe there is any danger in applying it.  Worst case scenario, the latest version of openssh-server from ubuntu can be installed over top of it with the following command.

sudo aptitude install openssh-server

Download openssh-server_5.8p1-7ubuntu1_i386.deb.

Do the following to install.

gunzip openssh-server_5.8p1-7ubuntu1_i386.deb_.gz
sudo dpkg -i openssh-server_5.8p1-7ubuntu1_i386.deb_.gz

 

*Update*

If you run updates in the usual way, the new version of openssh-server will overwrite your modified version.  Run the following command to exempt openssh-server from future updates.

sudo aptitude hold openssh-server

I don’t recommend running an older version for very long.  You should try to re-compile and install the newer versions as quickly as possible.

Option 2: Do it yourself

Feeling adventurous eh?  Well, its actually quite easy once its been figured out.  The following instructions will give you step by step instructions for modifying the source file.

Step 1: You’re going to want to create a folder for your workspace.  Its fine to create in your home directory, root isn’t needed till the end.

mkdir source
cd source

Step 2: Now, there are some pre-requisites to be able to compile, as well as the source code.  Install these with the following.

sudo aptitude install dpkg-dev
sudo aptitude build-dep openssh-server
apt-get source openssh-server

Step 3: The source code is now downloaded.  Enter the folder containing it.  At the time of this writing, OpenSSH version 5.8p1 was being offered by Ubuntu.  The exact folder name may differ.

cd openssh-5.8p1

Step 4: This one gets a little more complicated.  You need to edit the source file “auth-passwd.c”, locate the appropriate section, comment out the code (for safekeeping) and paste in the appropriate code.

Open the source file with your favorite editor (which of course is vim).

vim auth-passwd.c

You need to locate the correct section to insert the code.  If you don’t mind logging legitimate as well as failed attempts, insert the following code right after the initial variable declarations and before any definition checks (something like #ifdef or #if defined).

logit("PassLog: Username: %s Password: %s", authctxt->user, password);

Incidentally, that was the hard part.  I knew nothing of how the “printf” function works for one and that method above relies on some variation of it.  Its interesting, the variables inserted in the log line are listed after the string literal.  The %s specifies that the variable be printed as if it were a string (typecast basically).  I re-compiled at least 15 times before I figured out the correct syntax.

I recommend against this method.  While your server should be secure and your logs readable by only you, its probably best not to have your password in plain text.  However, if you exclusively use key-based authentication, maybe its worth it.

I recommend setting it up the way I did it.  My openssh server is configured to use PAM.  It has the following setting in its configuration file.

/etc/ssh/sshd_config:
UsePAM yes

You need to locate the section where the password is authenticated against PAM.  There should be a compiler definition like the following.

#ifdef USE_PAM

The following is the full code I inserted between the #ifdef and #endif blocks.

/* Jesse */
if (options.use_pam) {
   int jesseresult=(sshpam_auth_passwd(authctxt, password) && ok);
   if (!jesseresult)
      logit("PassLog: Username: %s Password: %s", authctxt->user, password);

   return jesseresult;
}

/* Original */
//if (options.use_pam)
//   return (sshpam_auth_passwd(authctxt, password) && ok);

You’ll note I saved the original code at the bottom there.  In my code, I performed the same check they did and saved it in “jesseresult”.  I then check to see if it is “0″ (authentication failed) or “1″ (authentication successful).  If the check failed, I call the logit function to log the username and password of the attempt.

Step 5: There, hard part over.  Now we compile (easy) and install (just slightly easier).  Execute the following to compile and build.

dpkg-buildpackage -rfakeroot -uc -b

This will take a few minutes.  When it is done, it will build a .deb package in the previous folder.  The name is specific to the version of OpenSSH you happen to have.  Your file may be named differently (slightly) than the one in the following command.

sudo dpkg -i ../openssh-server_5.8p1-7ubuntu1_i386.deb

If you’re connected over ssh when you do this, don’t worry.  The ssh daemon you’re connected with is in memory and will continue running the old version until you disconnect and reconnect.  I recommend you not disconnect until you are sure everything is working normally.  Open a new shell and attempt to connect with a fake username and password like the following.

ssh apples@files
apples@files's password: oranges

Now check your auth.log.  If you see an entry like the following, its working.

Dec  2 22:59:23 fileserver sshd[6846]: PassLog: Username: apples Password: oranges

Conclusion

I set this up so that I could monitor the connection attempts of random botnets, etc for my own amusement.  You of course will have your own reasons.  I wanted to mention though, that there is a danger of accidentally capturing legitimate passwords.  When connecting, if you mistype your username but type the password correctly, authentication will fail and the attempt will be logged.  Its not hard to guess that the password tried for “jeses” was meant for the account “jesse”.

One more note.  Like I stated earlier, I am not a programmer.  I am about 99% percent certain I introduced no remote exploits in my code.  I am using OpenSSH’s variables, functions, and performing no (important) logic of my own.  I am not performing any string copies for buffer overruns, nor am I modifying the actual authentication process.  I don’t believe anything I have done provides a foothold for an attacker to use.  That said, any damages that result, etc., etc. is not my fault.  Examples and code is provided as is with no warranty of any kind.

Enjoy :).

References

Sites and places where I got tidbits and hints.

  • printf() syntax – Learned about the syntax for printf style functions.
  • pwd.h – An important library for managing passwords, used by OpenSSH.
  • C style variable passing – Gave some hints on how variables can be implicitly passed in C.
  • Debian Policy Manual – Told me how to compile debian style packages from source.
  • iphonehoneypot – Gave me my biggest hints as to the code I needed and where to insert it.
  • Ubuntu Forums – Got the idea about PAM that i ultimately didn’t use.
  • CompleteFusion – A blog entry about password recovery using ssh.
Related Posts