HeroCTF v3 writeup
m1z0r3はWPICTFにも参加していたのですが難しすぎて私はすぐ撤退…。
HeroCTFはそこそこの難易度でcryptoは全完できたのでよかったです!
Result
もう少しで1000ptと2桁順位が見えたので悔しいですね…
Writeup
Blockchain
Transfer 25pt
We've been tracking drug dealers for a few years. The only thing we got from their network is a hash : bfa8b1c8b7f6acc867d6984968756cafd0da99060aa6d90dfb0db1a9ef0c96a2
Can you tell us where the money is gone?
Blockchainというジャンルは初めてです。いつもはよくEtherscanを使っているのですがそちらでは見つからず、こちらでhash検索で見つかりました。
Transaction: bfa8b1c8b7f6acc867d6984968756cafd0da99060aa6d90dfb0db1a9ef0c96a2 | Blockchain Explorer
Hero{1PQBh6tddet14bYDsSbUiox1YJb5EL185A}
Crypto
h4XOR 75 pt
Can you recover the flag.png image ?
Hint : The xor function is from the pwntools module.
ファイル:flag.png.enc, xor.py
まずxor.pyについて読んでいきます。flag.pngのバイナリデータと、ランダムな8bytesと[0-9]の内どれかをバイト列として繋げた9bytesをxorしてflag.png.encに書き込んでいます。ここでpwntoolsでのxorは特殊で、xorする際に両方の長さを揃えるようにします。長い方に合わせる形で短い方を伸ばします。短い方の長さが長い方の倍数で無い場合、先頭bytesを付け加えます。例えばb"ABCDE"を12bytesにしたい場合、b"ABCDEABCDEAB"という感じです。
ランダムな9bytesの方ですが、後ろ1bytesは10通りしかないのでbrute force可能です。ですが前8bytesをbrute forceするのは2568 = O(1020)とかなりかかるので不可能です。なので別の方法を考えましょう。
PNG画像ファイルのフォーマットはこちらで勉強しました。
PNG画像ファイルの先頭8bytesは16進数で "89504E470D0A1A0A"と決まっています。なのでこの値とencの先頭8bytesをxorするとランダムな8bytesの値が手に入ります。あとは0~9の10通りを試せばOKです。
from os import urandom from random import randint from pwn import xor from Crypto.Util.number import * outpout_img = open("flag.png.enc", "rb").read() head = 0x89504E470D0A1A0A k = long_to_bytes(bytes_to_long(outpout_img[:8])^head) img0 =open("flag0.png", "wb") img1 =open("flag1.png", "wb") img2 =open("flag2.png", "wb") img3 =open("flag3.png", "wb") img4 =open("flag4.png", "wb") img5 =open("flag5.png", "wb") img6 =open("flag6.png", "wb") img7 =open("flag7.png", "wb") img8 =open("flag8.png", "wb") img9 =open("flag9.png", "wb") key0 = k + bytes([0]) key1 = k + bytes([1]) key2 = k + bytes([2]) key3 = k + bytes([3]) key4 = k + bytes([4]) key5 = k + bytes([5]) key6 = k + bytes([6]) key7 = k + bytes([7]) key8 = k + bytes([8]) key9 = k + bytes([9]) img0.write(xor(outpout_img, key0)) img1.write(xor(outpout_img, key1)) img2.write(xor(outpout_img, key2)) img3.write(xor(outpout_img, key3)) img4.write(xor(outpout_img, key4)) img5.write(xor(outpout_img, key5)) img6.write(xor(outpout_img, key6)) img7.write(xor(outpout_img, key7)) img8.write(xor(outpout_img, key8)) img9.write(xor(outpout_img, key9))
もっと綺麗なsolverはあるはず
Hero{123_xor_321}
ExtractMyBlocks 125 pt
The company PasswordS3cure created a new password reset functionality. Could you crack it and find the flag ?
nc chall0.heroctf.fr 10000
ファイル:challenge.py
challenge.pyを読んでいきます。
文字列を投げるとaccount_idとして処理され、それやflagを含むmsg変数にある文字列がAESのECBモードで暗号化され、それを16進数にした値が渡されます。KEYの値は不明です。
AESのECBモードはもっとも単純な暗号化方式になります。
KEYが同じ場合、同じ平文なら同じ暗号文が返されます。CBCモードと異なり、同じ16bytesの平文を二つ繋げた文字列を暗号化すると、16bytesの同じ暗号文が二つ繋げた状態で返ってきます。何ブロック目かなんて関係ないです。flagの文字列も一緒に暗号化されるので、同じ文字列を送れば同じ暗号文になり情報が得られそうです。ただし16bytes毎に区切っているので開始位置に注意する必要があります。これらを考慮しながら入力を調整していく方向で考えていきます。
flagをいきなりbrute forceするのは無理があります。長さも分からないので無謀です。しかし、一文字ごと特定するのであれば64くらい×(flag長)なのでそんなに時間がかからないです。では一文字ずつ特定していきましょう。
flagが含まれるmsg変数のflagが始まる10文字を注目していきます。(その10文字)+"Hero{"+(flagの1文字目) (=Fとします )が一つのblockとして扱われるよう(blockを跨ぐことのないよう)入力を調整していきます。(その10文字)の先頭が16*k+1文字目になればOKです。※(その10文字) = "assword : "
ではこちらが送る文字列も(その10文字)+"Hero{"+(flagの1文字目をbrute forceで試している1文字) (=Tとします )が一つのblockとして扱われるようにこちらも入力を調整していきます。
下の図について、\は改行を、*はT,Fが1blockに収まるように調整を、?はbrute forceで試す1文字を表しています。これはflagの{以降の最初の文字を調べる時の図です。
上から2,4番目の文字列が等しくなる場合、つまり?にflagの1文字目が入った場合、暗号文の2,4 block目(16~32bytesと48~64bytes目)が同じ値になります。これで1文字目が"_"ということが分かりました(1文字目でこの文字は不安になる)。
次に2文字目についてです。
2block目を1文字シフトさせ3block目のpaddingを一つ減らすことで、上手く2,4block目を対応させます。
このようにして?に"}"が当てはまるまで繰り返していきます。3block目のpaddingが0になったら次は16個増やして2,5 block目が同じならOKという感じにシフトしていきます。flag長が16を超えたら3,6block目にしないと…と考えてたらかなり短かったです。
candi = "ABCDEFGHJIKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890{}_" FLAG = "Hero{test_flag}" #簡易的なflag。途中msgを出力している際に入力として送る文字列が正しい長さ確認する flag = "Hero{" isbreak = False #終了条件 #tempをシフトさせていって1文字ずつbrute forceしていく temp = "assword : Hero{" k = len(" !\n\nYour p") #paddingする際の長さ print(k) L = 16 #paddingで送る長さ調整。k=16になった時は32にする。 M = 3 #暗号化されたflagが何blockにあたるか while True: printmsg = True print("k :",k) for i in candi: print(i) HOST, PORT = "chall0.heroctf.fr", 10000 s, f = sock(HOST, PORT) _ = read_until(f) read_until(f,"ID : ") account_id = "12" + temp + i + "0"*(L-k) _msg = f""" Welcome back {account_id} ! Your password : {FLAG} Regards """ #送る入力が正しいものになっているか。特に長さの確認 if printmsg: for j in range(0,len(_msg),16): print(j//16,_msg[j:j+16]) msg = "12" + temp + i + "0"*(L-k) s.send(msg.encode()+b"\n") ct = read_until(f).strip() assert len(ct)%32 == 0 cip = [] for j in range(0,len(ct),32): cip.append(ct[j:j+32]) if cip[1] == cip[M]: print(i) s.close() flag += i if i == "}": print("This is the flag!") print(flag) isbreak = True break print(flag) temp = temp[1:] + i k += 1 if k == 16: L += 16 M += 1 break s.close() printmsg = False if isbreak: break
Hero{_BL0CK5_}
Forensics
We need you 1/5 50pt
Interpol and the FBI have been investigating for over a year now. They are trying to get their hands on two hackers very well known for their ransomware and their ultra efficient botnet.
After long months of investigation, they managed to get their hands on one of their servers. But, when they got it back the PC caught fire because of a defense mechanism set up by the two hackers.
The hard drive could not be saved, but they had time to put the RAM in liquid nitrogen and analyze it later.
You know what you have to do!
For this first step, find the name of the PC!
Download, here.
Format: Hero{Name}
ファイル:Challenge.zip
zipファイルを解凍するとcapture.memが得られます。memファイルの解析ってなんだ、とググるとvolatilityが使えることが判明!
ずばり欲しいデータを得られるコマンドを教えてくれるサイトがありました。
Volatility/Retrieve-hostname - aldeid
$ volatility -f capture.mem imageinfo Volatility Foundation Volatility Framework 2.6 INFO : volatility.debug : Determining profile based on KDBG search... Suggested Profile(s) : Win7SP1x86_23418, Win7SP0x86, Win7SP1x86 (省略) $ volatility -f capture.mem --profile=Win7SP1x86 hivelist Volatility Foundation Volatility Framework 2.6 Virtual Physical Name ---------- ---------- ---- (省略) 0x823859c8 0x2b5d99c8 \SystemRoot\System32\Config\SAM 0x8940c5e8 0x2d5415e8 [no name] 0x8941a2c0 0x2d58d2c0 \REGISTRY\MACHINE\SYSTEM (省略) $ volatility -f capture.mem --profile=Win7SP1x86 printkey -o 0x8941a2c0 -K 'ControlSet001\Control\ComputerName\ComputerName' Volatility Foundation Volatility Framework 2.6 Legend: (S) = Stable (V) = Volatile ---------------------------- Registry: \REGISTRY\MACHINE\SYSTEM Key name: ComputerName (S) Last updated: 2021-04-19 17:00:09 UTC+0000 Subkeys: Values: REG_SZ : (S) mnmsrvc REG_SZ ComputerName : (S) KANNIBAL
Hero{KANNIBAL}
We need you 2/5 75pt
It must be their team name.
For this second step, find the user's name and password in clear text.
Format: Hero{Username:Password}
先程使ったサイト、他にも欲しい情報くれるので最高過ぎる
Volatility/Retrieve-password - aldeid
1/5で使ったimageinfoとhivelistを使います
$ volatility -f capture.mem --profile=Win7SP1x86 hashdump -y 0x8941a2c0 -s 0x823859c8 Volatility Foundation Volatility Framework 2.6 Administrateur:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Invit:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Razex:1000:aad3b435b51404eeaad3b435b51404ee:78d9c7e905c695087ee3baa755ce43e4:::
UsernameがRazexであることに気付かず、crackしてから時間かかりました…。
Hero{Razex:liverpoolfc123}
We need you 3/5 80pt
We know for sure that this server allowed to connect to infected machines. Can you check if a connection was instantiated?
Format: Hero{IP:Port}
接続を確認するのはconnectionsコマンドだろうと実行するもサポートしてないと指摘される。うーん、他にないかな。
Volatility, my own cheatsheet (Part 5): Networking | Andrea Fortuna
netscanでもいいのかありがたい。
$ volatility -f capture.mem --profile=Win7SP1x86 netscan Volatility Foundation Volatility Framework 2.6 Offset(P) Proto Local Address Foreign Address State Pid Owner Created (省略) 0x7ee41538 TCPv4 10.0.2.15:49159 146.59.156.82:4444 ESTABLISHED 3296 nc.exe (省略)
他を省略していますがStateが唯一ESTABLISHEDとなっているものがあったのでForeign Addressを投げたら通りました。
Hero{146.59.156.82:4444}
Misc
Discord 1pt
Join our Discord server and read the rules !
URL : https://discord.gg/PhNkPrfeJG
discord内に分かりやすく書いてほしい…。
Hero{3njoy_th3_3v3nt}
Cubes 40pt
#257 ; #260 ; #282 ; #12 ; #349:2 ; #344 ; #383:120 ; #368
The flag is in in lowercase, without spaces.
これ解けたの嬉しい!
暗号ぽいので「cube cipher」でググるとrubik's cube cipherがヒットしました。ルービックキューブは9個*6面の54種類のスペース(?)があるのに対し、暗号文の数が大きすぎます。そもそも「383:120」などのコロンが付いているやつが何も分かりません。
この特徴的な値に注目し「383:120 cube」でググると…。
Minecraft ID List - Minecraft Info
めちゃくちゃぽい!!
頭文字を並べてみると"iamscese"となる。"iam"はそれっぽいのに最後がなんか変。提出してもincorrectでした。
方向性は間違っていないだろうとminecraftのIDリストを調べてみるとどうやら見ていたのが古いバージョンだった模様。こちらで調べて頭文字を調べるとcorrectとなりました!
Minecraft ID List (1.16) | Minecraft Item IDs
Hero{iamsteve}
Russian Doll 50pt
Go deeper !
ファイル:archive.zip
問題文と問題名よりzip解凍するとめちゃくちゃディレクトリ階層の深いのだろうと…ビンゴ。ただ予想をはるかに超える深さでした。最下層にflag.txtがあるのが見えたので、なんとか検索できる術はないかと模索したところ、見つかりました!
[Linux]grepでディレクトリ以下の全てのファイルを検索する │ TEAM T3A
$ find ./ -type f | xargs grep "Hero{" Binary file ./archive.zip matches ./you/are/about/to/get/rick/rolled/rickRollIncoming/no/iMean/really/lastWarning/toldYou/you/should/have/listened/now/stop/looking/in/someoneElse/stuff/cuteCatPictures/goAway/stop/clicking/manually/through/folders/like/that/write/a/script/to/do/it/for/you/come/on/waste/of/time/what/about/a/recipe/now/200/g/de/pois/chiches/500/g/de/feve/seches/1/oignon/moyen/2/gousses/dail/1/bouquet/de/persil/3/cuilleres/a/soupe/de/farine/1/cuillere/a/cafe/de/cumin/en/poudre/1/cuillere/a/cafe/de/coriandre/en/poudre/1/cuillere/à/cafe/de/paprika/3/cuilleres/a/soupe/de/basilic/frais/hache/sel/huile/de/friture/faites/tremper/les/pois/chiches/et/les/feves/dans/leau/12h/les/egoutter/et/les/cuire/45/mn/a/l/auto/cuiseur/peler/oignon/et/ail/les/hacher/ainsi/que/le/persil/passer/les/feves/et/les/pois/chiches/au/mixer/ourobot/melanger/avec/le/persil/loignon/lail/la/farine/les/epices/le/sel/petrissez/le/tout/avec/vos/mains/en/ajoutant/un/peu/deau/si/necessaire/rassemblez/la/pate/et/laisser/reposer/au/refrigerateur/pendant/minimum/30mn/faconner/une/trentaine/de/boulettes/de/la/grosseur/dune/piece/de/2/euros/les/faire/frire/2-3/mn/puis/les/egoutter/sur/du/papier/absorbant/servir/chaud/ou/froid/avec/des/petites/sauces/tomates/aux/herbes/ou/sauces/yaourts/et/voila/cest/pret/bon/appetit/notPorn/stillNotPorn/reallyNot/seriousStuff/work/realWork/porn/did/you/really/think/there/would/be/porn/inA/work/directory/now/stop/looking/in/someoneElseS/stuff/cuteCatPictures/goAway/stop/clicking/manually/through/folders/like/that/write/a/script/to/do/it/for/you/come/on/waste/of/time/what/about/a/recipe/now/200/g/de/pois/chiches/500/g/de/feve/seches/1/oignon/moyen/2/gousses/dail/1/bouquet/de/persil/3/cuilleres/a/soupe/de/farine/1/cuillere/a/cafe/de/cumin/en/poudre/1/cuillere/a/cafe/de/coriandre/en/poudre/1/cuillere/à/cafe/de/paprika/3/cuilleres/a/soupe/de/basilic/frais/hache/sel/huile/de/friture/faites/tremper/les/pois/chiches/et/les/feves/dans/leau/12h/les/egoutter/et/les/cuire/45/mn/a/l/auto/cuiseur/peler/oignon/et/ail/les/hacher/ainsi/que/le/persil/passer/les/feves/et/les/pois/chiches/au/mixer/ourobot/melanger/avec/le/persil/loignon/lail/la/farine/les/epices/le/sel/petrissez/le/tout/avec/vos/mains/en/ajoutant/un/peu/deau/si/necessaire/rassemblez/la/pate/et/laisser/reposer/au/refrigerateur/pendant/minimum/30mn/faconner/une/trentaine/de/boulettes/de/la/grosseur/dune/piece/de/2/euros/les/faire/frire/2-3/mn/puis/les/egoutter/sur/du/papier/absorbant/servir/chaud/ou/froid/avec/des/petites/sauces/tomates/aux/herbes/ou/sauces/yaourts/et/voila/cest/pret/bon/appetit/ok/you/win/hereIsTheFlag/haha/what/about/a/recipe/now/200/g/de/pois/chiches/500/g/de/feve/seches/1/oignon/moyen/2/gousses/dail/1/bouquet/de/persil/3/cuilleres/a/soupe/de/farine/1/cuillere/a/cafe/de/cumin/en/poudre/1/cuillere/a/cafe/de/coriandre/en/poudre/1/cuillere/à/cafe/de/paprika/3/cuilleres/a/soupe/de/basilic/frais/hache/sel/huile/de/friture/faites/tremper/les/pois/chiches/et/les/feves/dans/leau/12h/les/egoutter/et/les/cuire/45/mn/a/l/auto/cuiseur/peler/oignon/et/ail/les/hacher/ainsi/que/le/persil/passer/les/feves/et/les/pois/chiches/au/mixer/ourobot/melanger/avec/le/persil/loignon/lail/la/farine/les/epices/le/sel/petrissez/le/tout/avec/vos/mains/en/ajoutant/un/peu/deau/si/necessaire/rassemblez/la/pate/et/laisser/reposer/au/refrigerateur/pendant/minimum/30mn/faconner/une/trentaine/de/boulettes/de/la/grosseur/dune/piece/de/2/euros/les/faire/frire/2-3/mn/puis/les/egoutter/sur/du/papier/absorbant/servir/chaud/ou/froid/avec/des/petites/sauces/tomates/aux/herbes/ou/sauces/yaourts/et/voila/cest/pret/bon/appetit/bonOk/flag.txt:Hero{if_yOu_gOt_HEre_By_clIcKInG_mANnUaLly_YoU_sHOuLd_REalLy_SeE_SoMeOne}
Hero{if_yOu_gOt_HEre_By_clIcKInG_mANnUaLly_YoU_sHOuLd_REalLy_SeE_SoMeOne}
OSINT
Find me 10pt
Could you retrieve where this photo was taken ?
Format : Hero{place}
ファイル:find_me.jpg
画像検索で一発です。
Hero{portes mordelaises}
Social ID #1 15pt
Can you find the twitter ID of @HeroCTF.
Format : Hero{twitter_id}
twitter ID って@HeroCTFじゃないのか?と調べたところある整数値がIDだそうです。スクリーンネーム(@以降)を投げると教えてくれるサイトがありました。
idtwi | Twitter IDチェッカー(変更履歴の追跡)
Hero{815907006708060160}
Pushhhh 35pt
The flag is in one of the two Github repositories of the last HeroCTF edition. Could you find it ?
今回がv3なのでv2のgithubを調べれば良さそうです。色々見たところbranchが複数…。
ここを覗いてみるとflagがありました。
HeroCTF_v2/flag.txt at flag · HeroCTF/HeroCTF_v2 · GitHub
Hero{y0u_re_g00d_4t_g1t_250820}
Social ID #2 50pt
Can you find the @username of this Twitter ID 44196397.
Format : Hero{username}
先程のidtwiでOKです。
Hero{@elonmusk}
Prog
Ping Pong 45pt
Could you get the flag ?
ファイル:output.txt
ProgってProgrammingかな?
output.txtを見ると"PING"か"PONG"のどちらかが書いてあります。長さが176と8の倍数であることと、文字列として違うのがIとOなので、"PING" = 1, "PONG" = 0とした2進数を8桁ごとでchrしたらうまく復号されました。
from Crypto.Util.number import * f = open("output.txt") a = f.readlines() ans = "" for i in a: if i.strip() == "PING": ans += "1" else: ans += "0" for i in range(0,len(ans),8): print(chr(int(ans[i:i+8],2)),end="") print()
Hero{p1n6_p0n6_15_fun}
PRo Random Guesser 50pt
Everybody loves a little guessing challenge right ? Guess the number \o/
- Love, Mersenne
/!\ If you are using a script, you have to append '\n' to any data you wish to send back.
Host : chall0.heroctf.fr Port : 7003
数字を予測しろとのことなので、何かの乱数を生成しているのだろう。問題文から恐らくメルセンヌ・ツイスターかな。
細かい仕組みは全く分からないですが、こちらをコードをパクって解けました。ももテクさんには頭が上がらないです。
Mersenne Twisterの出力を推測してみる - ももいろテクノロジー
def untemper(x): x = unBitshiftRightXor(x, 18) x = unBitshiftLeftXor(x, 15, 0xefc60000) x = unBitshiftLeftXor(x, 7, 0x9d2c5680) x = unBitshiftRightXor(x, 11) return x def unBitshiftRightXor(x, shift): i = 1 y = x while i * shift < 32: z = y >> shift y = x ^ z i += 1 return y def unBitshiftLeftXor(x, shift, mask): i = 1 y = x while i * shift < 32: z = y << shift y = x ^ (z & mask) i += 1 return y HOST, PORT = "chall0.heroctf.fr", 7003 s, f = sock(HOST, PORT) print(read_until(f)) print(read_until(f)) print(read_until(f)) x = [] for i in range(624): print(i) read_until(f,"Guess me : ") s.send(b"1337\n") recv_m = read_until(f).split() x.append(int(recv_m[3])) read_until(f) mt_state = tuple([untemper(z) for z in x] + [624]) random.setstate((3, mt_state, None)) ans = int(random.getrandbits(32)) s.send(str(ans).encode()+b"\n") while True: print(read_until(f))
Hero{n0t_s0_r4nd0m_4ft3r_4ll}
Reverse
EasyAssembly 40pt
Don't worry, this one is quite easy :) Could be a good introduction to assembly !
Format : Hero{input:modified}
ファイル:EasyAssembly.asm
IDAなど色々ツールを使ったのですが、結局catすれば分かりました。
$ cat EasyAssembly.asm (省略) # EasyAssembly.c:19: modified = input >> 2; movl -8(%rbp), %eax # input, tmp89 sarl $2, %eax #, tmp88 movl %eax, -4(%rbp) # tmp88, modified # EasyAssembly.c:21: if(modified == 1337404) cmpl $1337404, -4(%rbp) #, modified jne .L5 #, # EasyAssembly.c:22: isGood = 0; movl $0, isGood(%rip) #, isGood .L5: # EasyAssembly.c:24: if(!isGood) movl isGood(%rip), %eax # isGood, isGood.1_1 # EasyAssembly.c:24: if(!isGood) testl %eax, %eax # isGood.1_1 jne .L6 #, # EasyAssembly.c:25: printf("Well done ! You can validate with the flag Hero{%d:%d}\n", input, modified); (省略)
"if(modified == 1337404)" とあるのでmodifiedは1337404でしょう。"modified = input >> 2" からinputはmodifiedを2ビット左シフトさせたものでしょう。エントロピーが2bitsなのでbrute forceすればいいかなと思い提出したら一発で通りました。
Hero{5349616:1337404}
Steganography
HolyAbbot 15pt
A certain abbot tried to give us a message...
(the message is in lower case) (No need to speak French)
Format : Hero{messageinlowercase}
ファイル:HolyAbbot.txt
steganoって全部画像ファイルの解析と思ってたらテキストでびっくり。
しかもテキストの先頭行をググったら一発。RITSEC CTFでもやった、Ave Maria cipherのフランス語バージョンでした。Steganoというよりcryptoじゃん。
Ave Maria de Trithème - Déchiffrer, Décoder, Encoder en Ligne
decodeしたものを小文字に変更して終了です。
Hero{substitution}
Nice PDF 20pt
Don't think to much ;)
ファイル:NicePDF.pdf
pdfの解析か…。問題文から察するにそんな難しいことはせずに解けそうです。exiftoolやbinwalkなどのツールやPDFを実際に開いてプロパティを見るとかしましたが分からず…。
藁にも縋る思いでgoogleに頼るとこんなオンラインツールが。
textで解析すると以下の結果が得られました。
93,02 760,68 H 99,86 760,68 ses 113,90 760,68 e 119,42 760,68 Histoires, 161,54 760,68 r 165,38 760,68 l'historien 209,93 760,68 o 215,81 760,68 grec 234,89 760,68 { 238,37 760,68 Hérodote 281,09 760,68 E 286,49 760,68 rapporte 325,99 760,68 4 331,63 760,68 ainsi 352,03 760,68 S 357,07 760,68 une 373,99 760,68 Y 379,39 760,68 anecdote 421,27 760,68 _ 426,79 760,68 qui 440,86 760,68 P 446,62 760,68 eut 461,50 760,68 D 468,34 760,68 lieu 484,66 760,68 F 489,70 760,68 au 500,74 760,68 }
一文字おきに読むとflagになりました。
Hero{E4SY_PDF}
Problems&solver
今回、ファイルサイズが大きくあげられないものがありました。ご了承ください。
- forensics We need you Challenge.zip
- OSINT Russian doll archive.zip