I am LAZY bones?
AN ancient AND boring SITE

[转] ldd 的一个安全问题

本文的英文原文来自这里,作者:Peteris Krumins;中文译文转自酷壳,译者:陈皓

我们知道“ldd”这个命令主要是被程序员或是管理员用来查看可执行文件所依赖的动态链接库的。是的,这就是这个命令的用处。可是,这个命令比你想像的要危险得多,也许很多黑客通过ldd的安全问题来攻击你的服务器。其实,ldd的安全问题存在很长的时间了,但居然没有被官方文档所记录来下,这听上去更加难以理解了。怎么?是不是听起来有点不可思议?下面,让我为你细细道来。

首先,我们先来了解一下,我们怎么来使用ldd的,请你看一下下面的几个命令:
(1)

(2)

(3)

第(1)个命令,我们运行了 ldd/bin/grep。我们可以看到命令的输出是我们想要的,那就是 /bin/grep 所依赖的动态链接库。
第(2)个命令设置了一个叫 LD_TRACE_LOADED_OBJECTS 的环境变量,然后就好像在运行命令 /bin/grep (但其实并不是)。 其运行结果和ldd的输出是一样的!
第(3)个命令也是设置了环境变量 LD_TRACE_LOADED_OBJECTS ,然后调用了动态链接库 ld-linux.so 并把 /bin/grep 作为参数传给它。我们发现,其输出结果还是和前面两个一样的。

具体发生了什么?

对于第二个和第三个命令来说,好像是对 ldd 的一个包装或是一个隐式调用。对于第二个和第三个命令来说, /bin/grep 这个命令就根本没有被运行。这是一个GNU动态载入器的怪异的特性。如果其注意到环境变量LD_TRACE_LOADED_OBJECTS 被设置了,那么它就不会去执行那个可运行的程序,而去输出这个可执行程序所依赖的动态链接库 (在BSD 系统上的ldd 是一个C 程序)。
如果你使用的是Linux,那么,你可以去看看 ldd 程序,你会发现这是一个 bash 的脚本。如果你仔细查看这个脚本的源码,你会发现,第二个命令和第三个命令的差别就在于 ld-linux.so 装载器是否可以被ldd所装载,如果不能,那就是第二个命令,如果而的话,那就是第三个命令。
所以,如果我们可以让ld-linux.so 装载器失效的话,或是让别的装载器来取代这个系统默认的动态链接库的话,那么我们就可以让 ldd来载入并运行我们想要程序了——使用不同的载装器并且不处理LD_TRACE_LOADED_OBJECTS 环境变量,而是直接运行程序。
例如,你可以创建一个具有恶意的程序,如: ~/app/bin/exec 并且使用他自己的装载器 ~/app/lib/loader.so。如果某人(比如超级用户root) 运行了 ldd /home/you/app/bin/exec ,于是,他就玩完了。因为,那并不会列出所依赖的动态链接库,而是,直接执行你的那个恶意程序,这相当于,那个用户给了你他的授权。

编译一个新的装载器

下载 uClibc C库。这是一个相当漂亮的代码,并且可以非常容易地修改一下源代码,使其忽略 LD_TRACE_LOADED_OBJECTS 检查。

解压这个包,并执行 make menuconfig,选项你的平台架构(比如:i386),剩下的事情保持不变。

编辑 .config 并设置目标安装目录:到 /home/you/app/uclibc

改成

(bones7456注: 其实上面这一步也可以在make menuconfig的界面里修改Library Installation Options。)
现在你需要改动一下其源代码,让其忽略LD_TRACE_LOADED_OBJECTS 环境变量的检查。下面是个这修改的diff,你需要修改的是 ldso/ldso/ldso.c 文件。你可把下面的这个diff存成一个叫file的文件,然后运行这个命令:patch -p0 < file。如果你不这样做的话,那么,我们的黑客程序就无法工作,而我们的这个装载器还是会认为 ldd 想列出动态链接库的文件列表。

下面让我们来编译并安装它。

(bones7456注:在我的gentoo系统里,make isntall的时候会出点小错,将extra/scripts/unifdef.c里所有的getline改成getline_就可以通过了。)

于是,我们的 uClibc 装载器就被安装了,并且libc 库指向了 /home/you/app/uclibc. 就这么简单,现在,我们需要做的就是把我们的uClibc的装载器 (app/lib/ld-uClibc.so.0)变成默认的。

小试牛刀

首先,先让我们来创建一个测试程序,这人程序也就是输出些自己的东西,这样可以让我们看到我们的程序被执行了。我们把这个程序放在 app/bin/下,叫“myapp.c”,下面是源代码

这是一个很简单的代码了,这段代码主要检查一下环境变量LD_TRACE_LOADED_OBJECTS 是否被设置了,如果是,那么恶意程序执行,如果没有,那么程序什么也不发生。

下面是编译程序的命令,大家可以看到,我们静态链接了一些函数库。我们并不想让LD_LIBRARY_PATH这个变量来发挥作用。

下面是GCC的各个参数的解释:
* -Wl,–dynamic-linker,$L/lib/ld-uClibc.so.0 — 指定一个新的装载器。
* -Wl,-rpath-link,$L/lib — 指定一个首要的动态装载器所在的目录,这个目录用于查找动态库。
* -nostdlib — 不使用系统标准库。
* myapp.c -o myapp — 编译myapp.c 成可执行文件 myapp,
* $L/usr/lib/crt*.o — 静态链接runtime 代码
* -L$L/usr/lib/ — libc 的目录(静态链接)
* -lc — C 库

现在让我们来运行一下我们的 myapp (没有ldd,一切正常)

LD_TRACE_LOADED_OBJECTS 没有设置,所以输出 “Nothing.” 。
现在,让我们来使用 ldd 来看看这个程序的最大的影响力,让我们以root身份来干这个事。

哈哈,我们可以看到,ldd触发了我们的恶意代码。于是,我们偷了整个系统!

邪恶的程序

下面这个例子更为实际一些,如果没有ldd ,那程序程序会报错 “error while loading shared libraries” ,这个错误信息会引诱你去去使用 ldd 去做检查,如果你是root的话,那么就整个系统就玩完了。而当你可以了 ldd 后,它会在干完坏事后,模仿正确的ldd的输出,告诉你 libat.so.0 不存在。
下面的代码仅仅是向你展示了一下整个想法,代码还需加工和改善。

邪恶的电话

事实上来说,上面的那段程序可以影响更具破坏性,因为大多数的系统管理员可能并不知道不能使用 ldd 去测试那些不熟悉的执行文件。下面是一段很可能会发现的对话,让我们看看我们的程序是如何更快地获得系统管理员的权限的。

系统管理员的电话狂响……
系统管理员: “同志你好,我是系统管理员,有什么可以帮你的?”
黑客:“管理员同志你好。我有一个程序不能运行,总是报错,错误我也看不懂,你能不能帮我看看?”
系统管理员:“没问题,你的那个程序在哪里?”
黑客: “在我的home目录下,/home/you/app/bin/myapp”。
系统管理员:“ OK,等一些”,黑客在电话这头可以听到一些键盘的敲击声。
系统管理员:“好像是动态链接库的问题,你能告诉我你的程序具体需要什么样的动态链接库吗?”
黑客说: “谢谢,应该没有别的嘛。”
系统管理员:“嗯,查到了,说是没有了 libat.so.0这是你自己的动态链接库吗?”
黑客说:“哦,好像是的,你等一下,我看看……” 黑客在那头露出了邪恶的笑,并且,讯速地输入了下面的命令:
mv ~/.hidden/working_app ~/app/bin/myapp
mv ~/.hidden/libat.so.0 ~/app/bin/
黑客说:“哦,对了,的确是我的不对,我忘了把这个链接库拷过来了,现在应该可以了,谢谢你啊,真是不好意思,麻烦你了”
系统管理员: “没事就行了,下次注意啊!”(然后系统管理心里暗骂,TMD,又一个白痴用户!……)

教训一:千万不要使用 ldd 去测试你不知道的文件!
教训二:千万不要相信陌生人!

Gentoo换了profile以后,鼠标键盘不能动的解决办法

Gentoo 10.0 的profile出来已经蛮久了,但是我一直都没换,直到昨天才设置成了 default/linux/x86/10.0/desktop ,结果一大堆包需要重新编译了(呃。。好吧,其实我本来就有好几天没更新系统了。。)。
编译完重启就发现问题了:启动到gdm以后,鼠标键盘都动不了了,按什么键都无效,输不了用户名了,包括ctrl+alt+F1都不管用了,但是触摸板却是有效的。
第一个想到的 qlist -I -C x11-drivers/ 里面的几个包重新编译一下,发现无效;然后看elogv,发现hal说要把xorg.conf里的input相关的都删掉,试了也无效。
最后的解决办法是:在 /etc/make.conf 的 INPUT_DEVICES= 里加上 evdev ,然后安装 x11-drivers/xf86-input-evdev 这个包。

欧拉工程

咳咳,我做为非正常网民网瘾戒除中心砖家,正式给介绍介绍一下这个欧拉工程
呃。。。还是请我们的校长──lerosua──来介绍吧~下面引自这篇博文

欧拉工程是一个用编程来解决一连串数学问题的项目。发现它对训练数学及编程挺有作用的。网上也有许多人做上面的题目并发布自己的算法。
上面共有261题,分几个等级,一级比一级难。我看了第261题的提交,目前只是22个。完成它绝对是时间及精力及耐力及智力的较量。
于是本人决定将此作为一个项目来做,逐步进阶。
骨头与xiooli同学也并肩作战。
我们解决的问题的源码将会发布在以下svn中。欢迎审阅.
http://nrciz.googlecode.com/svn/trunk/projecteuler

其实,之前(几个月前吧)我就已经做过几题了。可以说,正是因为欧拉工程,我才喜欢上python的,当我看到第一题用一句

就完美地搞定了,是多么地流畅,多么地自然,我就喜欢上了这门语言~
我们现在已经在逐步把很多题目翻译成中文了,所以,大家有空就去这里看看吧~最好是大家都能参与到其中来哦~

watch

watch命令包含在procps软件包内,procps是linux下一个很有用的基础包,里面包含了ps、pgrep、pkill、top、uptime、w等重要又常用的命令。
watch的具体功能就是定时执行后面跟的命令,并不间断地把输出命令的标准输出。
例如:

就可以监视内存使用率的状况了,原理就是每秒调用一次free,并集中显示结果。其中,-d表示高亮不同的地方,-n 1表示每1秒执行一次(默认是2秒)。此命令需要用Ctrl+C来结束。
另一个例子:

可以监视/var/log下的日志的变化情况。
另外:如man页所示,执行下面三个命令来体会单引号和双引号的区别

灵活运用此命令,可以让你的CLI增色很多哦。

gentoo的ACCEPT_LICENSE

最近 sudo emerge -avuDN @system @world 的时候,老是会有这样的提示:

也不知道哪个版本的portage引入的这个机制,不过看文档倒是3年前就有的。
不过,如果你像我一样是个人用户,并不是很在意版权问题的话(其实也没啥问题,呵呵),其实只需要在 /etc/make.conf 里加一行:

就可以解决这个烦人的提示了。
PS: 这个东西现在貌似还不是很完善,因为目前都还没有在 emerge –info 里体现出来。。。

这就是 chrome OS?

这里看到有人说这个可能就是是chrome OS的开发版,于是下载下来跑了跑,个人感觉除了文件大小(解压后500多M)比较像OS以外,更多的还是像一个浏览器。。。
看我的截图:
chrome_normal
这个模式下,很像是一个普通的chrome浏览器,但是也有些不寻常的地方,比如右上角依次显示了 系统时间、网络状态(截图中的小x就是,点上去显示No networks are avaliable)、电池状态(点上去提示了错误的信息,如下图,bug。。。) 等,这些又有点像是一个OS的特征。
chrome_err
另外点击左上角的小logo,会出现一个全屏的能挡住gnome的panel窗口,但是却只有如下的显示:
chrome_full
猜想以后这个可能就是所有操作的入口?需要连接google的服务器才能显示正确的内容,而这个服务端目前还未就绪?这么说来这个系统不是必须联网才能进行其他操作了?
另外就是怎么把系统单独引导起来呢,难道这个500多M的文件以后还会是一个像vmlinuz一样的可引导文件?总之现在情况还不是很明了,我们拭目以待吧。
PS:再贴一下ldd的结果:
点击查看全文 »

x11-drivers/xf86-video-radeonhd-1.3.0 会引起黑屏

今天对我的gentoo进行了解常规的uDN升级,但是等我晚上到家打开电脑就不能正常启动了,字符界面的信息输出完以后到了X就直接黑屏了,看了近期的升级日志,发现x11-drivers/xf86-video-radeonhd-1.3.0这个升级非常可疑,于是暂时mask掉,退回1.2.5版本,果然就好了。
我的显卡是x1700,用的是2.6.31内核里面的drm模块。有遇到相同问题的gentoo用户吗?

谁在我blog里留言最多呢?

今天备份blog数据的时候,突然想了解一下,谁在我blog里留言最多呢?
这样不仅可以满足自己的好奇心,还可以更好地做好读者回访工作,哈哈。
于是,在WP的后台里导出xml的备份数据以后,来了这么一行,如果你用的于是WordPress,那也可以做为参考哦:

或者是贴出来的加上链接的形式:

以下就是我blog的结果(已经人工去掉了自己和无意义的数据):

68 http://imtx.cn
47 http://joolix.com
41 http://www.sxnsx.com
29 http://hi.baidu.com/tpxc
23 http://oceanboo.cn
22 http://wdicc.com
20 http://lfeng.cn
19 http://young001.blogbus.com
18 http://frankyue.cn
17 http://millenniumdark.blog.ubuntu.org.cn/
15 http://zhan.blog.ubuntu.org.cn/
15 http://blog.imxifs.cn
13 http://www.ownlinux.cn/
12 http://www.kissuki.com/
12 http://muzuiget.blog.ubuntu.org.cn/
11 http://www.hicrokee.com
09 http://lerosua.org
08 http://www.ownlinux.cn
07 http://www.imkeke.net
07 http://ivenvd.blogspot.com/
06 http://tianhao.blog.ubuntu.org.cn/
06 http://maclpashideout.blogspot.com/
06 http://classfoo.googlepages.com
05 http://www.w3rep.cn/blog
05 http://www.shuge.org/lee
05 http://www.joolix.com
05 http://www.imkeke.net/
05 http://raychen1984.cublog.cn/
04 http://yegle.net
04 http://www.imchao.net

当然,这样就直接忽略掉了没有url字段的评论,如果你不想这样的话,也可以根据wp:comment_author字段来进线昵称的统计。

假期回顾

6号了,差不多该回顾下这个假期了吧~
首先,本来想看国庆的阅兵直播的,但是不巧,车票刚好买到那会儿的,所以阅兵的时候,我正在高速上颠簸着,我也没有啥3G手机之类的高级货,所以也就没看成直播。不过后来听说,其实CCAV的那个“直播”,其实也是延时30秒的快速“转播”而已,所以想来和我看的“重播”也没啥区别吧~
然后,这个假期应该是最累的吧,因为家里老房子在装修,所以貌似有干不完的杂活。也正是因为这个原因,最近上网的时间几乎是0了,只是偶尔用ipod上来看看。
那到底在干啥呢?
首先是铺完外墙砖以后,一切都很脏了,到处都是碎水泥和灰,搞卫生就成了第一重任了,最难搞的就是玻璃,擦玻璃就擦了2天。。。非常汗哦~
另外,还有一天去收稻子了哦,这个活,算起来应该有10年没干过了吧~这次这块地很小,而且没法用收割机,所以就人工上了,带上镰刀和脱粒机就去了,虽然其实也没割几下,但是也好好地体验了一下以前的生活。不过,我纳闷的是,这10几分地就把我们一伙都累趴下了,当年的3亩地是怎么搞定的呢?现在的人确实都退化了。。。
不管如何,明天就回杭州了~

神一样的Quine

有个很牛B的小日本搞出来的东西

这段ruby代码,相当牛,如作者所说,运行这段ruby,生成一段python代码,再运行python代码,生成一段perl代码,再运行perl代码,生成一段lua代码。。。这样一直下去,经过11种语言,最后。。。居然又能重新得到之前的ruby代码。。
这11种语言是:ruby 1.8.7-p72、Python 2.5.2、perl v5.10.0、Lua 5.0.3、OCaml 3.10.2、ghc-6.8.2、gcc 4.3.2、java “1.5.0_17″、beef 0.0.6-2、whitespace 0.3-2、unlambda 2.0.0-5。
est这里看到了介绍,实在忍不住,把所有解释器都装上验证了一把,果然是可以的。彻底无语了,特此把中间结果都打包放上来,供大家瞻仰。
ubuntu下也想自己试试的话,得确保有这些包: ruby lunar lua50 ocaml-interp ghc6 sun-java5-jdk beef whitespace unlambda

PS: 我以为 brainfuck 就已经很BT了,没想到还有更BT的 whitespace ,彻底无语了。