sprintf的栈溢出会比较难利用,因为&s比较大,有0x800,而v6是从&ptr里面strtok出来的,而&ptr更小,只有0x400。所以应该没法很好的利用。
0x04 操控垃圾数据
那么,我们怎么去操控&ptr中的垃圾数据呢?这个时候看看另外一个函数
int upload_book()
{
char *v1; // eax
int v2; // eax
char buf[1024]; // [esp+Ch] [ebp-42Ch]
char s[20]; // [esp+40Ch] [ebp-2Ch]
FILE *stream; // [esp+420h] [ebp-18h]
char *dest; // [esp+424h] [ebp-14h]
size_t v7; // [esp+428h] [ebp-10h]
int v8; // [esp+42Ch] [ebp-Ch]
if ( book_counter > 10 )
return send("too many booksn");
send("Book filename: ");
v8 = __isoc99_scanf("%20s", s);
if ( v8 != 1 )
return send("Wrong title formatn");
v7 = strlen(s);
if ( strcmp(&s[v7 - 3], ".bk") )
return send("The name needs to end with '.bk'n");
send("e-book contents: n");
read(0, buf, 0x400u);
if ( *(_DWORD *)buf != 'BBBB' )
return send("Not an e-booknaborting...n");
v1 = (char *)malloc(0x18u);
dest = v1;
*(_DWORD *)v1 = 0x2F62696C;
v1[4] = 0;
strcat(dest, s);
stream = fopen(dest, "w");
if ( !stream )
return send("Bad book filenamen");
v2 = book_counter++;
books[v2] = dest;
fwrite(buf, 1u, 0x400u, stream);
return fclose(stream);
}
其中,这在栈中也会分配0x400个字节,并且我们可以写入。
并且,调用完这个函数之后,清除栈空间时,只是简单地add esp,xxx,并不会清空其中数据。然后,再调用存在命令行注入的函数并分配栈空间时,也只是单纯地sub esp,xxx,也不会清空数据。在C语言中,如果此时对不赋值的局部变量直接访问的话,是UB行为。但是,从二进制安全的角度看的话,便是可利用的点了。其中这道题,本身就是一个局部字符串读取后未截断而造成的UB,然而我们便可以利用这个。
那么来试试:

很明显,BBBB123456789123456789123456789123456789AAAA的后面89123456789AAAA被拼接到du -sh lib/'%s'中了
动态调试看一下的话
第一次在system停下

第二次在system停下










