【问题标题】:Format string exploit length格式化字符串漏洞利用长度
【发布时间】: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


【解决方案1】:

\x15\x45\x41\x42\x17\x45\x41\x42%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 将包含 &lt;15-byte exploit&gt;&lt;remainder of exploit&gt;。 15 字节的漏洞利用会跳转到漏洞利用的其余部分。

【讨论】:

    猜你喜欢
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多