前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >雪城大学信息安全讲义 3.2 Set-UID 程序的漏洞

雪城大学信息安全讲义 3.2 Set-UID 程序的漏洞

作者头像
ApacheCN_飞龙
发布2022-12-01 17:02:08
3970
发布2022-12-01 17:02:08
举报
文章被收录于专栏:信数据得永生

2 Set-UID 程序的漏洞

2.1 隐藏的输入:环境变量

特权程序必须对所有输入进行安全检查。输入检查实际上是访问控制的一部分,特权程序必须这么做,来确保程序的安全。很多安全问题都是输入检查的错误造成的。

如果输入在程序中显式存在,程序员可能记得执行输入检查;如果输入隐式存在,输入检查可能会忘记,因为程序员可能不知道这个输入的存在。环境变量就是这类输入。

每个 Unix 进程都在特定环境下运行。环境由环境变量表组成,每个变量都有赋值。一些程序内部使用这些环境变量,Shell 程序就是这些程序的例子。换句话说,一些环境变量的值可以 Shell 程序的行为。

由于环境变量由用户控制,如果程序依赖这些变量,用户可以间接影响这类程序的行为,通过修改一些环境变量的值。因此,理解特权程序是否依赖任何环境变量的值就十分重要。一种程序可能被环境变量影响的方式,就是在程序中显式使用环境变量的值。在 C 语言中,程序可以使用getenv来访问环境变量的值。但是,也有许多例子,程序隐式使用环境变量。这就是我们在许多 Set-UID 程序中看到的漏洞。我们会在这一节中展示几个例子。

PATH环境变量

在 Shell 中执行命令式,Shell 会使用PATH环境变量搜索所有命令,它包含一个目录列表。Shell 程序通过目录列表(和他们在PATH环境变量的相同顺序)来搜索。第一个匹配命令名称的程序会被执行。

下面会发生什么?要注意system (const char *cmd)库函数首先调用/bin/sh程序,之后让 SHell 程序执行cmd

代码语言:javascript
复制
system ("mail");

攻击者可以将PATH修改成这个,并使当前目录下的mail被执行。

代码语言:javascript
复制
PATH=".:$PATH"; export PATH

拿超人来比喻的话,如果超人的指令是“左转”(坏人在左边而好人在右边,你可以假设他要攻击坏人)。如果攻击者准确知道左转指令什么时候以及在哪里执行,他就可以做出与上面类似的攻击。因为“左边”是个相对的方向,并不是绝对方向。如果攻击者事先在你想要左转的地方,放置一个旋转设备,并将你旋转 180 度,只要你踏上了它,“左转”就变成了转到好人那里。如果你遵循了指令,你最后就会攻击好人。

IFS环境变量

IFS变量决定了哪些字符被解释为空白字符。它代表了内部字段分隔符。假设我们设置它来包含斜杠字符:

代码语言:javascript
复制
IFS="/ \t\n"; export IFS 
PATH=".:$PATH"; export PATH

现在从 Bourne shell 中调用任何使用绝对PATH的程序(李儒system)。它现在解释为下面的东西,它会在当前用户目录下,尝试执行命令行调用bin

代码语言:javascript
复制
system("/bin/mail root"); ---> system(" bin mail root");

IFS 的 bug 现在已经在 SHell 中禁止了;所引用的新的 Shell 进程不会继承 IFS 变量。

假设在超人的故事中。超人知道使用“左转”指令的风险,所以它将其改为“转到北边”,它现在是个绝对方向。这仍然存在漏洞,因为“北”由磁场决定,不幸的是,磁场可以通过攻击者放置的磁铁来影响。

LD_LIBRARY_PATH环境变量

Linux 中,除非编译时期通过-static显式指定,所有 Linux 程序需要在运行时期链接到动态链接库。动态链接器或加载器ld.so/ld-linux.so加载程序所需的共享库,准备要运行的程序,之后运行它。你可以使用下面的命令来观察程序需要什么共享库。

代码语言:javascript
复制
% ldd /bin/ls

LD_LIBRARY_PATH是一个环境变量,被动态链接器或加载器(ld.so/ld-linux.so)使用。它含有一个目录列表,让链接器或者加载器在搜索共享库时寻找。可以列出多个目录,以冒号(:)分隔。对于任何可执行文件,这个列表放在现存的编译器加载路径,以及任何系统默认加载路径的前面。

基本上每个 Unix 程序都依赖于libc.so,并且每个 Windows 程序都一拉李雨 DLL。如果这些苦可以替换为恶意的副本,恶意代码就可以在共享库函数被调用时执行。

由于LD_LIBRARY_PATH可以由用户充值,攻击者可以修改这个变量,并强制库加载器在攻击者的目录中搜索库,从而加载攻击者的恶意库。

代码语言:javascript
复制
% setenv LD_LIBRARY_PATH .:$LD_LIBRARY_PATH

为了使 Set-UID 程序更加安全,不受LD_LIBRARY_PATH环境变量的影响,运行时的链接器或加载器(ld.so)会忽略环境变量,如果程序是个 Set-UID 程序。

防护应用也可以静态链接到可信库来避免这个问题。

在 Windows 主机上,通常在加载 DLL 的时候,在搜索系统目录之前,会搜索当前目录中的 DLL。如果你点击 Word 文档来启动 Office,会在包含该文档的目录下搜索 DLL。

LD PRELOAD环境变量

许多 Unix 系统允许你“预加载”共享库,通过设置环境变量LD PRELOAD。这些用户指定的库会在所有其它库之前加载。这可以用于选择性重载其他库中的函数。例如,如果你已经构建了一个库,你可以使用下列命令预加载它:

代码语言:javascript
复制
% export LD_PRELOAD=./libmylib.so.1.0.1

如果libmylib.so.1.0.1包含函数sleep,它是个标准的libc函数,当程序执行并调用sleep时,libmylib.so.1.0.1中的函数会被调用。

这里是一个程序,重载了libc中的sleep

代码语言:javascript
复制
#include <stdio.h> 

void sleep (int s) { 
    printf("I am not sleeping!\n"); 
}

我们可以使用下列命令编译程序(假设上面的程序名为name.c):

代码语言:javascript
复制
% gcc -fPIC -g -c a.c 
% gcc -shared -o libmylib.so.1.0.1 a.o -lc

现在,我们运行下列程序:

代码语言:javascript
复制
int main() { 
    sleep(1); 
    return 0; 
}

如果环境变量LD PRELOAD设为libmylib.so.1.0.1,标准libc中的sleep没有使用,反之我们共享库中的sleep函数会调用,并且打印"I am not sleeping!"

为了确保 Set-UID 程序安全,不受LD PRELOAD环境变量的控制,运行时链接器或加载器(ld.so)会忽略这个环境变量,如果程序是 Set-Root-UID 程序,除非真实 UID 也为 0。

2.2 调用其它程序

当特权程序调用其它程序时,必须注意是否调用了非预期的程序。我们知道,环境变量是个我们需要注意的地方,也有一些我们需要注意的其它地方。

如果 Set-UID 程序执行下面的事情,会发生什么?

代码语言:javascript
复制
// The contents of User_Input are provided by users. 
sprintf(command, "/bin/mail %s", User_Input); 
system(command);

User_Input可能包含 Shell 的特殊字符(例如| & < >)。要记住,system调用实际上先调用 Shell,之后让 Shell 程序执行/bin/mail。如果我们不注意,攻击者就可以执行其它程序,通过让User_Input是下面的字符串:

代码语言:javascript
复制
xyz@example.com ; rm -f /* ; /bin/sh

2.3 其它知名的漏洞模式

除了上面的输入校验漏洞,也有一些其他的知名漏洞模式。我们会在单独的章节中讨论它们。这里是这些模式的总结:

  • 缓冲区溢出
  • 竞态条件
  • 格式化字符串

2.4 杂项漏洞

有许多其他漏洞,并不易于归纳进上面讨论的任何分类。一些可能被归纳为更广泛的“呼入椒盐漏洞”,但是由于他们的独特特性,我们在这里单独讨论它们。我们不能枚举所有漏洞。我们只能给出一些示例,来展示程序员在程序逻辑中的不同错误,并且展示这些错误如何变为漏洞。

  • lpr漏洞:它在/tmp目录下生成临时文件。文件名称应该是随机的,但是,由于伪随机数生成的错误,文件名称每一千次就会发生重复。这个程序是 Set-UID 程序。将可预测的文件名称链接到/etc/passord会导致lpr覆盖/etc/passord
  • chsh漏洞:chsh让用户输入 Shell 程序的名称s,并在/etc/passwd中保存输入。chsh并不会做清晰的检查。程序假设用户的输入只有一行,不幸的是,这个假设可以为假:用户可以键入联行输入,其中第二行是类似xyz::0:0::的东西美丽如,用户可以插入一个新的超级用户账户(UID:0),不带密码。
  • sendmail漏洞
    • sendmail:(1)入境的邮件会添加在/var/mail/wedu。(2)如果/var/mail/wedu的所有者不是 Wedu,sendmail会使用chown将所有者修改为 Wedu。
    • 你能利用它来读取 Wedu 的邮件吗?
    • 你能利用它来给 Wedu 造成更大的损失吗?
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2 Set-UID 程序的漏洞
    • 2.1 隐藏的输入:环境变量
      • 2.2 调用其它程序
      • 2.3 其它知名的漏洞模式
      • 2.4 杂项漏洞
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档