---
# System prepended metadata

title: '2025-12-15_"Flag Printer 2100": 251217'
tags: [Rev, alpaca, medium, CTF]

---

# 2025-12-15_"Flag Printer 2100": 251217

{%preview https://alpacahack.com/daily/challenges/flag-printer-2100 %}
Level: Medium
Type: Rev
solved day: 2025,12,17

## solution

```sh
$ file ./print_flag
./print_flag: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=4779e9456734b25b443894084d1ef12e88a94719, for GNU/Linux 3.2.0, not stripped
$ ldd ./print_flag
	/work/fakesleep.so (0x00007fffff7bb000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fffff5c2000)
	/lib64/ld-linux-x86-64.so.2 (0x00007ffffffc8000)
$ strings -a ./print_flag | egrep -i 'flag|sleep|show_flag|year|2100|75'
sleep
I'll sleep for 75 years...
show_flag
sleep@GLIBC_2.2.5
```
```
# sleep/nanosleep を無効化する共有ライブラリを作成
$ cat > fakesleep.c <<'EOF'
#define _GNU_SOURCE
#include <time.h>
#include <unistd.h>
unsigned int sleep(unsigned int s){ return 0; }
int nanosleep(const struct timespec *req, struct timespec *rem){ return 0; }
EOF

$ gcc -shared -fPIC -o fakesleep.so fakesleep.c

# 実行（LD_PRELOAD と実行コマンドを同じ行で）
$ chmod +x print_flag
$ export LD_PRELOAD=$PWD/fakesleep.so
$ ./print_flag
I'll sleep for 75 years...
Alpaca{G00d_Morning_AlpacaH4ck!}
````

## How I thought.

```sh
# 重要な観察
file       # → ELF 64-bit, PIE, dynamically linked
ldd        # → libc.so.6 に依存（GLIBC）→ LD_PRELOAD が効く
strings    # → "sleep" / "I'll sleep for 75 years..." / "show_flag"
```

*   **仮説**: 「75年後にフラグ」＝ 実装は `sleep()` / `nanosleep()` による**長時間待機** → その後 `show_flag`
*   **戦術**: 動的リンクなので **`LD_PRELOAD`** で `sleep()` / `nanosleep()` を**即リターン**に差し替え、待機をスキップして**フラグ表示**
*   **ポイント**:
    *   `LD_PRELOAD=<so> ./binary` の形で**同じ行**に実行コマンドを書く。
    *   もし時刻比較型（2100年判定）なら、`time()/clock_gettime()` を **2100‑01‑01** の epoch（`4102444800`）に偽装するフックで突破可能
    *   静的リンク／フック不可なら、`objdump/gdb` で `sleep` 呼び出し直前の **`edi=0`** にして `sleep(0)` にする（または条件ジャンプ反転で直接フラグ側へ）
