读《白帽子讲Web安全》之服务器脚本应用安全

【第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向服务器发起请求时,提交两个相同参数,服务器会如何选择。不同服务器反应不同,又是会导致一些安全问题。

在具体的环境中,注意服务器环境的参数顺序。


你可能感兴趣的:(文件上传,sql注入,访问控制,加密算法,php安全,认证与会话管理,Web框架安全,拒绝服务)