根据条件执行或跳过ld.so.preload共享库代码

时间:2019-07-05 23:15:49

标签: c shared-libraries ld

TL; DR:执行二进制代码和RUID!= UID时,是否可以跳过加载ld.so.preload中的共享库或特定代码?

嗨。

我正在编写一个共享对象,一个库,我通过ld.so.preload加载了该库,以挂钩某些功能。我想知道是否可以根据某些条件跳过加载此类库或其中的某些部分。

上下文:我正在使用TOCTTOU(检查时间到使用时间)漏洞,并且正在编写一个userland库,该库将通过linux's loader ld.so.preload feature加载。主要思想是挂接所有与文件一起使用的函数,进行一些检查,然后调用原始函数,以便对用户和其他程序透明。

现在,问题是:由于我不想使系统超载,并且希望我的库对系统的影响尽可能小,因此开销尽可能大,我想执行它,即挂接函数,仅当RUID!= EUID时。这是基于文件的TOCTTOU前提之一,它发生在攻击者的特权低于易受攻击的应用程序的特权时。

到目前为止,我想到的唯一方法是将每个函数声明都包含在以下内容中:

if(RUID == EUID){
   call original function;
} else {
   do my checkings;
   call original function;
}

编辑:上面的代码可以用等效的,较短的代码代替:

if(RUID != EUID){
   do my checkings;
}
call original function;

但这实际上非常糟糕,因为我要挂接近50个函数以及使用__attribute构造函数和析构函数,并且这意味着在每个函数中用if-else块填充我的代码。

请记住,ld.so.preload会先加载列出的库,然后再加载任何其他库。

我想知道是否有任何方法不基于RUID != EUID条件加载库,或者加载库但跳过钩子代码。

1 个答案:

答案 0 :(得分:0)

  

由于我的库是系统范围的,因此无法为其创建任何包装器。

您希望仅将库 预加载到setuid或setgid程序中。

由于在任何系统上此类程序的数量都很少,并且是静态已知的(您可以每小时用.__file__作业找到它们,因此,最简单的解决方案是为每个此类程序创建一个包装器。< / p>

包装器本身可以是一个很小的程序,它具有与“目标”程序完全相同的setuid / setgid权限,并执行

cron
相关问题