设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

rm -rf的“幸存者”

2014-6-16 14:14| 发布者: joejoe0332| 查看: 3668| 评论: 0|原作者: honpey|来自: 伯乐在线

摘要: 自娱自乐,我决定启动一台Linux服务器,然后以root用户执行“rm –rf /”命令,然后观察下哪些文件或者指令会幸存下来。结果是什么也没少!因此你必须增加 —no-preserce-root再试一遍:…… ...

  自娱自乐,我决定启动一台Linux服务器,然后以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
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 }
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。


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


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


  UPDATE: Reddi用户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


  操作如下:

final.gif


原文链接: rm -rf remains   翻译: 伯乐在线 - honpey
译文链接: http://blog.jobbole.com/70971/


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部