OverTheWire - Semtex

semtex

semtex.labs.overthewire.org 2229

level 0 → level 1

1
2
3
4
SSH Information
Host: semtex.labs.overthewire.org
Port: 2229 (SSH after solving level 0)
Level 0 service: port 24000 (x86) / 24001 (amd64)

Semtex: network programming, reverse engineering, buffer overflows and combinatorial analysis. 本次 TCP 探测显示 222924000240012400224027 可建立连接;但 level 0 服务连接后没有立即吐出 binary(raw_size=0),和旧资料描述不完全一致。因此下面写的是解题路线和验证脚本,发布前仍要重新 live verify,不写未验证 password。

Level 0: "Get a shell" — Connect to port 24000, receive binary data with every second byte as trash. Strip trash, execute the ELF to get password.

1
2
3
4
5
6
7
8
9
10
# Example solution
nc -vv semtex.labs.overthewire.org 24000 > output
# Every second byte is trash — discard them
python3 -c "
data = open('output','rb').read()
clean = bytes(data[i] for i in range(0,len(data),2))
open('binary','wb').write(clean)
"
chmod +x binary
./binary

Level 1: Reverse engineer encryption algorithm

Has encrypted password (HRXDZNWEAWWCP) and semtex1 binary with -v switch. Verification flow:

  1. Run /semtex/semtex1 -v AAAAAAAAAAAAA and change one input character at a time.
  2. Record which output position changes and by how much.
  3. Recover the position permutation and per-position Caesar shift.
  4. Apply the inverse transform to the target ciphertext.

The writeup should show the derivation script and use <semtex2-password> as the final output until live verified.

Level 2: LD_PRELOAD trick

Binary checks EUID. The historical route is to hook the 32-bit uid function and return 666:

1
2
#include <sys/types.h>
uid_t geteuid(void) { return 666; }

Compile and run on the game host:

1
2
gcc -m32 -shared -fPIC hook.c -o /var/tmp/semtex2-hook.so
LD_PRELOAD=/var/tmp/semtex2-hook.so /semtex/semtex2

If this fails, trace first:

1
strace -f /semtex/semtex2 2>&1 | grep -E 'getuid|geteuid|setuid'

Level 3: Lock puzzle

The program has five locks and eight buttons. Each button adds a vector to the lock state; target is normally to move every lock from 300 to 400.

Verification script shape:

1
2
3
4
5
6
7
8
9
10
11
12
from itertools import product
vectors = [...] # measure by pressing 1..8 once
start = [300] * 5
target = [400] * 5
for length in range(1, 30):
for seq in product(range(8), repeat=length):
state = start[:]
for button in seq:
state = [x + y for x, y in zip(state, vectors[button])]
if state == target:
print(''.join(str(x + 1) for x in seq))
raise SystemExit

Level 4: Process tracing

semtex4 is historically static, so LD_PRELOAD no longer helps. Use ptrace to intercept the child syscall and patch the return value for the UID check.

Checklist:

1
2
file /semtex/semtex4
strace -f /semtex/semtex4

Tracer shape:

  1. fork().
  2. Child calls ptrace(PTRACE_TRACEME) then execl('/semtex/semtex4', ...).
  3. Parent loops with PTRACE_SYSCALL.
  4. On i386, inspect ORIG_EAX; when it is SYS_geteuid32, wait for syscall exit and set EAX to the required UID.

Level 5: Multi-IP timing challenge

Service is on semtex.labs.overthewire.org:24027. Public notes describe ten simultaneous connections from ten different source IPs. Each connection receives a 10-byte challenge; reply with:

1
response = xor(challenge, semtex5_password) + identifier

All connections must share the same 10-byte identifier. One connection then receives the next credential.

This is the least reproducible Semtex level: NAT, Tor exit reuse, timing windows, and “different IP” checks can all break the exploit. Do not publish a final spoiler until the multi-IP setup is actually verified.

Tools used

nc, python3, xxd, gcc -m32 -shared, LD_PRELOAD, strace.

当前发布状态:route mapped, live verification blocked。这篇不能直接发布为完整 spoiler writeup;至少需要重新验证 24000/24001 是否返回可清洗 ELF,并逐关确认密码链。Level 5 还需要真实多公网 IP 环境。