プロジェクト

全般

プロフィール

CTF Writeup SECCON 2017 » 履歴 » バージョン 1

kanata, 2025/04/13 15:19

1 1 kanata
# CTF Writeup SECCON 2017
2
3
{{toc}}
4
5
# 結果&感想
6
7
某チームでSECCON2017に参加しました。
8
4問解きました。全部100点だけどな!
9
10
チームの成績なんですが、もしかしたら国内決勝行けるかもという順位!
11
決勝行けたらめでたいね!!!
12
13
基本的に今回は
14
15
## こまけぇこたぁいいんだよ
16
17
![20171209_seccon2017_komaka.gif](20171209_seccon2017_komaka.gif)
18
19
解けりゃぁいいんだよ!ちゃんと実装しよ?[めんどくせぇ買ってこいよゴロリ](https://goo.gl/Utc5vb)
20
というスタンスで解いていたため、はたして公開していいのかというクソコードっぷりを披露する事になります。
21
22
# Log search (Web 100)
23
24
問題文はアクセス先のURLだけだったかな。。
25
26
これはなんで解けたのか、どういう趣旨だったか理解する前に解けてしまいました。
27
28
検索窓があるので、おもむろに flag と入力して検索
29
30
![20171209_seccon2017_log_search.jpg](20171209_seccon2017_log_search.jpg)
31
32
出てきたそれっぽいヤツにアクセスする。
33
34
35
フラグ取れた。
36
37
```
38
SECCON{N0SQL_1njection_for_Elasticsearch!}
39
```
40
41
# Simon and Speck Block Ciphers (Crypto 100)
42
43
平文と暗号文、キーの一部が提供されています。
44
45
```
46
Simon_96_64, ECB, key="SECCON{xxxx}", plain=0x6d564d37426e6e71, cipher=0xbb5d12ba422834b5 
47
```
48
49
Simon and Speck Block Ciphers という暗号方式を実装して、暗号キーを求めてねという問題。
50
51
さっそく問題文中で公開されている[404.pdf](https://eprint.iacr.org/2013/404.pdf)を見てみると暗号方式を解説している論文のようでございました。
52
いかんせん英語でございましたので、3分ぐらいで見るのを止めた訳です。英語は無理だと。
53
54
きっと、実装してくださっている方がいるだろうとGithubなんかを検索したら出てきました。
55
56
{{rawhtml(<blockquote class="embedly-card"><h4><a href="https://github.com/bozhu/NSA-ciphers">bozhu/NSA-ciphers</a></h4><p>NSA-ciphers - SIMON and SPECK the two lightweight block ciphers designed by the researchers from NSA</p></blockquote><script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script></script>)}}
57
58
simon.py はテストコードがついてるので、それをコメントアウトして目的のソースコードを書き加えます。
59
60
simon.py
61
62
```python
63
#!/usr/bin/env python
64
65
# ~中略~
66
67
    #for bsize, ksize, key, plain, cipher in test_vectors:
68
    #    my_simon = SIMON(bsize, ksize, key)
69
    #    encrypted = my_simon.encrypt(plain)
70
    #    assert encrypted == cipher
71
    #    for i in range(1000):
72
    #        encrypted = my_simon.encrypt(encrypted)
73
    #    for i in range(1000):
74
    #        encrypted = my_simon.decrypt(encrypted)
75
    #    decrypted = my_simon.decrypt(encrypted)
76
    #    assert decrypted == plain
77
78
    chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
79
    itr = permutations(chars,4)
80
    plain      = 0x6d564d37426e6e71
81
    encrypted  = 0xbb5d12ba422834b5
82
    key        = 0x00
83
    key_source = ""
84
85
    for i in itr:
86
      key_source="SECCON{"+"".join(map(str,i))+"}"
87
      answer=key_source
88
      key_source = "0x" + hex(ord(key_source[0]))[2:4]+hex(ord(key_source[1]))[2:4]+hex(ord(key_source[2]))[2:4]+hex(ord(key_source[3]))[2:4]+hex(ord(key_source[4]))[2:4]+hex(ord(key_source[5]))[2:4]+hex(ord(key_source[6]))[2:4]+hex(ord(key_source[7]))[2:4]+hex(ord(key_source[8]))[2:4]+hex(ord(key_source[9]))[2:4]+hex(ord(key_source[10]))[2:4]+hex(ord(key_source[11]))[2:4]
89
      key = long(key_source,16)
90
      c = SIMON(64, 96, key)
91
      if encrypted == c.encrypt(plain):
92
        print answer
93
94
    print 'All tests passed'
95
```
96
97
>int(key.encode('hex'), 16) # 文字列→intは、こんな感じでもっとスマートに書けたか
98
99
後はぶん回すだけなのですが、えらい時間がかかって、これはきっと競技時間中に終らないんじゃないかとも思いましたが、運良くフラグが出てくれました。
100
101
```
102
SECCON{6Pz0}
103
```
104
105
# SHA-1 is dead (Crypto 100)
106
107
この条件のファイルを作る問題
108
109
1. file1 != file2
110
2. SHA1(file1) == SHA1(file2)
111
3. SHA256(file1) <> SHA256(file2)
112
4. 2017KiB < sizeof(file1) < 2018KiB
113
5. 2017KiB < sizeof(file2) < 2018KiB
114
115
※1KiB = 1024 bytes
116
117
SHA1のハッシュ衝突が起こせるようになったのは有名な話題なので知ってはおりました。
118
知ってはおりましたが実装まではしたことがございません。
119
きっと誰かがPoCを公開してくださっているだろうと、調べるとすぐ出てきました。
120
121
{{rawhtml(<blockquote class="embedly-card"><h4><a href="https://github.com/73spica/sha1-collision">73spica/sha1-collision</a></h4><p>sha1-collision - Googleが発表したSHA-1衝突の原理で衝突PDFを生成するスクリプト</p></blockquote><script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script>)}}
122
123
このツールは、こんな仕様
124
125
* jpegを指定して、sha1ハッシュ値が同じpdfを作ってくれるツール
126
* jpegのファイルフォーマットを壊さずにハッシュ衝突してくれる
127
* それ故チェック処理が入っててフォーマットが壊れる場合は処理を中断する
128
129
いい感じのサイズのjpegを作るのが面倒だったため、ファイルの後ろに0x00を何byteかくっつけてサイズ調整しようと思った訳です。
130
するとチェックに引っかかるんですよね。困った。
131
132
なので、こうしました。
133
134
* sha1ハッシュ衝突ツール(collision.py)のチェック処理をコメントアウト
135
* jpegファイルのお尻に0x00を何Byteか加えてサイズを調節する
136
* pdfのサイズが 2065408~2066432 Byte になるよう以下のシェルスクリプトを作って何度か試す
137
138
```bash
139
#!/bin/bash
140
141
dd if=/dev/zero of=zero_a bs=1024 count=$1
142
sleep 2
143
cat sample1.jpg zero_a >a.jpg
144
cat sample2.jpg zero_a >b.jpg
145
146
python collision.py a.jpg b.jpg
147
148
ls -lrt collision*
149
```
150
151
ファイルアップロードしてフラグ取得
152
153
```
154
SECCON{SHA-1_1995-2017?}
155
```
156
157
>ちなみに、公開されているsha1ハッシュが同じpdfの後ろに0x00をくっつけてサイズ調整すればいいと気付いたのは競技終了後にwriteupを見た時
158
159
# JPEG file (Binary 100)
160
161
あぁ、これ進研ゼミでやってたやつだ!…じゃなくて、昔のSECCONで出た問題に似てる!
162
と、すぐ思い出した訳です。そしてそのwriteupを ~~パク~~参考にしようと思ったわけで、調べたら出てきました。
163
164
{{rawhtml(<blockquote class="embedly-card"><h4><a href="http://d.hatena.ne.jp/yasulib/20120512/1336826146">SECCON CTF 福岡大会の問題 - yasulib memo</a></h4><p>SECCON CTFの筑波大会に出場させて頂けることになりました。 他チームは各所で活躍されている方々が参加されるということもあり、勝ちを狙うのは難しそうなので、チーム全員で楽しんで出場できたら良いなと思います :) 今回のCTFをきっかけにセキュリティ&プログラミングキャンプ2010に参加した友人たちと連絡を取り合うきっかけになりました。(キャンプのCTFで同じチームだった人もいます) @ITの記事 を見ていて、福岡大会でどんな問題が出ていたのか書いてあったので、解いてみました。 問:以下のファイルダンプは宇宙からの中性子線で1bitのデータが反転したものである。 0000000 1f 8b 08 08 27 2c 39 4f 02 03 7a 2e 74 78 74 00 0000020 ed da 4d 0e 83 20 10 86 e1 7d 93 de 61 d6 de ff 0000040 80 ee 9a 54 65 f8 66</p></blockquote><script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script>)}}
165
166
```python
167
origGz = open("tktk.jpeg", "rb").read()
168
169
byteSize = len(origGz)
170
bits = []
171
for i in range(0, 8):
172
  bits.append(2**i)
173
174
for byte in range(0, byteSize):
175
  for bit in bits:
176
    change = chr( ord(origGz[byte]) ^ bit )
177
    newGz = origGz[0:byte] + change + origGz[byte+1:]
178
179
    filename = "out/" + str(byte) + "_" + str(bit) + ".jpeg"
180
    f = open(filename, "wb")
181
    f.write(newGz)
182
    f.close()
183
```
184
185
1bitずつ反転させたファイルを作って、それを全て目で確認するという手段を取りました。
186
187
>gzipなら、全ファイル展開を試してみるとか出来るんですが、jpegだとそうはいかない
188
189
よくよく考えなくても、全画像の枚数は **93024**枚になる訳で、それを目視で確認しようとしてたあの時の私は少しおかしかったのかもしれません。
190
191
![20171209_seccon2017_jpeg.jpg](20171209_seccon2017_jpeg.jpg)
192
193
Windowsのフォルダの表示を「特大」にして、こんなのを延々と確認しました。
194
途中で力尽きて他の方法を考える流れでしたが、割と早い段階で出てきました。
195
196
![20171209_seccon2017_jpeg_623_16.jpeg](20171209_seccon2017_jpeg_623_16.jpeg)
197
198
>いま思うと、ファイルヘッダが壊れている可能性が高い訳で、必然的にファイルの前半が被疑箇所になりますね
199
200
# Powerful_Shell (Binary 300)
201
202
難読化問題!?まかせろバリバリってやってたけど
203
私が解くよりも早くチームメイトのcatさんが光の速さで解いてくれました。
204
ほんまcatさんは神やでぇ
205
206
ちなみに私の第六感が囁くのだけれど、作問者は[@Sh1n0g1](https://twitter.com/sh1n0g1)さんだと思う。
207
208
以下、途中までやった結果
209
210
## 難読化の解除
211
212
最下行でデコード結果を実行しているように見えるため、その直前に以下の行を挿入してファイルへ出力
213
214
```
215
Write-Output $ECCON | Out-File -FilePath C:\Users\kanata\Desktop\20171209_SECCON\Binary_300_Powerful_Shell\dec.ps1
216
```
217
218
## adminチェック処理がある
219
220
管理者権限じゃないとチェックアウトされる。Exitをコメントアウトっと
221
222
```
223
<# Host Check #>
224
Write-Host -b 00 -f 15 Checking Host... Please wait... -n
225
Try{
226
	If ((Get-EventLog -LogName Security | Where EventID -Eq 4624).Length -Lt 1000) {
227
		Write-Host "This host is too fresh!"
228
		Exit
229
	}
230
}Catch{
231
	Write-Host "Failed: No admin rights!"
232
	#Exit
233
}
234
Write-Host "Check passed"
235
```
236
237
## 音が出る
238
239
![20171209_seccon2017_powerful_shell.jpg](20171209_seccon2017_powerful_shell.jpg)
240
241
スゴイ…音が出るよ。ソースを見ると以下がある。
242
243
```
244
$secret=@(440,440,493,440,440,493,440,493,523,493,440,493,440,349)
245
```
246
247
440ってあれですわ。周波数ですわ。440Hzで音叉の音(A:ラ)ですわ。
248
他の周波数も当てはめると以下になります。
249
250
```
251
$secret=@(440,440,493,440,440,493,440,493,523,493,440,493,440,349)
252
#音階     ラ  ラ  シ  ラ  ラ  シ  ラ  シ  ド  シ  ラ  シ  ラ  ファ
253
#押すキー h   h   j   h   h   j   h   j   k   j   h   j   h   f
254
```
255
256
>「さくらさくら」ですね
257
258
この通り押すと処理が進み、また最下行でデコード結果を実行しているように見えるため、その直前に以下の行を挿入してファイルへ出力
259
260
```
261
Write-Output $ECCON | Out-File -FilePath C:\Users\kanata\Desktop\20171209_SECCON\Binary_300_Powerful_Shell\dec.ps1
262
```
263
264
## 数字の羅列を得る
265
266
デコード結果は数字の羅列だった。
267
ASCIIコードやろ?おっちゃんわかるで、これ
268
269
```
270
10
271
36
272
123
273
59
274
125
275
61
276
43
277
36
278
279
以下、延々と続く
280
```
281
282
以下のシェルスクリプトでデコードする
283
284
```bash
285
#!/bin/bash
286
287
for WORD in `cat dec.ps1`
288
do
289
  WORD=`echo $WORD|col -bx`
290
  echo "obase=16; ibase=10; $WORD" | bc|xxd -ps -r
291
done
292
```
293
294
結果
295
296
297
```
298
${;}=+$();${=}=${;};${+}=++${;};${@}=++${;};${.}=++${;};${[}=++${;};${]}=++${;};${(}=++${;};${)}=++${;};${&}=++${;};${|}=++${;};${"}="["+"$(@{})"[${)}]+"$(@{})"["${+}${|}"]+"$(@{})"["${@}${=}"]+"$?"[${+}]+"]";${;}="".("$(@{})"["${+}${[}"]+"$(@{})"["${+}${(}"]+"$(@{})"[${=}]+"$(@{})"[${[}]+"$?"[${+}]+"$(@{})"[${.}]);${;}="$(@{})"["${+}${[}"]+"$(@{})"[${[}]+"${;}"["${@}${)}"];"${"}${.}${(}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${(}${+}+${"}${&}${@}+${"}${+}${=}${+}+${"}${|}${)}+${"}${+}${=}${=}+${"}${[}${]}+${"}${)}${@}+${"}${+}${+}${+}+${"}${+}${+}${]}+${"}${+}${+}${(}+${"}${.}${@}+${"}${[}${]}+${"}${&}${=}+${"}${+}${+}${[}+${"}${+}${+}${+}+${"}${+}${=}${|}+${"}${+}${+}${@}+${"}${+}${+}${(}+${"}${.}${@}+${"}${.}${|}+${"}${(}${|}+${"}${+}${+}${=}+${"}${+}${+}${(}+${"}${+}${=}${+}+${"}${+}${+}${[}+${"}${.}${@}+${"}${+}${+}${(}+${"}${+}${=}${[}+${"}${+}${=}${+}+${"}${.}${@}+${"}${+}${+}${@}+${"}${|}${)}+${"}${+}${+}${]}+${"}${+}${+}${]}+${"}${+}${+}${|}+${"}${+}${+}${+}+${"}${+}${+}${[}+${"}${+}${=}${=}+${"}${.}${|}+${"}${+}${.}+${"}${+}${=}+${"}${)}${.}+${"}${+}${=}${@}+${"}${[}${=}+${"}${.}${(}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${.}${@}+${"}${[}${]}+${"}${+}${=}${+}+${"}${+}${+}${.}+${"}${.}${@}+${"}${.}${|}+${"}${&}${=}+${"}${[}${&}+${"}${+}${+}${|}+${"}${(}${|}+${"}${+}${+}${[}+${"}${.}${(}+${"}${)}${@}+${"}${]}${+}+${"}${[}${|}+${"}${[}${|}+${"}${.}${|}+${"}${[}${+}+${"}${+}${@}${.}+${"}${+}${.}+${"}${+}${=}+${"}${|}+${"}${&}${)}+${"}${+}${+}${[}+${"}${+}${=}${]}+${"}${+}${+}${(}+${"}${+}${=}${+}+${"}${[}${]}+${"}${)}${@}+${"}${+}${+}${+}+${"}${+}${+}${]}+${"}${+}${+}${(}+${"}${.}${@}+${"}${.}${|}+${"}${)}${+}+${"}${+}${+}${+}+${"}${+}${+}${+}+${"}${+}${=}${=}+${"}${.}${@}+${"}${)}${[}+${"}${+}${+}${+}+${"}${|}${&}+${"}${.}${.}+${"}${.}${|}+${"}${]}${|}+${"}${+}${.}+${"}${+}${=}+${"}${|}+${"}${&}${)}+${"}${+}${+}${[}+${"}${+}${=}${]}+${"}${+}${+}${(}+${"}${+}${=}${+}+${"}${[}${]}+${"}${)}${@}+${"}${+}${+}${+}+${"}${+}${+}${]}+${"}${+}${+}${(}+${"}${.}${@}+${"}${.}${[}+${"}${&}${.}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${+}${@}${.}+${"}${.}${(}+${"}${(}${|}+${"}${(}${)}+${"}${(}${)}+${"}${)}${|}+${"}${)}${&}+${"}${+}${@}${]}+${"}${.}${[}+${"}${+}${.}+${"}${+}${=}+${"}${+}${@}${]}|${;}"|&${;}
299
```
300
301
おぉ・・・もぅこれ完全にJavaScriptの難読化と同じだわ。。。スゴイわ。。。
302
catさん「解けました」
303
ワイ「アッハイ」