4ensiX

4ensiX

Forensics専門でなければ、CTFはDFIRの勉強にほとんど役立たないことをを知ったこの頃

Locked KitKat - zer0ops CTF 2020 Forensics writeup

世間様は4月ですが、自分は3月を振り返っています。
2020/03/07 09:00 JST — 2020/03/09 09:00 JSTに行われた「zer0ops CTF 2020」の「Locked KitKat」のwriteupをお届け。
ctftime.org
色んな人が書いているので、見飽きているかもしれないけれど見ている方には感謝しかない。

Locked KitKat

We've extracted the internal disk from the Android device of the suspect. Can you find the pattern to unlock the device? Please submit the correct pattern here.

とりあえず与えられたファイルの情報収集。

# file evidence.tar.gz_1a9268f23f3fb6590d05f30901b7be7b.tar.gz 
evidence.tar.gz_1a9268f23f3fb6590d05f30901b7be7b.tar.gz: gzip compressed data, last modified: Thu Mar  5 01:11:34 2020, from Unix, original size modulo 2^32 536872960
# tar zxvf evidence.tar.gz_1a9268f23f3fb6590d05f30901b7be7b.tar.gz 
android.4.4.x86.img
# file android.4.4.x86.img 
android.4.4.x86.img: Linux rev 1.0 ext4 filesystem data, UUID=57f8f4bc-abf4-655f-bf67-946fc0f9f25b (needs journal recovery) (extents) (large files)

パターンロックを解くのが今回の目的で、androidのイメージが渡されたってことはパターンロックファイルを持って来ればいいのでしょう。
ということで 「android pattern lock」とかでおググります。
良さそうなのを発見する。

Can You Bypass the Android Lock Screen?
このサイトから、「/data/system/gesture.key」にパターンロックが記録されていることが分かる。
では、「android.4.4.x86.img」から「gesture.key」を取り出すために、The Sleuth Kitでの解析準備に入る。

# img_stat -t android.4.4.x86.img 
raw
# mmls android.4.4.x86.img 
Cannot determine partition type

てっきりファイル名「android.4.4.x86.img」からandroidの全体イメージかと思っていたけど違うようだ。
全体のイメージであれば複数のパーティション領域が確認できるはず。どういうことかというと。
Partitions and Images  |  Android Open Source Project
Android partitions explained
Android デバイスのパーティション構成概要 | まくまくAndroidノート
[Android] Androidの内部構成について - 攻撃は最大の防御なり
これらのサイトにあるように、androidlinuxでいうrootディレクトリにあるような重ディレクトリがパーティション分けされているような作りになっている。なので、本来ディスク全体のイメージは例えば、次のようになっている。

# mmls this_is_it.img 
GUID Partition Table (EFI)
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Safety Table
001:  -------   0000000000   0000000255   0000000256   Unallocated
002:  Meta      0000000001   0000000001   0000000001   GPT Header
003:  Meta      0000000002   0000000012   0000000011   Partition Table
004:  000       0000000256   0000131327   0000131072   modem
005:  001       0000131328   0000132351   0000001024   sbl1
006:  002       0000132352   0000132415   0000000064   DDR
007:  -------   0000132416   0000132607   0000000192   Unallocated
008:  003       0000132608   0000134655   0000002048   aboot
009:  -------   0000134656   0000135607   0000000952   Unallocated
010:  004       0000135608   0000136107   0000000500   rpm
011:  -------   0000136108   0000136607   0000000500   Unallocated
012:  005       0000136608   0000137607   0000001000   tz
013:  006       0000137608   0000137863   0000000256   hyp
014:  -------   0000137864   0000138631   0000000768   Unallocated
015:  007       0000138632   0000139655   0000001024   utags
016:  008       0000139656   0000143751   0000004096   logs
017:  -------   0000143752   0000143871   0000000120   Unallocated
018:  009       0000143872   0000143903   0000000032   sec
019:  -------   0000143904   0000144127   0000000224   Unallocated
020:  010       0000144128   0000151175   0000007048   factorytune1
021:  011       0000151176   0000154623   0000003448   padA
022:  012       0000154624   0000155647   0000001024   metadata
023:  013       0000155648   0000157695   0000002048   abootBackup
024:  -------   0000157696   0000158647   0000000952   Unallocated
025:  014       0000158648   0000159147   0000000500   rpmBackup
026:  -------   0000159148   0000159647   0000000500   Unallocated
027:  015       0000159648   0000160647   0000001000   tzBackup
028:  016       0000160648   0000161671   0000001024   utagsBackup
029:  017       0000161672   0000161927   0000000256   hypBackup
030:  -------   0000161928   0000162695   0000000768   Unallocated
031:  018       0000162696   0000172031   0000009336   padB
032:  019       0000172032   0000173055   0000001024   frp
033:  020       0000173056   0000176127   0000003072   modemst1
034:  021       0000176128   0000179199   0000003072   modemst2
035:  022       0000179200   0000180175   0000000976   hob
036:  023       0000180176   0000180239   0000000064   dhob
037:  -------   0000180240   0000180479   0000000240   Unallocated
038:  024       0000180480   0000183551   0000003072   fsg
039:  025       0000183552   0000183553   0000000002   fsc
040:  026       0000183554   0000183569   0000000016   ssd
041:  027       0000183570   0000183825   0000000256   cid
042:  028       0000183826   0000192017   0000008192   logo
043:  029       0000192018   0000200209   0000008192   clogo
044:  -------   0000200210   0000200447   0000000238   Unallocated
045:  030       0000200448   0000216831   0000016384   persist
046:  031       0000216832   0000217855   0000001024   misc
047:  032       0000217856   0000283391   0000065536   boot
048:  033       0000283392   0000348895   0000065504   recovery
049:  034       0000348896   0000369487   0000020592   factorytune2
050:  -------   0000369488   0000369663   0000000176   Unallocated
051:  035       0000369664   0000386047   0000016384   kpan
052:  036       0000386048   0000393215   0000007168   padC
053:  037       0000393216   0000425983   0000032768   sp
054:  038       0000425984   0000458751   0000032768   keystore
055:  039       0000458752   0000491519   0000032768   oem
056:  040       0000491520   0000524287   0000032768   carrier
057:  041       0000524288   0004227071   0003702784   system
058:  042       0004227072   0004751359   0000524288   cache
059:  043       0004751360   0015204095   0010452736   userdata
060:  -------   0015204096   0015269887   0000065792   Unallocated

凄いごちゃごちゃしている。そんで多分ちょっと古い。
~閑話休題~
話を戻して、「gesture.key」が必要なのでおそらく今回与えられたイメージはユーザーデータを扱う「/data」パーティションのハズ。

# fsstat -t android.4.4.x86.img 
ext4
# fls -i raw -f ext4 android.4.4.x86.img 
d/d 11: lost+found
d/d 12: app
d/d 27: nativebenchmark
d/d 29: nativetest
d/d 8193:   dontpanic
d/d 16385:  misc
d/d 24577:  local
d/d 8194:   data
d/d 24579:  app-private
d/d 8195:   app-asec
d/d 24580:  app-lib
d/d 8196:   property
d/d 8197:   ssh
d/d 24581:  dalvik-cache
d/d 24582:  resource-cache
d/d 24583:  drm
d/d 8199:   mediadrm
l/l 36: bugreports
d/d 24584:  security
d/d 8200:   user
d/d 24585:  media
d/d 8204:   system
d/d 16402:  backup
r/r 37: .layout_version
V/V 32769:  $OrphanFiles
(別にfls android.4.4.x86.imgでも良いんですけどね)

思った通り、androidの「data」パーティションのようである。つまり、「/data/system/gesture.key」にあるということだったので「/system」下に目的ファイルがある。

# fls -i raw -f ext4 android.4.4.x86.img 8204
r/r 8207:   batterystats.bin
d/d 8206:   procstats
d/d 8205:   ifw
d/d 8210:   users
d/d 8208:   usagestats
r/r 8214:   uiderrors.txt
r/r 8385:   packages.xml
r/r 8361:   packages.list
r/r 8346:   entropy.dat
d/d 8354:   sync
d/d 8359:   inputmethod
r/r 8363:   locksettings.db
d/d 8362:   netstats
r/r 8364:   locksettings.db-wal
r/r 8365:   locksettings.db-shm
r/r 8366:   framework_atlas.config
r/r 8383:   called_pre_boots.dat
s/h 8384:   ndebugsocket
d/d 8414:   dropbox
r/r 8396:   appops.xml
d/d 8421:   registered_services
r/r 8495:   gesture.key
r/r 8497:   device_policies.xml
r/r * 8497(realloc):    device_policies.xml.tmp
# icat -i raw -f ext4 android.4.4.x86.img 8495 > gesture.key

「gesture.key」は取得した。ここから脳死でパターンロックを解読する場合、「android gesture key decode」等とおググりなさって出てきたプログラムを走らせれば良い。

脳死でパターンロック解読例

GitHub - sch3m4/androidpatternlock: A little Python tool to crack the Pattern Lock on Android devices
この「aplc.py」を使用。

# python aplc.py gesture.key 

################################
# Android Pattern Lock Cracker #
#             v0.2             #
# ---------------------------- #
#  Written by Chema Garcia     #
#     http://safetybits.net    #
#     chema@safetybits.net     #
#          @sch3m4             #
################################

[i] Taken from: http://forensics.spreitzenbarth.de/2012/02/28/cracking-the-pattern-lock-on-android/

[:D] The pattern has been FOUND!!! => 321564

[+] Gesture:

  -----  -----  -----
  |   |  | 3 |  | 2 |  
  -----  -----  -----
  -----  -----  -----
  | 1 |  | 6 |  | 4 |  
  -----  -----  -----
  -----  -----  -----
  | 5 |  |   |  |   |  
  -----  -----  -----

It took: 0.7533 seconds

今回の場合は用意されたwebページでパターンロックを入力すると、flagが貰えた。
flag: zer0pts{n0th1ng_1s_m0r3_pr4ct1c4l_th4n_brut3_f0rc1ng}

「gesture.key」をもう少し詳しく見たい場合

「gesture.key」には、パターンロック画面の3×3に左上から例えば1,2,3,,,,9のように番号づけして、パターンロック解除に必要な数字の順番(最小4桁、最大9桁)がソルト無しのSHA-1ハッシュで記録されているらしい(参考  Password storage in Android M)。

Android's pattern unlock is entered by joining at least four points on a 3×3 matrix (some custom ROMs allow a bigger matrix). Each point can be used only once (crossed points are disregarded) and the maximum number of points is nine. The pattern is internally converted to a byte sequence, with each point represented by its index, where 0 is top left and 8 is bottom right. Thus the pattern is similar to a PIN with a minimum of four and maximum of nine digits which uses only nine distinct digits (0 to 8). However, because points cannot be repeated, the number of variations in an unlock pattern is considerably lower compared to those of a nine-digit PIN. As pattern unlock is the original and initially sole unlock method supported by Android, a fair amount of research has been done about it's (in)security. It has been shown that patterns can be guessed quite reliably using the so called smudge attack, and that the total number of possible combinations is less than 400 thousand, with only 1624 combinations for 4-dot (the default) patterns.

なので、ハッシュとパターンの番号のリスト(AndroidGestureSHA1.txt)と比較すれば、簡単に分かってしまう。

# grep -i `xxd -p gesture.key ` AndroidGestureSHA1.txt 
432675;03 02 01 05 06 04;179E58178A7C5195110E0A26D91C71926AF01349

よって脳死と同じ結果が得られた。
どういうことかというと、

  -----  -----  -----
  | 1 |  | 2 |  | 3 |  
  -----  -----  -----
  -----  -----  -----
  | 4 |  | 5 |  | 6 |  
  -----  -----  -----
  -----  -----  -----
  | 7 |  | 8 |  | 9 |  
  -----  -----  -----

例えばこのように番号付けして、パターンロック解除パターンをSHA1ハッシュしたものが「gesture.key」らしい。実際はこのようになっている。

# xxd gesture.key 
00000000: 179e 5817 8a7c 5195 110e 0a26 d91c 7192  ..X..|Q....&..q.
00000010: 6af0 1349                                j..I
# cat AndroidGestureSHA1.txt | head
; Android OS gesture.key dictionary 
; (c) Oxygen Software 2011 
; http://www.oxygen-forensic.com
; http://www.android-forensics.com
Gesture;Pattern sequence;Pattern SHA-1;
1234;00 01 02 03;A02A05B025B928C039CF1AE7E8EE04E7C190C0DB
1235;00 01 02 04;6E36A9BFACF6C4637D64042B11CB78BFDDAF8BF3
1236;00 01 02 05;101B2A675E9FB9546336D5B9EF70418B594184F4
1237;00 01 02 06;30F26B9825EA6F2EF6DBF6A88959774314D83F65
1238;00 01 02 07;8C33B9D8BB8398DA8F19D9E946D589F32321B7BD

じゃあ、同じように最小4桁、最大9桁の数字をSHA1ハッシュすればパターンロックファイルが再現できるのかというと、そうでは無かった。なぜか同じハッシュを作ろうと思っても作れなかった。単純に数字の組み合わせのハッシュではなく、パターンの座標とかがハッシュされているのだろうか。
このハッシュファイルは一体何のSHA1ハッシュ!
謎が謎を呼ぶ。
何か情報を持っている人がいれば教えてください。