Saturday, November 8, 2008

The End of Annoying OTP's

If you're a student in CS at the Hebrew University of Jerusalem, you're familiar with OTP's (one time password) used to connect to the university servers from remote, submitting exercises, receiving grades and so on.

There are currently two ways to generate OTP's:
  • If you have a java-enabled phone (Nokia only) you can download an application called HOTP which will allow you to generate an OTP with each button click.
  • If you don't have a Nokia phone (like I do) you have to enter a website, fill your unix username and password and answer a CAPTCHA. Then SMS is sent to your cellphone, including 5 OTP's.
Needless to say, the latter option is really annoying, especially when you need to use the OTP 4-5 times in a row while submitting an exercise (connect to an FTP server, use SSH, enter the submission system and so on).

So I decided to create my own OTP client which will be able to generate OTP's locally. The main target was to create a program that will copy the next OTP to the clipboard, which will allow easy transportation of the 5-digit password.

I simulated a download of the HOTP program, and decompiled it (Jad rules). The code was scrambled, but I figured out by using the koders search engine that Java's bouncycastle package is used there. This package gives a lot of encryption services, and here they use the Rijndael (original AES) and the HMAC SHA-1 encryption in order to generate the OTP.

I won't go into further details. If you're really interested in how it works, you can go over the script's source - it's not that complicated.

Some installation details:
  • Very important note: if you're currently using the HOTP application, installing this script (requesting a new HOTP application download) will make your cellphone HOTP application broken. This is caused because the key counter is randomally selected each time an application is generated for download.
    If anyone of you sees this as an important issue, leave me a reply here or send me an email.
  • You'll need ActiveState Python (version 2.4 and up).
  • If you're using other operating system than Windows, you can still use the script, but the clipboard option will not work (only printing to stdout).
  • After installing python and downloading the script, run it without parameters and installation will begin.
  • For further options, use the --help or -h switch.
You can download NOTP from here.

Have a great semester :)

18 comments:

Unknown said...

Wow! - a really useful app. Notice that currently you must run the program from the same directory everytime (it searches the ini file inside the current directory).
Thanx a lot

StatusReport said...

Fixed it (now it changes the current directory to the notp directory).

And thanks :)

Shir Peled said...

Great service for the community.
I forwarded it to some people here at work (who use CS services) and at school.

Anonymous said...

First of all, thanks! Great idea!

Does it work on windows mobile? if so, what is the procedure?

StatusReport said...

Thanks!

And I'm not sure about the Windows Mobile, but it should work: check PythonCE: http://pythonce.sourceforge.net/Wikka/HomePage

Please post your results :)

Unknown said...

Just a suggestion: I've added a sleep for 10 sec at the end of the script (Time.sleep) because the copy to the clipboard doesn't work and I'm running the program from windows (I have python2.5 and not ActivePython). So now I have 10 sec to copy the output (the pw) before the cmd is being closed (instead of running the program in IDLE or openning a cmd by myself).

D said...

Hi,

i think you had a fun time with Jad, but actually there is a reference java implementation in the RFC ;)

http://www.ietf.org/rfc/rfc4226.txt

Nice job though.

Domi

StatusReport said...

Oh well... next time I'll RTFM :)

Was more fun reversing it, though :P

kirillkh said...

I've just done exactly the same thing, i.e. reverse-engineered HOTP, this time to Java. It's ironical that *after* doing that, I went ahead to search for "huji otp" on Google (in hope to find a way to download the JAD file, bypassing the captcha) and stumbled upon your project. I was actually aware of the reference implementation, but HUJI's source code looked a bit differently, so I decided to stick with it.

My next step is to integrate it with SSH. This will make it possible to mount one's directories at the campus system as local directories at home through fuse.

GuySoft said...

Hey,
Thought I might let you know that the install process is broken on Linux.
I got :

guy@golem3:~/Desktop/downloads/notp$ python notp.py
Traceback (most recent call last):
File "notp.py", line 284, in
NOTP().run()
File "notp.py", line 210, in run
os.chdir(os.path.dirname(sys.argv[0]))
OSError: [Errno 2] No such file or directory: ''


.. commenting line 210 solved this.

Great job.

StatusReport said...

Thanks mate, I've added an exception handler there. The problem is that in Linux os.dirname can provide an empty string.

Anonymous said...

For Linux users, here is how you can ssh without copy and pasting:

#!/usr/bin/env bash
OTP=`cd ~/Desktop/downloads/notp ; python notp.py`
password=password
user=user
expect -c \
"spawn ssh -XC $user%inferno@gw.cs.huji.ac.il \
match_max 100000; expect \"(OTP) Password\";\
send -- \"$OTP\r\";\
expect \"*?assword:*\"; send -- \"$password\r\"; send -- \"\r\" ; interact "

Tomer said...

If anyone is interested, I made an iPhone application that generates OTPs (the generation algorithm was based on this script):

http://mutualexclusion.blogspot.com/2010/05/iotp-and-more.html

StatusReport said...

Cool, thanks for the port! :)

Anonymous said...

Hello!

I'm getting an error message:

"line 250 print self._getOTP()

SyntaxError: invalid syntax"

I just downloaded the .zip file, there were 2 .py files in it, either one just pops a cmd window for a second. An I missing something here?
Working on Windows 7 64bit btw.

thanks!

StatusReport said...

Hi,
You need to run the notp python script (the other .py file is a module this script uses).
I bet you're using Python 3 which is not backward compatible with Python 2.x scripts, and that's why you get this error. You can change this line to print(self._getOTP()) and it should fix the problem, but maybe some other will arise (I didn't test it on 3.x).

Anonymous said...

Thanks, that solved the problem.
I managed to create a .pyc file, but still it just pops a cmd window for a second and does nothing. Even when I try to run it from a cmd nothing happens. Since I know nothing about python, I think I'll just leave it and stick to the phone app

Unknown said...
This comment has been removed by a blog administrator.