LoginSignup
2
0

More than 3 years have passed since last update.

pico-CTF1(公開用)

Posted at

pico CTF

このCTFは、初心者向けの常設CTFである。
3カ月ほどコツコツやっていたが、その中でもいい感じに解法がまとめられた・まとめる価値があるものをピックアップする。

logon(web)

やったこと

ユーザ名とパスワードを入力するログインフォームがあった。

SQLインジェクションかなと、インジェクションができそうなものを打ち込んだら、通った。
しかし、flagは表示されなかった。
次に試しに雑なusernameとpasswordを打ち込んでも、同じように認証は通ったが、同じくflagはなかった。
つまり、入力は無関係だと分かった。
ページのスクリプトをみて、"pico"などで検索をかけてもflagは出てこなくて、やり方がわからなかったので調べた。

解き方

Edit this cookieというChromeの拡張機能を用いて、usernameとpasswordの他に、adminという情報が記録されていることが分かったので、これをTrueにして、読み込むとflagが表示された

"Where are the robots"(web)

やったこと

この問題のwebページでは、入力フォームが表示されることはなく、真っ黒な画面に赤文字でwelcome、白文字でWhere are the robots?と書いてあるだけだった。

スクリーンショット 2020-08-31 11.44.03.png

背景の色と文字が同化している、という可能性を感じて、CSSの色の設定を変えてみたが、何も表示されなかった。
また、コンテンツが再背面になっているかとも考え、順番を入れ替えることも行ってみたが、何も変わらなかった。

解き方

robots.txt ファイルは、クローラがどのページやファイルをサイトからリクエストできるか、またはできないかを検索エンジン クローラに知らせるもの(Google Search Consoleヘルプより)

これを用いて、指定されたページのURL/robots.txtにアクセスした。
そして、そこに書かれていた(リクエスト不可能とされている)ディレクトリにアクセスするち、flagを見つけた。

Client-Side-again(Web)

やったこと

ソースコードを見て、flagの要素が配列に入っているのを確認した。
そのあと、if文を使って判定している。

解き方

javascriptのコード整形ツールを利用して、きれいにする。

  var _0x5a46 = ['25df2}', '_again_b', 'this', 'Password Verified', 'Incorrect password', 'getElementById', 'value', 'substring', 'picoCTF{', 'not_this'];
  (function (_0x4bd822, _0x2bd6f7) {
    var _0xb4bdb3 = function (_0x1d68f6) {
      while (--_0x1d68f6) {
        _0x4bd822['push'](_0x4bd822['shift']());
      }
    };
    _0xb4bdb3(++_0x2bd6f7);
  }(_0x5a46, 0x1b3));
  var _0x4b5b = function (_0x2d8f05, _0x4b81bb) {
    _0x2d8f05 = _0x2d8f05 - 0x0;
    var _0x4d74cb = _0x5a46[_0x2d8f05];
    return _0x4d74cb;
  };

  function verify() {
    checkpass = document[_0x4b5b('0x0')]('pass')[_0x4b5b('0x1')];
    split = 0x4;
    if (checkpass[_0x4b5b('0x2')](0x0, split * 0x2) == _0x4b5b('0x3')) {
      if (checkpass[_0x4b5b('0x2')](0x7, 0x9) == '{n') {
        if (checkpass[_0x4b5b('0x2')](split * 0x2, split * 0x2 * 0x2) == _0x4b5b('0x4')) {
          if (checkpass[_0x4b5b('0x2')](0x3, 0x6) == 'oCT') {
            if (checkpass[_0x4b5b('0x2')](split * 0x3 * 0x2, split * 0x4 * 0x2) == _0x4b5b('0x5')) {
              if (checkpass['substring'](0x6, 0xb) == 'F{not') {
                if (checkpass[_0x4b5b('0x2')](split * 0x2 * 0x2, split * 0x3 * 0x2) == _0x4b5b('0x6')) {
                  if (checkpass[_0x4b5b('0x2')](0xc, 0x10) == _0x4b5b('0x7')) {
                    alert(_0x4b5b('0x8'));
                  }
                }
              }
            }
          }
        }
      }
    } else {
      alert(_0x4b5b('0x9'));
    }
  }

javascriptのアンダーバーは、プライベート変数として定義するために利用することが多いらしい。
いくつか細かいところの疑問

  1. _0x2d8f05 = _0x2d8f05 - 0x0;これはどのような意味があるのか->今後整数として扱うため
  2. 変数名が16進数なのはなぜ->わざと難読化するため
  3. documentやcheckpassとは何か->documentはブラウザが持つ変数

if文で、細かく区切られた範囲ごとに一致するか調べている。
区切る範囲は、if文の条件である、checkpassの引数()の二つの数値の間である。
writeupを参考にして、上に貼ったコードの後に出力の処理を書くと、

console.log(_0x4b5b('0x3')) // -> picoCTF{
console.log(_0x4b5b('0x4')) // -> not_this
console.log(_0x4b5b('0x5')) // -> 9f266}
console.log(_0x4b5b('0x6')) // -> _again_1
console.log(_0x4b5b('0x7')) // -> this
console.log(_0x4b5b('0x8')) // -> Password Verified
console.log(_0x4b5b('0x9')) // -> Incorrect password

以下のような出力が得られた。

picoCTF{
not_this
9f266}
_again_1
this
Password Verified
Incorrect password

これを、checkpassの引数の数値を参考にして、並べて全体を合わせてみるとflagが得られる。

picobrowser(Web)

user agentの偽装をする。
問題のリンクを踏み、デベロッパツールで(command+option+I)で一番右のさらなるツールを選択する。
more toolsでnetwork conditionを選択し、UAのagentをcustomにして、今回の指定のpicobrowserと設定して更新すると、flagが出てくる。

Irish-Name-Repo 1(Web)

ユーザ名とパスワードが必要なログインページを抜けられるか、という問題。
SQLインジェクションを用いる。

' OR 'A' = 'A'

を入れれば良いと思っていたが、入れなかったので、手元に合った「安全なWebアプリケーションの作り方」(徳丸本)を読んだ。

' OR 'A' = 'A' --

として、以降のSQLをコメントアウトする必要があった。

JPEGファイルから文字列を抽出する

様々な方法がある

  • stringsコマンドで、ファイルないの抽出可能な文字列を表示できる
  • hexdump -Cコマンドを用いると16進数とASCII文字を出力することができる
  • バイナリGUIエディタを用いる

[tips]画像からflagを見つけるとき

バイナリエディタのGhexを使ってみた!

macに以下のコマンドでghexをインストールすることができた。

brew install ghex

そして、開きたいjpegファイルを引数にとってghexコマンドを叩く。

スクリーンショット 2020-09-10 12.17.36.png

最後にflagがあることはわかっていたので、最後までスクロールした。
文字列検索の機能があったが、使ってみようとするとうまく動作しなかった。

  • VSCodeの拡張機能である、hexdunmp for VSCodeを用いると、文字検索ができる上に使いやすかった。(動作が安定している)タブの上で右クリックをすると拡張機能が使える。

Easy1

ヴィジュネル暗号についての問題。キーと暗号化された文字列が教えられている。
ヴィジュネル暗号を解くためのプログラムを作成した。
なお、これはキーと暗号文が同じ長さのもののみ対応している(キーを同じ長さになるように繰り返してもらえれば大丈夫)

import sys

print("input crypted string in CAPITAL LETTER")
crypted = []
key = []
crypted = input()
print("input key in CAPITAL LETTER")
key = input()

# keyの文字の行まで下がる(行列では下方向)
# keyの文字から始まって、cryptedの文字が何列目かを求める(行列で右方向)
# Aから(左から)何列目かわかったら、それが復号した文字(行列で上方向)

if(len(crypted) != len(key)):
    print("key and crypted don't match")
    sys.exit()
original = []
for i in range(len(crypted)):
    c = ord(crypted[i])-64  # Aから何文字目か(Aは65なので一文字目)
    k = ord(key[i])-64

    if(c >= k):
        num = c-k+65
    else:
        num = 91-k+c  # Zは90

    original.append(chr(num)) # 一文字ずつ復号した文字を格納
print(''.join(original))
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0