【问题标题】:A same suid + system program, different outputs on different systems同一个suid+系统程序,不同系统输出不同
【发布时间】:2020-02-17 18:59:46
【问题描述】:

我写了一个名为suid.c的简单程序:

int main(int argc, char* argv[]) {
        system(argv[1]);
}

用 gcc 编译,然后设置 suid 权限(现在是 root 用户):

# gcc suid.c -o suid
# chmod +s suid

我尝试在不同的虚拟机上使用 www-data 用户运行./suid id,但输出不同。

  • kali 2019 中的输出:id=33(www-data) gid=33(www-data) groups=33(www-data)
  • ubuntu trusty(旧的 linux)中的输出:uid=33(www-data) gid=33(www-data) euid=0(root) egid=0(root) groups=0(root),33(www-data)

这是为什么呢? Linux 有什么变化吗?

【问题讨论】:

  • 这可能与不同shell的删除SUID权限的差异有关。
  • man id 在 Kali 上说了什么?它是否说它输出有效的用户和组ID?运行id 说明了什么?
  • 请勿发布代码、数据、错误消息等的图片 - 将文本复制或输入到问题中。 How to Ask
  • @Rob 抱歉,我会尽快更新。

标签: c linux suid


【解决方案1】:

这取决于您的发行版中 /bin/sh 是 bash 还是 dash。重击always drops setuid/setgid privileges unless invoked with the option -p。 Dash 没有对特权做任何特别的事情。

在 Ubuntu 上,system 函数调用sh,即/bin/sh,即破折号,不会放弃权限。在 Kali 上,system 函数调用 sh,即/bin/sh,即 bash,它会丢弃特权。发行版安装为sh 是一个问题,而不是发行版的新近程度。

Bash 的行为可能是一种安全对策,但它不是一种非常有效的对策。这是防止错误配置或编写错误的程序的第二道防线,这些程序以不应具有的权限运行,并允许对 system 等函数进行不受信任的输入。但是,此类程序通常还有其他漏洞,允许潜在的攻击者无论如何都可以进行攻击,例如写入文件的能力。

【讨论】:

    【解决方案2】:

    如上面评论中所述,您会看到 system() 故意删除 setuid 的效果(间接通过 bash)。

    system(3) 我的 Amazon Linux 实例笔记:

    不要在具有 set-user-ID 或 set-group-ID 权限的程序中使用 system(),因为某些环境变量的奇怪值可能 用于破坏系统完整性。请改用 exec(3) 系列函数,但不要使用 execlp(3) 或 execvp(3)。 system() 不会,在 事实上,在 /bin/sh 是 bash 版本 2 的系统上,具有 set-user-ID 或 set-group-ID 权限的程序可以正常工作,因为 bash 2 在启动时删除权限。 (Debian 使用修改后的 bash,当作为 sh 调用时不会这样做。)

    从 setuid 程序运行 system()超级危险,因为它比你想象的更容易颠覆你的意图(劫持 $IFS 将是一个很好的起点)。

    使用其中一个 exec 函数至少可以让 shell 不碍事,但通常还会有另一个 shell。

    如果你绝对必须这样做,你可以在system() 之前调用setuid(geteuid());,这基本上抛弃了你处于setuid 环境中的事实——真实用户和有效用户不同——通过说both 都是提升的用户。组也是如此。这可能是个糟糕的主意。

    我可能会建议,如果您必须询问 SO 如何执行 setuid,您可能不是安全执行此操作的最佳位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-05
      • 2014-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多