【发布时间】:2020-10-26 23:03:43
【问题描述】:
我是软件安全的新手,现在正在大学学习它。我对格式字符串漏洞利用有一些疑问,特别是如何计算格式字符串漏洞利用的长度(以字节数为单位)。
假设我有以下易受攻击的代码:
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);),因此存在格式字符串漏洞。
我想用包含我的 shellcode 的环境变量的地址覆盖 EIP。
我假设(这是一个理论练习,我知道在实践中还有许多其他含义)我的环境变量的地址是 0x44674234,EIP 的地址是 0x42414515,并且我的格式字符串堆栈上的位移是 7。
所以我的格式字符串漏洞将是\x15\x45\x41\x42\x17\x45\x41\x42%16940c%7$hn%563c%8$hn,我将其放入user,然后将其复制到s.usr并由printf (s.usr);执行
现在我注意到只有 15 个字符从 user 复制到 s.usr。
我的格式字符串不能被利用吗?我在我的漏洞利用中计算了 30 个字符,因此 strcpy 只会复制我的漏洞利用的一半。
我计算的字符数是否正确?我应该如何计算它们?
【问题讨论】:
-
你的问题是为什么
snprintf (s.usr, 16, ...)只将16 个字节复制到s.usr中? (实际上它只复制了 15 个,因为它为 NUL 节省了空间。) -
我喜欢这篇文章的一切,你的努力,你的问题陈述的精确性等等。但是把行号放进去会让别人把你的代码粘贴到他们的编译器中变得比需要的更难并运行它。您可以标记第 26 行,例如用注释标记它。 +1
-
@ikegami 不,我的问题是:1) 我还能“执行”我的格式字符串漏洞利用吗?因为在 s.usr 中只复制了 15 个字符/字节。 2) 我对格式字符串漏洞利用长度的计算是否正确?是不是我想的 30 个字节/字符长?
-
Re "我的问题是:1) 我还能“执行”我的格式字符串漏洞利用吗?”,显然不能。如果你需要 30 个字节,而你有 15 个字节,那就行不通了。 /// 但是如果你问是否可以通过其他方式利用它,那么我不知道。 15 个字节的长度是否足以跳转到较大的
user中的某个位置? -
Re "2) 我对格式字符串漏洞利用长度的计算是否正确?",长度为 30 个字符/字节。你需要
snprintf (s.usr, 31, "%s", user);来复制它。
标签: c security string-formatting exploit format-string