原文:http://blog.jobbole.com/70971/

以 root 用户执行 rm –rf / 命令,然后观察下哪些文件或者指令会幸存下来。结果是什么也没少!因此你必须增加 —no-preserce-root 再试一遍:

1
# rm -rf --no-preserve-root /

当你按下 Enter 时,一些重要的工具,比如

 
1
2
3
4
5
6
7
/bin/ls
 
/bin/cat
 
/bin/chmod
 
/usr/bin/file

将会应声消失!但是你当前的 SSH 连接以及 bash 终端都还在,这表明所有 bash 相关的内建指令都没有受影响,比如 echo。

成为 Bash 达人

 
1
2
3
root@rmrf:/# ls
 
-bash: /bin/ls: No such file or directory

执行以上命令,发现已没有 ls 可用,但是 echo 和 fileglobs 还在。利用这些“幸存者”们,我们可以做点什么呢?

1
2
3
4
5
6
7
root@rmrf:/# echo *
 
dev proc run sys
 
# echo /dev/pts/*
 
/dev/pts/0 /dev/pts/3 /dev/pts/ptmx

注意!/dev,/proc,/run,/sys还在,我们一定要保存好它们。如果有了ls指令,那么对目录下内容的读取操作将会更加简单。

1
2
3
4
5
6
7
root@rmrf:/# for ii in /dev/pts/*; do echo $ii; done
 
/dev/pts/0
 
/dev/pts/3
 
/dev/pts/ptmx

许多 Reddit 用户指出,printf 仍是可用的。CAMH 说:printf 会将参数依次格式化到输出字符串中去。

1
root@rmrf:/# ls() { printf '%s\n' ${1:+${1%/}/}*; }

既然在bash下可以定义函数,那么我们可以自建一个ls工具,虽然功能还不是很完善。

1
root@rmrf:/# ls() { printf '%s\n' ${1:+${1%/}/}*; }

 
1
-bash: syntax error near unexpected token `('

不对啊,这种操作应该完全合法才对,难道 ls 已经被映射,或者它是其他命令的别名?

1
2
3
root@rmrf:/# type ls</code>
 
ls is aliased to `ls --color=auto'</code>

原来如此,我们上面的指令被扩展成了 ls--color=auto () { printf '%s\n' ${1:+${1%/}/}*; }。那么,我们可以先使用unalias 指令,去掉 ls 与 ls—color 的关联。

1
root@rmrf:/# ls () { for ii in $1/*; do echo $ii; done }

1
2
3
4
5
6
7
8
9
root@rmrf:/# ls
 
/dev
 
/proc
 
/run
 
/sys

 
1
2
3
root@rmrf:/# ls /dev
 
/dev/pts

把函数存储到 utils.sh 文件

1
root@rmrf:/# echo 'ls () { for ii in $1/*; do echo $ii; done }' >> utils.sh

1
root@rmrf:/# source utils.sh

cat 命令怎么样实现呢?借助 read!read 是幸存者之一,使用 read 结合管道和重定向,一个基本的 cat 就基本成型了!

 
1
2
3
root@rmrf:/# (while read line; do echo "$line"; done) < utils.sh
 
ls () { for ii in $1/*; do echo $ii; done }

结合上述通过“幸存者”逐渐恢复一些指令的方法,以及 echo 可以写入任意多字节的特性,我们可以重新构建出 linux 的工具系统,并可以通过 curl 或者 wget 直接获得我们想要的二进制文件。首先,参照 echoed by others,获取 busybox。Busybox 是嵌入式 Linux 的瑞士军刀,内嵌 wget、dd、tar等许多工具。Eusebeîa 详细介绍了如何获得一个 busybox 的 escaped 版本,我在这里就不多做赘述了。

但是,还有一个问题。

即使我们 echo 了整个二进制文件需要的所有字节,这些二进制文件仍无法执行。没法启动 busybox!针对这个问题,早期的解决方法是找到一些可执行的程序,然后用 echo 覆盖它们。我们对 /usr 和 /bin 下的文件进行了诸如此类的改造,但这确实稍显复杂。

可以利用 shell 通配符和 bash 筛选出带有可执行位组的文件,记住要把目录排除在外。

 
1
executable () { if [[ ( ! -d $1 ) && -x $1 ]] ; then echo "$1"; fi }

找到了可执行文件!

 
1
root@rmrf:/# for ii in /*; do executable $ii; done

 
1
root@rmrf:/# for ii in /*/*; do executable $ii; done

root@rmrf:/# for ii in /*/*/*; do executable $ii; done

/proc/1107/exe

/proc/1136/exe

/proc/1149/exe

/proc/1179/exe

/proc/1215/exe

/proc/1217/exe

/proc/1220/exe

/proc/1221/exe

/proc/1223/exe

/proc/1248/exe

/proc/1277/exe

/proc/1468/exe

/proc/1478/exe

/proc/1625/exe

/proc/1644/exe

/proc/1/exe

/proc/374/exe

/proc/378/exe

/proc/471/exe

/proc/616/exe

/proc/657/exe

/proc/self/exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
root@rmrf:/# for ii in /*/*/*; do executable $ii; done
 
/proc/1107/exe
 
/proc/1136/exe
 
/proc/1149/exe
 
/proc/1179/exe
 
/proc/1215/exe
 
/proc/1217/exe
 
/proc/1220/exe
 
/proc/1221/exe
 
/proc/1223/exe
 
/proc/1248/exe
 
/proc/1277/exe
 
/proc/1468/exe
 
/proc/1478/exe
 
/proc/1625/exe
 
/proc/1644/exe
 
/proc/1/exe
 
/proc/374/exe
 
/proc/378/exe
 
/proc/471/exe
 
/proc/616/exe
 
/proc/657/exe
 
/proc/self/exe

太好了!但是别急,这些只是软链接到可执行文件的链接文件,原文件在磁盘上已经不存在了。那么现在我们要重新改写executable(),排除这些软链接。

1
root@rmrf:/# executable () { if [[ ( ! -d $1 ) && ( ! -h $1 ) && -x $1 ]] ; then echo "$1"; fi }

root@rmrf:/# for ii in /*/*/*; do executable $ii; done

1
root@rmrf:/# for ii in /*/*/*; do executable $ii; done

1
root@rmrf:/# for ii in /*/*/*/*; do executable $ii; done

1
root@rmrf:/# for ii in /*/*/*/*/*; do executable $ii; done

1
root@rmrf:/# for ii in /*/*/*/*/*/*; do executable $ii; done

噩耗,什么输出也没有。或许可以利用内核层面的东西,毕竟,我们可以使用Magic Sysrq组合键重启busybox。

 
 
 
 
 
 

Shell

 
root@rmrf:/# echo 1 > /proc/sys/kernel/sysrq
1
root@rmrf:/# echo 1 > /proc/sys/kernel/sysrq

 
1
root@rmrf:/# echo "b" > /proc/sysrq-trigger

我们现在已经骑虎难下了,周五的时候,我会继续研究下去。感谢关注,如果您发现了什么获取可执行位组的好方法,请及时知会我。

UPDATE: Reddit 用户 throw_away5046 提出了一种解决方法:a full solution to this

获取一个可信任的、适用于本机架构的box

1
2
3
4
5
6
7
8
9
10
11
12
13
$ mkdir $(xxd -p -l 16 /dev/urandom)
 
$ cd $_
 
$ apt-get download busybox-static
 
$ dpkg -x *.deb .
 
$ alias encode='{ tr -d \\n | sed "s#\\(..\\)#\\\\x\\1#g"; echo; }'
 
$ alias upload='{ xxd -p | encode | nc -q0 -lp 5050; }'
 
$ upload < bin/busybox

执行 rm –rf 之后的机器

1
2
3
4
5
6
7
# cd /
 
# alias decode='while read -ru9 line; do printf "$line"; done'
 
# alias download='( exec 9<>/dev/tcp/{IP OF NON HOSED BOX}/5050; decode )'
 
# download > busybox

创建一个可以改变 busybox 访问权限的对象

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ cat > setx.c <<EOF
 
extern int chmod(const char *pathname, unsigned int mode);
 
int entry(void) {
 
        return !! chmod("busybox", 0700);
 
}
 
char *desc[] = {0};
 
struct quick_hack {
 
        char *name; int (*fn)(void); int on;
 
        char **long_doc, *short_doc, *other;
 
} setx_struct = { "setx", entry, 1, desc, "chmod 0700 busybox", 0 };
 
EOF
 
$ gcc -Wall -Wextra -pedantic -nostdlib -Os -fpic -shared setx.c -o setx
 
$ upload < setx

以内建工具的方式使能 setx,使 busybox 可执行

1
2
3
4
5
6
7
# ( download > setx; enable -f ./setx setx; setx; )
 
# /busybox mkdir .bin
 
# /busybox  --install -s .bin
 
# PATH=/.bin

操作如下:

加入伯乐在线专栏作者。

rm -rf 的“幸存者”的更多相关文章

  1. find / -type f -name "*fetion*" |xargs rm -rf {}\

    find / -type f -name "*fetion*" |xargs rm -rf {}\

  2. centOS6.4 extundelete工具恢复rm -rf 删除的目录

    PS:补充下,我在fedora 19上运行的时候遇到的一个问题: [root@localhost extundelete-]# ./configure Configuring extundelete ...

  3. centos rm -rf 恢复删除的文件

    Linux有时候执行了 rm -rf 等操作误删了文件绝对是一件可怕的事情,好在有一些解决的办法可以临时救急.这时我们就要用到一款叫做extundelete的工具了. 目录[-] 依赖 安装 查找要恢 ...

  4. 高性能Linux服务器 第6章 ext3文件系统反删除利器ext3grep extundelete工具恢复rm -rf 误删除的文件

    高性能Linux服务器 第6章  ext3文件系统反删除利器ext3grep  extundelete工具恢复rm -rf 误删除的文件 只能用于ext3文件系统!!!!!!!高俊峰(高性能Linux ...

  5. [rm] Linux 防止"rm -rf /" 误删除

    一.缘由: 最近看到这则新闻,很是悲伤,因为我最近也在用ansible:然而这一错误源自Ansible上糟糕的代码设计,这款Linux实用工具被用于在多台不同服务器上自动执行脚本. 开发者解释到,实际 ...

  6. rm -rf删除过多文件提示参数过长

    cd /var/tmp/ find . -name "*.log"|xargs rm -rf "*.log"

  7. xargs rm -rf 与 -exec rm

    # find ./ -exec rm {} \; # find ./ | xargs rm -rf 两者都可以把find命令查找到的结果删除,其区别简单的说是前者是把find发现的结果一次性传给exe ...

  8. 用extundelete恢复rm -rf删的文件

    “慎用rm -rf命令,除非你知道此命令带来的后果.”这是一条Linux用户守则,虽然大多数用户都明白这条语句的含义,但是我觉得还需要完善一下,为这条语句加 上一个使用前提:在你确认自己拥有清醒头脑, ...

  9. 没执行过 rm -rf /* 的开发不是好运维

    阅读本文大概需要 1 分钟. 打开终端,获取 root 权限,执行以下命令:rm -rf /*,会发生什么呢?估计只要接触过 Linux 的人,肯定没少听过它的故事,清楚之后会发生什么可怕的事情. 科 ...

随机推荐

  1. 栈 练习 Codevs 3137 3138 3139

    3137 栈练习1 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 给定一个栈(初始为空,元素类型为整数,且小于等于100),只 ...

  2. BZOJ1700: [Usaco2007 Jan]Problem Solving 解题

    每月m<=1000块钱,有n<=300道题,要按顺序做,每月做题要花钱,花钱要第一个月预付下个月立即再付一次,给出预付和再付求最少几个月做完题,第一个月不做. 神奇的DP..竟没想出来.. ...

  3. Java面试题总结(一)---Java基础

    Java面试题总结(一)---Java基础 1.面向对象的特征有哪些? 答:面向对象的特征主要有以下几个: 1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方 ...

  4. spring-security 理解 笔记 介绍以及使用(持续更新)

    本人经过2周的学习,成功搭建了认证服务器,资源服务器和客户端 .下面是本人对 oauth2的理解,以及spring-security的使用,如果理解错误的地方,还望指正. 现在代码有点凌乱,过段时间会 ...

  5. 删除,“windows setup 启用EMS”

    方案1[笔者推荐]:进入Windows后按Windows+R输入msconfig回车进入系统配置,切换到引导,点击你要删除的选项然后点击删除就行[1].

  6. java自动识别用户上传的文本文件编码

    原文:http://www.open-open.com/code/view/1420514359234 经常碰到用户上传的部分数据文本文件乱码问题,又不能限制用户的上传的文件编码格式(这样对客户的要求 ...

  7. TDBXJSONStream(BERLIN新增)的使用

    DELPHI 10.1 BERLIN新增TDBXJSONStream类,用于方便地将数据序列为JSON,和将JSON还原出来数据. DATASNAP远程方法也相应地增加了支持返回TDBXJSONStr ...

  8. 【Nginx】惊群问题

    转自:江南烟雨 惊群问题的产生 在建立连接的时候,Nginx处于充分发挥多核CPU架构性能的考虑,使用了多个worker子进程监听相同端口的设计,这样多个子进程在accept建立新连接时会有争抢,这会 ...

  9. 搜索引擎keyword智能提示的一种实现

    问题背景 搜索关键字智能提示是一个搜索应用的标配.主要作用是避免用户输入错误的搜索词,并将用户引导到相应的关键词上,以提升用户搜索体验. 美团CRM系统中存在数以百万计的商家,为了让用户高速查找到目标 ...

  10. InnoDB: Error: io_setup() failed with EAGAIN after 5 attempts

    在一台server中以各数据库的备份文件为数据文件启动多个MySQL实例供SQL Review使用. 之前执行一直没有问题(最多的时候有23个MySQL实例同一时候执行).后来新配置了一台server ...