pico-CTF1(公開用)

# 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411088/215de66a-5e05-758d-5628-2d0ec1ed6984.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411088/57ea1093-9c88-5f30-0f0b-bc0484acf312.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))
```