iPhone Honeypot Project

July 13, 2010

Capturing SSH Keystrokes

Filed under: bash,gcc,logging,Network,router,SSH — abnev @ 5:08 pm
Tags: , , , , , ,

I have been looking into the final element of this project – methods and techniques to capture and record keystrokes within a SSH tunnel. The various methods I’ve found were kernel modules (similar to the Sebek approach), hacking openssh to record keystrokes to a file on the filesystem, hacking bash to record keystroes, or using a program like tee, logger or script to capture everything by having it launch automatically from /etc/profile, ~/.profile or something similar.

In order to try retain the security of the iPhone and the data collected isn’t tampered with, I’d like to somehow use syslog or syslog-ng to log everything to a remote host in real time using UDP. To do this, I ran a quick test on my Macbook using tee which worked quite well and writing a quick and dirty script to add to /etc/profile which logs everything to syslog which can then be sent to a remote host.

function log2syslog
declare COMMAND
COMMAND=$(fc -ln -0)
logger -p local1.notice -t bash -i -- "${USER}:${COMMAND}"
trap log2syslog DEBUG

Inspecting /var/log/system.log we can see the keystrokes being captured:

Jul 13 17:33:44 abnev-lpt2 bash[95803]: abnev:
Jul 13 17:33:44 abnev-lpt2 bash[95805]: abnev:
Jul 13 17:33:47 abnev-lpt2 bash[95807]: abnev: pico .profile
Jul 13 17:33:53 abnev-lpt2 bash[95810]: abnev: fail -f /var/log/system.log
Jul 13 17:34:09 abnev-lpt2 login[95815]: USER_PROCESS: 95815 ttys004
Jul 13 17:34:10 abnev-lpt2 bash[95820]: abnev:
Jul 13 17:34:10 abnev-lpt2 bash[95822]: abnev:
Jul 13 17:34:11 abnev-lpt2 bash[95824]: abnev: pico .profile
Jul 13 17:34:14 abnev-lpt2 login[95815]: DEAD_PROCESS: 95815 ttys004

This is promising. By replacing syslogd with syslog-ng I can easily whip up a config file to relay everything over to a remote host on the network. I have also looked into getting syslog-ng on the iPhone. This may be possible using cross-compiling for the iPhone architecture. I’ll have to look into this further. In the mean time, I’ve picked up a spare phone so I can use the iPhone for the project when everything is redirected from the router. I have to run a test to ensure wifi works when the simcard is removed from the phone. I have been told otherwise but requires testing.

I also found this neat ssh server written in python using the Twisted framework from http://twistedmatrix.com/users/z3p/files/conch-talk.html and a tutorial covering it at http://www.devshed.com/c/a/Python/SSH-with-Twisted/.

#!/usr/bin/env python

# Copyright (c) 2009 Twisted Matrix Laboratories.
# See LICENSE for details.

from twisted.cred import portal, checkers
from twisted.conch import error, avatar
from twisted.conch.checkers import SSHPublicKeyDatabase
from twisted.conch.ssh import factory, userauth, connection, keys, session
from twisted.internet import reactor, protocol, defer
from twisted.python import log
from zope.interface import implements
import sys

Example of running another protocol over an SSH channel.
log in with username "user" and password "password".

class ExampleAvatar(avatar.ConchUser):

def __init__(self, username):
self.username = username

class ExampleRealm:

def requestAvatar(self, avatarId, mind, *interfaces):
return interfaces[0], ExampleAvatar(avatarId), lambda: None

class EchoProtocol(protocol.Protocol):
"""this is our example protocol that we will run over SSH
def dataReceived(self, data):
if data == '\r':
data = '\r\n'
elif data == '\x03': #^C

publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+BR3utDS555mV'

privateKey = """-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----"""

class InMemoryPublicKeyChecker(SSHPublicKeyDatabase):

def checkKey(self, credentials):
return credentials.username == 'user' and \
keys.Key.fromString(data=publicKey).blob() == credentials.blob

class ExampleSession:

def __init__(self, avatar):
We don't use it, but the adapter is passed the avatar as its first

def getPty(self, term, windowSize, attrs):

def execCommand(self, proto, cmd):
raise Exception("no executing commands")

def openShell(self, trans):
ep = EchoProtocol()

def eofReceived(self):

def closed(self):

from twisted.python import components
components.registerAdapter(ExampleSession, ExampleAvatar, session.ISession)

class ExampleFactory(factory.SSHFactory):
publicKeys = {
'ssh-rsa': keys.Key.fromString(data=publicKey)
privateKeys = {
'ssh-rsa': keys.Key.fromString(data=privateKey)
services = {
'ssh-userauth': userauth.SSHUserAuthServer,
'ssh-connection': connection.SSHConnection

portal = portal.Portal(ExampleRealm())
passwdDB = checkers.InMemoryUsernamePasswordDatabaseDontUse()
passwdDB.addUser('user', 'password')
ExampleFactory.portal = portal

if __name__ == '__main__':
reactor.listenTCP(5022, ExampleFactory())

This required installing py-crypto via MacPorts:

sudo port -v install py-crypto

1 Comment »

  1. Well done impressive work🙂 , keep at it🙂

    Comment by Morry — July 15, 2010 @ 5:06 pm | Reply

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: