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