ブログ未満のなにか

ブログなのか誰にも分からない

camp ctf 2016 writeup -ジャンルが分からない問題編 part 1-

はじめに

前回の記事に引き続き、セキュリティキャンプで開催されたCTFのwriteupです。
今回は、問題のジャンルが判別できなかったものです。

secret.zip

/home/pi/problems/に、いくつかのファイルが置いてある。
その中の一つで、forensic系の問題。

解凍して、種類を確認してみる。

$ unzip secret.zip 
Archive:  secret.zip
  inflating: camp_forensic.bin

$ file camp_forensic.bin 
camp_forensic.bin: Linux rev 1.0 ext4 filesystem data, UUID=1da7d7fb-a2a2-405b-95ee-c506c875aa7e (needs journal recovery) (extents) (huge files)

ext4なので、マウントしてみる。中身は、以下の通りだった。flagディレクトリの中にflagファイル、隠しディレクトリの.keysの中にid_rsa.pubといった感じ(lost+foundは知らない。見れない理由は分からないけど、解いていく過程で必要なかった)
各ファイルの中身は以下の通り。
flagファイルはダミー。id_rsa.pubは、名前とファイルの形式から、RSAの公開鍵だと思われる。

$ sudo mount -o loop camp_forensic.bin /mnt/
$ tree -a /mnt/
/mnt/
├── flag
│   └── flag
├── .keys
│   └── id_rsa.pub
└── lost+found [error opening dir]

$ cat /mnt/flag/flag 
FLAG{dummy}
$ cat /mnt/.keys/id_rsa.pub 
-----BEGIN PUBLIC KEY-----
MDcwDQYJKoZIhvcNAQEBBQADJgAwIwIcDDw+ASni/QBnuKaXy1ZrfUn32msWl9ky
YSP6jQIDAQAB
-----END PUBLIC KEY-----

ここで、消去されたファイルがないか探してみる。あった。

$ sudo extundelete --after 1470068040 --restore-all ./camp_forensic.bin
Only show and process deleted entries if they are deleted on or after 1470068040 and before 9223372036854775807.
NOTICE: Extended attributes are not restored.
WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set.
The partition should be unmounted to undelete any files without further data loss.
If the partition is not currently mounted, this message indicates 
it was improperly unmounted, and you should run fsck before continuing.
If you decide to continue, extundelete may overwrite some of the deleted
files and make recovering those files impossible.  You should unmount the
file system and check it with fsck before using extundelete.
Would you like to continue? (y/n) 
y
Loading filesystem metadata ... 8 groups loaded.
Loading journal descriptors ... 45 descriptors loaded.
Searching for recoverable inodes in directory / ... 
1 recoverable inodes found.
Looking through the directory structure for deleted files ... 
0 recoverable inodes still lost.

% ls
RECOVERED_FILES/  camp_forensic.bin  secret.zip

% tree -a RECOVERED_FILES
RECOVERED_FILES
└── flag
    └── flag.txt

中身は、暗号化されているようなので、復号する必要がある。

% cat RECOVERED_FILES/flag/flag.txt 
#J4?j?-?v=???R*E&???YH? %                                                                                                     

% xxd RECOVERED_FILES/flag/flag.txt 
0000000: 0623 4a34 ff6a 9910 2da1 763d a2e7 e652  .#J4.j..-.v=...R
0000010: 042a 4526 8ab8 8259 48c7 1320            .*E&...YH.. 

ここで、最初に見つけたRSAの公開鍵を使うんだなと考える。鍵長も長くなさそうだしゴリ押しで行けるだろwという発想。
公開鍵のファイルから、eとNを取り出す。220bitなので、現実的時間内に、pとqを求めることができる。

% openssl rsa -text -modulus -pubin < id_rsa.pub 
Public-Key: (220 bit)
Modulus:
    0c:3c:3e:01:29:e2:fd:00:67:b8:a6:97:cb:56:6b:
    7d:49:f7:da:6b:16:97:d9:32:61:23:fa:8d
Exponent: 65537 (0x10001)
Modulus=C3C3E0129E2FD0067B8A697CB566B7D49F7DA6B1697D9326123FA8D
writing RSA key
-----BEGIN PUBLIC KEY-----
MDcwDQYJKoZIhvcNAQEBBQADJgAwIwIcDDw+ASni/QBnuKaXy1ZrfUn32msWl9ky
YSP6jQIDAQAB
-----END PUBLIC KEY-----

pとqは、1067720436041231358402956670029837と1206804386570390765714542811755649だった。

% msieve -q -v 0x0c3c3e0129e2fd0067b8a697cb566b7d49f7da6b1697d9326123fa8d


Msieve v. 1.52 (SVN unknown)
Wed Aug 31 21:40:02 2016
random seeds: e9b0fdb9 aae3203b
factoring 1288529705845408357244049553359282722253970863715459988603183299213 (67 digits)
searching for 15-digit factors
commencing quadratic sieve (67-digit input)
using multiplier of 13
using generic 32kb sieve core
sieve interval: 12 blocks of size 32768
processing polynomials in batches of 17
using a sieve bound of 153941 (7152 primes)
using large prime bound of 10621929 (23 bits)
using trial factoring cutoff of 23 bits
polynomial 'A' values have 8 factors
restarting with 3567 full and 38233 partial relations

7753 relations (3567 full + 4186 combined from 38233 partial), need 7248
sieving complete, commencing postprocessing
begin with 41800 relations
reduce to 11350 relations in 2 passes
attempting to read 11350 relations
recovered 11350 relations
recovered 8996 polynomials
attempting to build 7753 cycles
found 7753 cycles in 1 passes
distribution of cycle lengths:
   length 1 : 3567
   length 2 : 4186
largest cycle: 2 relations
matrix is 7152 x 7753 (1.1 MB) with weight 215230 (27.76/col)
sparse part has weight 215230 (27.76/col)
filtering completed in 4 passes
matrix is 6588 x 6652 (0.9 MB) with weight 178112 (26.78/col)
sparse part has weight 178112 (26.78/col)
commencing Lanczos iteration
memory use: 0.9 MB
lanczos halted after 106 iterations (dim = 6582)
recovered 61 nontrivial dependencies
prp34 factor: 1067720436041231358402956670029837
prp34 factor: 1206804386570390765714542811755649
elapsed time 00:00:01

あとはやるだけ。
private.keyの生成は、過去の記事を見てください。dを求めたら、後はスクリプト内の各パラメータを設定するだけ
hama.hatenadiary.jp

% openssl rsautl -decrypt -inkey private.key < flag.txt                   
f0r3n51c515fun

さいごに

本当は他の問題も書く予定だったが、長くなったので分割します。
自分で書いたスクリプトを、後から見返すとセンスなさすぎ、汚すぎで見てられない。
問題自体は、結構楽しめて解けた。フラグからforensicとあるが、RSAで詰まった人の方が多いような気もする。
実際に自分も競技時間中にopensslで公開鍵のパラメータの表示方法を忘れて詰まってしまった。
競技中にインターネットから遮断されていたのが辛かった。