It was late in the evening when I saw the challenge for September. To
crack the zip as I tried the fzipcrack with
the most popular password list from 10,000 Top
Passwords. It didn't work. Then I tried to crack it with an English
dictionary generated from aspell I had from another case:
aspell -d en dump master | aspell -l en expand | tr ' ' '\n' > en_words
That didn't work either. Then I let fcrackzip run to brute-force for the
night. The next day, the brute-force was still going. I had various
ideas of what to try. I decided to try the English dictionary again and
to my surprise it quickly found that the password was "infected".
Facepalm! Why it didn't work before, I don't know, it must have been
late night bugs.
After that it was the time for the android package. Looking at the
strings there were a few candidates, but I knew it wouldn't be that
easy. After unpacking the package with apktool, I
noticed interesting activity declaration, which contained:
<action android:name="android.provider.Telephony.SECRET_CODE" />
<data android:scheme="android_secret_code" android:host="374" />
A quick search revealed that it is activated by entering
*#*#374#*#* in the dialer app. So I installed the Android SDK and
fired up the emulator, but to my frustration the dialer app was not
available. It seems that current Jelly Bean v4.3
(installed by default) is for tablets and does not contain the dialer.
After installing v4.1 (which was known to be designed for phones and
also the one mentioned in the package's manifest) I was able to enter
the secret code, but only a blank screen was displayed. DEX strings
contained clues, that something was being logged, but watching the logs
did not reveal the hidden message, only reassured that "The right answer
is definitely not here there be Dragons!"
I quickly checked the ssh cloud
page which is loaded by default when opening the application, but I
was not able to find anything of interest and quickly moved on.
Then I analyzed the smali code produced by unpacking with the apktool.
Line by line I had reconstructed the functionality as a pseudo code. It
<script>var data = '';var s1 = '2VjcmV0cw';data =
interfaces.jsFunction(s1);document.write('getting warm. must be dragons nearby');</script>
It was strange that it wasn't shown after entering the secret code. And
the definition for the
jsFunction() was nowhere to be
found. So I thought that it might be intentionally left out and fixated
on the string "2VjcmV0cw". It was quite short and apparently non too
random. It wasn't of correct length for base64. Other binary-to-text
algorithms didn't fit either and the same goes for common text ciphers,
which usually do not include numbers. Then I tried some primitive
chained xor and what do you know:
I thought it is start of some combination of "dragon", but that wasn't
the case. Any further xor'ing sooner or later produced non ascii
The string "2VjcmV0cw" looked familiar to url shorteners, but none of
the ones i knew had such id. Then I've visited the twitter of Jason Ross (his name
was in the apk signing certificate) to see what URL shorteners he did
use, but again, none of them contained the id.
I was at a loss and decided to look at all the files again more closely.
The idea was to check if there was anything hidden in between the
fields. I did some unpacking and repacking of files to check if they
would differ, but the closest thing was few bytes of zip's padding
(created by a tool called zipalign)
and an extra field "0xcafe" (used to denote jar).
During this time i was looking for the tools included in Android SDK
package, one line in the documentation gave me the idea that something
might be wrong:
"The ProGuard tool shrinks, optimizes, and obfuscates your code by
removing unused code and renaming classes, fields, and methods with
semantically obscure names."
One of the classes was named "a" which was similar to how ProGuard obfuscates.
Furthermore it was the class which was supposed to contain the
jsFunction method. This method was invoked dynamically and
could be treated as unused code by the ProGuard's static analysis.
I didn't want to bother the challengers with a hunch and I decided to
check it for my self. So I wrote my first android app and indeed, my
prediction was valid. The app would work while debugging but it would
stop working after exporting if ProGuard was active and wasn't
explicitly configured to keep the class intact.
With all this data I was confident enough to ask if the challenge was
solvable "as is" and a day later I have received the confirmation that
there was a mix up.
Once I had the correct file I have noticed that it was a debug version
of the application and it contained a lot more classes. But since I knew
what to look for, it was only a matter of minutes to locate the missing
function and to figure out what it does.
After entering the secret code the the app would log the concatenated
m9Nb3JlU2VjcmV0cw== which is a base64 encoding of
Once again it was a great opportunity to learn something new and I am
very grateful for that!
For further details on how the challenge was constructed along with
notes and write-ups from all challenge players who solved solved the
challenge, please see the updated DRG
Online Challenge September 2013 page. The newest, DRG Online Challenge October 2013 is
now available. Visit the DRG Challenges page
for information about all current, future and past challenges.