先日2017/3/18から3/20の日程で、g0tiu5aというチームでEasyCTF 2017に参加しました。これは私が解いた問題のWriteupです。

チーム全体では2985ポイント。そのうち私は1905ポイントを獲得しました。

最近CTFにはまっていて、今回が初めて真面目に取り組んだ大会でした。常設CTFは現在もいくつかチャレンジしています。

リンク

チームメイトのWriteup (CTFに誘い入れてくれた張本人)
http://jtwp470.hatenablog.jp/entry/2017/03/21/223834

Official Writeups
https://writeups.easyctf.com

問題一覧(フラッグが容易に見れてしまうので注意)
https://github.com/EasyCTF/easyctf-2017-problems

注意点

私はRubyistなので、解答のために書いたスクリプトはほとんどRubyになっています。CTF界隈ではPythonが主流っぽいですが、個人的な慣れを優先しています。書き捨てレベルのコードだとRubyもPythonも大差ないので、読めるかとは思います。

[Miscellaneous 5] IRC

指定のIRCチャンネルに接続して、そこに書いてあるフラッグを入力する。

「最初はIRCかようげぇ……」とか思って放置していたが、ヘッダの “Chat” リンクをクリックしたらWebクライアントがブラウザ上で立ち上がったので簡単に見れた。

[Programming 10] Hello, world!

プログラムに Hello, world! と表示させる問題。以上。

[Programming 15] Things Add Up

最初に入力回数が与えられ、そのあとの数値を読んで足していくだけ。以上。

[Cryptography 20] Clear and Concise Commentary on Caesar Cipher

DLできるpdfをヒントにフラッグを探す問題。

pdf中に RNFLPGS{LBHTBGVG} というあからさまな文字列があるので、この暗号を解く。また、同様にそれっぽいURLがある http://www.dcode.fr/caesar-cipher。シーザー暗号をといてくれるサイトなので、暗号文をこのサイトに食わせると EASYCTFYOUGOTIT が得られる。これを問題文の注意通り小文字に整形した easyctf{yougotit} がフラッグとなる。

[Cryptography 20] Flip My Letters

easyctf{r_wlmg_vevm_mvvw_zm_zhxrr_gzyov} からフラッグを複合する。

タイトル通り、カッコ内のアルファベット順が反転(flip)している。下記のようなコードで複合。フラッグは easyctf{i_dont_even_need_an_ascii_table} となる。

# ruby

# easyctf{r_wlmg_vevm_mvvw_zm_zhxrr_gzyov}

str = "r_wlmg_vevm_mvvw_zm_zhxrr_gzyov"
alphabet = ("a".."z").to_a.join

puts str.tr(alphabet, alphabet.reverse)

[Reverse Engineering 25] Hexable

stringsするだけ。 フラグはeasyctf{abcdef__123456}

[Miscellaneous 30] A-maze-ing

迷路の攻略手順がフラッグとなる問題。

正直、どうしてこの問題を解けたのかわからない。 easyctf{j} で通らず、エラーメッセージとしてNope. The maze is a bit longer than that. と表示されたので easyctf{jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj} といった感じにひたすら長い文字列を打って見たら通った。

Webページからフラッグを探す問題。

問題名のとおり、Cookieを見るとフラッグやブログの内容が書かれている。

[Reverse Engineering 30] Phunky Python I

Pythonで書かれたコードの動きを解読する問題。

配列 digs の数値から x を引いて、その数値をASCIIに変換している。問題文の指定により、出力を easyctf にすれば良いので、xは4681127626939562201 - 101となる。したがってフラッグは easyctf{4681127626939562100}

[Forensics 50] Mane Event

jpgがらフラッグを探す問題。

stringsをするとフラッグ easyctf{pride_in_african_engin33ring} が得られる。

[Programming 50] Fizz Buzz 1

単純にFizz Buzzを実装する問題。以上。

[Cryptography 50] RSA 1

RSA暗号を複合する問題。

p,q,e,cが全て与えられているため、ただただRSAを複合化する。コードは拾い物なので割愛する。

[Reverse Engineering 50] Useless Python

テキストを解析する。

まずBase16でエンコードされていると問題文に指定されているので、デコードする。Pythonなら標準装備らしい。Rubyでは base16 gemを使った。デコードすると以下のようなコードになる。

exec(chr(101)+chr(120)+chr(101)+chr(99)+ #省略

このまま実行しても、どうやら chr(*)で書いてあるコードがまちがっているらしくエラーが出るので、evalの内部のみを実行する。これが何層にも行われているので、何回も実行する。最終的には以下のコードが得られ、フラッグは easyctf{python_3x3c_exec_3xec_ex3c} となる。

flag = 'easyctf{python_3x3c_exec_3xec_ex3c}'
priint flag

[Forensics 70] scisnerof

バイナリからフラッグを得る問題。

files の結果はただのdata、binwalkでも反応なし。hexdump -Cで眺めていたら、ファイルの末尾がGNPPNGの逆になっていることを発見。バイナリファイルそのものを逆転させる。得られたPNG画像からフラッグを読み取る。フラッグは easyctf{r3v3r5ed_4ensics}

File.open("elif", "rb") do |f|
  data = f.read
  data = data.reverse
  File.write("reved.png", data)
end

よくよくタイトルを見ると、 forensics の逆になっている。

[Forensics 75] Petty Difference

2つのテキストファイルからフラッグを探す問題。

問題文に、「この二つは同じに見える」的なことが書かれているので差分をとってみる。普通に diff コマンドを使うとわからなくなりそうなので、スクリプトを書く。

# ruby

str1 = File.read("file1.txt")
str2 = File.read("file2.txt")

str1.size.times do |i|
  if str1[i] != str2[i]
    print str1[i]
  end
end
puts
}4_gn1k00l_3r3w_u0y_3cn3r3ff1d_3ht_3b_y4m_s1ht{ftcysae

出力を反転した easyctf{th1s_m4y_b3_th3_d1ff3r3nc3_y0u_w3r3_l00k1ng_4} がフラッグ

[Cryptography 80] RSA 2

今度はn,e,cが与えられている。nの素因数分解はMsieveにお願いしたら解けた。

[Forensics 80] Flag Collection

DLできるzipファイルからフラッグを探す問題。

解凍すると Thumbs.db と大量のpng画像が生成される。pngは全て国旗の画像だったため、Thumbs.dbに目をつけた。Thumbs.dbにはサムネイル画像が保持されている(初めて知った)。Thumbs.dbは 7z で解凍できる(初めて知った)。ただ、解凍ののちに加工が必要で、この記事を参考に編集した。そうするとQRコードの書かれた画像が得られる。QRの内容がフラッグとなる。

[Forensics 85] Zooooooom

DLできるjpgデータを解析する問題。

binwalkして見ると以下のようになる。

$ binwalk hekkerman.jpg 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
30            0x1E            TIFF image data, little-endian offset of first image directory: 8
212           0xD4            JPEG image data, JFIF standard 1.01
242           0xF2            TIFF image data, big-endian, offset of first image directory: 8
414           0x19E           JPEG image data, JFIF standard 1.01
444           0x1BC           TIFF image data, big-endian, offset of first image directory: 8
28428         0x6F0C          Copyright string: "Copyright International Color Consortium, 2009"

最後のJPEGヘッダ以降を切り出して画像を確認すると、画像にフラッグが書かれている。フラッグはeasyctf{d33p_zo0m_HeKker_2c1ae5}

offset = 414
# size = 0


File.open("hekkerman.jpg", "rb") do |f|
  f.read(offset)
  data = f.read()
  # data = f.read(size)

  File.write("flag.jpg", data)
end

[Forensics 100] QR 1

DLできる壊れたQRコードを復元してフラッグを得る問題。

QRの位置合わせを行う4箇所のマークが白黒反転しているので、それを直すとQRコードとして成立する。それを読み取るとフラッグが得られる。

[Cryptography 100] Hash On Hash

DLできるテキストからフラッグを複合する問題。

複数のハッシュ値が行区切りで登場する。しかも、同じハッシュ値が何度か出現する。先頭のハッシュ値をGoogleで検索したところ、平文1文字のMD5ハッシュ値だった。下記のようなコードで複合し平文を得た。平文の末尾に書かれている easyctf{1_h0p3_y0u_d1dn7_d0_7h47_by_h4nd} がフラッグとなる。

# ruby

require 'digest/md5'

arr = (32..126).to_a.map{|i| i.chr}
h = {}

arr.each do |c|
  h[Digest::MD5.hexdigest(c)] = c
end

lines = File.read("hexstrings.txt").split
lines.each do |hex|
  print h[hex]
end

[Cryptography 100] Decode Me

暗号文からフラッグを復号化する問題。

文末が = で終了しているため、Base64で暗号かされていると判断。一度複合しても再度同様の形式だったため、何度かデコードしたらフラッグが得られた。どこぞの常設CTFで見たような問題。

[Web 100] TinyEval

Webページからフラッグを見つけ出す問題。

inputフォームにphpのコードを入れてPOSTするとその文字列をevalしてくれる。ただし文字数制限があり、11文字より多い文字列を実行しようとすると実行前に弾かれる。チームメイトから実行演算子を使ってはどうかとアドバイスを受けた。

まず ls を実行して見る。

echo `ls`
Dockerfile flag_pnvgx1Qco7gx0ApLCUhH index.php

フラッグらしきファイルを発見。ファイル名は直接指定できそうにない長さなので、ワイルドカードを使って乗り切る。

echo`cat *`
[Dockerfileの中身]

easyctf{it's_2017_anD_we're_still_using_PHP???}

[index.phpの中身]
省略

以上の easyctf{it's_2017_anD_we're_still_using_PHP???} がフラッグ。ポイントとしては、echoの後は空白を入れなくてもバッククォートをうまくパースしてくれるらしい。これでちょうど11文字制限ギリギリで実行できる

[Forensics 100] Ogrewatch

DLしたバイナリからフラッグを見つけ出す問題。

バイナリは files によるとmkvファイル。動画を再生すると何かのゲームのキャラ画像とともに音声が数秒間再生される。 strings をして眺めていたら、以下のような文字列を発見。これを整形するとフラッグ easyctf{subs_r_b3tt3r_th@n_dub5} が得られる。これは字幕情報を示すものだが、字幕ありで再生しても1フレームレベルでしか表示されないため、 strings で見つけるのが正攻法と思われる。

0,0,Default,,0,0,0,,e\N
1,0,Default,,0,0,0,,a\N
2,0,Default,,0,0,0,,s\N
3,0,Default,,0,0,0,,y\N
4,0,Default,,0,0,0,,c\N
Lavc55.34.1
5,0,Default,,0,0,0,,t\N
6,0,Default,,0,0,0,,f\N
7,0,Default,,0,0,0,,{\N
8,0,Default,,0,0,0,,s\N
9,0,Default,,0,0,0,,u\N
10,0,Default,,0,0,0,,b\N
11,0,Default,,0,0,0,,s\N
12,0,Default,,0,0,0,,_\N
13,0,Default,,0,0,0,,r\N
14,0,Default,,0,0,0,,_\N
15,0,Default,,0,0,0,,b\N
@_]+
g7zp
.ZZ"FH
z,g{8
16,0,Default,,0,0,0,,3\N
17,0,Default,,0,0,0,,t\N
18,0,Default,,0,0,0,,t\N
19,0,Default,,0,0,0,,3\N
20,0,Default,,0,0,0,,r\N
21,0,Default,,0,0,0,,_\N
22,0,Default,,0,0,0,,t\N
23,0,Default,,0,0,0,,h\N
24,0,Default,,0,0,0,,@\N
25,0,Default,,0,0,0,,n\N
26,0,Default,,0,0,0,,_\N
27,0,Default,,0,0,0,,d\N
28,0,Default,,0,0,0,,u\N
29,0,Default,,0,0,0,,b\N
30,0,Default,,0,0,0,,5\N
31,0,Default,,0,0,0,,}\N

[Reverse Engineering 115] Phunky Python II

Pythonで書かれたコードの動きを解読する問題。出力が True となるような jkx の値を求める。

porkjkx - 1の値となる。ppには素数の配列が格納される。bはjkx * (jkx - 1)の計算結果の整数を文字列として扱った時に、各文字のindexに相当するppのindexをその文字が示す数だけ掛けた値となる。 よって、bがなるべき指定の値を、素数表の先頭から順に何回割れるか検査することで jkx * (jkx - 1) を復元できる。 jkx * (jkx - 1)からjkxの逆算は、jkx * (jkx - 1)jkx * jkxに近いのを元に頑張る。

# ruby

num = 72081737207748276720511180145077459841982685864664727468076278464152411344311601114385585569894954836943131129966857536471622282317725593001777889426645920685256328084968053358987560901991055855380525752386569788433432855935059472625943932000189976007576109960699881253442685624860214663782047430193757528740778892093750

primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973]

ans = ""

primes.each do |prime|
  cnt = 0
  while num % prime == 0
    num /= prime
    cnt += 1
  end
  # p cnt

  ans = ans + cnt.to_s
  if num == 1
    break
  end
end

ans = ans.to_i
# puts ans


aaa = Math.sqrt(ans).to_i - 100000

loop do
  aaa += 1
  if ans == aaa * (aaa - 1)
    break
  end
end

p aaa
3830672873694420327

[Cryptography 135] RSA 3

2と同様n,e,cが与えられているが、nは十分に長いサイズになっている。こちらのWrite upを参考にFermat法で素因数分解ができた。

[Forensics 150] My USB

USBのイメージデータがDLできる。そこからフラッグを探す。

Autopsyで開いて画像を眺めたらフラッグが書かれていた。あとで普通にmountしてみたが、その画像は見れなかった。

[Cryptography 230] Genius

指定のWebページにアクセスするとHash値が与えられる。Hash前の文字列を求めて、Webページのinputフォームから送信するとフラッグが得られる。

HTMLを見ると、Hash化の手順がjsでコーディングされていた。Hash化の手順は、平文を4文字づつに分割し、それぞれを何かのHash関数に投げ、そのハッシュ関数の結果文字列を結合するというものだった。4文字づつHash関数に投げていたので、4文字づつ貪欲に探索していくことにした。初めはjsのコードを使って探索を試みたが、遅すぎて探索できなかった。

既存のHash関数をjsで実装しただけなのではないかと思いつき調べた。Hash値が16進数なこと、ダイジェスト長が128bitであることを元に調べると既存手法ではMD5が該当した。jsのコードとWikipediaを見比べると合致したため、MD5と断定。下記のようなRubyコードを書いて探索した。

# ruby

require 'digest/md5'

Arr = (32..126).to_a.map{|i| i.chr}
# Arr = ["_"] + ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a


def gen(size, target, str="")
  if size == 0
    if Digest::MD5.hexdigest(str) == target
      puts str
      exit
    end
  else
    s = size - 1
    Arr.each do |c|
      gen(s, target, str + c)
    end
  end
end

h = "8a7fca9234d2f19c8abfcd812971a26c8c510dcaefd5061b191ad41d8b57d0ce631f5074f94b32730d0c025f1d7aacd7be1ab1632e4285edc3733b142935c60b90383bad42309f7f6850d2b4250a713d0b2d7a97350465a02554d29d92bfefafd64ddd0de1b187cd670783f5e28d681dd401ed3009d05ce4ef600d364a2c953e4cc801b880dddef59829a5ad08bd8a6373d559bc117f816333174e918d0587de5cca214701dbe9f7f42da7bccf074b811292b9d4dc398866ef95869b22b3941e78635bc95eaa7662a2ddf3e3d45cf1084f4233d6c396e8a0e6fbf597d07b88178d03f3f7757bdbdaaed60729d08bb180b42dad5453b2128a32f6612b13ea5d9fef843bee79633652a6d6ae08e964609f00e883ab809346226dff6887080fb68b"
i = 0 # 何個目のMD5を知りたいか書いておく

p i
piece = h[i*32, 32]
gen(4, piece)
gen(3, piece)
gen(2, piece)
gen(1, piece)

疲れていたのか、実行毎に知りたい部分をソースコードに書いておく実装になったが、地道に実行した。Hash前の文字列は以下のとおり。

OMG_it_took_like_LITerally_s0oO00_lo0_long_2_MAK3_md5_werrk_you_have_no_id34

あとはこれをWebフォームから送るとフラッグが得られる。

Writeupは以上。