PWN dragon echo1 echo2 [pwnable.kr]CTF writeup題解系列16

由於pwnable.kr說明了不要將題解的利用腳本直接提出來,所以我就簡單說下思路,本篇包括三個題目


目錄

0x01 dragon

0x02 echo1

0x03 echo2


0x01 dragon

執行步驟

整數溢出漏洞:pDragon->HP 的類型是 signed byte,所以當超過127,就是負數了。這就是整數溢出漏洞

uaf漏洞:
1. malloc person
2. malloc dragon
3. free dragon
4. malloc pInput=dragon
((void (__cdecl *)(dragon *))pDragon->f_printinfo)(pDragon); = ((void (__cdecl *)(dragon *))pInput->f_printinfo)(pInput);

ida struct

00000000 person          struc ; (sizeof=0x10, mappedto_5)
00000000 type            dd ?
00000004 HP              dd ?
00000008 MP              dd ?
0000000C f_printinfo     dd ?                    ; offset
00000010 person          ends
00000010
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 dragon          struc ; (sizeof=0x10, mappedto_6)
00000000 f_printinfo     dd ?                    ; offset
00000004 type            dd ?
00000008 HP              db ? //signed byte
00000009 LifeRegeneration db ?
0000000A                 db ? ; undefined
0000000B                 db ? ; undefined
0000000C Damage          dd ?
00000010 dragon          ends

 FightDragon函數

void __cdecl FightDragon(int nPersonType)
{
  char nCount; // al
  int nWin; // [esp+10h] [ebp-18h]
  person *pPerson; // [esp+14h] [ebp-14h]
  dragon *pDragon; // [esp+18h] [ebp-10h]
  void *pInput; // [ebp-Ch]

  pPerson = (person *)malloc(0x10u);
  pDragon = (dragon *)malloc(0x10u);
  nCount = Count++;
  if ( nCount & 1 )
  {
    pDragon->type = 1;
    pDragon->HP = 80;
    pDragon->LifeRegeneration = 4;
    pDragon->Damage = 10;
    pDragon->f_printinfo = (char *)PrintMonsterInfo;
    puts("Mama Dragon Has Appeared!");
  }
  else
  {
    pDragon->type = 0;
    pDragon->HP = 50;
    pDragon->LifeRegeneration = 5;
    pDragon->Damage = 30;
    pDragon->f_printinfo = (char *)PrintMonsterInfo;
    puts("Baby Dragon Has Appeared!");
  }
  if ( nPersonType == 1 )
  {
    pPerson->type = 1;
    pPerson->HP = 42;
    pPerson->MP = 50;
    pPerson->f_printinfo = (char *)PrintPlayerInfo;
    nWin = PriestAttack(pPerson, pDragon);
  }
  else
  {
    if ( nPersonType != 2 )
      return;
    pPerson->type = 2;
    pPerson->HP = 50;
    pPerson->MP = 0;
    pPerson->f_printinfo = (char *)PrintPlayerInfo;
    nWin = KnightAttack(pPerson, pDragon);
  }
  if ( nWin )
  {
    puts("Well Done Hero! You Killed The Dragon!");
    puts("The World Will Remember You As:");
    pInput = malloc(0x10u);
    __isoc99_scanf("%16s", pInput);
    puts("And The Dragon You Have Defeated Was Called:");
    ((void (__cdecl *)(dragon *))pDragon->f_printinfo)(pDragon);
  }
  else
  {
    puts("\nYou Have Been Defeated!");
  }
  free(pPerson);
}

0x02 echo1

漏洞利用函數: 

__int64 echo1()
{
  char s; // [rsp+0h] [rbp-20h]

  ((void (__fastcall *)(object *))o->f_func1)(o);
  get_input(&s, 128);
  puts(&s);
  ((void (__fastcall *)(object *, signed __int64))o->f_func2)(o, 128LL);
  return 0LL;
}


get_input 可以做棧溢出
64位
root@mypwn:/ctf/work/pwnable.kr# checksec echo1 
[*] '/ctf/work/pwnable.kr/echo1'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments

1、可以直接在棧中上傳shellcode
2、或者泄漏got表函數地址,然後根據got表地址查找libc的system、binsh,再繼續溢出執行system

0x03 echo2

漏洞利用函數: 

__int64 echo2()
{
  char format; // [rsp+0h] [rbp-20h]

  (*((void (__fastcall **)(void *))o + 3))(o);
  get_input(&format, 0x20LL);
  printf(&format);
  (*((void (__fastcall **)(void *))o + 4))(o);
  return 0LL;
}

printf(&format);
這裏有格式化字符串漏洞
可以泄漏got表,然後根據got表地址查找libc的system、binsh,再繼續溢出執行system

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章