之前看了seay写的PHP代码审计的书,全部浏览了一遍,作为一个代码审计小白,希望向一些和我一样的小白的人提供一下我的收获,以及一个整体的框架和常见漏洞函数。这也算是这本书的一个学习笔记吧,可以结合我捋顺的思路来看这本书。: )
学习代码审计的目标是能够独立完成对一个CMS的代码安全监测。其通用的思路有:
include
文件夹下的common_fun.php
,或者有类似关键字的文件。config
关键字的文件,找到mysql.class.php文件的connect()函数,查看在数据库连接时是否出现漏洞。index.php
,了解程序运作时调用了哪些函数和文件 以index.php文件作为标线,一层一层去扩展阅读所包含的文件,了解其功能,之后进入其功能文件夹的首页文件,进行扩展阅读。..
,/
,\
检查传入的参数,做出限制,停止程序往下执行(1) 本地文件包含:
include()/include_once()
,require()/require_once()
寻找可控变量 (2) 远程文件包含:
allow_url_include = on
(3) 文件包含截断:
搜索关键函数:
file_get_contents()
,highlight_file()
,fopen()
,read file()
,fread()
,fgetss()
, fgets()
,parse_ini_file()
,show_source()
,file()
等
搜索关键函数:
move_uploaded_file()
接着看调用这个函数的代码是否存在为限制上传格式或者可以绕过。
(1) 未过滤或本地过滤:服务器端未过滤,直接上传PHP格式的文件即可利用。
(2) 黑名单扩展名过滤:
.asp
,.cdx
, .asa
,.cer
等。不被允许的文件格式.php
,但是我们可以上传文件名为1.php
(注意后面有一个空格)
(3) 文件头 content-type
验证绕过:
getimagesize()
函数:验证文件头只要为GIF89a,就会返回真。$_FILES["file"]["type"]
的值 就是人为限制content-type为可控变量。(4) 防范:
in_array()
或 利用三等于===
对比扩展名。md5(time() + rand(1,1000))
。搜索关键函数:
unlink()
利用回溯变量的方式 session_destroy()
,可以删除文件,现已基本被修复。Metinfo的任意文件删除漏洞:
$action = delete
即可删除.sql
的文件,如果文件不是sql
直接删除提交的文件名
target.com/recovery.php?&action=delete&filename=../../index.php
搜索关键函数:eval()
, assert()
, preg_replace()
, call_user_func()
, call_user_func_array()
, array_map()
(1) preg_replace()
函数:
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
当$pattern处存在e修饰符时,$replacement 会被当做php代码执行。
(2)mixed call_user_func( callable $callbank [ , mixed $parameter [ , mixed $…)
:
第一个参数为回调函数,第二个参数是回调函数的参数
(3)eval()
和assert()
:
当assert()的参数为字符串时 可执行PHP代码
【区分】:
eval(" phpinfo(); ");【√】 eval(" phpinfo() ");【X】
assert(" phpinfo(); ");【√】 assert(" phpinfo() ");【√】
动态函数后门:
#!php
<?php
$_GET['a']($_GET['b']);
?>
搜索关键函数:system()
, exec()
, shell_exec()
, passthru()
,pcntl_exec()
, popen()
,proc_open()
(1) popen
和proc_open()
:
#!php
<?php
popen( 'whoami >> /Users/bingdaojueai/Desktop/1.txt', 'r' );
?>
所在路径就会出现一个1.txt 里面的内容为命令执行后的结果
(2) 反引号命令执行:
echo whoami
; 直接就可以执行命令
双引号和单引号的区别:
#!php
$a = 1
echo " $a " output:1
echo ' $a ' output:$a
双引号时,可以直接解析变量,造成代码执行漏洞,过狗绕过。
int extract( array &$var_array , int $extract_type = EXTR_OVERWRITE , string $prefix = null )
void parse_str( string $str , array &$arr )
bool import_request_variables( string $type , string $prefix )
需要思考的问题:
(1) in_array()
: 比较之前会自动转换类型
(2)is_numeric()
:当传入参数为hex时 直接通过并返回true 并且MYSQL可以直接使用hex编码代替字符串明文 可以二次注入 并且可能造成XSS漏洞
(3)双等于==
和三等于===
:
in_array()
是一样的问题。(1) 未exit
/return
/die
:
#!php
<?php
if(file_exists('install.lock)){
header("Location:xxx.com");
//exit();
}
echo "test";
?>
test 依旧会被输出,替换成安装流程,PHP依旧会进行。
(2) 支付漏洞:
重复发包利用时间差:
#!php
<?php
if (check_money($price)){
//Do something
//花费几秒
$money = $money - $price;
}
?>
可能导致漏洞函数: str_replace()
#!php
<?php
$a = addslashes($_GET['a']);
$b = addslashes($_GET['b']);
echo "$a<br>$b<br>";
$c = str_replace($a,'',$b);
echo trim($c);
?>
COOKIE验证:没有使用SESSION验证,将信息直接保存在COOKIE中
审计代码时,查看登录处代码
==>
SQL注入 / XSS(1) 钻GPC等转义的空子:
$_SERVER
变量:PHP5以后,$_SERVER取到的header不再受GPC影响,就算开启特殊字符也不会被转义,存在注入编码问题转换:
%df '
单引号自动被转义成(%5c),同时%df
与%5c
连在一起组合成運
字单引号依然在,成功闭合。【php与mysql交互过程中发生的编码转换问题】mb_convert_encoding()
:
#!php
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<?php
$sql = "WHERE id='".urldecode("-1%df%5c' == ")."'";
print_r(mb_convert_encoding($sql,"UTF-8","GBK"));
?>
(2)字符串问题:
字符串截断:
%00空字符截断:【PHP版本小于5.3】
#!php
<?php
include($_GET['file'].'.php');
//1.php?file=2.txt%00
//2.txt里面是 <?php phpinfo()?>
?>
iconv函数字符编码转换截断:【对PHP版本有要求】
#!php
chr(128)—chr(255)可以截断字符
<?php
$a = '1'.chr(130).'2’;
echo $a."<br>"; //1�2
echo iconv("UTF-8", "GBK", $a); //1
?>
php:// 输入输出流:
#!php
<?php
include($_GET[‘file']);
?>
1.php?file=php://filter/convert.base64-encode(内容被base64编码)/resource=example.txt(远程文件)
php代码解析标签:
<script language="php">…</script>
<?…?>
:php3.0.4版本后可用<%…%>
:asp标签,需要asp_tags=on,默认是off正则表达式:
报错注入:
windows findfirstfile
利用:若要搜索12345.txt文件,可使用1<<
来代替或者12<<
,不可以单独使用一个"<"
或">"
,因为单独一个只是代表了一个字符,两个代表多个字符。
自己走上安全这条路既是兴趣也是偶然,选择白盒完全是因为喜欢php,毕竟是初识代码审计,seay的书确实帮了我不少,抱作者大腿(我是萌妹纸),希望这篇文章能够帮助像我一样小白的人,花了两天总结的,如果有什么缺陷也等着大家指出。
不会开发的谈审计都是耍流氓!:)