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ゲット。
speeds and feeds
There is something on my shop network running at nc mercury.picoctf.net 53740, but I can't tell what it is. Can you?
まずはncしてみましょう。
└─# nc mercury.picoctf.net 53740 G17 G21 G40 G90 G64 P0.003 F50 G0Z0.1 G0Z0.1 G0X0.8276Y3.8621 G1Z0.1 G1X0.8276Y-1.9310 G0Z0.1 G0X1.1034Y3.8621 G1Z0.1 G1X1.1034Y-1.9310 ・ ・ ・
何かしらが起こっているのかな? chat-GPTに投げ込んでみた。
これは、Gコード (G-code) と呼ばれるプログラムの一部です。主にCNC(コンピュータ数値制御)マシン、例えば工作機械や3Dプリンターで使用され、機械の動作を指示するためのコマンドの集合です。この例は、CNCマシンで特定の加工や移動を行うための指示を表しています。
座標の移動を行っているようだ。もしかしたらこれでflagを書いているのか?
ということで、オンライン上でg-codeを実行できる(NC Viewer)に出力された値を入力するとflagが書かれた。flagゲット。
unpackme.py
Can you get the flag? Reverse engineer this Python program. まずはpythonファイルが渡されたので、見ていく。
import base64 from cryptography.fernet import Fernet payload = b'gAAAAABkzWGWvEp8gLI9AcIn5o-ahDUwkTvM6EwF7YYMZlE-_Gf9rcNYjxIgX4b0ltY6bcxKarib2ds6POclRwCwhsRb1LOXVt4Q3ePtMY4BmHFFZlIHLk05CjwigT7hiI9p3sH9e7Cpk1uO90xbHbuy-mfi3nkmn411aBgwxyWpJvykpkuBIG_nty6zbox3UhbB85TOis0TgM0zG4ht0-GUW4wTq2_5-wkw3kV1ZAisLJHzF-Z9oLMmwFZU0UCAcHaBTGDF5BnVLmUeCGTgzVLSNn6BmB61Yg==' key_str = 'correctstaplecorrectstaplecorrec' key_base64 = base64.b64encode(key_str.encode()) f = Fernet(key_base64) plain = f.decrypt(payload) exec(plain.decode())
最後の方を見ると復号が行われている。ことから何かしら暗号化されているpayloadが復元されて実行されるようだ。さすがに実行させるのは怖いので、print(plain.decode())を行うように書き換えて実行する。
└─# python3 unpackme.flag.py
b"\npw = input('What\\'s the password? ')\n\nif pw == 'batteryhorse':\n print('picoCTF{175_chr157m45_85f5d0ac}')\nelse:\n print('That password is incorrect.')\n\n"
パスワードの入力を求めて、あっていたらflagを返すふるまいだったようだ。べた書きされていなかったらもう少し難しくなりそう。でも、flagゲット。