off-by-one
本题主要是堆上面的off-by-one漏洞利用。off-by-one的成因主要是输入边界考虑不周导致的单字节溢出。一种利用方式是通过修改chunk大小造成结构块之间的重叠,本题就是这种利用方式。
程序分析
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__int64 savedregs; // [rsp+20h] [rbp+0h]
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
welcome();
change_author();
while ( (unsigned int)select() != 6 )
{
switch ( (unsigned int)&savedregs )
{
case 1u:
create();
break;
case 2u:
delete();
break;
case 3u:
edit();
break;
case 4u:
print();
break;
case 5u:
change_author();
break;
default:
puts("Wrong option");
break;
}
}
puts("Thanks to use our library software");
return 0LL;
}
pwn题的逆向分析通常难度不大,关键是还原数据结构以及漏洞点的寻找。
很容易还原book的结构
book struc ; (sizeof=0x20, mappedto_6)
00000000 ID dq ?
00000008 name dq ?
00000010 description dq ?
00000018 size dq ?
00000020 book ends
在偏移0x9F5处的字符串输入函数存在off-by-one漏洞,由于边界考虑不周,导致\x00的单字节溢出,即该函数输入的字符串长度实际上比参数中指定的大小多1字节\x00。
signed __int64 __fastcall MyGets(char *chr, int length)
{
int i; // [rsp+14h] [rbp-Ch]
char *buf; // [rsp+18h] [rbp-8h]
if ( length <= 0 )
return 0LL;
buf = chr;
for ( i = 0; ; ++i )
{
if ( (unsigned int)read(0, buf, 1uLL) != 1 )
return