V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
rrfeng
V2EX  ›  问与答

前几天遇到的一个状况,给大家探讨一下: Linux 下普通用户使用 sudo 删掉了 libc.so,如何恢复?

  •  
  •   rrfeng · 2017-12-28 18:18:15 +08:00 · 3600 次点击
    这是一个创建于 2507 天前的主题,其中的信息可能已经有所发展或是发生改变。
    问题已经解决了,就想看看大家能想到什么办法。
    34 条回复    2017-12-28 20:53:21 +08:00
    xmadi
        1
    xmadi  
       2017-12-28 18:19:56 +08:00 via iPhone
    从其他电脑或者启动个 livecd 然后复制一个就好了 标准库反正都一样
    Kirscheis
        2
    Kirscheis  
       2017-12-28 18:34:28 +08:00
    另起一个系统复制一个进去

    或者如果内存里还有没挂掉的能写东西的进程,就塞一个静态编译好的 busybox 之类的工具覆盖掉一个有执行权限的文件,然后用 busybox 复制一个
    ironx
        3
    ironx  
       2017-12-28 18:37:04 +08:00 via Android
    下载一个就可以了
    geelaw
        4
    geelaw  
       2017-12-28 18:38:58 +08:00 via iPhone
    Windows 的系统文件都是有多个名字的(硬链接),而且也会自动恢复它们…… Linux 或许没有自动恢复的功能,但总该是可以从另一个名字恢复的吧😅
    prolic
        5
    prolic  
       2017-12-28 18:40:24 +08:00
    LD_PRELOAD=
    rrfeng
        6
    rrfeng  
    OP
       2017-12-28 18:48:22 +08:00
    @xmadi
    @Kirscheis
    @ironx
    @geelaw
    非 root 用户并不能在它原来的位置写入文件(没有权限),所以有合适的文件,问题是怎么放进去。

    @prolic
    感觉比上面几位都厉害一点。如果没有这个,基本上所有命令都无法执行了,包括 ls copy mv ...
    但是 LD_PRELOAD 不会对特权相关的程序生效,例如 su / sudo
    Kirscheis
        7
    Kirscheis  
       2017-12-28 18:52:11 +08:00
    @rrfeng 另起一个系统之后,根本就不需要原本系统的权限啊
    geelaw
        8
    geelaw  
       2017-12-28 18:57:21 +08:00 via iPhone
    @rrfeng 不太懂,能 sudo 的普通用户是知道 root 的密码的,而且 sudo 似乎有一段的时间是可以免去再次验证的。
    msg7086
        9
    msg7086  
       2017-12-28 18:58:02 +08:00
    不是厉害不厉害,是你没有把题目限定成不能新启一个系统。
    LD_PRELOAD 不能过特权是安全原因,否则人人都能篡改系统调用了。
    提权依赖 sticky bit,至于系统里有哪个程序既有 sticky 又不依赖 glibc 我就不知道了。
    msg7086
        10
    msg7086  
       2017-12-28 18:58:43 +08:00
    @geelaw sudo 用户不知道 root 密码。
    ironx
        11
    ironx  
       2017-12-28 19:03:46 +08:00 via Android
    @rrfeng 要不然进去恢复模式,挂载 u 盘,拷贝个文件
    turnrut
        12
    turnrut  
       2017-12-28 19:07:40 +08:00 via Android
    @msg7086 不知道 root 密码可以 sudo su
    msg7086
        13
    msg7086  
       2017-12-28 19:11:21 +08:00
    @turnrut 这不是我想说的。
    rrfeng
        14
    rrfeng  
    OP
       2017-12-28 19:30:35 +08:00 via Android
    @geelaw
    简单来说删掉 libc 之后 sudo 就运行不了了。


    @ironx
    你觉得恢复模式能起来吗?


    @Kirscheis
    哦原来是另起一个系统去写原系统文件,开始理解错了。这个肯定没问题。


    @msg7086
    确实这样
    geelaw
        15
    geelaw  
       2017-12-28 19:48:25 +08:00
    @msg7086 如果不知道密码又是如何 sudo 的?即使是别人代为输入,发现删除错误之后还不立刻让旁边那人再来一次?

    @rrfeng 这个理由倒是不错
    msg7086
        16
    msg7086  
       2017-12-28 19:52:28 +08:00
    @geelaw 还请你先了解一下 sudo 的工作机制。
    sudo 这个工具制作以会被制造出来,就是为了杜绝把 root 密码交给用户。
    blless
        17
    blless  
       2017-12-28 19:54:38 +08:00
    好像记得可以用恢复模式 操作 不过安装时候要是加密了分区好像就没办法了
    geelaw
        18
    geelaw  
       2017-12-28 20:00:56 +08:00
    @msg7086 所以有“别人代为输入”。
    wdlth
        19
    wdlth  
       2017-12-28 20:06:37 +08:00 via Android
    sudo 不是看 sudoers 设置么?和 root 密码有什么关系?
    msg7086
        20
    msg7086  
       2017-12-28 20:08:40 +08:00
    @geelaw 你到底在说什么?
    sudo 从来是验证账号本人的密码,你上面那句「能 sudo 的普通用户是知道 root 的密码的」是哪出来的?

    更不说一旦 libc 删除以后 sudo 就无法运行了,你再输一次密码,输给谁?
    ironx
        21
    ironx  
       2017-12-28 20:11:56 +08:00 via Android
    @rrfeng 当然可以,不然怎么能叫恢复模式
    geelaw
        22
    geelaw  
       2017-12-28 20:15:09 +08:00
    @msg7086 展开来说:

    - 如果按照 UAC (管理员确认模式)的思路用 sudo,那么用户是知道 root 的密码的。
    - 如果是 run as different user 的模式用,那么用户旁边有一个知道 root 密码的人,发现出错的时候(我并不知道此时 sudo 用不了了,如果造成的错误不会无效化 sudo 的运行),那么这个人可以请旁边的人再输入一次密码。

    应该把“能 sudo 的普通用户”理解为让 sudo 改变用户成功那一刻的电脑使用对象,它可以是一个人(第一种情况)或者几个人(第二种情况)。同时提到另一个我们正在讨论的话题的话,这就像是“攻击者”并不需要是一个具体的人,可以是一段单机程序,或者一个黑客组织,或者一个分布式网络。
    msg7086
        23
    msg7086  
       2017-12-28 20:20:33 +08:00
    @rrfeng 补充一下 @ironx 的回答。
    恢复模式下是由内核 initrd 直接转交给 init = busybox 启动的,因为 busybox 不依赖任何其他组件,所以可以独立工作,比如 mount 或者 cp mv。
    msg7086
        24
    msg7086  
       2017-12-28 20:25:34 +08:00
    @geelaw 相反,很多现代化发行版的 root 甚至是没有密码的,所以你可能连「知道 root 密码」这件事都做不到。
    (比如典型安装的 Ubuntu 就没有 root 密码。)
    另外,如我所说,sudo 是验证「本人」密码。哪怕你知道 root 密码,也不可能在普通用户账号上通过 sudo 提权,只有知道当前账号密码的人才能过 sudo 验证。

    最后,删掉系统库以后,整个系统所有依赖 C 运行时的程序都无法运行,不仅仅是 sudo,几乎所有的程序都是无法启动的。
    a1044634486
        25
    a1044634486  
       2017-12-28 20:25:51 +08:00
    @geelaw 你是来搞笑的吗?
    sudo 输入的不是当前用户的密码???
    a1044634486
        26
    a1044634486  
       2017-12-28 20:26:38 +08:00
    上面少打一个吗
    sudo 输入的不是当前用户的密码吗?
    Kirscheis
        27
    Kirscheis  
       2017-12-28 20:29:12 +08:00
    这楼感觉要歪了,我解释一下吧

    1. 如果你能接触到物理机,只要你没有开磁盘加密,最简单的方法就是直接用另一个系统挂载原来的磁盘,这时候原本的权限已经无效了。

    2. 我给的第二个方法是假设你接触不到物理机,rsync, cp, wget 这些都失效的情况下,怎样可以在机器上弄出一个 glibc。因为这种事故下不见得一定要先去搞环境。先把 libc.so 放在自己的目录下,用这个 glibc 把数据先救出来转移到备机,然后再恢复环境。

    3. 因为我假设你已经把 glibc 删干净了,所以我没说 LD_PRELOAD。如果你系统里甚至还有 libc.so 的副本,那这根本就不算什么问题。。

    4. 我提了一下 busybox,因为它可以静态编译,所以不受没有 glibc 的影响。这种情况下,一般要先想办法稳定环境,所以要先开一个不依赖 glibc 的备用接入点,以免在修复中途因为网络之类的问题导致唯一剩下的接入点坏掉。另外,busybox 可以加入 /dev, /etc 和 kernel 做成一个新的系统,用来恢复原本的系统。
    gam2046
        28
    gam2046  
       2017-12-28 20:31:07 +08:00
    @geelaw sudo 并不需要知道 root 密码。实际上你可以试试。sudo 验证的是当前用户的密码,即执行 sudo 命令的用户密码。

    $ sudo su
    # passwd // 重置 root 密码
    # exit
    $ sudo // 此时要求你输入的并不是 rootd 的密码
    geelaw
        29
    geelaw  
       2017-12-28 20:37:44 +08:00   ❤️ 1
    @msg7086 #24
    @a1044634486 #25

    我应该换一种说法,请把 sudoers 和 root 理解为 Windows 下的 Administrators 组,并假设我用这些词儿的时候意思都是“具有控制电脑权限的人”。(*nix 用户和非 *nix 用户果然还是很难交流)

    问题:一个用户是 sudoer,它和 root 有什么区别?
    (问这个问题是因为在 Windows 上内置管理员和其他管理员没有什么区别:惟一的区别是是否有一个特殊设置可以免除 UAC 确认,但是这个功能没有安全意义——一个用户可以以高权限令牌启动 PowerShell,此后便不再需要 UAC )
    rrfeng
        30
    rrfeng  
    OP
       2017-12-28 20:39:49 +08:00   ❤️ 1
    @geelaw
    sudo 就是 linux 下的一个指令。还是不要搞混了的好。
    geelaw
        31
    geelaw  
       2017-12-28 20:44:01 +08:00
    @geelaw #29
    @rrfeng #30

    Ah I see,Wikipedia 告诉我 sudo 允许的权限是 root 的权限的子集。能删除但不能修改和创建似乎也不是没有道理的设置。但无论如何,既然 sudo 已经无法运行,那就当我没说即可。
    rrfeng
        32
    rrfeng  
    OP
       2017-12-28 20:45:08 +08:00
    @Kirscheis
    @msg7086

    确实对于 busybox 不熟悉,所以只需要下载一个 busybox (通过 LD_PRELOAD 之类的办法),然后重启并引导到 busybox 启动。
    赞。
    msg7086
        33
    msg7086  
       2017-12-28 20:49:37 +08:00
    @geelaw 不是很难交流,而是混淆了一些基本概念。
    Windows 上也是类似的,唯有一点不同的是你用户本身就是特权组身份,提权不会切换身份,只会切换权限旗标。
    而 Linux 下 root 仅有 ID=0 账号,特权组提权是通过切换身份完成的。

    Windows 上 UAC 提权是输入自己账号的密码,相当于 Linux 下的 sudo。
    Windows 上普通权限用户提权是输入特权账号和密码,相当于 Linux 下的 su。

    问题:一个用户是 sudoer,它和 root 有什么区别?
    完全不同,而且没有任何相同点。
    一个 sudoer 和 root 的关系是完全依靠 sudo 程序来提权的,没有了 sudo (比如,没有安装 sudo 软件的话),sudoer 和 root 便没有任何关系。
    你完全可以自己花几分钟写一个脚本,根据用户的年龄、生日、体重、身高、天气等等,来决定谁能够提权成为 root,而不是是否为 sudoers。
    msg7086
        34
    msg7086  
       2017-12-28 20:53:21 +08:00
    @rrfeng 很多系统都预装了 busybox。毕竟万一文件系统出错,内核异常,各种不可预见的错误发生时,busybox 是最后一道防线,很少会有系统不自带 busybox。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   936 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:34 · PVG 04:34 · LAX 12:34 · JFK 15:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.