富德生命人寿保险公司官方网站,wordpress如何使用教程,连云港市城乡建设局网站,陕西中交基础建设有限公司网站《白帽子讲Web安全》13-14章 《白帽子讲Web安全》13-14章13、应用层拒绝服务攻击13.1、DDOS简介13.2、应用层DDOS13.2.1、CC攻击13.2.2、限制请求频率13.2.3、道高一尺#xff0c;魔高一丈 13.3、验证码的那些事儿13.4、防御应用层DDOS13.5、资源耗尽攻击13.5.1、Slowloris攻击… 《白帽子讲Web安全》13-14章 《白帽子讲Web安全》13-14章13、应用层拒绝服务攻击13.1、DDOS简介13.2、应用层DDOS13.2.1、CC攻击13.2.2、限制请求频率13.2.3、道高一尺魔高一丈 13.3、验证码的那些事儿13.4、防御应用层DDOS13.5、资源耗尽攻击13.5.1、Slowloris攻击13.5.2、HTTP POST DOS13.5.3、Server Limit DOS 13.6、一个正则引发的血案ReDOS13.7、小结 14、PHP安全14.1、文件包含漏洞14.1.1、本地文件包含14.1.2、远程文件包含14.1.3、本地文件包含的利用技巧 14.2、变量覆盖漏洞14.2.1、全局变量覆盖14.2.2、extract()变量覆盖14.2.3、遍历初始化变量14.2.4、import_request_variables变量覆盖14.2.5、parse_str()变量覆盖 14.3、代码执行漏洞14.3.1、“危险函数”执行代码14.3.1.1、phpMyAdmin 3.4.3.1远程代码执行漏洞14.3.1.2、MyBB 1.4 远程代码执行漏洞 14.3.2、“文件写入”执行代码14.3.3、其他执行代码方式 14.4、定制安全的PHP环境14.5、小结 《白帽子讲Web安全》13-14章
13、应用层拒绝服务攻击
13.1、DDOS简介 分布式拒绝服务Distributed Denial of Service, DDOS利用合理的请求造成资源过载导致服务不可用。 分布式拒绝服务攻击将正常请求放大了若干倍通过若干个网络节点同时发起攻击以达成规模效应。这些网络节点往往是黑客们所控制的“肉鸡”数量达到一定规模后就形成了一个“僵尸网络”。大型的僵尸网络甚至达到了数万、数十万台的规模。如此规模的僵尸网络发起的DDOS攻击几乎是不可阻挡的。 SYN flood是一种最为经典的DDOS攻击利用了TCP协议设计中的缺陷。 对抗SYN flood的主要措施有SYN Cookie/SYN Proxy、safereset等算法。SYN Cookie的主要思想是为每一个P地址分配一个“Cookie”并统计每个IP地址的访问频率。如果在短时间内收到大量的来自同一个IP地址的数据包则认为受到攻击,之后来自这个IP地址的包将被丢弃。 13.2、应用层DDOS DDOS攻击更为可怕因为今天几乎所有的商业Anti-DDOS设备只在对抗网络层DDOS 时效果较好而对应用层DDOS攻击却缺乏有效的对抗手段。 13.2.1、CC攻击 CC 攻击的原理非常简单就是对一些消耗资源较大的应用页面不断发起正常的请求以达到消耗服务端资源的目的。在 Web应用中查询数据库、读/写硬盘文件等操作相对都会消耗比较多的资源。 应用层 DDOS 攻击是针对服务器性能的一种攻击那么许多优化服务器性能的方法都或多或少地能缓解此种攻击。比如将使用频率高的数据放在memcache 中相对于查询数据库所消耗的资源来说查询memcache所消耗的资源可以忽略不计。 13.2.2、限制请求频率 最常见的针对应用层 DDOS攻击的防御措施是在应用中针对每个“客户端”做一个请求频率的限制。 通过IP地址与Cookie定位一个客户端如果客户端的请求在一定时间内过于频繁则对之后来自该客户端的所有请求都重定向到一个出错页面。 13.2.3、道高一尺魔高一丈 从以下几个方面着手防御应用层DDOS 首先应用代码要做好性能优化。合理地使用memcache就是一个很好的优化方案将数据库的压力尽可能转移到内存中。此外还需要及时地释放资源比如及时关闭数据库连接减少空连接等消耗。其次在网络架构上做好优化。善于利用负载均衡分流避免用户流量集中在单台服务器上。同时可以充分利用好CDN和镜像站点的分流作用缓解主站的压力。最后也是最重要的一点实现一些对抗手段比如限制每个IP地址的请求频率。 13.3、验证码的那些事儿 验证码是互联网中常用的技术之一它的英文简称是CAPTCHA (Completely AutomatedPublic Turing Test to Tell Computers and Humans Apart全自动区分计算机和人类的图灵测试)。 除了直接利用图像相关算法识别验证码外还可以利用Web实现上可能存在的漏洞破解验证码。 实现原理验证码的验证过程是比对用户提交的明文和服务器端Session里保存的验证码明文是否一致。存在漏洞验证码消耗掉后SessionID未更新导致原有的SessionID可以一直重复提交同一个验证码。 实现原理将所有的验让码图片生成好以哈希过的字符串作为验证码图片的文件名。在使用验证码时则直接从图片服务器返回已经生成好的验证码这种设计原本的想法是为了提高性能。存在漏洞攻击者可以事先采用枚举的方式遍历所有的验证码图片并建立验证码到明文之间的一一对应关系从而形成一张“彩虹表”这也会导致验证码形同虚设。修补方式验证码的文件名需要随机化满足“不可预测性”原则。
13.4、防御应用层DDOS
做好人机识别、在Web Sever这一层做些防御
在人机识别方面
判断HTTP头中的User-Agent字段来识别客户端。 存在的缺陷可能会被客户端篡改。 让客户端解析一段JavaScript并给出正确的运行结果。因为大部分的自动化脚本都是直接构造HTTP包完成的并非在一个浏览器环境中发起的请求。因此一段需要计算的JavaScript可以判断出 客户端到底是不是浏览器。类似的发送一个flash让客户端解析也起到同样的作用。 存在的缺陷有的自动化脚本是内嵌在浏览器中的“内挂”就无法检测出来了。“内挂”指的是嵌入在浏览器中的自动化脚本或插件。这些脚本或插件直接在浏览器环境中运行因此能够模拟正常用户的行为
在Web Server层做防御其好处是请求尚未到达后端的应用程序里因此可以起到一个保护的作用。
在Apache的配置文件中有一些参数可以缓解DDOS攻击。比如调小Timeout、KeepAliveTimeout值增加MaxClients值。 存在的缺陷这些参数的调整可能会影响到正常应用因此需要视实际情况而定。 “mod_qos”是Apache的一个Module原理是限制单个IP地址的访问频率。 存在的缺陷面对单个IP地址或者IP地址较少的情况下比较有用。 应用层DDoS攻击使用真实IP地址攻击者的IP地址数量有限。2. 攻击者的IP地址在一定范围内轮询单个IP地址的请求频率会增加。基于以上两点Yahoo设计了一套算法根据IP地址和Cookie信息计算客户端的请求频率并进行拦截。该系统在整体架构上有一台master服务器集中计算所有IP地址的请求频率并将策略同步到每台Web服务器上。 存在的缺陷未开源
13.5、资源耗尽攻击
除CC攻击外还有一些利用Web Sever的漏洞或设计缺陷直接造成拒绝服务。
13.5.1、Slowloris攻击 Slowloris攻击原理是以极低的速度往服务器发送HTTP请求。由于WebSever对于并发的连接数都有一定的上限因此若是恶意地占用住这些连接不释放那么Web Sever的所有连接都将被恶意连接占用从而无法接受新的请求导致拒绝服务。 在正常的HTTP包头中是以两个CLRF表示HTTP Headers部分结束的。 Content-Length: 42\r\n\r\n 由于Web Server只收到了一个\r\n因此将认为HTTP Headers部分没有结束并保持此连接不释放继续等待完整的请求。此时客户端再发送任意HTTP头保持住连接即可。 当构造多个连接后服务器的连接数很快就会达到上限。此类拒绝服务攻击的本质实际上是对有限资源的无限制滥用。 13.5.2、HTTP POST DOS HTTP POST DOS的原理是在发送 HTTP POST包时指定一个非常大的Content-Length值然后以很低的速度发包比如10~100s 发一个字节保持住这个连接不断开。这样当客户端连接数多了以后占用住了Web Server 的所有可用连接从而导致DOS。本质也是针对Apache的MaxClients限制的。 要解决此类问题可以使用Web应用防火墙或者一个定制的Web Server安全模块。 13.5.3、Server Limit DOS web Server对 HTTP包头都有长度限制以Apache举例默认是8192字节。也就是说Apache所能接受的最大HTTP包头大小为8192字节这里指的是 Request Header如果是 Request Body则默认的大小限制是2GB。如果客户端发送的HTTP包头超过这个大小服务器就会返回一个4xx错误提示信息为: Your browser sent a request that this server could not understand.Size of a request header field exceeds server limit.假如攻击者通过XSS攻击恶意地往客户端写入了一个超长的 Cookie则该客户端在清空Cookie之前将无法再访问该Cookie所在域的任何页面。这是因为Cookie也是放在HTTP包头里发送的而 Web Server 默认会认为这是一个超长的非正常请求从而导致“客户端”的拒绝服务。 要解决此问题需要调整Apache配置参数LimitRequestFieldSize这个参数设置为0时对HTTP包头的大小没有限制。 通过以上几种攻击的介绍我们了解到“拒绝服务攻击”的本质实际上就是一种“资源耗尽攻击”因此在设计系统时需要考虑到各种可能出现的场景避免出现“有限资源”被恶意滥用的情况这对安全设计提出了更高的要求。 13.6、一个正则引发的血案ReDOS ReDOS是一种代码实现上的缺陷 ReDOS (Regular Expression Denial of Service) 是一种通过精心设计的恶意输入利用正则表达式的匹配过程来导致服务拒绝的攻击。ReDOS 攻击通常利用正则表达式引擎在处理复杂、低效正则表达式时的性能瓶颈使得服务器需要大量时间和资源进行匹配从而导致系统崩溃或变慢。 原理 ReDOS 攻击主要发生在使用“回溯算法”的正则表达式引擎中。当正则表达式中包含大量的“重复结构”如嵌套的分组、多重或模式等时匹配输入时可能会触发指数级的回溯。例如带有重复的 (a|aa) 或 (a) 结构的正则表达式在匹配特定长字符串时会因为回溯而导致计算时间急剧上升。 例 考虑一个简单的正则表达式 (a|aa)b用来匹配一个由 a 和 aa 组成的序列最后以 b 结尾。如果用户传入 aaaaaaaaaaaaaaaaaaaaaaaaaaaa 这样没有结尾的 b引擎会进行大量的回溯尝试导致系统资源被耗尽。 防御 ReDOS 的方法 限制正则表达式的复杂性避免使用容易导致回溯的重复结构比如 (a)(a|aa) 等。使用非回溯正则表达式引擎一些正则引擎如 RE2不使用回溯算法因而不会受到 ReDOS 攻击的影响。检测和过滤恶意输入提前过滤或限制输入的长度和复杂度降低攻击可能性。设置超时为正则匹配操作设置合理的超时时间避免因为长时间计算导致的系统资源耗尽。
13.7、小结 在本章中讲述了应用层拒绝服务攻击的原理和解决方案。应用层拒绝服务攻击是传统的网络拒绝服务攻击的一种延伸其本质也是对有限资源的无限制滥用所造成的。所以解决这个问题的核心思路就是限制每个不可信任的资源使用者的配额。在解决应用层拒绝服务攻击时可以采用验证码但验证码并不是最好的解决方案。Yahoo的专利为我们提供了更宽广的思路。在本章最后介绍了ReDOS这种比较特殊的拒绝服务攻击在应用安全中需要注意这个问题。 14、PHP安全
14.1、文件包含漏洞 其原理就是注入一段用户能控制的脚本或代码并让服务器端执行。“代码注入”的典型代表就是文件包含(File Inclusion)。文件包含可能会出现在JSP、PHP、ASP等语言中常见的导致文件包含的函数如下。 PHP: include(), include_once(), require(), require_once(), fopen(), readfile(), ...
JSP/Servlet: ava.io.File(), java.io.FileReader(), ...
ASP: include file, include virtual,...文件包含是PHP的一种常见用法主要有四个函数完成 include()
require()
include_once()
require_once()当使用这4个函数包含一个新的文件时该文件将作为PHP代码执行PHP内核并不会在意该被包含的文件是什么类型。所以如果被包含的是txt文件、图片文件、远程URL也都将作为PHP代码执行。这一特性在实施攻击时将非常有用。 要想成功利用文件包含漏洞需要满足下面两个条件: 1include()等函数通过动态变量的方式引入需要包含的文件; 2用户能够控制该动态变量。 14.1.1、本地文件包含 能够打开并包含本地文件的漏洞被称为本地文件包含漏洞(Local File Inclusion简称LFI)。 include /home/wwwrun/.$file..php;对于以上代码就存在LFI漏洞用户能够控制参数file当file值为../../etc/passwd时PHP将访问/etc/passwd.php文件为了使其正确的访问到/etc/passwd还需要做一个截断操作。 00截断 由于PHP内核是由C语言实现的因此使用了C语言中的一些字符串处理函数。在连接字符串时0字节\x00将作为字符串结束符。攻击者在最后加入一个0字节就能截断file变量之后的字符串即 l ../../etc/passwd\0通过Web输入时只需UrlEncode变成 ../../etc/passwd%00构造长目录 在一般的Web应用中0字节用户其实是不需要使用的因此完全可以禁用0字节但目录字符串在Windows下256字节、Linux下4096字节时会达到最大值最大值长度之后的字符将被丢弃。可以通过./来构造 ./././././././././././././abc或者 /abc或者 ../1/abc/../1/abc/../1/abc使用../../../来返回到上层目录中这种方式又被称为“目录遍历”Path Traversal常见的目录遍历漏洞还可以通过不同的编码方式来绕过一些服务器端逻辑。
防御方法
PHP配置open_basedir open_basedir 的作用是限制在某个特定目录下PHP能打开的文件其作用与safe_mode是否开启无关。限定用户可以控制的变量值 尽量避免包含动态的变量尤其是用户可以控制的变量。一种变通方式则是使用枚举将$file值枚举出来只处理这些值。
14.1.2、远程文件包含 如果PHP的配置选项allow_url_include为ON的话则include/require函数是可以加载远程文件的这种漏洞被称为远程文件包含漏洞Remote File Inclusion简称RFI)。 14.1.3、本地文件包含的利用技巧 远程文件包含漏洞之所以能够执行命令就是因为攻击者能够自定义被包含的文件内容。因此本地文件包含漏洞想要执行命令也需要找到一个攻击者能够控制内容的本地文件。有以下技巧 1包含用户上传的文件。 2包含data:// 或 php://input等伪协议。 3包含Session文件。 4包含日志文件比如Web Sever的access log。 5包含/proc/self/environ文件。 6包含上传的临时文件RFC1867 7包含其他应用创建的文件比如数据库文件、缓存文件、应用日志等需要具体情况具体分析。 1包含用户上传文件能否攻击成功取决于文件上传功能的设计比如要求知道用户上传后文件所在的物理路径有时这个路径很难猜到。在本书“文件上传漏洞”一章中给出了很多设计安全文件上传功能的建议。 2伪协议如php://input等需要服务器支持同时要求allow_url_include设置为ON。在 PHP5.2.0之后的版本中支持 data: 伪协议可以很方便地执行代码它同样要求allow_url_include为ON。 3包含Session文件的条件也较为苛刻,它需要攻击者能控制部分Session文件的内容。比如: php ×|s:19: ?php phpinfo(); ? PHP默认生成的Session文件往往存放在/tmp目录下比如: bash /tmp/ sess_SESSIONID 4包含日志文件是一种比较通用的技巧。因为服务器一般都会往 Web Server 的access_log里记录客户端的请求信息在 error_log里记录出错请求。因此攻击者可以间接地将PHP 代码写入到日志文件中在文件包含时只需要包含日志文件即可。 但需要注意的是如果网站访问量大的话日志文件有可能会很大比如一个日志文件有2GB)当包含一个这么大的文件时PHP进程可能会僵死。但 Web Server往往会滚动日志或每天生成一个新的日志文件。因此在凌晨时包含日志文件将提高攻击的成功性因为此时的日志文件可能非常小。 如果 httpd 的配置文件和日志目录完全猜不到怎么办?如果PHP的错误回显没有关闭那么构造一些异常也许能够暴露出 Web目录所在位置。此外还可以利用下面的方法。 5包含/proc/self/environ是一种更为通用的方法因为它根本不需要猜测被包含文件的路径同时用户也能控制它的内容。 http://www.website.com/view. php?page..../../../../proc/self/environ包含/proc/self/environ文件可能看到Web进程运行时的环境变量在用户可以控制的地方注入代码以完成攻击。 以上这些方法都要求PHP能够包含这些文件而这些文件往往都处于Web目录之外如果PHP配置了open_basedir则很可能会使得攻击失效。 但PHP创建的上传临时文件往往处于PHP 允许访问的目录范围内。包含这个临时文件的方法其理论意义大于实际意义。根据RFC1867PHP处理上传文件的过程是这样的 6PHP会为上传文件创建临时文件其目录在 php.ini的 upload_tmp _dir 中定义。但该值默认为空此时在Linux下会使用/tmp目录在 Windows下会使用C:\windows\temp目录。 该临时文件的文件名是随机的攻击者必须准确猜测出该文件名才能成功利用漏洞。PHP在此处并没有使用安全的随机函数因此使得暴力猜解文件名成为可能。在 Windows下仅有65535种不同的文件名。 14.2、变量覆盖漏洞
14.2.1、全局变量覆盖 变量如果未被初始化且能被用户所控制那么很可能会导致安全问题。而在 PHP中这种情况在register_globals为ON时尤其严重。 PHP中使用变量并不需要初始化因此register_globalsON时变量来源可能是各个不同的地方比如页面的表单、Cookie等。类似的通过GLOBALS获取的变量也可能导致变量覆盖。 防范措施 销毁全局变量必须使用GLOBALS如果实现代码关闭register_globals则一定要覆盖superglobals。 14.2.2、extract()变量覆盖
extract()函数能将变量从数组导入当前的符号表其函数定义如下
int extract ( array $var_array [, int $extract_type [, string $prefix ]] )$extract_type 可选用于指定 extract() 如何处理数组中的键与当前作用域已有变量名冲突的情况。常用的选项包括 EXTR_OVERWRITE覆盖已有的同名变量默认。EXTR_SKIP跳过已有的同名变量不覆盖。EXTR_PREFIX_SAME给同名变量加上指定的前缀。EXTR_PREFIX_ALL给所有变量加上指定的前缀。EXTR_PREFIX_INVALID只给无效或非法的变量名加前缀。
当用户可以控制传入 extract() 的数组时他们可以通过构造特定的键名来覆盖已有的关键变量。比如如果 PHP 程序在使用 extract() 时没有合理地限制输入攻击者可以覆盖诸如 $is_admin 或 $username 等变量从而改变程序逻辑进而进行攻击操作。 一种较为安全的做法是确定register_globals OFF后在调用extract()时使用EXTR_SKIP保证已有变量不会被覆盖。但extract()的来源如果能被用户控制则仍然是一种非常糟糕的使用习惯。同时还要留意变量获取的顺序在 PHP中是由php.ini中的variables_order所定义的顺序来获取变量的。 14.2.3、遍历初始化变量 常见的一些以遍历的方式释放变量的代码可能会导致变量覆盖。 14.2.4、import_request_variables变量覆盖
import_request_variables()将GET、POST、Cookie中的变量导入到全局使用这个函数只需要简单地指定类型即可。其中第二个参数是为导入的变量添加的前缀如果没有指定则将覆盖全局变量。
14.2.5、parse_str()变量覆盖
parse_str()函数往往被用于解析URL的query string但是当参数值能被用户控制时很可能导致变量覆盖。 还有一些变量覆盖的方法难以一次列全但有以下安全建议: 首先确保register_globals OFF。若不能自定义php.ini则应该在代码中控制。其次熟悉可能造成变量覆盖的函数和方法检查用户是否能控制变量的来源。最后养成初始化变量的好习惯。 14.3、代码执行漏洞 PHP 中的代码执行情况非常灵活但究其原因仍然离不开两个关键条件第一是用户能够控制的函数输入第二是存在可以执行代码的危险函数。 14.3.1、“危险函数”执行代码 在 PHP中能够执行代码的方.式远不止文件包含漏洞一种比如危险函数 popen()、system()、passthru()、exec()等都可以直接执行系统命令。 14.3.1.1、phpMyAdmin 3.4.3.1远程代码执行漏洞
14.3.1.2、MyBB 1.4 远程代码执行漏洞
从“找到敏感函数”到“成为一个代码执行漏洞”。
14.3.2、“文件写入”执行代码 在database.inc.php导入 zip文件时存在写文件操作但其对安全的判断过于简单导致用户可以将此文件内容修改为PHP代码。 14.3.3、其他执行代码方式
直接执行代码的函数。eval()、assert()、system()、exec()、shell_exec()、passthru()、escapeshellcmd()、pcntl_exec()等。文件包含函数include()、include_once()、require()、require_once()。本地文件写入。常见的有file_put_contents()、fwrite()、fputs()等。 需要注意的是写入文件的功能可以和文件包含、危险函数执行等漏洞结合最终使得原本用户无法控制的输入变成可控。在代码审计时要注意这种“组合类”漏洞。 preg_replace的第一个参数如果存在/e模式修饰符则允许代码执行。需要注意的是即便第一个参数中并没有e模式修饰符也是有可能执行代码的。这要求第一个参数中包含变量并且用户可控有可能通过注入/e%00 的方式截断文本注入一个“/e”。 动态函数执行。用户自定义的动态函数可以导致代码执行。Curly Syntax。PHP的Curly Syntax 也能导致代码执行它将执行花括号间的代码并将结果替换回去。回调函数执行代码。很多函数都可以执行回调函数当回调函数用户可控时将导致代码执行。unserialize()导致代码执行。unserialize()这个函数也很常见它能将序列化的数据重新映射为PHP变量。但是unserialize()在执行时如果定义了_destruct()函数或者是_wakeup()函数则这两个函数将执行。unserialize()代码执行有两个条件: 一是unserialize()的参数用户可以控制这样可以构造出需要反序列化的数据结构;二是存在_destruct()函数或者_wakeup()函数这两个函数实现的逻辑决定了能执行什么样的代码。
14.4、定制安全的PHP环境 除了熟悉各种 PHP漏洞外还可以通过配置php.ini来加固PHP的运行环境。 PHP官方也曾经多次修改 php.ini的默认设置。在本书中推荐 php.ini中一些安全相关参数的配置。 register_globals 当register_globalsON时PHP不知道变量从何而来也容易出现一些变量覆盖的问题。因此从最佳实践的角度强烈建议设置register_globalsOFF 这也是PHP新版本中的默认设置。 open_basedir open_basedir可以限制PHP只能操作指定目录下的文件。这在对抗文件包含、目录遍历等攻击时非常有用。我们应该为此选项设置一个值。需要注意的是如果设置的值是一个指定的目录则需要在目录最后加上一个“/”否则会被认为是目录的前缀。 open basedir / home /web/html/allow_url_include 为了对抗远程文件包含请关闭此选项一般应用也用不到此选项。同时推荐关闭的还有allow_url_fopen。 display errors 错误回显一般常用于开发模式但是很多应用在正式环境中也忘记了关闭此选项。 log_errors 在正式环境下用这个就行了把错误信息记录在日志里。 magic_quotes_gpc 推荐关闭它并不值得依赖请参考“注入攻击”一章)已知已经有若干种方法可以绕过它甚至由于它的存在反而衍生出一些新的安全问题。 cgi.fix_pathinfo 若 PHP 以CGI的方式安装则需要关闭此项以避免出现文件解析问题。 session.cookie_httponly 开启 HttpOnly。 session.cookie_secure 若是全站HTTPS则请开启此项。 safe_mode PHP的安全模式是否应该开启的争议一直比较大。一方面它会影响很多函数;另一方面它又不停地被黑客们绕过因此很难取舍。如果是共享环境比如App Engine)则建议开启safe_mode可以和 disable_functions 配合使用;如果是单独的应用环境则可以考虑关闭它更多地依赖于disable_functions控制运行环境安全。 disable_functions disable_functions能够在PHP中禁用函数。这是把双刃剑禁用函数可能会为开发带来不便但禁用的函数太少又可能增加开发写出不安全代码的几率同时为黑客获取 webshell提供便利。
14.5、小结