Plaid CTF 2016 Write Up

2016/04/15-17でやってたPlaid CTF 2016のWrite Up...だけど一問も解けなかったなぁ。難しかった...でもこれくらいのレベルのものが解けると面白いなぁ。

用事もあった関係でまともにチャレンジしたのは以下くらいだった。どちらもスタートラインに立ったくらいで死んでる。ので、以下はただのメモ。

reversing 175: quick

何者か確認する。

$ file quick_a2f3cce1589f4fb6d339a785cfe78c4d
quick_a2f3cce1589f4fb6d339a785cfe78c4d: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, stripped

$ ./quick_a2f3cce1589f4fb6d339a785cfe78c4d
./quick_a2f3cce1589f4fb6d339a785cfe78c4d: error while loading shared libraries: libswiftCore.so: cannot open shared object file: No such file or directory

$ ldd ./quick_a2f3cce1589f4fb6d339a785cfe78c4d
	linux-vdso.so.1 =>  (0x00007ffc967dd000)
	libswiftCore.so => not found
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fed74c89000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fed74980000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fed74769000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fed7439f000)
	/lib64/ld-linux-x86-64.so.2 (0x0000560b18fe9000)

Linuxの実行ファイルでlibswiftCore.soがみえないのでそれをくべてやったら
よさそうだ。以下によるとUbuntuでもできるのね。へー。

libswiftCore.soの素性にもよるけど、以下を見るにここからダウンロードしたものっぽい。展開してみるとビルド済みのものみたいだからそれを使う。

$ strings quick_a2f3cce1589f4fb6d339a785cfe78c4d
...
/home/ctf/swift-2.2-RELEASE-ubuntu15.10/usr/lib/swift/linux
...

/home/ctf/swift-2.2-RELEASE-ubuntu15.10に配置するか、`$ LD_LIBRARY_PATH=/path/to/展開した場所 ./quick_a2f3cce1589f4fb6d339a785cfe78c4d` とすればlddから「not found」が消えると思うけど仮想環境でやってたので雑に前者でやった。

さて、実行できるようになったはいいんだけど、これが何かわからなくて解けず。

$ ./quick_a2f3cce1589f4fb6d339a785cfe78c4d
Please provide your input.

Good job!
$ ./quick_a2f3cce1589f4fb6d339a785cfe78c4d
Please provide your input.
a
Nope!

コード書いて解くかgdbで頑張るかだと思うけど後者だと解けないなぁ。

ひとさまのwrite upを見た後

以下を見るに更にgdbで処理の一部を回避したりすると抜けるようだが...うーん、難しい(諦めた)。

misc 50: morset

  • まずはtelnetで繋いでみる
  • ...-- - .--. といったテキストを受け取るのでmorsetなだけにモールス信号として読んでみる
$ telnet morset.pwning.xxx 11821
Trying 40.117.46.42...
Connected to morset.pwning.xxx.
Escape character is '^]'.
...-- - .--. ..--- . ..-. .. --- ----- -.-- -.-. ... .-. ...- .--- .... -.- ..-. .- -... .-.. ...-- ...- -. .-.. -.- ----- ... -.... . .-.. .--- --.- .-. ...-- .--- -- --. -- .. ..... -.-- -... ----. - -..- ---.. ...-- .... .. .- - -..- .-- .. -.- ----- -.- .-.. --. ...-- ..... .--- .- --.- -.... -. -.-. -... .- --.. -.- -. ...--

"3TP2EFIO0YCSRVJHKFABL3VNLK0S6ELJQR3JMGMI5YB9TX83HIATXWIK0KLG35JAQ6NCBAZKN3" などが手に入るがbase64でもないし換字暗号にしては空白がないなぁ。単語の区切りが使ってるgemの想定と違ってるのだろうか?morse gemを使ってたんだけど止めてみても同じだ。

ひとさまのwrite upを見た後

結局わからなかった。以下を見るに更にbase36でdecodeしてsha1を計算したらよかったようだ。そうか空白をなくすためにbase36ね...頭いいなぁ。

という事でコードを書いておわり。Rubyだとbase36はto_i(36)すればいいの楽ね。base36 gemが存在しない訳だ。

$ cat solve.rb

# gem install net-telnet morse
require 'net/telnet'
require 'digest/sha2'
require 'morse'

module Base36
  def encode36(s)
    s.unpack("H*").first.to_i(16).to_s(36)
  end

  def decode36(s)
    hex = s.to_i(36).to_s(16)
    size = hex.length % 2 == 0 ? hex.length : hex.length + 1
    [hex.rjust(size, "0")].pack("H*")
  end

  module_function :encode36, :decode36
end

telnet =
  Net::Telnet.new("Host" => "morset.pwning.xxx", "Port" => 11821, "Timeout" => 10)
begin
  telnet.login("", "") do |s1|
    problem = Base36.decode36(Morse.decode(s1))
    puts problem
    if md = /What is the SHA256\(([^)]+)\)/.match(problem)
      digest = Digest::SHA256.hexdigest(md[1])
      res1 = Base36.encode36(digest)
      res2 = Morse.encode(res1)
      puts "sha256: #{digest}"
      puts "res(base36): #{res1}"
      puts "res(morse): #{res2}"
      telnet.cmd(res2) do |flag|
        puts Base36.decode36(Morse.decode(flag))
      end
    end
  end
rescue
ensure
  telnet.close
end

$ ruby solve.rb

 ,+.
((|))
 )|(
((|))
 `-'
What is the SHA256(Peanut2219310921)?
sha256: fdc0470c02ae587b49028dc7f63b511517ab2826203c13bcf7c6bd78383d7202
res(base36): ga709sl0xr5ubktb7qbvgbaocwfz7yjor3yg80024agbfxx2kjlo77wpsh76lkyrobcjm4ggn90o0cs1uildrptzgdk804broky
res(morse): --. .- --... ----- ----. ... .-.. ----- -..- .-. ..... ..- -... -.- - -... --... --.- -... ...- --. -... .- --- -.-. .-- ..-. --.. --... -.-- .--- --- .-. ...-- -.-- --. ---.. ----- ----- ..--- ....- .- --. -... ..-. -..- -..- ..--- -.- .--- .-.. --- --... --... .-- .--. ... .... --... -.... .-.. -.- -.-- .-. --- -... -.-. .--- -- ....- --. --. -. ----. ----- --- ----- -.-. ... .---- ..- .. .-.. -.. .-. .--. - --.. --. -.. -.- ---.. ----- ....- -... .-. --- -.- -.--

Nice! Here's a flag for you: PCTF{c0c0c0nutBaze_4__d4ys}.
flag: PCTF{c0c0c0nutBaze_4__d4ys}