Destination: Defcon CTF Quals 2011 - Retro Revisited 300
Your tour guides: p4fg & fLa [vImeDhuSocHbarN]

This is a very quick writeup, if you are from Sweden you can take a look at our team-name
and try to guess why now is not really the best time to write in-depth writeups... ;-)

File: rr3001d8bcd25d1849ac5a 

unpacking this gives us:
retro300  (ELF 32-bit Intel 80386 for GNU/Linux 2.6.32)
auth.db   (sqlite3 database)
# sqlite3 auth.db
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> .dump users
INSERT INTO "users" VALUES(1,'aaron','7345');
INSERT INTO "users" VALUES(2,'dave','3245');
INSERT INTO "users" VALUES(3,'bob','8367');
INSERT INTO "users" VALUES(4,'joe','8305');
INSERT INTO "users" VALUES(5,'vulcan','2945');
INSERT INTO "users" VALUES(6,'merc','2345');
INSERT INTO "users" VALUES(7,'mars','3473');
INSERT INTO "users" VALUES(8,'jupi','1234');
INSERT INTO "users" VALUES(9,'jeff','1315');

Where to start?
In order to start playing with the service we need a password..
A quick peek in the binary using strings reveals a good candiate "letmeinpls" 
which turns out is the password to continue.

We also notice from the strings output that the SQL statement for authentication 
could be vulnerable for a SQL-injection attack, more on that later...

select id,pin from users where user='%s'

Binary analysis
Firing up IDA lets us know a few things about the execution flow of this binary:

* Passcode needs to be 14 characters long.

* No sanity checking on the username is performed

* There are two hidden menu options: '8' and '9'.
  '8' will display the key and '9' will display our favourite animal...

* The extra 10 characters in the passcode after the actual PIN is calculated 
  in a really annoying way based on the number of 10 minute increments since 
  2009-03-16 00:00:00 or something, and is then multiplied with the id in the db plus one
  and padded to 10 characters with leading zeroes.

* Different errorcodes are printed based on how far into the code you get:  
  "Bad Username or Pin" will be displayed if you fail the username/pin db-check.
  "Bad Username or Passcode" will be displayed if the 10 last characters in the passcode is wrong.

What about that SQL-injection?
After testing a bit we found that we could get past the first check 
of username and four-digit PIN with a old-school SQL-injection. 

using a username such as

randomcrap' union select 123,'1234

translates internally to

select id,pin from users where user='randomcrap' union select 123,'1234'

Using this and the different errormessages we found ourselves trying to crack the
last 10 digits which are time-based and user-id dependant.

The last 10 digits
The time-based calculation for the last 10 digits in the passcode was a bit 
annoying and time-consuming to crack so we decided to bypass it completely 
with our newly found SQL-injection.

Remember the calculation is multiplied with the id in the db plus one.

Lessons to learn here: 
(-1) + 1 = 0  (Thanks fLa for pointing that out)
0 x stupid_ddtek_algorithm_output = 0

Moment of triumph

# nc 5500
                                           _____ ______ _____ _     _
               __    ____       __        / ____|  ____/ ____(_)   | |
          ____/ /___/ / /____  / /__     | (___ | |__ | |     _  __| |
         / __  / __  / __/ _ \/ //_/      \___ \|  __|| |    | |/ _` |
        / /_/ / /_/ / /_/  __/ ,<         ____) | |___| |____| | (_| |
        \__,_/\__,_/\__/\___/_/|_|       |_____/|______\_____|_|\__,_|    (beta)

    ( cause everyone is looking for a new provider right?!)

Username:x' union select -1,'0000
   DDTEK VPN console

    Choose an option:
       1:  change pin
       2:  re-sync sec token
       3:  add user
       4:  change username
       5:  exit