【第7章 注入攻击】
注入攻击的本质:是把用户输入的数据当做代码执行。
这里有两个关键条件:
第一个是用户能够控制输入;
第二个是原本程序要执行的代码,拼接了用户的输入。
1、SQL注入第一次为公众所知,实在1998年的著名黑客杂志《Phrack》第54期上,一位名叫rfp的黑客发表了一篇题为“NT Web Technology Vulnerabilities”的文章。
2、所谓“盲注”,就是在服务器没有错误回显时完成的注入攻击。
服务器没有错误回显,对于攻击者来说缺少了非常重要的“调试信息”,所以攻击者必须找到一个方法来验证注入的SQL语句是否得到执行。
最常见的盲注验证方法是,构造简单的条件语句,根据返回页面是否发生变化,来判断SQL语句是否得到执行。
3、Timing Attack是盲注的一种高级技巧。在不同的数据库中,都有类似于BENCHMARK()的函数,这个函数可以让同一个函数执行若干次,使得结果返回的时间比平时要长;通过时间长短的变化,可以判断注入语句是否执行成功。
4、搜集、学习和练习不同数据库的常用数据库攻击技巧。
1)猜数据库版本
2)命令执行
3)攻击存储过程
4)编码问题:比如GBK的双字节。
要解决这些编码问题,需要统一数据库、操作系统、Web应用所使用的字符集,以避免各层对字符的理解存在差异。统一设置为UTF-8是一个很好的方法。
5)超长值得阶段问题
5、正确地防御SQL注入
1)找到所有的SQL注入漏洞
2)修补这些漏洞
6、防御方法
1)防御SQL注入的最佳方式,就是使用预编译语句,绑定变量。
2)使用存储过程
3)检查数据类型
4)使用安全函数
7、其他注入攻击
1)XML注入
2)代码注入
3)CRLF注入:
CRLF实际上是两个字符:CR是Carriage Return(ASCII 13,\r),LF是Line Feed(ASCII 10,\n)。\r\n这两个字符是用于表示换行的,期十六进制编码分别为 0x0d、0x0a。
CRLF常被用作不同语义之间的分隔符。因此通过“注入CRLF字符”,就有可能改变原有的语义。
【第8章 文件上传漏洞】
定义:文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,有时候几乎没有什么技术门槛。
“文件上传”本身没有问题,但有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
在大多数情况下,文件上传漏洞一般都是指“上传Web脚本能够被服务器解析”的问题。
要完成这个攻击,要满足如下几个条件:
1)首先,上传的文件能够被Web容器解释执行。所以文件上传后所在的目录要是Web容器所覆盖到的路径。
2)其次,用户能够从Web上访问这个文件。
3)最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则可能导致攻击不成功。
1、某些时候,在文件名后添加一个%00 字节,则可以截断某些函数对文件名的判断。因为在许多语言的函数中,比如在C、PHP等语言的常用字符串处理函数中,0x00被认为是终止符。受影响的环境有Web应用和一些服务器。
注意:%00字符截断的问题不只在上传文件漏洞中有所利用,因为这是一个被广泛用于字符串处理函数的保留字符,因此在各种不同的业务逻辑中都可能出现问题。
2、黑名单策略,安全上容易出问题。
3、Apache1.x、2.x中,对文件名的解析存在以下特性:从后往前解析,直到遇见一个Apache认识的文件类型为止。
比如,phpshell.php.rar.rar,因为Apache不认识rar,所以遍历到最后为php
4、IIS和Windows环境下曾经出现过截断符号为分号的漏洞“;”
5、曾经爆出过,在PHP5.2.12和5.3.1版本下,Nginx配置fastcgi 使用PHP时,会存在文件类型解析问题。映射URI时,两个环境变量很重要,一个是PATH_INFO,一个是SCRIPT_FILENAME。
6、设计安全的文件上传功能
1)文件上传的目录设置为不可执行
2)判断文件类型
3)使用随机数改写文件名和文件路径
4)单独设置文件服务器的域名。
【第9章 认证与会话管理】
1、认证的目的是为了认出用户是谁,而授权的目的是为了决定用户能够做什么。
(Who am I? What can I do?)
2、认证实际上就是一个验证凭证的过程。
3、密码必须以不可逆的加密算法,或者是单向散列函数算法,加密后存储在数据库中。
4、Session那些事:
1)密码与证书等认证手段,一般仅仅用于登录(Login)的过程。当登录完成后,用户访问网站的页面,不可能每次浏览器请求页面时都再使用密码认证一次。因此,当认证成功后,就需要替换一个队用户透明的凭证。这个凭证就是SessionID.
2)当用户登录完成后,在服务器就会创建一个新的会话(Session),会话中会保存用户的状态和相关信息。服务器维护所有在线用户的Session,此时的认证,只需要知道是哪个用户在浏览当前的页面即可。为了告诉服务器应该使用哪一个Session,浏览器需要把当前用户持有的SessionID告知浏览器。
3)最常见的做法就是把SessionID加密后保存在Cookie中,因为Cookie会随着HTTP请求头发送,且受到浏览器同源策略的保护。
4)SessionID一旦在生命周期内被窃取,就等同于账户失窃。Session劫持就是一种通过窃取用户SessionID后,使用该SessionID登录进目标账户的攻击方法。
5)SessionID除了可以保存在Cookie中外,还可以保存在URL中,作为请求的一个参数。
在手机操作系统中,由于很多手机浏览器暂不支持Cookie,所以只能将SessionID作为URL的一个参数用于认证。
其中一个典型的场景就是通过Referer泄露URL中的sid,QQ的WAP邮箱曾经出现过此漏洞。
6)Session Fixation攻击,由于登陆前后的SessionID未改变造成的,攻击者构造一个带有sid的链接,发给目标用户,目标用户点开登录,然后sid也没变,然后攻击者也可以用这个sid登陆了。
7)Session保持攻击:通过不停地发起访问请求,让Session一直“活”下去
5、单点登录(SSO)
目前互联网上最为开放和流行的单点登录系统是OpenID。
【第10章 访问控制】
定义:访问控制,或者说权限控制,广泛用于各个系统中。抽象地说,都是某个主体(subject)对某个客体(object)需要实施某种操作(operation),而系统对这种操作的限制就是访问控制。
1、Linux 系统中,一般文件可以执行的操作位“读”、“写”、“执行”三种(当然还有一种特殊权限),分别由r、w、x表示。这三种操作同时对应着三种主体:文件拥有者、文件拥有者所在的用户组、其他用户。
主体、客体、操作者三者的对应关系,构成了访问控制表。
2、垂直权限管理,比如RBAC(Role-Based Access Control基于角色的访问控制)。垂直权限管理可以说是一种“基于角色的访问控制”。
3、水平权限管理,是一种“基于数据的访问控制”。
注意:在今天的互联网中,垂直权限问题已经得到了普遍的重视,并已经有了很多成熟的解决方案。但水平权限问题却尚未得到重视。
4、OAuth:是一个在不提供用户名和密码的情况下,授权第三方应用访问Web资源的安全协议。
OAuth 1.0于2007年12月公布。
涉及3个角色:
1)Consumer:消费方(Client)
2)Service Provider:服务提供方(Server)
3)User:用户(Resource Owner)
5、访问控制设计方案是都应满足“最小权限原则”。
【第11章 加密算法与随机数】
1、常见的加密算2法通常分为“分组加密算法”和“流加密算法”两种。
分组加密算法基于“分组”(block)进行操作。
流加密算法,则每次只处理一个字节,密钥独立于消息之外,两者通过异或实现加密与解密。
2、Reused Key Attack
在流密码的使用中,最常见的错误便是使用同一个密钥进行多次加解密。这使得破解流密码变得非常简单。在这种攻击下,攻击者不需要知道密钥即可还原出明文。
3、Bit-flipping Attack
在密码学中,攻击者在不知道明文的情况下,通过改变密文,使得明文按其需要的方式发生改变的攻击方式,称为“Bit-flipping Attack”。
4、弱随机IV(初始化向量)的问题
5、WEP破解
WEP在加密过程中,有两个关键因素,一个是初始化向量IV,一个是对消息的CRC-32较验。而这两者都可以通过一些方法克服。
6、分组加密中常见的加密模式有:ECB、CBC、CFB、OFB、CTR等。
如果加密模式被攻击,不论加密算法的密钥有多长,都可能不再安全。
7、分组加密中ECB(电码簿)模式的缺陷
对于ECB模式来说,改变分组密文的顺序,将改变解密后额明文顺序;替换某个分组密文,解密后该对应分组的明文也会被替换,而其他分组不受影响。
注意:当需要加密的明文多于一个分组长度时,应该避免使用ECB模式。
8、Padding Oracle Attack
以CBC模式为例,2010年曝出过ASP.NET存在的Padding Oracle问题。它可以再不知道密钥的情况下,通过对padding bytes的尝试,还原明文,或者构造出任意明文的密文。
9、基本原则:密码系统的安全性应该依赖于密钥的复杂性,而不应该依赖于算法的保密性。
10、密钥管理中最常见的错误,就是将密钥硬编码在代码里。
1)代码被广泛传播,尤其是开源的
2)软件开发团队成员都能查看代码,从而获取硬编码的密钥。开发团队流动性较大,可能会泄露代码
对于第一种情况,如果一定要将密钥硬编码在代码中,我们尚可通过Diffie-Hellman交换密钥体系,生成公私钥来完成密钥的分发。
对于第二种情况,则只能通过改善密钥管理来保护密钥。
11、对于Web应用来说,常见的做法是将密钥(包括密码)保存在配置文件或者数据库中。在使用时由程序读出密钥并加载进内存。密钥所在的配置文件或数据库需要严格的控制访问权限,同时也要确保运维或DBA中具有访问权限的人越少越好。
12、在应用发布到生产环境时,需要重新生成新的密钥或密码,以免与测试环境中使用的密钥相同。
13、伪随机数(pseudo random number)问题
伪随机数不够随机。
密码学上的安全伪随机数应该是不可压缩的。对应的“真随机数”,则是通过一些物理系统生成的随机数,比如电压的波动、硬盘磁头读/写时的寻道时间、空中电磁波的噪声等。
14、时间真的随机吗?
时间是顺序增长的,可以用时间上进行预测,从而存在安全隐患。
注意:不要把时间函数当成随机数使用。
15、破解伪随机数算法的种子
伪随机数是由数学算法实现的,它真正随机的地方在于“种子(seed)”。种子一旦确定后,再通过同一伪随机数算法计算出来的随机数,其值是固定的,多次计算所得值得顺序也是固定的。
16、在重要或敏感的系统中,一定要使用足够强壮的随机数生成算法。
Java中,可以使用java.security.SecureRandom。
在Linux 中,可以使用/dev/random 或者 /dev/urandom来生曾随机数,只需要读取即可。
除了以上方法为,在算法上还可以通过多个随机数的组合,以增加随机数的复杂性。
17、小结
在加密算法的选择和使用上,有以下最佳实践:
1)不要使用ECB模式;
2)不要使用流密码(比如RC4);
3)使用HMAC-SHA1代替MD5(甚至是代替SHA1);
4)不要使用相同的key做不同的事情
5)salts与IV需要随机产生;
6)不要自己实现加密算法,尽量使用安全专家已经实现好的库;
7)不要依赖系统的保密性。
当你不知道该如何选择时,有以下建议:
1)使用CBC模式的AES256用于加密;
2)使用HMAC-SHA512用于完整性检查;
3)使用带salt的SHA-256或SHA-512用于Hashing.
18、Understanding MD5 Length Extension Attack
曾经大家的眼光都放在Padding Oracle上,而有意无意地忽略了Flickr API的问题。而Flickr API签名这个漏洞,实际上用的是MD5 Length Extension Attack。
1)什么是Length Extension Attack?
以MD5为例,首先算法将消息以512bit(也就是64字节)的长度分组。最后一组必然不足512bit,这时算法就会自动往最后一组中填充字节,这个过程被称为padding。
而 Length Extension 是这样的:
当知道MD5(secret)时,在不知道secret的情况下,可以很轻易地推算出MD5(secret||padding||m),这里m是任意数据。
2)Length Extension 使得可以再原文之后附加任意值,并计算出新的哈希。最常见的地方就是签名。
3)很多哈希算法都存在 Length Extension 攻击,这是因为这些哈希算法都使用了 Merkle-Damgard hash construction进行数据压缩,流行算法比如MD5、SHA-1都受到影响。
【第12章 Web框架的安全】
1、实施安全方案,要达到好的效果,必须要完成两个目标:
1)安全方案正确、可靠
2)能够发现所有可能存在的安全问题,不出现遗漏。
只有深入理解漏洞原理之后,才能设计出真正有效、能够解决问题的方案。
2、在Web开发中,使用MVC架构师一种流行的做法。MVC是Model-View-Controller的缩写。
它将Web应用分为三层,View层负责用户视图、页面展示等工作;Controller负责应用的逻辑实现,接收View层传入的用户请求,并转发给对应的Model做处理;Model则实现模型,完成数据的处理。
从数据的流入来看,用户提交的数据先后流经了View层、Controller、Model层,数据的流出恰好相反。、
牢牢把握住数据这个关键因素。在MVC框架中,通过切片、过滤器等方式,往往能对数据进行全局处理,这为设计安全方案提供了极大便利。
一个优秀的安全方案:在正确的地方,做正确的事情。
3、在View层,可以解决XSS问题。
4、CSRF攻击的目标,一般都会产生“写数据”的操作URL,比如“增”、“删”、“改”;而读数据操作并不是CSRF攻击的目标,因为在CSRF的攻击过程中攻击者无法获取到服务器端返回的数据。
在Web应用中,有必要对“读操作”和“写操作”予以区分,比如要求所有的“写操作”都使用HTTP POST。
5、HTTP Headers管理,比如针对HTTP返回头的CRLF注入。
6、使用ORM(Object/Relation Mapping)框架对SQL注入是有积极意义的。我们知道对抗SQL注入的最佳方式就是使用“预编译绑定变量”。
7、在设计Web框架安全解决方案时,还需要保存好安全检查的日志。
8、Web框架自身的安全。因为Web框架本身也是应用程序的一个组成部分。
【第13章 应用层拒绝服务攻击】
DDOS攻击被认为是安全领域中最难解决的问题之一,迄今为止也没有一个完美的解决方案。
本章主要讨论Web安全中的“应用层”拒绝服务攻击。
1、DDOS又称分布式拒绝服务,全称是Distributed Denial of Service。
DDOS本是利用合理的请求造成资源过载,导致服务不可用。比如一个停车场总共有100个车位,当100个车位都停满车后,再有车想要进来,就必须等已有的车先出去才行。要是已有的车一直不出去。
2、应用层DDOS
不同于网络层的DDOS,由于发生在应用层,因此TCP三次握手已经完成,连接已经建立,所以发起攻击的IP地址也都是真实的。但应用层DDOS有时甚至比网络层DDOS更可怕,因为今天几乎所有的商业Anti-DDOS设备,只在对抗网络层DDOS的效果较好,对应用层DDOS攻击缺乏有效的对抗手段。
3、CC攻击
“CC攻击”的前身是一个叫fatboy的攻击程序,当时黑客为了挑战绿盟的一款反DDOS设备开发了它。绿盟有一款叫“黑洞(Collapasar)”的反DDOS设备,能够有效地清洗SYN Flood等有害流量。而黑客则挑衅式的将fatboy所实现的攻击方式命名为:Challenge Collapasar(简称CC),意指在黑洞的防御下,仍然能够有效完成拒绝服务攻击。
CC攻击原理非常简单,就是对一些消耗资源较大的应用页面不断发起正常的请求,已达到消耗服务端资源的目的。
在Web应用中,查询数据库、读写硬盘文件等操作,相对会消耗比较多的资源。
4、限制请求频率,在应用中针对每个“客户端”做一个请求频率的限制。
5、应用代码做好性能优化。
6、网络架构上做好优化。
7、验证码的核心是识别人和机器。
验证码的英文简称是CAPTCHA(Completely Automated Public Turing Test to Tell Computers and Humans Apart,全自动区分计算机和人类的图灵测试)。
8、其实,在人机识别方面,我们还能在做一些工作。
一种比较可靠的方法是让客户端解析一段JS,并给出正确地运行结果。因为大部分的自动化脚本就是直接构造HTTP包完成的,并非在浏览器环境,无法正确计算JS。
9、Slowloris攻击:由于Web Server对并发的连接数有一定的上限,因此若是恶意占用这些连接不释放,就可导致拒绝服务。
10、此类拒绝服务的本质,实际上是对有限资源的无限制滥用。
11、HTTP POST DOS
12、Server Limit DOS:比如Cookie超长导致服务器认为非正常请求。
13、一个正则引发的血案:ReDOS
当正则表达式写得不好时,就有可能被恶意输入利用,消耗大量资源,从而造成DOS。
正则表达式是基于NFA(Nondeterministic Finite Automaton)的,它是一个状态机,每个状态和输入符号都可能有许多不同的下一个状态。正则解析引擎将遍历所欲可能的路径直到最后。如果一个正则表达式的遍历路径太多,极大增加正则引擎解析数据时的消耗。
【第14章 PHP安全】
1、文件包含漏洞
1)PHP主要有4个函数完成文件包含:include() require() include_once() require_once(),
当使用这个4个函数包含一个新的文件时,该文件将作为PHP代码执行,PHP内核并不会在意该被包含的文件是什么类型
2)本地文件包含
3)远程文件包含
4)PHP内核是由C语言实现的,0字节(\x00)将作为字符串截断符。
5)%25的原型就是%
2、本地文件包含的利用技巧
1)包含用户上传的文件
2)包含data://或 php://input 等伪协议。
3)包含Session文件
4)包含日志文件,比如Web Server 的accesss log
5)包含/proc/self/environ文件
6)包含上传的临时文件
7)包含其他应用创建的文件,比如数据库文件、缓存文件、应用日志等,需要具体情况具体分析。
上传文件是否被更改、物理路径、相对路径能够猜到都是问题。
注意:如果网站访问量大, 日志文件可能会很大(比如一个日志2GB),当包含一个这么大文件时,PHP进程可能会僵死。但Web Server往往会滚动日志,或每天生成一个新的日志文件。因此凌晨包含日志文件,将提高攻击的成功性。
3、变量覆盖漏洞
如全局变量覆盖、extract()变量覆盖、遍历初始化变量、import_request_variables变量覆盖、parse_str()变量覆盖、mb_parse_str()等。
4、针对变量覆盖的安全建议:
1)首先,确保register_globals = OFF.若补丁自定义php.ini,则应该在代码中控制。
2)其次,熟悉可能造成变量覆盖的函数和方法,检查用户能否控制变量的来源。
3)最后,养成初始化变量的好习惯。
5、代码执行漏洞
1)危险函数:popen() system() passthru() exec() eval()等
2)“文件写入”执行代码
3)其他指定代码的方式
直接执行代码的函数、文件包含、本地文件写入、preg_replace()代码执行、动态函数执行、Curly Syntax 、回调函数指定代码、unserialize()导致代码执行
6、挖掘漏洞的过程
通常需要先找到危险函数,然后回溯函数的调用过程,最终看在整个调用的过程中用户是否有可能控制输入。
7、定制安全的PHP环境
1)register_globals:建议关闭。
2)open_basedir:限制PHP只能操作指定目录下的文件。
3)allow_url_include,allow_url_fopen:为了对抗远程文件包含,请关闭。
4)display_errors:错误回显,一般用于开发模式。
5)log_errors:正式环境下用这个,把错误信息记到日志中。
6)magic_quotes_gpc:推荐关闭,它并不值得依赖,已知已经有若干种方法可以绕过它。
7)cgi.fix_pathinfo:若PHP以CGI方式安装,则需要关闭此项,以避免出现文件解析问题。
cgi.fix_pathinfo = 0
8)session.cookie_httponly = 1:开启HttpOnly
9)session.cookie_secure = 1:若是全站HTTPS,请开启此项。
10)safe_mode:
PHP的安全模式是否应该开启的争议一直比较大。一方面,它会影响很多函数,另一方面,它又不停地被黑客绕过,因此很难取舍。如果是共享环境,(比如App Engine),则建议开启safe_mode,可以和disable_functions配合使用;如果是单独的应用环境,则可以考虑关闭它,更多依赖disable_functions。
11)disable_functions:禁用一些函数和类
【第15章 Web Server配置安全】
1、Apahce我们说一般就是指 Apache Httpd。
2、Web Server的安全我们关注亮点:一是Web Server本身是否安全;而是WebServer 是否提供了可使用的安全功能。
3、Apache安全
纵观Apahce的漏洞史,大部分高危是Apache的Module造成的,Apache核心的高危漏洞几乎没有。
1)检查Apahce的Module安装情况,根据“最小权限原则”,尽可能减少不必要的Module,对于要使用的Module,则检查其对应版本是否存在已知的安全漏洞。
2)指定Apache进程以单独的身份运行,通常要为Apache建立一个user/group。
注意,Apahce以root或者amin身份运行是一个非常糟糕的决定。
3)配置一些安全参数
4)保护好Apache log
4、Nginx安全
就软件本身来看,Nginx与Apahce最大的区别在于,检查Apache安全时更多的要关注Module的安全,而Nginx则需要注意软件本身的安全,及时升级软件版本。
5、jBoss
jBoss是J2EE环境中的一个流行的Web容器,但是jBoss在默认安装时提供的一些功能不太安全,配置不好容易造成远程命令执行。
比如jBoss安装时,会有一个管理后台,叫 JMX-Console,8080端口访问/jmx-console。默认安装时访问JMX-Console是没有认证的。要移除JMX-Console,只需要删除jmx-console.war和web-console.war即可。
6、Tomcat
和jBoss类似,8080端口,某认一个管理后台,可以导致远程命令执行
7、HTTP Parameter Pollution
就是通过GET或POST向服务器发起请求时,提交两个相同参数,服务器会如何选择。不同服务器反应不同,又是会导致一些安全问题。
在具体的环境中,注意服务器环境的参数顺序。