【write-up】SECCON BeginnersCTF【[Rev]mask】
前書き
5/23~24にかけて開催されていたSECCON BeginnersCTFに参加するべく全裸待機していたのですが、何やかんやあって結局参加できず…。後で解き直せそうな問題は何問か回収してきたので、これをシコシコとやっていくことにします。やっていく問題は以下。
- [Misc]emoemoencode
- [Crypto]R&B
- [Rev]mask
- [Rev]yakisoba
- [Rev]ghost
- [Rev]siblangs
- [Rev]sneaky
- [Pwn]Beginner's Stack
- [Pwn]Elementary Stack
- [Pwn]ChildHeap
- [Pwn]flip
あと、write-upはどこまで詳細に書くべきか非常に迷うのですが、今回は自分がとった行動をなるべく詳細に書いていこうと思います。
write-up
バイナリが渡されるのでfileコマンドで基本的な情報を確認する。
ELF-64bitでnot striped、IDAでコントロールフローを確認する。バイナリを動かしてみると、入力された文字列対して何らかの操作が行われているので、この操作の部分を特定することにする。main関数以外にユーザー定義の関数が見当たらないので、main関数内を見てみると、以下のベーシックブロックを得る。
入力文字列に対して、0x75と0xebでand演算を行い、その結果がそれぞれ別のアドレスに保存されている。すべての入力文字にmaskをかけた後のベーシックブロックを見てみると、先にmaskをかけた2つの文字列がそれぞれatd4`qdedtUpetepqeUdaaeUeaqau
とc`b bk`kj`KbababcaKbacaKiacki
に等しいかをstrcmp関数で確認している。
よって、以下のスクリプトで元の文字列を求める。
#convert binary and conbine them #0x75 = 0111 0101 #0xeb = 1110 1011 string1="atd4`qdedtUpetepqeUdaaeUeaqau" string2="c`b bk`kj`KbababcaKbacaKiacki" flag="" for i in range(len(string1)): char1=string1[i] char2=string2[i] flag += chr(ord(char1)+((0x8a)&ord(char2))) print(flag)
ctf4b{dont_reverse_face_mask}