C语言 格式化字符串漏洞利用长度



我是软件安全的新手,现在在大学里学习。我对格式字符串漏洞有一些疑问,特别是如何计算格式字符串漏洞的长度(以字节数为单位(。

假设我有以下易受攻击的代码:

int guess(char *user) {
struct {
int n;
char usr[16];
char buf[16];
} s;
snprintf (s.usr, 16, "%s", user);
do {
scanf ("%s", s.buf);
if ( strncmp (s.buf, "DEBUG", 5) == 0) {
scanf ("%d", &s.n);
for ( int i = 0; i < s.n; i++) {
printf ("%x", s.buf[i]);
}
} else {
if ( strncmp (s.buf, "pass", 4) == 0 && s.usr[0] == '_') {
return 1;
} else {
printf ("Sorry User: ");
printf (s.usr); //#line 26 vulnerable line
printf ("nThe secret is wrong! n");
abort ();
}
}
} while ( strncmp (s.buf, "DEBUG", 5) == 0);
}
int main(int argc, char** argv) {
guess(argv[1]);
}

并且代码是在具有 cdecl 调用约定的 IA-32 架构(32 位(中编译的,并且没有实施攻击缓解(没有堆栈金丝雀、没有 ALSR 等......,我在一个完全易受攻击的机器中(

在第 26 行存在一个格式字符串漏洞,因为缺少占位符 (printf (s.usr);(。

我想用包含我的外壳代码的环境变量的地址覆盖 EIP。

我假设(这是一个理论练习,我知道在实践中还有许多其他含义(我的环境变量的地址是0x44674234,EIP 的地址是0x42414515我的格式字符串堆栈上的位移是 7。

所以我的格式字符串漏洞将被x15x45x41x42x17x45x41x42%16940c%7$hn%563c%8$hn,我会把它放到user中,然后它会被复制到s.usr中并由printf (s.usr);执行

现在我注意到的是,只有 15 个字符从user复制到s.usr中。

我的格式字符串不可利用吗?我在漏洞利用中数了 30 个字符,因此 strcpy 只会复制我漏洞利用的一半。

我计算的字符数是否正确?我应该如何计算它们?

x15x45x41x42x17x45x41x42%16940c%7$hn%563c%8$hn确实引用了 30 个字符/字节的序列。 因此,需要snprintf (s.usr, 31, "%s", user);来复制它。[1]额外的计数是因为snprintf为 NUL 保留了一个空间。

由于您需要s.usr成为 30 个字符序列的开头,并且您只能在此处放置 15 个必要的字符,因此您的漏洞利用无法按原样工作。

这并不意味着该错误不能被利用。可以编写一个较短的漏洞利用,跳转到位于其他地方的剩余漏洞,例如在user[2]但我没有必要的知识来评估它的可行性。


  1. 当然,至少在正常情况下,您还需要更大的s.usr面积。
  2. user将包含<15-byte exploit><remainder of exploit>.15 字节漏洞将跳转到漏洞利用的其余部分。

相关内容

  • 没有找到相关文章

最新更新