Dec 9, 2017

ph0wn CTF 2017 Write-up: Misc/helpxman - Stage 2 and 3

After successfully getting the flag of Stage 1, the challenge told us to continue looking for something interesthing from the app. After playing around with the app's UI, we found nothing special and decided to look into the internal of the app.
By saying internal we meant: let's reverse the source code of the application!

Get the application's APK file from the glasses.

  1. Connect the glasses with the computer as described in Stage 1
  2. List all current application installed in the smart glasses:
> adb shell pm list packages
=> We can easily identify the app we are looking for is package:ph0wn.reconjet
  1. With the package name found, we can find the actual filename and the location of the APK file:
> adb shell pm path ph0wn.reconjet
(Author's note: When writing this write-up, I have to run the app again on my phone, so the path appear above might be different from the one actually found on smartglasses.)
  1. Pull the APK to our host computer for further analysis:
> adb pull /data/app/ph0wn.reconjet-1/base.apk ./ph0wn.reconjet-1.apk

Analyse the APK file

  1. We use [apktook] to decompile the APK file.
On the host computer:
$ apktool d ./ph0wn.reconjet-1.apk 
I: Using Apktool 2.2.3-dirty on ph0wn.reconjet-1.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /root/.local/share/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files... 
All the source/resource files are decoded and saved at ph0wn.reconjet-1 directory.
  1. After some quick investigation, we found one suspecious file (and with suspecious name): ph0wn.reconjet-1/smali/ph0wn/reconjet/HiddenActivity.smali.
Look inside the file, we found one suspecious part of source code (at the end of file): from line 114 to line 1012.
    .array-data 4
=> This is definitely suspecious and we have to find a way to decode this set of hexa codes, it may store our flag(s).
  1. By some simple tricks to copy and paste, we put all the hexa codes next to each other for better view, and save them to a file called hexacodes:
$ cat hexacodes
(Trick: merge all the lines and remove spaces in VIM
:%s/\n        //g
  1. One more thing, these hexa codes look pretty much a set of ASCII codes of a very long string, let's try to print them out by a simple python print function.
In []: print((open('hexacodes').read().replace('0x','')).decode('hex'))
TypeError                                 Traceback (most recent call last)
<ipython-input-36-ba53ed228ee2> in <module>()
----> 1 print((open('hexacodes').read().replace('0x','')).decode('hex'))

/usr/lib/python2.7/encodings/hex_codec.pyc in hex_decode(input, errors)
     40     """
     41     assert errors == 'strict'
---> 42     output = binascii.a2b_hex(input)
     43     return (output, len(input))

TypeError: Non-hexadecimal digit found
Oops! It should work, but why doesn't it?!
  • We tried to read only 30 first characters:
In []: print((open('hexacodes').read().replace('0x',''))[:30].decode('hex'))
=> It works with the first 30 characters. (And the word Congratulations makes us believe that we are on the right way). There must be some thing wroing in the middle of the string makes our process doesn't work.
  • Look at closely to the string, we found the problem: it is the code 0xa that made our print command failed. Isn't it supposed to be a newline character (0x0a)? Let's fix it and try again.
  • Secondly, we noticed that the final '\n' in our hexacodes also makes a problem, so that let's remove it as well.
  • The final command is as follows:
In [57]: print((open('hexacodes').read().replace('0xa','0x0a').replace('0x',''))[:-1].decode('he
    ...: x'))
Congratulations, this is stage 2 !
To flag this stage, flag is: Ph0wn{KKKPicoIsEverywhere} where you must replace KKK with the key you found during stage 1.
Key for stage 3 is: c_Hqopef91

Stage 3:
Search in the room, direction NW, for a hidden treasure :) Be quiet so that other teams do not understand what you are doing.
To flag this stage, flag format is: Ph0wn{KKKKKKKKKKAAABBBCCCDDDEEEFFFGGG}.
Where KKKKKKKKKK is the key you found during stage 1.
- AAA is the coordinates of the first lettter of word FORTINET is the treasure. First letter is column (A, B, C...). Second letter is row (1,2,3...). Third letter is word direction: H for horizontal, V for vertical. So, if FORTINET starts at row A, column 3, horizontally, we will have A3H.
- BBB is the coordinates for TELECOM,
- and GGG for GREHACK.
Good luck.
BINGO!! All the information of flags for Stage 2 and Stage 3 are revealed!
  1. The rest are simple (we hoped :) ), it actually require some physical exercises and playing with some word game (as described above), no computer skills needed. (But personally I think this kind of thing made this challenge a lot of fun and unlike any other CTF challenges before. Plus 1 for ph0wn organizers!)
  2. So,to conclude, the flags are as follows:
  • Stage 2: Ph0wn{X@MPicoIsEverywhere}
  • Stage 3: Ph0wn{c_Hqopef91M17HI10VO19VK1VL14VA8VC12V
BONUS Here is the hidden treasure we found (with some beautiful original handwriting):

ph0wn CTF 2017 Write-up: Misc/helpxman - Stage 1

When wearing the smart glasses, we can see there is an application called Ph0wn Glasses. Go to that application (by using controller on the glasses, we can see one QR code appears on the screen.
The QR code is much likely have information about the flag. Let's try to read it!
  1. Connect the smart glasses with the (ADB already installed) computer.
  2. From the command prompt of the computer (Ctrl+R --> Type cmd --> Press Enter). Type:
> adb devices
List of devices attached
* daemon not running. starting it now at tcp:5037 *
* daemon started successfully *
=> Make sure the ID of the device appear as above. Otherwise, we have to:
  • Turn on Developer options in the Settings of the glasses. (The glasses is running Android, so it's the same as any other Android devices).
  • Restart ADB service on host computer: > adb kill-server
  • Try to connect with the device (glasses) again: > adb devices
  1. On the smart glasses, browse to the application, so that the QR code image appears on the screen. The idea is we try to take a screenshot of the glasses, pull it to our host computer and read it by QR code reader.
  2. Take a screen shot by adb command:
> adb shell screencap -p /sdcard/screencap.png
The screenshot will be saved in the glasses' SDcard.
  1. Pull the file to host computer (current working folder):
> adb pull /sdcard/screencap.png .
  1. View the image:
> screencap.png
We will see it on our computer's screen:
  1. Now, let's read the QR code. No need to make things complecated, let's choose a very simple way: show the image on computer's creen, read it with the Barcode scanner app on our normal phone.
It's quickly be recognized as follows:
So, the flag is: Ph0wn{ScottWishesHeHadOurSmartGlasses}
And, we note the key X@M for the next stage.

Sep 24, 2017

CSAW 2017 CTF Write-up: Web littlequery

### Points

### Readme
I've got a new website for BIG DATA analytics!

### Steps

0. The website has nothing than one login page. When trying to login with some dummy data like test/test; we noticed that the password field is somehow modified before the data is submitted to server.

Open the source of the page, we find that there is one javascript file at `js/login.js` that is used to handle the form data.

Open the javascript file, it contains only one function:

$(".form-signin").submit(function () {
    var $password = $(this).find("input[type=password]");

So, we know that the input password is actually be hashed to SHA1 format before submitting (and probably saved in the same format) to server.

We then come up with the idea, if we can know the username and hashed password, we can use that directly to login to the website without the need of finding original unhashed password. (That can be achieved pretty easily by disabling javascript in login page).

1. A quick scanning with the provided link (by some tools such as `OWASP ZAP`) result in finding a hidden file. The file is called `db_explore.php` located inside a sub-directory `api`.

2. Check the file:

Resulted in:
Must specify mode={schema|preview}

3. Let's add one parameter `mode=schema` as it suggested.

Resulted in:


Looks like we have seen the database name, and it is: `littlequery`

4. What if we add one more param, such as `db=littlequery` to see if it can show us the schema of the database?

Resulted in:

Exactly as we thought. It showed us that the database has one table named `user`.

5. We think inside this `user` table, there must be some columns related to `username` and `password`, let's verify that:

Resulted in:


Exactly! The table has two columns, one is `username` (maximum length is 128 chars) and the other is `password` (with the maximum length is 40 characters for each value). It seems to be pretty matched with our assumption at the beginning.

6. Now, if we could see the detail content of this table, we can know that username and password in order to login to the site, then our mission will be done!

We also remember that there is one more `mode` to use is `preview`. Let's use it to see it can help us to see the content of the table:

Resulted in:

Database 'littlequery' is not allowed to be previewed.

What?! How could it be?? We cannot see the content of the database because it is not allowed to do so.

7. We try to change the database name to see what would happen:

Resulted in:
`anything`.`user` doesn't exist.

Note that the character "`" is added around the name of the database and the table.

8. So, we can come up with the followng two ideas:

  * Firstly, there must be a filter of database name inside the PHP source code that blocks us from requesting the `littlequery` db. So, our mission now is: How to cheat the PHP filter function that it thinks we are not requesting the `littlequery` database, but actually the SQL query later on still work as we expected (the table `user` inside `littlequery` database is still be requested).

Or, in other words, we should provide one database-name-payload to the `db` param so that it actually request directly to the table inside the database (and not the database itself).

  * Secondly, the character "`" could (hopefully) be used to fool the filter in the PHP code.

9. We try to append the table name directly to the database name, to see what happen:`.`user&table=user

(Note that the "`" will be added at the beginning and the end of `db` param value).

Resulted in:
`littlequery`.`user`.`user` doesn't exist.

Almost there. It looks like the `table` param's value is still being taken into account.

10. Now what we need to do is to put something at the end of database name query so that it ignores everything else come after.

That something is: two hiphen and one space characters: `-- ` (Characters used for comments in SQL)

And because the character "`" added by the PHP source code also be ignored, so we have to put it by ourselve.

So, finally, we have to append the following characters to the `db` param: ``-- `

12. The final request will be:`.`user`-- &table=user


Resulted in:

Bingo! Now we can use this username/password to login to the site (with disabled Javascript) at:

13. After logging in, the flag is appeared right away!

### NOTE:
The same result can be achieved by using `%23` (`#`) instead of `%2d%2d%20` (`-- `).

Sep 22, 2017

CSAW 2017 CTF Write-up: Web orange v1

### Points

### Readme
I wrote a little proxy program in NodeJS for my poems folder.
Everyone wants to read flag.txt but I like it too much to share.

### Steps
1. We clicked to the provided link. It show us the content of a normal plain text file.
i love oranges

2. We can realize that this might be a kind of `Path traversal` attack. So, let's try some possible ways:

* Firstly, we try to see if the `..` is being blocked:

Resulted in:
So, we know that it filters out and block: `..` characters.

* Secondly, we try with the unicode format of the character `.` as `%25e`:

Resulted in:
Error response
Error code 404.
Message: File not found.
Error code explanation: 404 = Nothing matches the given URI. 

Wow, the printed result is different from the previous try. So, we know that the `%25e` character has not been filtered out. Now, it is just the matter of `File not found`.

3. Next, we know that if we put so many `../` or `%25e%25e/`, we possibly able to traverse to the root of file system, eventually. So, let's try it with:

Oh! We can see some interesting files here:
Directory listing for /poems/../../../../../../../


4. The `flag.txt` is the file we need. Let's read it:

=> Flag: `flag{thank_you_based_orange_for_this_ctf_challenge}`

(Ref: WAH, chapter 10, page 375)

### Written by: 
@duykham - NOPS team.

Mar 12, 2017

Shellcode that bring back tty input

There are cases that you think you have been able to exploit the bug (e.g. buffer-overflow) but the program is terminated right away. You have nothing to do with your shell-code.
One of the reasons is your shell-code does not bring back the input terminal so you can not type your commands.
The solution is to try with another shell-code, like the one below. It will "closes stdin descriptor and re-opens /dev/tty, then does an execve() of /bin/sh/".

Feb 25, 2011

Gingerbread (Android 2.3.3) for Nexus One - GRI40

I just could not wait until my phone get the OTA update from Google. :p

So, I decided update it manually.

And, here is the link for the one who wants to taste the latest gingerbread (Android 2.3.3 - GRI40).
(for the Nexus One that using Froyo-FRG83G only).

If you got the failed message while updating, maybe you could update the Hboot first.(the required version of Hboot is 0.35.0017 )

Jun 20, 2010

Latest of Android 2.2 Froyo - FRF72

I've just updated my N1 to the latest of Android 2.2 (Froyo), build number: FRF72.

You can find the official release package on the Google server, here:

(Requirement: you are running Froyo FRF50!)

Apr 8, 2010

How to change SMSC number of Android

Changing SMSC (Short Message Service Center) is necessary when you go to another country (for biz trip or traveling) and still want to send SMS (SMS roaming).

Basically, Android phone have NO setting or application to do this. But, I found a tip.

Here you are:

1. Go to Phone Dialer, and press: *#*#4636#*#*
2. Select Phone information
3. Scroll down to bottom of the screen, you'll see the field for SMSC setting.
4. [Optional] Click Refresh to see current SMSC number.
5. Change the SMSC number as you want. Then, click Update.

That's it!

P/S: I checked on my Nexus One. Maybe, in other Android phones, it's a little bit difference. But, the code is the same: *#*#4636#*#*

Jan 5, 2010

Auto-shutdown for Linux machine

If you want to schedule more than just a shutdown, crontab is the tool generally used for running commands on a recurring schedule.

You should to be root:

# su
Then, type the root's password

Then, use this command:

# crontab -e
Add the following line:

55 18 * * /sbin/shutdown -h 19:00

It will auto-shutdown computer at 19:00 (after prompt users at 18:55) everyday.

To make it works immediately, you need to restart cron service:

# /etc/init.d/crond restart

That's it. :)

Nov 3, 2009

Setting proxy for Android by GUI (official way)

UPDATE: [2010-05-21] It works with Froyo (Android 2.2)

If you read my earlier post, maybe you already known the way to set proxy for Android (1.6 and earlier versions).

But, that is "un-official way", you need to modify something (the settings.db file) in core system of Android, and you must "restart" emulator to make it available.

Now, I found a new way, such a very simple way (I don't know why I haven't found it before). You can use GUI of Android to set proxy, and it works immediately.

(Note: this guide line for all versions before 2.0 only. It NOT works with Eclair, and I don't know the reason >"<. [---Update: It works with Froyo---] ) 1. Firstly, go to Settings menu, then select Wireless controls

2. In the Wireless controls menu, select Mobile networks,

3. Then, select Access Point Names

4. Press Menu hard key, then select New APN

5. Fill information of your proxy, ex:

Name: YourProxyName
APN: internetProxy:
Port: 8080

(You can use your own proxy host and port for Proxy and Port fields)

6. Press Menu hard key, then select Save.

7. You will be returned to Mobile network settings menu, you need to select Access Point Names again and select your new APN to activate it.

8. Press Home hard key to return Home screen. Go to Browser application.
Now, you can use your own proxy for Android browser.

Have fun! ^^

Sep 15, 2009

How to get EMMA code coverage of Android

Here are some basic steps How to get Emma code coverage of Android.

Thanks to Brett Chabot and Gabor for useful support at Android Developer Group

Before doing these steps, you need to get full source code of Android (follow this link for more details )

After that, go to root folder of Android source code and do extractly this instruction below.

A. Generating code coverage using runtest script

1. Firstly, you need to add the target system/framework/emma.jar to the device's boot classpath. So that, modify the BOOTCLASSPATH variable in /system/core/rootdir/init.rc .

a. Open /system/core/rootdir/init.rc

b. The system/framework/emma.jar entry needs to be added in the exact position shown below:
export BOOTCLASSPATH=/system/framework/core.jar:/system/framework/ext.jar:/system/framework/emma.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar

c. Save and close init.rc file

2. Since EMMA will save the coverage result into SDCard, you need to ensure that the SDCard can be mounted properly. So that,

a. Open this file: build/core/

b. Ensure that these lines have already added (around line number 212 to 219), if not, do it by yourself!
# Install a vold.conf file is one's not already being installed.
ifeq (,$(filter %:system/etc/vold.conf, $(PRODUCT_COPY_FILES)))
ifeq ($(filter eng tests,$(TARGET_BUILD_VARIANT)),)
$(warning implicitly installing vold.conf)

(Please follow this link for more details )

3. Build the bootimage to pick up the init.rc changes
make bootimage

4. Build a full system image
make -j4

5. Make EMMA

make emma

6. Start emulator
[path_to_SDK_tools]/emulator -sdcard [path_to_your_sdcard]

7. Next, use the script. Runtest will do all the necessary steps to instrument your test and target package, run the test, and generate the code coverage report.
cd [path_to_android_source_code]

python development/testrunner/ --coverage [Test_package]

[Test_package] can be: apidemos, core, music, email... (Leave this option null to see the list).

8. After finish this script, the coverage report will be generated and saved into


folder. You can find a html report of EMMA code coverage for [Test_package] there.


B. Generating code coverage for your own test

If you want to running code coverage for your own test, please follow steps as described above, but skip step 6 to 8, continue with step 9 (after step 5) shown below:

9. Setting the environment and additional bash commands. (like m,mm,mmm, choosecombo etc) Notice the space after the dot!
. build/

10. Set the ANDROID_PRODUCT_OUT directory for the emulator to know the image location
export ANDROID_PRODUCT_OUT=[path_to_Android_source_code]/out/target/product/generic

This step is important. The emulator will know where are the images it need to be synchronized with.


12. Compile the Application would like to instrument
mmm development/samples/[your_project]

(You can use apidemos for example)

After run this step, new images can be generated and saved into ANDROID_PRODUCT_OUT (in step 10)

13. Run emulator
[path_to_SDK_tools]/emulator -sdcard [path_to_your_sdcard]

14. Remount the drive - it is needed to have a writable drive. without that sync wont work
adb remount

15. Synchronize the local content (new images) with the emulator
adb sync

16. Run instrumentation
adb shell am instrument -w -e coverage true [source_code_of_test]

Here is example for apidemos
adb shell am instrument -w -e coverage true

See this for more details of InstrumentationTestRunner options.

17. This command will dump a runtime coverage data file at /sdcard/ on the device.

Extract it to local host
adb pull /sdcard/

18. Now generate a coverage report. You'll need to pass in the path to the coverage metadata generated at build time.
java -cp external/emma/lib/emma.jar emma report -r html -in -sp [path_to_your_project_source_code] -in out/target/common/obj/APPS/[your_project]_intermediates/coverage.em

Here is example for apidemos:
java -cp external/emma/lib/emma.jar emma report -r html -in -sp development/samples/ApiDemos/src -in out/target/common/obj/APPS/ApiDemos_intermediates/coverage.em

19. Now, you will get the HTML report of EMMA code coverage for your own project.

Check it out!

Notes: In the first time running instrumentation (step 7 or 16) the Android system may be crashed. But, don't worry, it will automatically restart. Then, you can run the instrumentation again successfully!

ph0wn CTF 2017 Write-up: Misc/helpxman - Stage 2 and 3

After successfully getting the flag of  Stage 1 , the challenge told us to continue looking for something interesthing from the app. After ...