View difference between Paste ID: pp0JvE4w and YzdwggHE
SHOW: | | - or go back to the newest paste.
1
Decrypt it!(Crypt 300) - write up(分かったところまで)
2
3
問題のファイルはzipファイルが2つ。
4
flag.zip はパスワードがかかっている。
5
crypt.zip は普通に展開でき、中には crypt というELF実行ファイルが入っている。
6
7
% zipinfo flag.zip
8
Archive:  flag.zip
9
Zip file size: 1089394 bytes, number of entries: 3
10
-rw-a--     2.3 ntf    13956 Bl defN 14-Jul-15 14:34 crypt
11
-rw-a--     2.3 ntf  1088958 Bl defN 14-Jul-15 14:35 flag.bin
12
-rw-a--     2.3 ntf       89 Tl defN 14-Jul-15 14:50 readme.txt
13
3 files, 1103003 bytes uncompressed, 1089014 bytes compressed:  1.3%
14
15
% ls -l crypt
16
-rwxr-xr-x 1 *** users 13956  7月 15 14:34 crypt
17
18
とファイルサイズ、ファイル名が一致するので、pkcrackでflag.zip中のほかのファイルを抽出。
19
20
% pkcrack -C flag.zip -c crack -P crypt.zip -p crypt -d decrypted.zip
21
% unzip decrypted.zip
22
23
で flag.bin と readme.txt をゲット。ここまでは簡単。
24
次に readme.txt を見てみる。
25
26
% cat readme.txt
27
---
28
$ ./makekey pri.txt pub.txt
29
$ ./crypt 1 pub.txt flag.pdf flag.bin
30
$ rm *.txt flag.pdf
31
---
32
33
どうやら crypt プログラムは引数を4つとるようだ。
34
% ./crypt [フラグ?] [暗号鍵] [元ファイル] [出力ファイル]
35
といったところだろうか。
36
37
crypt の動作が分からないで解析してみようと思い立つ。
38
39
% file crypt
40
crypt: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), BuildID[sha1]=0xf5788d393c6092979ad6854f778d22f7df35922f, stripped
41
42
stripされていて面倒そうだ。それにこの問題ってジャンルは暗号だし。方針を切り替える。
43
最初は公開鍵暗号関係かと思ったが、readme.txtの中で最後に rm *.txt をして pri.txt も消してしまっている。
44
ということは pri.txt がなくても復号化できるのか?
45
とりあえず適当な平文ファイルと暗号鍵ファイルを作って色々試してみたところ、出力ファイルの形式が見えてきた。
46
47
% hexdump -vC flag.bin | head -3
48
00000000  bc ca 2a 00 78 9c c4 bd  7b a8 55 d5 fa ff bf d6  |..*.x...{.U.....|
49
00000010  9a 73 b9 53 4c c2 bc 54  d0 0d cd c8 28 33 cd 2e  |.s.SL..T....(3..|
50
00000020  98 54 46 97 03 95 97 22  4a 2c cb 8d a6 24 98 5b  |.TF...."J,...$.[|
51
52
最初の4バイトは 平文ファイルのサイズ*4 の値が入っているようだ。
53
その直後には 78 9c から始まる文字列が。78 9cでぐぐるとzlib関係のヘッダのようだ。
54
そういえば crypt のバイナリ中にも compress/uncompress の文字列が含まれていた。
55
平文ファイルより暗号化したファイルの方がサイズが小さくなることもあったし。
56
57
% strings crypt | fgrep compress
58
uncompress
59
compressBound
60
61
ということで、この辺に書かれていたプログラムを拝借して適当に修正し、最初の4バイトを除いた部分を展開してみる。
62
63
http://stackoverflow.com/questions/12147484/extract-zlib-compressed-data-from-binary-file-in-python
64
% python decompress.py flag.bin > flag.dec
65
% hexdump -vC flag.dec | head -3
66
00000000  b7 01 00 00 36 01 00 00  0a 01 00 00 9b 02 00 00  |....6...........|
67
00000010  24 02 00 00 e3 01 00 00  62 02 00 00 74 03 00 00  |$.......b...t...|
68
00000020  fe 01 00 00 b7 01 00 00  86 02 00 00 09 04 00 00  |................|
69
% hexdump -vC flag.dec | tail -3
70
002acaa0  fe 01 00 00 b7 01 00 00  b7 01 00 00 5d 02 00 00  |............]...|
71
002acab0  5b 04 00 00 9b 02 00 00  fe 01 00 00 0a           |[............|
72
73
色々なパターンで作成してcryptにかけたファイルを展開してみると、法則が見えてくる。
74
75-
・最後は必ず「0a」で終わっている
75+
・最後は必ず「0a」で終わっている(python側のプログラムの問題かも?)
76
・最後の1バイトを除くと、flag.binの最初の4バイトに格納されていた数値(0x002acabc)と同じとなる
77
78
ということは、flag.decを4バイト区切りで見て行って、各4バイトが平文ファイルの1バイトにマッピングされるのではないかと推測。
79
readme.txt に書かれていたコマンドから、flag.binの元ファイルはflag.pdfであると推測できる。
80
適当にその辺のPDFのヘッダを見てみる。
81
82
% hexdump -vC FAQ.pdf | head -3
83
00000000  25 50 44 46 2d 31 2e 34  0a 25 d0 d4 c5 d8 0a 31  |%PDF-1.4.%.....1|
84
00000010  20 30 20 6f 62 6a 0a 3c  3c 20 2f 53 20 2f 47 6f  | 0 obj.<< /S /Go|
85
00000020  54 6f 20 2f 44 20 28 73  65 63 74 69 6f 6e 2e 31  |To /D (section.1|
86
87
ということは、flag.decの先頭から順番に以下のようなマッピングとなる。
88
89
 b7 01 00 00 => %
90
 36 01 00 00 => P
91
 0a 01 00 00 => D
92
 9b 02 00 00 => F
93
 24 02 00 00 => -
94
 e3 01 00 00 => 1
95
 62 02 00 00 => .
96
 74 03 00 00 => 4 (ここはバージョンによって異なるかも?)
97
 fe 01 00 00 => 0x0a
98
 b7 01 00 00 => %
99
  :
100
  
101
b7 01 00 00はどちらも % に対応付いているようなので、推測は間違えていなさそうだ。
102
flag.dec を4バイト毎に区切った値をuniqしてみると256種類となることも確認。
103-
さらに最後の5バイトはヒント?になっていそう。最後が「11 22 33 44 0a」であれば、
103+
104-
 11 22 33 44 => 0x0a
104+
あとはマッピングのルール(計算式)を見つけ出して変換してあげれば答えが書かれているであろうPDFが出来上がる予定だったが、時間切れで終了。