Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • 当該関数は次のような機能をします。
    • 当該関数は、除隊変数gAccount[]。stateの値が'0'だった場合、次のように動作します。
      • 当該関数はmalloc()を使用して128 byteのheap領域を割り当てられます。を使用して128 byteのheap領域を割り当てられます。
        • 当該関数は、当該領域の住所をgAccount[i]。fdに保存します。
        • 当該関数は、該当領域にID、Password、profile情報を保存します。

...

  • 当該関数は次のような機能をします。
    • 当該関数はmalloc()関数を利用して1200 byteのHeap領域を割り当てられます。関数を利用して1200 byteのHeap領域を割り当てられます。
    • 当該関数は、該当領域に使用者から値を入力を受けて保存します。

...

  • 当該関数は次のような機能をします。
    • 当該関数は使用者から充電する金額の番号は、入力されます。
    • 当該関数は、当該金額を当該関数は、当該金額を"gLoginAccount→bk"領域に加えます。
Code Block
languagecpp
titlecharge()
unsigned __int64 charge()
{
  unsigned int chargeInfo[2]; // [rsp+0h] [rbp-10h]
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  chargeInfo[0] = 0;
  puts("Please select the amount to charge.");
  puts("0) 1");
  puts("1) 10");
  puts("2) 100");
  puts("3) 1000");
  puts("4) 10000");
  puts("5) 100000");
  chargeInfo[1] = retNumber(2LL);
  switch ( chargeInfo[1] )
  {
    case 0u:
      chargeInfo[0] = 1;
      break;
    case 1u:
      chargeInfo[0] = 10;
      break;
    case 2u:
      chargeInfo[0] = 100;
      break;
    case 3u:
      chargeInfo[0] = 1000;
      break;
    case 4u:
      chargeInfo[0] = 10000;
      break;
    case 5u:
      chargeInfo[0] = 100000;
      break;
    default:
      break;
  }
  gLoginAccount->bk += chargeInfo[0];
  printf("%ld yen charged.\n", chargeInfo[0], *(_QWORD *)chargeInfo);
  return __readfsqword(0x28u) ^ v2;
}

...

  • 当該関数は次のような機能をします。
    • 当該関数は、除隊変数gAccount[]を利用して削除可能なアカウントを出力します。
    • 当該関数は使用者から削除する勘定の番号を入力されます。
    • 当該関数は使用者が選択したアカウントのstate情報が'3'ある場合、削除を進めます。
      • 当該関数は、該当アカウント(gAccount[num])の情報を初期化します。
        • state=0
        • fd→state=0
        • memset(gAccount[num]。fd、0、0x80uLL);
      • 当該関数は、該当アカウント(gAccount[num])のfd領域fd領域(heap)を解除します。を解除します。
    • 当該関数はgAccount[num]。fd領域に"gAccount[num]。fd-16"演算した値を保存します。
      • 保存される値はFree chunkのHeadアドレスです。
      • これによってThe House of Lore、UAF脆弱性が発生することになります。

...

  • 当該関数は次のような機能をします。
    • 当該関数はchoiceCandy()関数を使用して注文するキャンディーの番号を入力されます。
    • 当該関数はmalloc()関数を使用して24 byteのheap領域を割り当てられます。関数を使用して24 byteのheap領域を割り当てられます。
      • 当該関数は、該当領域に注文するキャンディーの情報を保存します。

...

  • 当該関数は次のような機能をします。
    • 当該関数はfree()関数を利用してgOrderList関数を利用してgOrderList[a1]領域を解除します。領域を解除します。
Code Block
languagecpp
titlereSort(unsigned int a1)
unsigned __int64 __fastcall reSort(unsigned int a1)
{
  int i; // [rsp+14h] [rbp-Ch]
  unsigned __int64 v3; // [rsp+18h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  free(gOrderList[a1]);
  if ( a1 < gOrderCnt )
  {
    for ( i = 0; a1 + i < gOrderCnt; ++i )
      gOrderList[a1 + i] = gOrderList[a1 + i + 1];
  }
  gOrderList[gOrderCnt--] = 0LL;
  return __readfsqword(0x28u) ^ v3;
}

...

  • 当該関数は次のような機能をします。
    • 当該関数は使用者からキャンディ注文の進めるかどうかを確認します。
    • 当該関数はgetStockNum()関数を使用してgOrderList[]に保存された値がgStock[]に存在するかどうか確認します。
      • 当該関数はgOrderList[]に保存された値gStock[]に存在する場合、次のように処理されます。
        • "gStock[]->candyNumber"に"gOrderList[]→orderNumber"の値を加えることになります。
      • 当該関数はgOrderList[]に保存された値gStock[]に存在しない場合、次のように処理されます。
        • 当該関数はmalloc()関数を使用して24 byteのheap領域を割り当てます。関数を使用して24 byteのheap領域を割り当てます。
        • 当該関数は、該当領域にキャンディに対する情報を保存します。
          • キャンディの名前や価格、キャンディの情報が保存されているアドレス値
          また、当該関数は124 byteのheap領域を割り当てて、当該領域に使用者から入力を受けたキャンデー情報を保存します。
        • また、当該関数は124 byteのheap領域を割り当てて、当該領域に使用者から入力を受けたキャンデー情報を保存します。
    • 当該関数はgOrderList[]に保存された値gStock[]にすべて保存した後、gOrderListにすべて保存した後、gOrderList[]領域を全て解除します。領域を全て解除します。
Code Block
languagecpp
titleorderCandy()
unsigned __int64 orderCandy()
{
  struct STOCK *dest; // ST10_8
  unsigned int i; // [rsp+4h] [rbp-1Ch]
  int num; // [rsp+Ch] [rbp-14h]
  unsigned __int64 v4; // [rsp+18h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  if ( gOrderCnt )
  {
    orderList();
    puts("\nWould you like to order these candies?");
    puts("0) Yes, 1) No");
    if ( !(unsigned int)retNumber(2LL) )
    {
      for ( i = 0; i < gOrderCnt; ++i )
      {
        num = getStockNum(i);
        if ( num )
        {
          gStock[num - 1]->candyNumber += gOrderList[i]->orderNumber;
        }
        else if ( (unsigned int)gStockCnt > 4 )
        {
          puts("The warehouse is full. Your new order can not be completed.");
        }
        else
        {
          puts("\nEnter information about newly added candy.");
          dest = (struct STOCK *)malloc(24uLL);
          strncpy(dest->candyName, gOrderList[i]->orderCandyName, 8uLL);
          dest->candyNumber = gOrderList[i]->orderNumber;
          printf("Enter the price of %s candy.\n", dest);
          dest->candyPrice = retNumber(5LL);
          printf("Enter a description of the %s candy.\n", dest);
          dest->candyDescription = (char *)malloc(124uLL);
          UserInput(dest->candyDescription, 124LL);
          gStock[gStockCnt++] = dest;
        }
      }
      while ( gOrderCnt )
      {
        free(gOrderList[gOrderCnt - 1]);
        gOrderList[gOrderCnt-- - 1] = 0LL;
      }
    }
  }
  else
  {
    puts("You have never ordered a product.");
  }
  return __readfsqword(0x28u) ^ v4;
}

Proof of concept

  • 説明は進行する前に出題者はプレイヤーたちが"House of lore"脆弱性を利用して解決することを望んでいました。
    • しかし、当該脆弱性のほかにもさまざまな形で攻撃が可能です。

Fake chunk

  • 当該番組で脆弱性を理解するため、ACCOUNT構造体に対する理解が必要です。
    • 該当構造体は、除隊変数で宣言されています。
    • 当該番組は3つのACCOUNT構造体を使用します。
      • 最初の構造体には'Admin'のアカウント情報が保存されています。
      • 2、3番目の構造体は使用者が生成したアカウントの情報が保存されます。

...

Panel
titleHeap area structure

AddressStateHeap sizefdbk
Order list[0]

0xa175e0

A0x20

None

None
창고에 저장된 캔디 정보倉庫に保存されたキャンディー・情報

0xa17600

A0x20NoneNone
창고에 저장된 캔디 설명倉庫に保存されたキャンディー・説明

0xa17620

A0x90NoneNone
Order list[1]

0xa176b0

A0x20NoneNone

...

Panel
titleHeap area structure

AddressStateHeap sizefdbk
Order list[0]0xa175e0A0x20NoneNone
倉庫に保存されたキャンディー・&キャンディ説明창고에 저장된 캔디 & 캔디 설명

0xa17600

F0xb0

0x7ff5052a2c18

0x7ff5052a2c18

Order list[1]

0xa176b0

A0x20NoneNone
구매한 캔디 평가購入したキャンディー・評価

0xa176d0

A0x4c0NoneNone
  • 次のような方法でLibc addressを抽出することができます。
    • 攻撃者は1つの飴をOrder listに追加します。
      • Order listに追加されたキャンディの情報は一つの領域(0xb0)に変更領域に割り当てられます。
    • 攻撃者はOrder listの内容を出力してLibc addressを抽出することができます。

...

Panel
titleHeap area structure

AddressStateHeap sizefdbk
Order list[0]0xa175e0A0x20NoneNone
Order list[2]0xa17600

A

0x20NoneNone
창고에 저장된 캔디 & 캔디 설명倉庫に保存されたキャンディー&キャンディ説明(Unsorted bin)

0xa17620

F0x90

0x7ff5052a2c18

0x7ff5052a2c18

Order list[1]

0xa176b0

A0x20NoneNone
구매한 캔디 평가

0xa176d0

A0x4c0NoneNone

...

Panel
titleHeap area structure

AddressStateHeap sizefdbk
창고에 저장된 0번 캔디 정보倉庫に保存された0度キャンデー情報0xa175e0A0x200x0None
Order list[2]0xa17600

F

0x20NoneNone
창고에 저장된 0번 캔디 설명倉庫に保存された0度キャンデー説明

0xa17620

A0x90

0xa17600

None

Order list[1]

0xa176b0

F0x20NoneNone
구매한 캔디 평가購入したキャンディー・評価

0xa176d0

A0x4c0NoneNone
gAccount[1].fd0xA17B90A0x90NoneNone
gAccount[2].fd0xA17c20A0x90NoneNone

...

Panel
titleHeap area structure

AddressStateHeap sizefdbk
창고에 저장된 0번 캔디 정보倉庫に保存された0度キャンデー情報0xa175e0A0x20NoneNone
Order list[2]0xa17600

F

0x200x0None
창고에 저장된 0번 캔디 설명倉庫に保存された0度キャンデー説明

0xa17620

A0x90

None

None

Order list[1]

0xa176b0

F0x200xa17600None
구매한 캔디 평가購入したキャンディー・評価

0xa176d0

A0x4c0NoneNone
gAccount[1].fd(Unsortbin)0xA17B90F0x90

0x7ff5052a2b78

0x7ff5052a2b78
gAccount[2].fd0xA17c20A0x90NoneNone

...

Panel
titleHeap area structure

AddressStateHeap sizefdbk
창고에 저장된 0번 캔디 정보倉庫に保存された0度キャンデー情報0xa175e0A0x20NoneNone
Order list[0]0xa17600

A

0x20NoneNone
창고에 저장된 0번 캔디 설명倉庫に保存された0度キャンデー説明

0xa17620

A0x90

None

None

창고에 저장된 1번 캔디 정보倉庫に保存された1度キャンデー情報

0xa176b0

F0x200x0None
구매한 캔디 평가購入したキャンディー・評価

0xa176d0

A0x4c0NoneNone
창고에 저장된 1번 캔디 설명倉庫に保存された1度キャンデー説明0xA17B90A0x90

None

None
gAccount[2].fd0xA17c20A0x90NoneNone

...

Panel
titleHeap area structure

AddressStateHeap sizefdbk
창고에 저장된 0번 캔디 정보倉庫に保存された0度キャンデー情報0xa175e0A0x20NoneNone
Order list[0]0xa17600

A

0x200x7ff5052a2b880xa176b0
창고에 저장된 0번 캔디 설명倉庫に保存された0度キャンデー説明

0xa17620

A0x90

None

None

창고에 저장된 1번 캔디 정보倉庫に保存された1度キャンデー情報

0xa176b0

F0x200xa176b00x7ff5052a2b88
구매한 캔디 평가購入したキャンディー・評価

0xa176d0

A0x4c0NoneNone
창고에 저장된 1번 캔디 설명倉庫に保存された1度キャンデー説明0xA17B90A0x90

0x7ff5052a2bf8

0x7ff5052a2bf8
gAccount[2].fd0xA17c20A0x90NoneNone
구매한 캔디 평가購入したキャンディー・評価

0xa17cb0

A0x4c0NoneNone
  • 次のように2度アカウントのパスワードの変更を通じて、bk領域の値を引き続き変更できます。
    • bkの領域に最初のFake chunkの開始アドレスを保存しました。

...