我刚刚在我的机器上销毁了libc.so。我现在能做什么?

时间:2014-12-15 17:34:27

标签: libc

当我运行以下命令时,我以root用户身份登录到远程框:

ln -sf /nonexistent /.../libc.so

我的提示立即开始抛出错误:

basename: could not find shared library

我甚至无法运行任何东西:

root@toastbox# ls
ls: could not find shared library

我该如何解决这个问题?我有两个用Bash打开的SSH会话,但没有其他进程可访问。我在本地计算机上有一个针对目标的交叉编译器,但是SCP文件无法再远程到远程端。

编辑:此框中没有其他libc副本;我覆盖了真正的libc文件。有些事情仍然有效:我可以echo,我可以使用制表符来模拟ls。但正常的程序(mvrm等)是MIA。

1 个答案:

答案 0 :(得分:6)

我发现我仍然可以使用echo和重定向来写文件(感谢Iwillnotexist Idonotexist!)。此外,echo -ne允许我将任意字节写入文件。因此,我可以使用echo -ne '' > file截断文件,然后使用

重复写入该文件
echo -ne '\001' >> /file

使用这种方法,我可以用这种方式覆盖系统中存在的任何可执行文件(因为我仍然是root用户)。

我编译了一个简单的程序来重命名文件:

#include <unistd.h>
int main(int argc, char **argv) { return rename(argv[1], argv[2]); }

使用cross-gcc -static mv.c mv(消除libc.so依赖关系)。然后,我编写了一个脚本,将任何二进制文件编码为一系列echo命令(受readline允许我输入的长度限制):

# Encode a file as a series of echo statements.

# settings
maxlen = 1020
infile = '/tmp/mv'
outfile = '/usr/bin/mv'

print "echo -ne '' > %s" % outfile

template = "echo -ne '%%s' >> %s" % outfile
maxchunk = maxlen - len(template % '')
pos = 0
data = open(infile, 'rb').read()

transtable = {}
for i in xrange(256):
    c = chr(i)
    if i == 0:
        transtable[c] = r'\0'
    elif c.isalpha():
        transtable[c] = c
    else:
        transtable[c] = r'\0%o' % i

while pos < len(data):
    chunk = []
    chunklen = 0
    while pos < len(data):
        bit = transtable[data[pos]]
        if chunklen + len(bit) < maxchunk:
            chunk.append(bit)
            chunklen += len(bit)
            pos += 1
        else:
            break
    print template % ''.join(chunk)

我使用echo编码器生成一系列echo命令,并将其大量粘贴到ssh会话中。这些看起来像

echo -ne '' > /usr/bin/mv
echo -ne '\0177ELF\01\01\01\0\0\0\0\0\0\0\0\0\02\0\050\0\01\0\0\0\0360\0200\0\0\064\0\0\0\030Q\05\0\0\0\0\05\064\0\040\0\05\0\050\0\034\0\033\0\01\0\0\0\0\0\0\0\0\0200\0\0\0\0200\0\0P\03\01\0P\03\01\0\05\0\0\0\0\020\0\0\01\0\0\0\0\017\01\0\0\0237\01\0\0\0237\01\0x\02\0\0X\046\0\0\06\0\0\0\0\020\0\0Q\0345td\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\06\0\0\0\0\0\0\0\01\0\0p\0244\0356\0\0\0244n\01\0\0244n\01\0\0350\010\0\0\0350\010\0\0\04\0\0\0\04\0\0\0R\0345td\0\017\01\0\0\0237\01\0\0\0237\01\0\0\01\0\0\0\01\0\0\06\0\0\0\040\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\020\0265\04\034\0\040\0\0360\053\0371\040\034\016\0360r\0375\0134\0300\0237\0345\0H\055\0351X\060\0237\0345\04\0260\0215\0342\020\0320M\0342\014\0300\0217\0340\03\060\0234\0347\024\060\013\0345D\060\0237\0345\04\0\0213\0342\03\060\0234\0347\020\060\013\0345\070\060\0237\0345\0\020\0240\0343\03\060\0234\0347\014\060\013\0345\054\060\0237\0345\03\060\0234\0347\010\060\013\0345\044\060\0237\0345\03\040\0234\0347\024\060K\0342\0223\072\0\0353\04' >> /usr/bin/mv
echo -ne '\0320K\0342\0\0210\0275\0350\0350\036\01\0\0174\0377\0377\0377\0200\0377\0377\0377\0204\0377\0377\0377\0210\0377\0377\0377\0214\0377\0377\0377\0H\055\0351\04\0260\0215\0342\010\0320M\0342\010\0\013\0345\014\020\013\0345\014\060\033\0345\04\060\0203\0342\0\040\0223\0345\014\060\033\0345\010\060\0203\0342\0\060\0223\0345\02\0\0240\0341\03\020\0240\0341\06\0\0\0353\0\060\0240\0341\03\0\0240\0341\04\0320K\0342\0\0210\0275\0350\0\0\0\0\0\0\0\0\0\0\0\0\0220\0\055\0351\046p\0240\0343\0\0\0\0357\0220\0\0275\0350\0\0\0260\0341\036\0377\057Qr\072\0\0352\0\0\0240\0341\020\0265\04\034\0\0360\014\0370\04\0140\01\040\0100B\020\0275\020\0265\03\034\0377\063\02\0333\0100B\0377\0367\0361\0377\020\0275\020\0265\02K\0230G\010\060\020\0275\0300F\0340\017\0377\0377\0360\0265\031N\0203\0260\034\034\0176D\07\034\01\0222\0\0360\0253\0371\045h\0\0340\0230G\04\065\053h\0\053\0372\0321\0345h\0\0340\0230G\04\065\053h\0\053\0372\0321eh\0\0340\0230G\04\065\053h\0\053\0372\0321\075\034\0200\0315y\034\0210\0' >> /usr/bin/mv
...

我测试了替换mv几次以确保它有效(使用Bash tab-completion替代ls),然后使用echo编码器编写了一个将libc.so替换为临时目录。最后,我使用我推送的静态libc.so将替换mv移到了正确的位置。

成功!它可能花了大约一个小时,但我的盒子已经恢复运行,除了一个被破坏的/usr/bin/mv之外没有人员伤亡:)