[๐Ÿฅ‰ Bronze 3] stripped Rust ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ ์Šคํƒ key ๋ฅผ ๋ฝ‘์•„ XOR ์—ญ์‚ฐ โ€” DreamHack Rusty Gyul ํ’€์ด

2026-07-16ยท1๋ถ„ ์ฝ๊ธฐยท

[๐Ÿฅ‰ Bronze 3] stripped Rust ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ ์Šคํƒ key ๋ฅผ ๋ฝ‘์•„ XOR ์—ญ์‚ฐ โ€” DreamHack Rusty Gyul ํ’€์ด

์‹ฌ๋ณผ์„ ๋ชจ๋‘ ๊ฑท์–ด๋‚ธ Rust ELF ํ•˜๋‚˜๊ฐ€ "ํ”Œ๋ž˜๊ทธ๋ฅผ ๋งž์ถฐ๋ด"๋ผ๊ณ  ํ•œ๋‹ค. ltrace ์—๋Š” strcmp ํ•˜๋‚˜ ์•ˆ ์žกํžˆ๊ณ  main ์€ ๊ป๋ฐ๊ธฐ๋ฟ์ด๋‹ค. ์ง„์งœ ๊ฒ€์‚ฌ ๋ฃจํ‹ด์„ ์–ด์…ˆ๋ธ”๋ฆฌ์—์„œ ์ฐพ์•„ ๋“ค์–ด๊ฐ€ ๋ณด๋ฉด, ์ž…๋ ฅ์„ trim ํ•œ ๋’ค ์Šคํƒ์— ์‹ค์–ด๋‘” 32๋ฐ”์ดํŠธ key ์™€ ํ•œ ๋ฐ”์ดํŠธ์”ฉ XOR ํ•ด์„œ ์ „๋ถ€ 0x55 ์ธ์ง€๋งŒ ๋ณธ๋‹ค. key ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฝ‘์•„ 0x55 ๋กœ ๋˜XOR ํ•˜๋ฉด ํ”Œ๋ž˜๊ทธ๊ฐ€ ๋‚˜์˜จ๋‹ค.

๋ฌธ์ œ: DreamHack โ€” Rusty Gyul ๋ถ„๋ฅ˜: Reversing ๋‚œ์ด๋„: ๐Ÿฅ‰ Bronze 3 FLAG: B1N4RY{Z2FtZ3l1bG11a2dvc2lwZGE=}

๋ฐ”์ด๋„ˆ๋ฆฌ ํ•˜๋‚˜๊ฐ€ ๋œ๋  ์ฃผ์–ด์ง„๋‹ค. ์‹คํ–‰ํ•˜๋ฉด ๊ตต์€ = ๋ฐฐ๋„ˆ์™€ ํ•จ๊ป˜ Gyullllllllll!!!!! ๋ฅผ ์™ธ์น˜๊ณ  ํ”Œ๋ž˜๊ทธ๋ฅผ ์ž…๋ ฅ๋ฐ›์€ ๋’ค, ํ‹€๋ฆฌ๋ฉด [-] Wrong flag. Try again. ์„ ๋ฑ‰๋Š”๋‹ค. ์„œ๋ฒ„๋„ ์—†๊ณ  ํžŒํŠธ๋„ ์—†๋‹ค. ์ด ์•ˆ์— ์ •๋‹ต์„ ํŒ๋ณ„ํ•˜๋Š” ๋กœ์ง์ด ํ†ต์งธ๋กœ ๋“ค์–ด ์žˆ์œผ๋‹ˆ, ๊ทธ ํŒ๋ณ„์„ ๊ฑฐ๊พธ๋กœ ๋Œ๋ฆฌ๋ฉด ํ”Œ๋ž˜๊ทธ๊ฐ€ ์†์— ์žกํžŒ๋‹ค๋Š” ๋œป์ด๋‹ค.

Rust ๋กœ ์งœ์—ฌ ์‹ฌ๋ณผ์ด ์ „๋ถ€ stripped ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ผ ์ฒ˜์Œ์—” ํ•จ์ˆ˜ ์ด๋ฆ„ ํ•˜๋‚˜ ์•ˆ ๋ณด์ด์ง€๋งŒ, ๊ฒ€์‚ฌ ๋กœ์ง ์ž์ฒด๋Š” ํ—ˆ๋ฌดํ•  ๋งŒํผ ๋‹จ์ˆœํ•˜๋‹ค. ์ด ๊ธ€์€ "๊ทธ ๋‹จ์ˆœํ•œ ํ•œ ์ค„"์„ ์–ด์…ˆ๋ธ”๋ฆฌ์—์„œ ์ฐพ์•„ ๋“ค์–ด๊ฐ€ ํ™•์ธํ•˜๊ณ  ๋˜๋Œ๋ฆฌ๋Š” ๊ณผ์ •์ด๋‹ค.


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…Rusty Gyul
๋‚œ์ด๋„๐Ÿฅ‰ Bronze 3
๋ถ„๋ฅ˜Reversing
์ œ๊ณต ํŒŒ์ผrusty_gyul (x86-64 ELF, PIE, stripped)
ํ•ต์‹ฌ ๊ธฐ๋ฒ•stripped Rust ๋ฐ”์ด๋„ˆ๋ฆฌ ์ •์ ๋ถ„์„ ยท ์Šคํƒ ์ƒ์ˆ˜ key ์ถ”์ถœ ยท XOR ์—ญ์‚ฐ

Rusty Gyul ์€ ๋“œ๋ฆผํ•ต์˜ "๊ทค(gyul)" ํ…Œ๋งˆ ๋ฆฌ๋ฒ„์‹ฑ ์‹œ๋ฆฌ์ฆˆ ์ค‘ ํ•˜๋‚˜๋‹ค. Packing Tangerines, Gyul Bomb ์ฒ˜๋Ÿผ ์ด๋ฆ„๋งŒ ๊ท€์—ฝ๊ณ  ์•ˆ์€ ํ‰๋ฒ”ํ•œ crackme ์ธ๋ฐ, ์ด๋ฒˆ์—” ๊ทธ crackme ๋ฅผ Rust ๋กœ ์ปดํŒŒ์ผํ•ด ์‹ฌ๋ณผ๊ณผ ๋””๋ฒ„๊ทธ ์ •๋ณด๋ฅผ ๊ฑท์–ด๋‚ธ ๊ฒŒ ์ „๋ถ€๋‹ค. Rust ๋ผ๊ณ  ๊ฒ๋จน์„ ํ•„์š”๋Š” ์—†๋‹ค โ€” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ป๋ฐ๊ธฐ(๋Ÿฐํƒ€์ž„ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ, UTF-8 ์ฒ˜๋ฆฌ)๋งŒ ๊ฑท์–ด๋‚ด๋ฉด ๊ฒ€์‚ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ C ๋กœ ์ง  ๊ฒƒ๊ณผ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค.


๐Ÿ”ฌ ์ •์ฐฐ

๋จผ์ € ํŒŒ์ผ ์ •์ฒด์™€ ์•ˆ์— ๋ฐ•ํžŒ ๋ฌธ์ž์—ด๋ถ€ํ„ฐ ๋ณธ๋‹ค.

์ด ๊ธ€์˜ ๋ช…๋ น์€ ๋ชจ๋‘ extracted/ ์—์„œ ์‹คํ–‰ํ•œ๋‹ค.

file rusty_gyul; strings -n 6 rusty_gyul | grep -iE 'Input the flag|Correct! The|Wrong flag|Gyul|Enjoy'

file ๋กœ ํŒŒ์ผ ์ข…๋ฅ˜ ํ™•์ธ, strings ๋กœ ์ถœ๋ ฅ ๋ฉ”์‹œ์ง€ ํ™•์ธ
file ๋กœ ํŒŒ์ผ ์ข…๋ฅ˜ ํ™•์ธ, strings ๋กœ ์ถœ๋ ฅ ๋ฉ”์‹œ์ง€ ํ™•์ธ

  • ELF 64-bit ... pie executable ... stripped โ€” PIE ๋ผ ์ฃผ์†Œ๋Š” ๋กœ๋“œ ์‹œ๋งˆ๋‹ค ๋ฐ”๋€Œ๊ณ , ์‹ฌ๋ณผ ํ…Œ์ด๋ธ”์€ ์—†๋‹ค.
  • ๋ฌธ์ž์—ด์— Input the flag:, [-] Wrong flag. Try again., [+] Correct! The flag is yours. ๊ฐ€ ๋ณด์ธ๋‹ค. ํŒ์ • ๋ถ„๊ธฐ๊ฐ€ ์ด ์„ธ ๋ฌธ์ž์—ด ๊ทผ์ฒ˜์— ์žˆ์„ ๊ฒƒ์ด๋‹ค.
  • src/main.rs ๊ฐ™์€ Rust ํ”์ ๋„ ๋‚จ์•„ ์žˆ์–ด ์†Œ์Šค ์–ธ์–ด๊ฐ€ Rust ์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์‹œ์ง€๋งŒ ๋ด์„  ์–ด๋–ค ๊ฐ’๊ณผ ๋น„๊ตํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค. ํŒ๋ณ„ ์ฝ”๋“œ๋กœ ์ง์ ‘ ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค.

๐Ÿ•ณ๏ธ ์‚ฝ์งˆ ๊ธฐ๋ก โ€” strcmp ๋ฅผ ์ฐพ๋‹ค๊ฐ€ ํ—ˆํƒ•, main ์€ ๊ป๋ฐ๊ธฐ์˜€๋‹ค

์ฒ˜์Œ์—” "์–ด๋”˜๊ฐ€์—์„œ ๋‚ด ์ž…๋ ฅ์„ ์ •๋‹ต ๋ฌธ์ž์—ด๊ณผ strcmp/memcmp ํ•˜๊ฒ ์ง€" ํ•˜๊ณ  ๋™์  ๋ถ„์„๋ถ€ํ„ฐ ๋ถ™์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ltrace ๋กœ ๋Œ๋ ค๋ด๋„ ๋น„๊ต ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ํ•˜๋‚˜๋„ ์•ˆ ์žกํžŒ๋‹ค. Rust ๋Š” == ๋น„๊ต๋ฅผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ถœ์ด ์•„๋‹ˆ๋ผ ์ธ๋ผ์ธ ๋ฐ”์ดํŠธ ๋ฃจํ”„๋กœ ํŽผ์ณ ์ปดํŒŒ์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—, libc ์‹ฌ๋ณผ ํ›„ํ‚น์œผ๋กœ๋Š” ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ๋‚˜์˜จ๋‹ค. (์ด ์ง€์ ์—์„œ ์„ธ ๋ฒˆ์ฏค ๋‹ค๋ฅธ ๊ธธ๋กœ ์ƒœ๋‹ค.)

๊ทธ๋‹ค์Œ์—” main ์„ ๋ดค๋Š”๋ฐ, ์ด๊ฒƒ๋„ ํ•จ์ •์ด์—ˆ๋‹ค. ์ •์  ๋ถ„์„๊ธฐ๊ฐ€ main ์ด๋ผ๊ณ  ํ‘œ์‹œํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๊ณ ์ž‘ ์ด ์ •๋„๋‹ค.

; main (0x165e0) โ€” ์ง„์งœ ๋กœ์ง์ด ์—†๋‹ค
mov  rdx, rsi                  ; argv
movsxd rsi, edi                ; argc
lea  rdi, [0x16099]            ; <-- ์ง„์งœ main ํด๋กœ์ € ์ฃผ์†Œ๋ฅผ ๋„˜๊ธด๋‹ค
xor  ecx, ecx
jmp  0x16457                   ; std::rt::lang_start(...)

Rust ํ”„๋กœ๊ทธ๋žจ์˜ main ์€ ์‚ฌ์šฉ์ž ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ std::rt::lang_start ๋กœ ๋„˜์–ด๊ฐ€๋Š” ์–‡์€ ๋ž˜ํผ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ง  ์ง„์งœ main ์€ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋กœ ์ „๋‹ฌ๋˜๋Š” ํด๋กœ์ €(์—ฌ๊ธฐ์„  0x16099)์— ๋“ค์–ด ์žˆ๋‹ค. lea rdi, [0x16099] ์ด ํ•œ ์ค„์ด "์—ฌ๊ธฐ๊ฐ€ ์ง„์งœ ์‹œ์ž‘์ "์ด๋ผ๋Š” ์ด์ •ํ‘œ์˜€๋‹ค. ์—ฌ๊ธธ ๋†“์น˜๊ณ  ๋ž˜ํผ๋งŒ ๋“ค์—ฌ๋‹ค๋ณด๋А๋ผ ์‹œ๊ฐ„์„ ๋ฒ„๋ ธ๋‹ค.


๐Ÿ’ฃ ์ง„์งœ ๊ฒ€์‚ฌ ๋ฃจํ‹ด ์ฐพ๊ธฐ

main ๋ž˜ํผ๊ฐ€ lang_start ์— ๋„˜๊ธฐ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ 0x16099 ๊ฐ€ ์‹ค์ œ ํ”„๋กœ๊ทธ๋žจ ๋ณธ์ฒด๋‹ค. ์ด ํ•จ์ˆ˜๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉด ๋ฐฐ๋„ˆ ์ถœ๋ ฅ โ†’ ํ•œ ์ค„ ์ž…๋ ฅ โ†’ ํŒ์ •๊นŒ์ง€ ์ „๋ถ€ ๋“ค์–ด ์žˆ๋‹ค. ์ž…๋ ฅ์„ ์ฝ์€ ์งํ›„ ๋‘ ๊ฐœ์˜ ๋น„์Šทํ•œ ๋ฃจํ”„๊ฐ€ ๋„๋Š”๋ฐ, ๋‘˜ ๋‹ค ๊ฐ™์€ ์„œ๋ธŒ๋ฃจํ‹ด(0x1653b)์„ ํ˜ธ์ถœํ•œ๋‹ค. ๊ทธ ์„œ๋ธŒ๋ฃจํ‹ด์„ ์—ด์–ด๋ณด๋ฉด ์ •์ฒด๊ฐ€ ๋ณด์ธ๋‹ค.

; fcn 0x1653b โ€” char::is_whitespace
lea  ecx, [rdi - 9]
cmp  ecx, 0x18
...                            ; 0x09..0x0d(ํƒญ/๊ฐœํ–‰๋ฅ˜), 0x20(๊ณต๋ฐฑ),
cmp  edi, 0x1680               ; ๊ทธ๋ฆฌ๊ณ  ์œ ๋‹ˆ์ฝ”๋“œ ๊ณต๋ฐฑ(0x1680, 0x2000.., 0x3000 โ€ฆ)
cmp  edi, 0x3000

0x09~0x0d, 0x20, 0x1680, 0x3000 โ€ฆ ๋”ฑ ๋ด๋„ ๊ณต๋ฐฑ ํŒ์ •์ด๋‹ค. ์ฆ‰ ๋‘ ๋ฃจํ”„๋Š” ์ž…๋ ฅ ์•ž์ชฝ๊ณผ ๋’ค์ชฝ์—์„œ ๊ณต๋ฐฑ์„ ๊ฑท์–ด๋‚ด๋Š” str::trim() ์ด๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์—”ํ„ฐ๋ฅผ ์น˜๋ฉฐ ๋‚จ๊ธด ๊ฐœํ–‰(\n)์„ ๋–ผ์–ด๋‚ด๋Š” ์ „ํ˜•์ ์ธ ํŒจํ„ด์ด๋‹ค. ์ •๋ฆฌํ•˜๋ฉด ํ๋ฆ„์€ ์ด๋ ‡๋‹ค.

  1. ํ•œ ์ค„ ์ž…๋ ฅ์„ ๋ฐ›๋Š”๋‹ค.
  2. input.trim() โ€” ์•ž๋’ค ๊ณต๋ฐฑ/๊ฐœํ–‰ ์ œ๊ฑฐ.
  3. trim ํ•œ ๊ธธ์ด๊ฐ€ ์ •ํ™•ํžˆ 32 ์ธ์ง€ ๋ณธ๋‹ค.
  4. 32๋ฐ”์ดํŠธ๋ฅผ ํ•œ ๋ฐ”์ดํŠธ์”ฉ ๊ฒ€์‚ฌํ•œ๋‹ค.

ํ•ต์‹ฌ์€ 4๋ฒˆ์ด๋‹ค. 0x16099 ํ•จ์ˆ˜์˜ ํŒ์ • ๊ตฌ๊ฐ„(0x16302~)์„ objdump ๋กœ ์ž˜๋ผ, ์–ด๋–ค ๋ช…๋ น์ด ๋ฌด์Šจ ์ผ์„ ํ•˜๋Š”์ง€ ์ฃผ์„์„ ๋‹ฌ์•„ ๋ณด๋ฉด ํŒ์ •์˜ ์ •์ฒด๊ฐ€ ๊ทธ๋Œ€๋กœ ๋“œ๋Ÿฌ๋‚œ๋‹ค.

objdump -d --no-show-raw-insn --start-address=0x16302 --stop-address=0x16342 rusty_gyul \
  | sed -E -f notes.sed

objdump ๋””์Šค์–ด์…ˆ๋ธ” โ€” ํ”Œ๋ž˜๊ทธ ๊ฒ€์‚ฌ ๋ฃจํ”„์— ์ฃผ์„
objdump ๋””์Šค์–ด์…ˆ๋ธ” โ€” ํ”Œ๋ž˜๊ทธ ๊ฒ€์‚ฌ ๋ฃจํ”„์— ์ฃผ์„

์ฝ์–ด๋ณด๋ฉด ์ด๋ ‡๋‹ค.

  • movaps -0x101b1(%rip),%xmm0 / movaps -0x101ed(%rip),%xmm0 โ€” .rodata ๋‘ ๊ณณ(0x6160, 0x6130)์—์„œ 16๋ฐ”์ดํŠธ์”ฉ ์ฝ์–ด ์Šคํƒ(rsp+0x30, rsp+0x40)์— ์ด์–ด๋ถ™์ธ๋‹ค. ์ด๊ฒŒ 32๋ฐ”์ดํŠธ key ๋‹ค.
  • cmp $0x20,%rbp โ€” trim ๋œ ์ž…๋ ฅ ๊ธธ์ด๊ฐ€ 0x20(=32)์ด ์•„๋‹ˆ๋ฉด ๋ฐ”๋กœ ์˜ค๋‹ต์œผ๋กœ ์ ํ”„.
  • ๊ทธ๋ฆฌ๊ณ  ๋ฃจํ”„:
loop:
  cmp  $0x20,%rax                 ; i == 32 ์ด๋ฉด -> ์ •๋‹ต ์ถœ๋ ฅ
  je   correct
  mov  0x30(%rsp,%rax,1),%cl      ; cl = key[i]
  xor  (%rdx,%rax,1),%cl          ; cl ^= input[i]
  inc  %rax
  cmp  $0x55,%cl                  ; (key[i] ^ input[i]) == 0x55 ?
  je   loop                       ; ๋งž์œผ๋ฉด ๋‹ค์Œ ๊ธ€์ž, ํ‹€๋ฆฌ๋ฉด ์˜ค๋‹ต

์ฆ‰ ๊ฒ€์‚ฌ์‹์€ ๋‹จ ํ•˜๋‚˜๋‹ค โ€” ๋ชจ๋“  i(0..31)์— ๋Œ€ํ•ด key[i] ^ input[i] == 0x55. XOR ์€ ์ž๊ธฐ ์—ญ์›์ด๋‹ˆ, ์ด๊ฑธ ๋’ค์ง‘์œผ๋ฉด ๊ณง๋ฐ”๋กœ ์ •๋‹ต์ด ๋œ๋‹ค: input[i] = key[i] ^ 0x55.

Rusty Gyul ๊ฒ€์‚ฌ ๋กœ์ง ์š”์•ฝ โ€” ๋‘ rodata ๋ธ”๋ก์ด ์Šคํƒ key ๋กœ ํ•ฉ์ณ์ง€๊ณ  input ๊ณผ XOR
Rusty Gyul ๊ฒ€์‚ฌ ๋กœ์ง ์š”์•ฝ โ€” ๋‘ rodata ๋ธ”๋ก์ด ์Šคํƒ key ๋กœ ํ•ฉ์ณ์ง€๊ณ  input ๊ณผ XOR

key ๋ฅผ ์ด๋ฃจ๋Š” ๋‘ ๋ธ”๋ก์€ ์ˆœ์„œ๊ฐ€ ๋’ค๋ฐ”๋€Œ์–ด ์‹ค๋ฆฐ๋‹ค๋Š” ์ ๋งŒ ์ฃผ์˜ํ•˜๋ฉด ๋œ๋‹ค. ์Šคํƒ์—์„œ ๋‚ฎ์€ ์ฃผ์†Œ(rsp+0x30)์— ๋จผ์ € ์‹ค๋ฆฌ๋Š” ๊ฑด 0x6160 ์ชฝ 16๋ฐ”์ดํŠธ(= key ์•ž๋ถ€๋ถ„), ๊ทธ๋‹ค์Œ rsp+0x40 ์— 0x6130 ์ชฝ 16๋ฐ”์ดํŠธ(= key ๋’ท๋ถ€๋ถ„)๋‹ค.


๐Ÿงช ๋Ÿฐํƒ€์ž„์œผ๋กœ ํ•œ ๋ฒˆ ๋” ํ™•์ธ

์ •์  ๋ถ„์„๋งŒ ๋ฏฟ๊ณ  ๋„˜์–ด๊ฐ€์ง€ ์•Š๊ณ , gdb ๋กœ ์‹ค์ œ ์‹คํ–‰ ์ค‘์— ๊ทธ ์˜คํ”„์…‹๊ณผ ๊ฐ’์ด ๋งž๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. PIE ๋ผ ๋กœ๋“œ ์ฃผ์†Œ๊ฐ€ ๋งค๋ฒˆ ๋ฐ”๋€Œ๋ฏ€๋กœ set disable-randomization on ์œผ๋กœ ๊ณ ์ •ํ•œ ๋’ค, ๊ฒ€์‚ฌ ์ง„์ž…์  (0x16322)๊ณผ per-char ๋น„๊ต(0x1633d)์— ๋ธŒ๋ ˆ์ดํฌํฌ์ธํŠธ๋ฅผ ๊ฑธ๊ณ  ์ •๋‹ต ํ”Œ๋ž˜๊ทธ๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋„ฃ์–ด๋ดค๋‹ค.

gdb -q -batch -x check.gdb --args ./rusty_gyul < input.txt

gdb ๋Ÿฐํƒ€์ž„ ํ™•์ธ โ€” ์Šคํƒ์— ์‹ค๋ฆฐ 32๋ฐ”์ดํŠธ key ์™€ key^input=0x55
gdb ๋Ÿฐํƒ€์ž„ ํ™•์ธ โ€” ์Šคํƒ์— ์‹ค๋ฆฐ 32๋ฐ”์ดํŠธ key ์™€ key^input=0x55

  • rbp = 32 โ€” trim ๋œ ๊ธธ์ด๊ฐ€ 32๋กœ, ๊ธธ์ด ๊ฒ€์‚ฌ๋ฅผ ํ†ต๊ณผํ•œ๋‹ค.
  • ์Šคํƒ(rsp+0x30)์—์„œ ๋คํ”„ํ•œ 32๋ฐ”์ดํŠธ๊ฐ€ 17 64 1b 61 07 0c 2e 0f โ€ฆ โ€” objdump ๋กœ ์ •์ ์œผ๋กœ ์งš์€ .rodata ๊ฐ’๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•œ๋‹ค. key ๊ฐ€ ์‹คํ–‰ ์‹œ์ ์— ์Šคํƒ ์–ด๋””์— ์‹ค๋ฆฌ๋Š”์ง€๊นŒ์ง€ ๋ˆˆ์œผ๋กœ ํ™•์ธ๋œ ์…ˆ์ด๋‹ค.
  • key[i] ^ input[i] ๊ฐ€ i=0,1,2 โ€ฆ ๋ชจ๋‘ 0x55 โ€” ๊ฒ€์‚ฌ์‹์ด ์‹ค์ œ๋กœ ๊ทธ๋ ‡๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

์ •์ ์œผ๋กœ ์ฝ์–ด๋‚ธ ๊ตฌ์กฐ๊ฐ€ ๋Ÿฐํƒ€์ž„์—์„œ๋„ ๊ทธ๋Œ€๋กœ์˜€๋‹ค. ์ด์ œ ๋˜๋Œ๋ฆฌ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.


๐ŸŽฏ ํ’€์ด โ€” key ๋ฅผ ๋ฝ‘์•„ 0x55 ๋กœ ๋˜XOR

๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ .rodata ์˜ ๋‘ ๋ธ”๋ก์„ ๊ทธ๋Œ€๋กœ ์ฝ์–ด, ์Šคํƒ์— ์‹ค๋ฆฌ๋Š” ์ˆœ์„œ(0x6160 โ†’ 0x6130)๋Œ€๋กœ ์ด์–ด๋ถ™์ธ 32๋ฐ”์ดํŠธ key ๋ฅผ ๋งŒ๋“ค๊ณ  ๊ฐ ๋ฐ”์ดํŠธ๋ฅผ 0x55 ๋กœ XOR ํ•œ๋‹ค. .rodata ๋Š” ํŒŒ์ผ ์˜คํ”„์…‹๊ณผ ๊ฐ€์ƒ์ฃผ์†Œ๊ฐ€ ๊ฐ™์€ ๊ตฌ๊ฐ„(๋‘˜ ๋‹ค 0x6100 ์‹œ์ž‘)์ด๋ผ ํŒŒ์ผ์—์„œ ๋ฐ”๋กœ ์ž˜๋ผ ์“ฐ๋ฉด ๋œ๋‹ค.

# solve.py
BIN = "rusty_gyul"
XOR = 0x55
 
data = open(BIN, "rb").read()
 
# ์Šคํƒ์— ์‹ค๋ฆฌ๋Š” ์ˆœ์„œ: 0x6160(์•ž 16B) + 0x6130(๋’ค 16B)
key = data[0x6160:0x6160 + 16] + data[0x6130:0x6130 + 16]
 
flag = bytes(b ^ XOR for b in key)
print(f"[*] key   = {key.hex()}")
print(f"[*] flag  = {flag.decode()}")
 
import base64
inner = flag[flag.index(b"{") + 1: flag.index(b"}")]
print(f"[*] inner = {base64.b64decode(inner).decode()}   # (base64 decode)")

solve.py ์‹คํ–‰ โ€” key ์ถ”์ถœ๊ณผ XOR ์—ญ์‚ฐ์œผ๋กœ ๋ณต์›ํ•œ ํ”Œ๋ž˜๊ทธ
solve.py ์‹คํ–‰ โ€” key ์ถ”์ถœ๊ณผ XOR ์—ญ์‚ฐ์œผ๋กœ ๋ณต์›ํ•œ ํ”Œ๋ž˜๊ทธ

ํ”Œ๋ž˜๊ทธ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋–จ์–ด์ง„๋‹ค.

B1N4RY{Z2FtZ3l1bG11a2dvc2lwZGE=}

์žฌ๋ฏธ์žˆ๋Š” ๊ฑด ํ”Œ๋ž˜๊ทธ ์•ˆ์ชฝ Z2FtZ3l1bG11a2dvc2lwZGE= ๋ฅผ base64 ๋กœ ํ•œ ๋ฒˆ ๋” ํ’€๋ฉด gamgyulmukgosipda โ€” "๊ฐ๊ทค ๋จน๊ณ  ์‹ถ๋‹ค" ๊ฐ€ ๋‚˜์˜จ๋‹ค๋Š” ์ ์ด๋‹ค. ๋ฌธ์ œ ์ œ๋ชฉ์ด ์™œ Rusty Gyul ์ธ์ง€ ์•Œ ๊ฒƒ ๊ฐ™์€ ์†Œ์†Œํ•œ ์žฅ๋‚œ์ด๋‹ค.


โœ… ๊ฒ€์ฆ

๋ณต์›ํ•œ ๊ฐ’์ด ์ง„์งœ ์ •๋‹ต์ธ์ง€, ๋กœ์ปฌ ๋ฐ”์ด๋„ˆ๋ฆฌ์— ๊ทธ๋Œ€๋กœ ๋จน์—ฌ ํ™•์ธํ•œ๋‹ค. ํŒŒ์ดํ”„(echo | ./bin)๋Š” ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์˜ค๋™์ž‘ํ•  ์ˆ˜ ์žˆ์–ด subprocess ๋กœ ๋„ฃ๋Š”๋‹ค.

# verify.py
import subprocess
 
flag = "B1N4RY{Z2FtZ3l1bG11a2dvc2lwZGE=}"
r = subprocess.run(["./rusty_gyul"], input=flag + "\n",
                   capture_output=True, text=True)
print("Input :", flag)
print("Output:")
print(r.stdout.strip())

verify.py ์‹คํ–‰ โ€” ๋ณต์›ํ•œ ํ”Œ๋ž˜๊ทธ๋กœ Correct ์ถœ๋ ฅ ํ™•์ธ
verify.py ์‹คํ–‰ โ€” ๋ณต์›ํ•œ ํ”Œ๋ž˜๊ทธ๋กœ Correct ์ถœ๋ ฅ ํ™•์ธ

[+] Correct! The flag is yours. ๊ทธ๋Œ€๋กœ ๋œฌ๋‹ค. ๋“œ๋ฆผํ•ต์— ์ œ์ถœํ•ด๋„ ์ •๋‹ต ์ฒ˜๋ฆฌ๋œ๋‹ค.


๐Ÿ›ก๏ธ ์ •๋ฆฌ & ๋ฐฉ์–ด ๊ด€์ 

์ด ๋ฌธ์ œ๊ฐ€ ์ฃผ๋Š” ๊ตํ›ˆ์€ ๋‘ ๊ฐ€์ง€๋‹ค.

๋ฆฌ๋ฒ„์„œ ์ž…์žฅ โ€” Rust ๋ฐ”์ด๋„ˆ๋ฆฌ๋ผ๊ณ  ์ ‘๊ทผ์ด ๋‹ฌ๋ผ์ง€์ง€ ์•Š๋Š”๋‹ค. ์‹ฌ๋ณผ์ด ์—†์–ด๋„ (1) ์ถœ๋ ฅ ๋ฌธ์ž์—ด ๊ทผ์ฒ˜์˜ ๋ถ„๊ธฐ, (2) main ์ด lang_start ์— ๋„˜๊ธฐ๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ, ์ด ๋‘ ์ด์ •ํ‘œ๋งŒ ์žก์œผ๋ฉด ์‚ฌ์šฉ์ž ๋กœ์ง์œผ๋กœ ๋ฐ”๋กœ ๋‚ด๋ ค๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. libc ํ›„ํ‚น(ltrace)์ด ๋น„์–ด ์žˆ์œผ๋ฉด "๋น„๊ต๊ฐ€ ์ธ๋ผ์ธ๋๊ตฌ๋‚˜" ํ•˜๊ณ  ์ •์  ๋ถ„์„์œผ๋กœ ์ „ํ™˜ํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ •์ ์œผ๋กœ ์งš์€ ์˜คํ”„์…‹ยท์ƒ์ˆ˜๋Š” gdb ๋Ÿฐํƒ€์ž„์œผ๋กœ ํ•œ ๋ฒˆ ๋” ํ™•์ธํ•˜๋Š” ์Šต๊ด€์ด, "๋‚ด๊ฐ€ ์ž˜๋ชป ์ฝ์€ ๊ฒƒ"๊ณผ "์ง„์งœ ๊ทธ๋Ÿฐ ๊ฒƒ"์„ ๊ฐ€๋ฅธ๋‹ค.

๋ฐฉ์–ด(๋ฌธ์ œ ์ถœ์ œ) ์ž…์žฅ โ€” ์ •๋‹ต์„ ์ƒ์ˆ˜๋กœ ๊ทธ๋Œ€๋กœ ๋“ค๊ณ  ์žˆ์œผ๋ฉด(์„ค๋ น XOR ํ•œ ๊ฒน์„ ์”Œ์›Œ๋„) ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๊ฐ€์ง„ ์‚ฌ๋žŒ์—๊ฒ ์•„๋ฌด ๋น„๋ฐ€๋„ ์•„๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„  key 32๋ฐ”์ดํŠธ๊ฐ€ .rodata ์— ๊ทธ๋Œ€๋กœ ์žˆ๊ณ  XOR ์ƒ์ˆ˜๋„ 0x55 ํ•œ ๋ฐ”์ดํŠธ๋ผ, ๊ฒ€์‚ฌ ๋ฃจํ”„ ํ•œ ๋ˆˆ์— ์ „๋ถ€ ๋ณต์›๋œ๋‹ค. ์‹ค์ œ๋กœ ๊ฐ’์„ ์ˆจ๊ธฐ๋ ค๋ฉด ํด๋ผ์ด์–ธํŠธ ์ธก ์ƒ์ˆ˜ ๋น„๊ต๊ฐ€ ์•„๋‹ˆ๋ผ ์„œ๋ฒ„ ๊ฒ€์ฆ(์ž…๋ ฅ์„ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด ํŒ์ •)์ด๋‚˜, ์ตœ์†Œํ•œ ์ž…๋ ฅ์—์„œ ํŒŒ์ƒํ•œ ํ‚ค๋กœ๋งŒ ํ’€๋ฆฌ๋Š” ๊ตฌ์กฐ์—ฌ์•ผ ํ•œ๋‹ค. crackme ๋Š” ์›๋ž˜ "์ˆจ๊ธด ์ฒ™"์ผ ๋ฟ, ๋ฐ”์ด๋„ˆ๋ฆฌ ์•ˆ์˜ ๋น„๊ต๋Š” ์–ธ์ œ๋‚˜ ๋’ค์ง‘ํžŒ๋‹ค.

์ด ๊ธ€์ด ๋„์›€์ด ๋๋‚˜์š”?

Comments

๋Œ“๊ธ€

0๊ฐœ

๋Œ“๊ธ€์„ ๋‚จ๊ธฐ๋ ค๋ฉด ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ด์š”. (๋„ค์ด๋ฒ„ ยท ๊ตฌ๊ธ€ ๊ณ„์ •)

๋Œ“๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘โ€ฆ

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅ‰ Bronze 2] XOR 0x42 ๋’ค์— ์ˆจ์€ ๋ช…๋ น ํ•œ ๊ฐœ โ€” DreamHack flag printer ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] XOR 0x42 ๋’ค์— ์ˆจ์€ ๋ช…๋ น ํ•œ ๊ฐœ โ€” DreamHack flag printer ํ’€์ด

print/id/help ์„ธ ๊ฐœ๋งŒ ๋ฐ›๋Š”๋‹ค๋˜ ํ”„๋กœ๊ทธ๋žจ์ด, ์‚ฌ์‹ค์€ ๋„ค ๋ฒˆ์งธ ๋ช…๋ น์„ ๋ชฐ๋ž˜ ๋ฐ›๊ณ  ์žˆ์—ˆ๋‹ค. ๋ชจ๋ฅด๋Š” ํ† ํฐ์„ strdup ํ•ด์„œ XOR 0x42 ํ•œ ๋’ค ์Šคํƒ์— ์กฐ๋ฆฝํ•ด ๋‘” ๋„ค ๋ฐ”์ดํŠธ์™€ ๋น„๊ตํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ๊ณ , ๊ทธ๊ฑธ ํ†ต๊ณผํ•˜๋ฉด print ๊ฐ€ art ๋Œ€์‹  flag ๋ฅผ ์—ฐ๋‹ค. objdump ๋กœ ๋น„๊ต๊ฐ’์„ ์ฝ๊ณ  gdb ๋กœ ๋Ÿฐํƒ€์ž„๊นŒ์ง€ ํ™•์ธํ•ด ํ•œ ์ค„๋กœ flag ๋ฅผ ๋ฝ‘์•˜๋‹ค.
#dreamhack#ctf#reversing+5
2026-08-11#dreamhack +6
[๐Ÿฅˆ Silver 2] Rust ํฌ๋ž™๋ฏธ์˜ ๋น„ํŠธ ์น˜ํ™˜์„ ๊ฑฐ๊พธ๋กœ ๋Œ๋ ค 64๊ธ€์ž ์ž…๋ ฅ ๋ณต์› โ€” DreamHack CrabME ํ’€์ด
blog

[๐Ÿฅˆ Silver 2] Rust ํฌ๋ž™๋ฏธ์˜ ๋น„ํŠธ ์น˜ํ™˜์„ ๊ฑฐ๊พธ๋กœ ๋Œ๋ ค 64๊ธ€์ž ์ž…๋ ฅ ๋ณต์› โ€” DreamHack CrabME ํ’€์ด

Rust ๋กœ ๋นŒ๋“œ๋œ ํฌ๋ž™๋ฏธ. ์ž…๋ ฅ์€ 64๊ธ€์ž ์†Œ๋ฌธ์ž hex ๋กœ ๊ณ ์ •๋ผ ์žˆ๊ณ , ๋‘ ๊ธ€์ž์”ฉ ๋ฌถ์€ 32๋ฐ”์ดํŠธ๋ฅผ flagchecker ๊ฐ€ "๋น„ํŠธ ์น˜ํ™˜ โ†’ XOR 0x63 โ†’ +0x22" ์„ธ ๋‹จ๊ณ„๋กœ ๋ฐ”๊ฟ” .rodata ์— ๋ฐ•ํžŒ ์ƒ์ˆ˜ 32๊ฐœ์™€ ๋น„๊ตํ•œ๋‹ค. ์„ธ ๋‹จ๊ณ„๊ฐ€ ์ „๋ถ€ ๋ฐ”์ดํŠธ ๋‹จ์œ„ ์ „๋‹จ์‚ฌ๋ผ ๋ธŒ๋ฃจํŠธํฌ์Šค ์—†์ด ๊ทธ๋Œ€๋กœ ์—ญ์‚ฐ๋˜๊ณ , ๋‚˜์˜จ 64๊ธ€์ž๊ฐ€ ๊ณง ํ”Œ๋ž˜๊ทธ ๋ณธ๋ฌธ์ด๋‹ค. objdump ๋กœ ์น˜ํ™˜ํ‘œ๋ฅผ ์œ ๋„ํ•˜๊ณ  gdb ๋กœ ๋Ÿฐํƒ€์ž„์—์„œ ๊ฐ™์€ ๊ฐ’์ด ๋‚˜์˜ค๋Š”์ง€ ํ™•์ธํ–ˆ๋‹ค.
#dreamhack#ctf#reversing+6
2026-07-26#dreamhack +6
[๐Ÿฅ‰ Bronze 2] .rodata 247๋ฐ”์ดํŠธ๊ฐ€ ์Šคํƒ VM ๋ฐ”์ดํŠธ์ฝ”๋“œ์˜€๋‹ค โ€” DreamHack SelfStatus ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] .rodata 247๋ฐ”์ดํŠธ๊ฐ€ ์Šคํƒ VM ๋ฐ”์ดํŠธ์ฝ”๋“œ์˜€๋‹ค โ€” DreamHack SelfStatus ํ’€์ด

ํ”„๋กœ๊ทธ๋žจ์ด ์ž๊ธฐ /proc/self/status ๋ฅผ ์ฝ์–ด TracerPid ๋กœ ๋””๋ฒ„๊ฑฐ๋ฅผ ์•Œ์•„์ฑ„๊ณ  ์กฐ์šฉํžˆ ์ฃฝ๋Š”๋‹ค. ์ง„์งœ ๊ฒ€์‚ฌ๋Š” .rodata ์— ๋ฐ•ํžŒ 247๋ฐ”์ดํŠธ๋ฅผ ๋„๋Š” ์Šคํƒ VM ์ด ๋งก๋Š”๋ฐ, ๊ทธ VM ์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์•„์˜ˆ ์ณ๋‹ค๋ณด์ง€ ์•Š๊ณ  ์ •๋‹ต ๋ฌธ์ž์—ด์„ ์Šค์Šค๋กœ ์กฐ๋ฆฝํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์—ญ์‚ฐํ•  ๊ฒƒ์ด ์—†๋‹ค โ€” VM ๋งŒ ์˜ฎ๊ฒจ ์ ์œผ๋ฉด ๋๋‚œ๋‹ค.
#dreamhack#ctf#reversing+6
2026-08-19#dreamhack +5