PRELOAD 去欺骗、注入特性和研究程序(3)

dlfcn.h 是我们后面用到的 dlsym 函数所需要的。那个奇怪的 #define 是命令编译器去允许一些非标准的东西,我们需要它来启用 dlfcn.h 中的 RTLD_NEXT。那个 typedef 只是创建了一个函数指针类型的别名,它的参数等同于原始的 open —— 它现在的别名是 orig_open_f_type,我们将在后面用到它。

我们定制的 open(...) 的主体是由一些代码构成。它的最后部分创建了一个新的函数指针 orig_open,它指向原始的 open(...) 函数。为了得到那个函数的地址,我们请求 dlsym 在动态库堆栈上为我们查找下一个 open() 函数。最后,我们调用了那个函数(传递了与我们的假冒 open() 一样的参数),并且返回它的返回值。

我使用下面的内容作为我的 “邪恶的注入代码”:

inspect_open.c (片段):

printf("The victim used open(...) to access '%s'!!!\n",pathname);//remember to include stdio.h!

要编译它,我需要稍微调整一下编译参数:

gcc-shared -fPIC  inspect_open.c -o inspect_open.so -ldl

我增加了 -ldl,因此,它将这个共享库链接到 libdl —— 它提供了 dlsym 函数。(不,我还没有创建一个假冒版的 dlsym ,虽然这样更有趣)

因此,结果是什么呢?一个实现了 open(...) 函数的共享库,除了它有 输出 文件路径的意外作用以外,其它的表现和真正的 open(...) 函数 一模一样。:-)

如果这个强大的诀窍还没有说服你,是时候去尝试下面的这个示例了:

LD_PRELOAD=$PWD/inspect_open.so gnome-calculator

我鼓励你去看看自己实验的结果,但是简单来说,它实时列出了这个应用程序可以访问到的每个文件。

我相信它并不难想像为什么这可以用于去调试或者研究未知的应用程序。请注意,这个特定诀窍并不完整,因为 open() 并不是唯一一个打开文件的函数 …… 例如,在标准库中也有一个 open64(),并且为了完整地研究,你也需要为它去创建一个假冒的。

可能的用法

如果你一直跟着我享受上面的过程,让我推荐一个使用这个诀窍能做什么的一大堆创意。记住,你可以在不损害原始应用程序的同时做任何你想做的事情!

获得 root 权限。你想多了!你不会通过这种方法绕过安全机制的。(一个专业的解释是:如果 ruid != euid,库不会通过这种方法预加载的。)

欺骗游戏:取消随机化。这是我演示的第一个示例。对于一个完整的工作案例,你将需要去实现一个定制的 random() 、rand_r()、random_r(),也有一些应用程序是从 /dev/urandom 之类的读取,你可以通过使用一个修改过的文件路径来运行原始的 open() 来把它们重定向到 /dev/null。而且,一些应用程序可能有它们自己的随机数生成算法,这种情况下你似乎是没有办法的(除非,按下面的第 10 点去操作)。但是对于一个新手来说,它看起来很容易上手。

欺骗游戏:让子弹飞一会 。实现所有的与时间有关的标准函数,让假冒的时间变慢两倍,或者十倍。如果你为时间测量和与时间相关的 sleep 或其它函数正确地计算了新的值,那么受影响的应用程序将认为时间变慢了(你想的话,也可以变快),并且,你可以体验可怕的 “子弹时间” 的动作。或者 甚至更进一步,你的共享库也可以成为一个 DBus 客户端,因此你可以使用它进行实时的通讯。绑定一些快捷方式到定制的命令,并且在你的假冒的时间函数上使用一些额外的计算,让你可以有能力按你的意愿去启用和禁用慢进或快进任何时间。

研究应用程序:列出访问的文件。它是我演示的第二个示例,但是这也可以进一步去深化,通过记录和监视所有应用程序的文件 I/O。

研究应用程序:监视因特网访问。你可以使用 Wireshark 或者类似软件达到这一目的,但是,使用这个诀窍你可以真实地控制基于 web 的应用程序发送了什么,不仅是看看,而是也能影响到交换的数据。这里有很多的可能性,从检测间谍软件到欺骗多用户游戏,或者分析和逆向工程使用闭源协议的应用程序。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b1d2aed790ac3b2e0320209dc9ef7dbc.html