新幹線での移動中に参加でした。
1問解くことを目標に参加して何とか達成したものの、
後日残りの問題を見たらフルタイム参加しても厳しそうでした。
Rev頑張りたい。
次のようなchecker
ファイルが渡される。
# file checker
checker: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c2dd390ecbb794a78e20db0151832e9dd5c6359d, for GNU/Linux 3.2.0, not stripped
[checksec]
Canary : Enabled
NX : Enabled
PIE : Enabled
RELRO : Full RELRO
Fortify : Found
# ./checker
flag? aaaaaaaa
Wrong...
まずはGhidraで眺めてみる。
入力文字列は49byte。
1byte毎にupdate
で16byteに変換され、table
の値と比較を行っている。
この入力を求めたい。
update
を見るが規則的な変換は多いものの追うにはしんどそうなので動的解析を試みる。
memcmp
の結果が0
になれば正解なので1byteずつ探索していく。
pythonからgdbのサブプロセスを作って回したが時間がかかったので
途中で並列化してゴリ押した。
gdbの処理内でやり直したりできるんだろうけど上手く書けなかったです。
import subprocess
from concurrent.futures import ThreadPoolExecutor
binary_path = "./checker"
partial_flag = "Alpaca{"
candidate_chars = "ea0413256789_@?!riotnslcudpTAOISWmhgbfywkvxzjqCBPHFMDRELNGUKVYJQZX#%$*+-|~\"'(),./:;<=>[]\\^`{} "
def check_byte(candidate_char, current_flag, binary_path):
result = subprocess.run(
["gdb", "-q", "--nx", "--batch", "-x", "find_flag_byte.gdb", "--args", binary_path],
input=f"{current_flag + candidate_char}\n",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
if "byte found" in result.stdout:
print("Found:", current_flag + candidate_char)
return current_flag + candidate_char
return None
def find_next_byte_parallel(candidate_chars, current_flag, binary_path, max_workers=12):
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = [
executor.submit(check_byte, char, current_flag, binary_path)
for char in candidate_chars
]
for future in futures:
result = future.result()
if result:
return result
while len(partial_flag) < 49:
gdb_check_steps = ''.join(['c\nif ($eax == 0)\nprintf ""\nend\n' for _ in range(len(partial_flag))])
gdb_script = f"""
b main
r
b *main+175
{gdb_check_steps}
c
if ($eax == 0)
printf "byte found\\n"
quit
end
quit
"""
with open("find_flag_byte.gdb", "w") as gdb_file:
gdb_file.write(gdb_script)
partial_flag = find_next_byte_parallel(candidate_chars, partial_flag, binary_path)
※補足
自分の普通のノートPCだと6分30秒くらい
candidate_chars
は普通のprintableな文字ですがなんとなく出現高そうな順に並んでます
(ちゃんとフラグの統計取ったら面白そう)
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing