はじめに
初参戦の初心者ですが、とても楽しめました
余韻に浸りながらwrite up書きたいと思います。
解いた問題は5つ(うち1つは協力して解いた)で、
それらをどんな感じに解いたのか流れも書いてみます!
拡張されたIPv6
問題文の整数以外を使うをヒントに、Google先生に検索。
Qiitaの記事が見つかった
ありがとうGoogle先生。
答えはCTFKIT{RFC8135}
プログラミング言語を当てよう
最近話題になったBlawnでしたね...。それはないやろ思ってたのに...。
@name = name
みたいな書き方が独特?だなって感じて、それで検索したら与えられたソースコードまんまのやつが見つかった...。
記事の先にこんなソースコードが書いてありました。
function add1(x)
x = x + 1 // 字下げしなくても同じ意味
return x // returnが来たら定義の終わり
class Person(name)
@name = name
@function speak()
print("Hello, ")
print(self.name)
return // returnが来たら定義の終わり
ネタが新鮮すぎるぞ作成者!
答えはCTFKIT{BLAWN}
ちなみに、解決に至るまでに時間少しだけ割いてしまいました...。
最初の段階でBlawn挙げて、入力したようだけど、スペルミスしていたらしい...。
emacs向け拡張機能?(このためだけにemacs入れたvimmerです...。)で、
プログラミング言語を自動判定してくれるものがあったので、それで判定してやろうと思ってました
機械学習で8割くらいの精度で検出できるらしい。
andreasjansson/language-detection.el
language-detection.el : elispでプログラミング言語を自動判定できるってホント?
候補として出てきたのは、Python,VisualBasic,Luaでした。
全部違ったんですがね...。
名前を解決したい!
問題文がSTEINS;GATEをリスペクトしてて楽しくなりました
スーパーハカーになりましょう
http://futuregadget-9.tech/
サイトにアクセスできないみたいですが、問題タイトルにもあるようにDNS解析出来ないだけ?って思って
digコマンドでドメイン名からIPアドレスを調べてみた
➜ dig futuregadget-9.tech
futuregadget-9.tech. 120 IN TXT "ip=153.126.212.45"
futuregadget-9.tech. 120 IN NS ns12.value-domain.com.
futuregadget-9.tech. 120 IN NS ns13.value-domain.com.
futuregadget-9.tech. 120 IN NS ns11.value-domain.com.
futuregadget-9.tech. 2560 IN SOA ns13.value-domain.com. hostmaster.futuregadget-9.tech. (
1572079737 ; serial
16384 ; refresh (4 hours 33 minutes 4 seconds)
2048 ; retry (34 minutes 8 seconds)
1048576 ; expire (1 week 5 days 3 hours 16 minutes 16 seconds)
2560 ; minimum (42 minutes 40 seconds)
)
ip出た...。ブラウザのURLに直接入力してアクセスするとフラグページに飛べた。
答えはCTFKIT{naki_nureshi_megami_no_kikan}
これは、未来ガジェット9号機、泣き濡れし女神の帰還ですね!!!!!!
なんでブラウザだとDNS解決できなかったんでしょう?どうやって問題作ったのか気になりますね...。
最後に消したファイル
直前にpicoCTF 2018解いていたのですが、そこで消されたファイルを復元してフラグを得る問題がありました
Recovering From the Snap - Points: 150 - (Solves: 8944)
There used to be a bunch of animals here, what did Dr. Xernon do to them?
やったぜ!解けそう!!
アニメ好きの友人のディスクイメージとのことで、beelmamaっていうファイル名からベルゼブブ嬢のお気に召すまま。
だなってわかりました。
なので、問題解く前は購入したもののデータなんじゃないかなって予想してました。
$ 7z x beelmama.7z
$ file beelmama
beelmama: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, reserved sectors 4, root entries 512, Media descriptor 0xf8, sectors/FAT 100, sectors/track 32, heads 64, hidden sectors 2048, sectors 102400 (volumes > 32 MB), serial number 0x6d826f3d, unlabeled, FAT (16 bit)
$ fls beelmama
r/r 3: 1
r/r 4: 2
r/r 5: 3
r/r 6: 4
r/r 7: 5
r/r 8: 6
r/r 9: 7
r/r 10: 8
r/r 11: 9
r/r 12: 10
r/r 14: test.txt
r/r 16: flag.txt
r/r 18: flag3.txt
r/r 20: flag_no.txt
d/d 22: flag
d/d * 24: .flag
v/v 1635139: $MBR
v/v 1635140: $FAT1
v/v 1635141: $FAT2
V/V 1635142: $OrphanFiles
解凍してflsコマンドで見てみると、削除された.flag
があることがわかりました
dって書いてあったので、ディレクトリ?と思いつつ、picoCTF同様icatで復元してみます
$ icat beelmama 24 > data
$ cat data
. AI�M�MAI.. AI�M�MAI�M�beelz@ebub.key�EELZE~1KEY dmI�M�MmI�M
w%
なにこれ...。Beelzebub.keyみたいな文字が見えますが、肝心のフラグがありません...。
.key
なんてつけてるし、最初は@ebub.key
が@epub.key
に空目して、電子書籍なんかなって思ったくらいです...。
だから、電子書籍のこと調べて回ってました...。
その後、ディスクイメージをマウントして
$ sudo mount beelmama /run/media/hiroya/beelmama
test.txtやflag.txtをcatしたり、stringsしたりしてみてましたが、
ある時、ディスクイメージ自体をcatしたようで、
$ cat beelmama
...省略
�MAI.. AI�M�MAI�M�beelz@ebub.key�EELZE~1KEY dmI�M�MmI�M
w[/P��q�3KF��|vA�����O^��W0�C\:�,��s��m)����I�x+��(�m�#$�H�B�r��4
� �Y���YL�(`�Pzd��Y(�:I9�9:kz��(S�@ ˮk{*6��-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDY0YYMzR/sHGdsRjA7vdH+7NT042GUblG282bRZf0Yu+Sss6QU
jVw2laKt7nYz/FGr86K/YGc5Wk2fePujXtl6FnOADsmaAAUODlYyHOfiNjOitY3D
vooHIROiIGiv4lk/3EuJsmNkC7KYFFvEXQc0G4OWMgw9rIdoh7cScgUh9wIDAQAB
AoGBAMuf80IgfyNzBZqFTJU+z3KYH+QhjCondWzZqS1tmEZbaAbd63I11G2bGJ46
/x4RkO5psOYE9szBR3dG2yVyVdD9sAcrNCVxgx1ya7lvHkAI9mKreRmZTsUc3MKl
O3+mkK8CLJuaVDKzz3t0Fv0lbT9szqvq7i6N19vEvc0ilxgZAkEA69qNMn0zktGQ
BmbR61hUaOSQEjZTuMcpG1AqhPymgk2siCZQDrytRoG6TvqYPW9q1Ez4oUYgzOjv
ehaFR+ChQwJBAOtWuZ+lehSjpt5qlTEgFqmXYR/YvLBfp27yw7fLy+AswpQrwZPY
xVYIfKDjaDCrWAVCVVZE2CIDFE8CP9vEpz0CQQCguMpHgbJHdq9i7WZXrlW3NSpI
fuUGohGNH1AaV+FQIoZUMWeU41ZhGb5QW8yq8OYnzlwP6q4ndQTcecRReu3pAkAC
7iGBi13pw9/gBRO2eN/PXMMo0loHGCnNh9hIAZGYSPZjQeg3HwvV9mUW274AXSHL
bvgBCvpl8gPet/hzlA9BAkBmo2ywHcJICVjjK3io78T5QUbIYe2I8YwvAERaALuD
DQzHowZGb0uLoIeuJDqp7gx0NN4ZOp2CHdLLnLqhIIoR
-----END RSA PRIVATE KEY-----
なんか秘密鍵出てきた。
**ん?**ってなったのをよく覚えてる。
チームメンバーに聞いてみると、「暗号化されたファイル復元できるんじゃね?」って言われたので、
明らかに暗号化されたであろうflag/mullin.encrypted
を秘密鍵を使って復元してみることに。
private_keyファイルに秘密鍵を書き込んで、
$ openssl rsautl -decrypt -inkey private_key -in flag/mullin.encrypted -out output
$ cat output
CTFKIT{Pandemonium_Mont_Blanc}
でた!!!!!パンデモニウムモンブラン!!!!!
アニメ好きを深く考えすぎてしまいました...。
正解はCTFKIT{Pandemonium_Mont_Blanc}
ファイルの復元いらんかった?どうやるのが良かったんでしょう?
お茶をさぐれ
解答チームが2桁を超えだした(はず)ので、僕らも解かないと!って感じで解き始めました。
apkファイルがもらえるので、Android端末にインストールしてみることに。
ほーん、E-mailアドレスとパスワード探せばええんか。ソースコード読むか。
ってことで、apkファイルはzipで解凍できるらしいのでサクッと解凍して。
$ unzip tea.apk
$ ls
resources.arsc classes.dex AndroidManifest.xml META-INF/ res/
ファイル見てもなんもわからんかったので、調べてみたらclasses.dex
にソースコードあるとか。
apktoolっていう、.apk用のリバースエンジニアリングツールもあるということも分かりました。
やってみる。
$ apktool d tea.apk
$ cd tea
$ ls
AndroidManifest.xml res/ smali/ original/ apktool.yml
$ cd smali/com/example/ureshino/ctfmondai_android
$ ls
'LoginActivity$5.smali' 'LoginActivity$2.smali' 'LoginActivity$UserLoginTask.smali' 'R$animator.smali' 'R$integer.smali' 'R$dimen.smali' 'R$layout.smali' R.smali 'R$attr.smali'
'LoginActivity$4.smali' 'LoginActivity$1.smali' 'R$bool.smali' LoginActivity.smali 'R$id.smali' 'R$string.smali' 'R$interpolator.smali' 'R$style.smali'
'LoginActivity$3.smali' BuildConfig.smali 'R$anim.smali' 'LoginActivity$ProfileQuery.smali' 'R$drawable.smali' 'R$mipmap.smali' 'R$color.smali' 'R$styleable.smali'
それっぽいファイルがあったので、ファイルを調べていると、LoginActivity.smali
にCTFKIT{}
という文字を見つけた。
const-string v7, "CTFKIT{"
invoke-virtual {v6, v7}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual {p0, v5}, Lcom/example/ureshino/ctfmondai_android/LoginActivity;->nyaho(Ljava/lang/String;)Ljava/lang/String;
move-result-object v7
invoke-virtual {v6, v7}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
const-string v7, "}"
しかも、コロンで区切られたメールアドレスとパスワードらしきものが。
これ入力すれば、文字列が表示されるんじゃないでしょうか!!!
const-string v1, "herfuvab@sr2b3.wc:tenaoyhr"
ダメでした!!!!!
なんでやねん。
おとなしく逆コンパイルしてソースコード眺めようとここで方法を調べます。
APKファイルのダウンロードとファイル構造、解析方法のまとめ
Arch Linux向けにはdex2jar
はyay、jad
はpacmanでインストールできました。
じゃあまずはclasses.dex
をjarファイルに変換...。
$ dex2jar classes.dex
dex2jar classes.dex -> ./classes-dex2jar.jar
Detail Error Information in File ./classes-error.zip
Please report this file to http://code.google.com/p/dex2jar/issues/entry if possible.
dex2jar classes.dex 22.12s user 0.48s system 313% cpu 7.219 total
なんかError言われてるんやけど...。って失敗してできなかったものだと思っていました。
エラーで終了したし、エラー情報レポートしてくださいって言われてるもんだと...。
今から思えば、エラーで終了したなんて書いてないし、エラー情報レポートしてってだけだったんか、これ...?
ちゃんとファイルは出来ていたので、失敗してても中身確認してみればよかった。
$ ls
classes-dex2jar.jar classes-error.zip
で、classes-dex2jar.jar
をzipとして展開。
中にあるLoginActivity.class
を逆コンパイル。
$ jad LoginActivity.class
出力されたLoginActivity.javaを見てみます。
private static final String DUMMY_CREDENTIALS[] = {
"herfuvab@sr2b3.wc:tenaoyhr"
};
**ダミーとか書いてあるんやが!!!**どうりでそのまま入力してもあかんわけやな...。
if(LoginTask(s, s1))
{
TextView textview = (TextView)findViewById(0x7f080048);
textview.setVisibility(0);
Object obj2 = new StringBuilder();
((StringBuilder) (obj2)).append(f());
((StringBuilder) (obj2)).append(l());
((StringBuilder) (obj2)).append(o());
((StringBuilder) (obj2)).append(g());
((StringBuilder) (obj2)).append(g2());
((StringBuilder) (obj2)).append(e());
((StringBuilder) (obj2)).append(h());
((StringBuilder) (obj2)).append(i());
((StringBuilder) (obj2)).append(j());
((StringBuilder) (obj2)).append(k());
((StringBuilder) (obj2)).append(l2());
((StringBuilder) (obj2)).append(n());
((StringBuilder) (obj2)).append(o2());
obj2 = ((StringBuilder) (obj2)).toString();
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("CTFKIT{");
stringbuilder.append(nyaho(((String) (obj2))));
stringbuilder.append("}");
textview.setText(stringbuilder.toString());
return;
f()
,l()
...は1文字のアルファベットを返す関数として定義されています。
それを連結して、nyaho()
でひと手間加えて出力されてると。
じゃあ、それぞれ関数見て文字列作って、
nyaho()
を実行して、フラグゲットですね!
public String nyaho(String s)
{
char ac[] = new char[s.length()];
for(int i1 = 0; i1 < s.length(); i1++)
{
char c1 = s.charAt(i1);
char c;
if(c1 >= 'a' && c1 <= 'm')
c = (char)(c1 + 13);
else
if(c1 >= 'A' && c1 <= 'M')
c = (char)(c1 + 13);
else
if(c1 >= 'n' && c1 <= 'z')
{
c = (char)(c1 - 13);
} else
{
c = c1;
if(c1 >= 'N')
{
c = c1;
if(c1 <= 'Z')
c = (char)(c1 - 13);
}
}
ac[i1] = c;
}
return String.valueOf(ac);
}
実装の早い子にC++で実装してって投げて代わりにフラグとってもらいました。
疲れてた上、Javaのプログラミング環境整えたことなかった環境だったので、別の言語で書き直さなきゃってことしか考えられなかったんです。
javaインストールされてるし、コンパイルして実行もできるよ...?
このままコピペしてmain書けばできたやん???
この記事書いてるときに気が付きました。やっちまったぜ!!!
しかも後で見た先輩にこれrot13やでって言われて
!!!!
ってなりました。相当疲れてました。
でも、サクッと書いてフラグとってくれました。ありがとう。
やっぱり経験値の差がここで表れるかぁって感じます。
そうゆう時に上手く対処できるか、できないか...。
恥ずかしい...。
正解はCTFKIT{uresino_tea_}でした
アプリでも答え得られたんでしょうか。おそらく成功ルートはそっちでしょうし、メールアドレスとパスワードがどれなのか気になります!
おわりに
先輩に誘われ、参加した初めてのセキュリティコンテストでした。
勉強もあまり出来ていなかった中、メンバーでワイワイと問題を解くことができ、とても楽しい、あっという間の6時間でした。
残念ながら5年生なので、最初で最後のKOSENセキュリティコンテストになってしまいました。
でも、思った以上に楽しめたので、来年からは別の大会に参加しようかなって思っています。
更に勉強してリベンジしたいですね!
運営、作問をされた皆様、お疲れ様でした!
そして、49チームの皆様、対戦ありがとうございました!
楽しかったです!