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

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

    PATH=".:$PATH"; export PATH

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

  • IFS环境变量

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

      IFS="/ \t\n"; export IFS
      PATH=".:$PATH"; export PATH
    • 现在从 Bourne shell 中调用任何使用绝对PATH的程序(李儒system)。它现在解释为下面的东西,它会在当前用户目录下,尝试执行命令行调用bin

      system("/bin/mail root"); ---> system(" bin mail root");
    • IFS 的 bug 现在已经在 SHell 中禁止了;所引用的新的 Shell 进程不会继承 IFS 变量。

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

  • LD_LIBRARY_PATH环境变量

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

      % ldd /bin/ls
    • LD_LIBRARY_PATH是一个环境变量,被动态链接器或加载器(ld.so/ld-linux.so)使用。它含有一个目录列表,让链接器或者加载器在搜索共享库时寻找。可以列出多个目录,以冒号(:)分隔。对于任何可执行文件,这个列表放在现存的编译器加载路径,以及任何系统默认加载路径的前面。
    • 基本上每个 Unix 程序都依赖于libc.so,并且每个 Windows 程序都一拉李雨 DLL。如果这些苦可以替换为恶意的副本,恶意代码就可以在共享库函数被调用时执行。
    • 由于LD_LIBRARY_PATH可以由用户充值,攻击者可以修改这个变量,并强制库加载器在攻击者的目录中搜索库,从而加载攻击者的恶意库。

      % 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。这些用户指定的库会在所有其它库之前加载。这可以用于选择性重载其他库中的函数。例如,如果你已经构建了一个库,你可以使用下列命令预加载它:

      % export LD_PRELOAD=./libmylib.so.1.0.1

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

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

    
    #include <stdio.h> void sleep (int s) { printf("I am not sleeping!\n");
    }

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

    % gcc -fPIC -g -c a.c
    % gcc -shared -o libmylib.so.1.0.1 a.o -lc

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

    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 程序执行下面的事情,会发生什么?

    // 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是下面的字符串:

    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 造成更大的损失吗?

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

  1. 雪城大学信息安全讲义 3.3 提升 Set-UID 程序的安全性

    3 提升 Set-UID 程序的安全性 exec函数 exec函数系列通过将当前进程映像包装为新的,来运行紫禁城.有许多exec函数的版本,工作方式不同.它们可以归类为: 使用/不适用 Shell 来 ...

  2. 雪城大学信息安全讲义 4.1~4.2

    四.缓冲区溢出漏洞和攻击 原文:Buffer-Overflow Vulnerabilities and Attacks 译者:飞龙 1 内存 这个讲义的"区域"(Area)和&quo ...

  3. 雪城大学信息安全讲义 3.1 Set-UID 机制如何工作

    三.Set-UID 特权程序 原文:Set-UID Programs and Vulnerabilities 译者:飞龙 这个讲义的主要目标就是来讨论特权程序,为什么需要他们,他们如何工作,以及它们有 ...

  4. 雪城大学信息安全讲义 七、格式化字符串漏洞

    七.格式化字符串漏洞 原文:Format String Vulnerability 译者:飞龙 printf ( user_input ); 上面的代码在 C 程序中十分常见.这一章中,我们会发现如果 ...

  5. 雪城大学信息安全讲义 六、输入校验

    六.输入校验 原文:Input Validation 译者:飞龙 1 环境变量(隐藏的输入) 环境变量是隐藏的输入.它们存在并影响程序行为.在编程中忽略它们的存在可能导致安全隐患. PATH 在 Sh ...

  6. 雪城大学信息安全讲义 五、竞态条件

    五.竞态条件 原文:Race Condition Vulnerability 译者:飞龙 1 竞态条件漏洞 下面的代码段属于某个特权程序(即 Set-UID 程序),它使用 Root 权限运行. 1: ...

  7. 雪城大学信息安全讲义 4.5

    5 堆或 BSS 的缓冲区溢出 堆或 BSS 的内容 字符串常量 全局变量 静态变量 动态分配的内存 示例:覆盖文件指针 /* The following variables are stored i ...

  8. 雪城大学信息安全讲义 4.3~4.4

    3 对抗措施 3.1 应用安全工程原则 使用强类型语言,例如 Java.C#,以及其他.使用这些语言,可以避免缓冲区溢出. 使用安全的库函数 可能拥有缓冲区溢出问题的函数:gets.strcpy.st ...

  9. 雪城大学信息安全讲义 二、Unix 安全概览

    二.Unix 安全概览 原文:Unix Security Basics 译者:飞龙 1 用户和用户组 用户 root:超极用户(UID = 0) daemon:处理网络. nobody:不拥有文件,用 ...

最新文章

  1. Win10 + RTX3090 安装CUDA11.2 + CUDNN8.1.0 安装
  2. Nginx的upstream目前支持5种分配方式
  3. linux搭建vsftp服务器_Linux安装配置vsftp搭建FTP的详细配置
  4. 涨跌因子计算器下载哪里下载_小白计算器软件下载-小白计算器app下载 v1.0 安卓版...
  5. 为什么代码正确却没有爬虫的信息_为什么敷面膜没有效果?原来这才是敷面膜的正确步骤...
  6. iLogtail使用入门-iLogtail本地配置模式部署(For Kafka Flusher)
  7. ps读写ddr3里面的数据 zynq_Zynq:用PS控制DDR3内存读写
  8. 1000道Python题库系列分享十二(9道编程题)
  9. 如何保证消息队列的高可用啊
  10. 关于学习Swift的一些感受
  11. 论文笔记_S2D.53_2013-ICCV_单目相机半稠密视觉里程计(VO)
  12. opencv读取摄像头实时流代码
  13. 值得关注的开源软件推荐
  14. 微信支付二维码生成工具类
  15. linux系统安装firefox的flash player插件
  16. 兔子能不能跑得过乌龟
  17. MEMORY系列之“DDR概述”
  18. 关于CList的小知识
  19. 洗料系列-杂谈篇-麻将自动化---第一章、麻将基础入门
  20. 钦州学院计算机好吗,罗雁(数学与计算机科学系)老师 - 钦州学院 - 院校大全

热门文章

  1. (07)Verilog HDL组合逻辑:assign
  2. (5)FPGA面试题同步电路和异步电路
  3. (23)FPGA面试技能提升篇(SSC接口、V35接口)
  4. 主程序与子程序不在同一程序模块中_数控车床子程序M98、M99编程实例!
  5. 图片不能及时显示_电脑主机正常运行,显示器黑屏,有六种原因,前三种方法要掌握!...
  6. python删除列表空元素_Python 如何删除列表中的空值
  7. efcore 有值才加where_lol手游怎么加好友 日服英雄联盟手游邀请好友一起玩方法[多图]...
  8. VS Code调试C代码
  9. nasm纠正性训练指南pdf_PDF转word,一键转换?没有这么简单
  10. 学历史能学计算机吗,历史专业学计算机好吗