了解 getlogin()

了解 getlogin()

我觉得上一次迭代这个问题有点像地毯式炸弹问题,所以这可能会让人们对它失去兴趣(以至于几乎被标记为删除),所以我将开始一个新的问题,希望人们能有一个更轻松的时间和。

基本上,我的整体兴趣在于理解logname以及getlogin()与审计跟踪相关的内容。它是这样分解的:

1)我的理解是,logname两者getlogin()都显示auid将/将最终显示在会话的审核日志中。那是对的吗?我知道auid是一个不可变的过程属性,但我有兴趣知道两者是否必然相同或通常相同。这将帮助我编写脚本/帮助程序,这些脚本/帮助程序可以根据用户的原始身份做出访问控制决策,而不仅仅是他们当时的身份或可变的环境变量。

2)我还是不明白如何开发CVE 2003-0388被展示应该是有效的。如果有人可以向我解释这一点,那就太好了。

不过,我的主要兴趣是第一点。

答案1

getlogin()并且logname(仅调用getlogin())通过查找当前 ttyutmp并报告在该utmp记录中找到的登录名来获取登录用户名。他们这样做的原因是,它们被设计为在多个用户名可能映射到相同 uid 的系统上工作(这种做法通常令人不悦,但有时用于创建多个 root 帐户或启动自定义 shell 的不同登录名,但都映射到相同的底层 uid)。当与此类帐户一起使用时,getpwuid(getuid())只会报告 passwd 数据库中的第一个匹配项,而getlogin()会找到实际用于登录的帐户。

但是,由于该函数依赖于可写文件的内容,因此不值得与getpwuid(getuid()).确实,只有特权进程才应该能够写入utmp,但是有一些“额外”程序通常被配置为能够写入它(通常通过 setgid- utmp),例如 GNU screen ,您可能不想信任这些程序。我知道,历史上我曾经管理的一些 SysV 系统utmp很容易偶尔被损坏。

答案2

正如 @Celada 指出的,logname和都getlogin()依赖于/var/run/utmp,这使它们处于中等可信度(它是一个常规文件,而不是重新启动时必然重新生成的文件,与内核结构不同,因此如果它们可以从CD什么的,然后又是什么不能如果他们这样做了,他们就会妥协吗?)。不过,希望就在眼前。到目前为止,我一直有意忽略/proc/$$/loginuid这一点,因为它由调用用户拥有,并且为所有者设置了可写位,所以我认为这主要只是一种便利,而不是安全机制。看来这个假设是不正确的。这是描述性文字一个内核补丁2011年底提交:

目前,如果任务具有 CAP_AUDIT_CONTROL,我们允许任务设置其 loginuid。实际上,我们希望任务在登录时设置 loginuid,并且不可能重置。即使在设置后(使用 CAP),我们也必须使其可变,因为更新时和管理员可能必须重新启动 sshd。现在 sshd 将获取他的 LoginUID,而下一个使用 ssh 登录的用户将无法设置他的 LoginUID。

Systemd 改变了用户空间的工作方式,并允许我们让内核按其应有的方式工作。使用 systemd 用户(甚至管理员)不应该直接重新启动服务。系统将为他们重新启动服务。因此,由于systemd将loginuid==-1,sshd将得到-1,并且sshd将被允许设置新的loginuid而无需特殊权限。

如果该系统中的管理员要手动启动 sshd,他会将自己插入到系统信任链中,因此从逻辑上讲,应该使用他的登录用户名!

那么它是否被用户列为可写?是的。用户真的可以改变它吗?仅当他们是 root 或具有 CAP_AUDIT_CONTROL 时(可能不是很多人)。我能找到的最安全的解决方案是实际从/proc/$$/loginuid(如果编写 shell 脚本或在命令行上)或audit_getloginuid()程序中提取它。

相关内容