from:http://drops./tips/12751 0x01 整体
学习代码审计的目标是能够独立完成对一个CMS的代码安全监测。其通用的思路有: 通读全文代码,从功能函数代码开始阅读,例如include 文件夹下的common_fun.php ,或者有类似关键字的文件。 看配置文件,带有config 关键字的文件,找到mysql.class.php文件的connect()函数,查看在数据库连接时是否出现漏洞。 继续跟读首页文件,index.php ,了解程序运作时调用了哪些函数和文件 以index.php文件作为标线,一层一层去扩展阅读所包含的文件,了解其功能,之后进入其功能文件夹的首页文件,进行扩展阅读。
0x02 各种洞洞
a.文件操作漏洞能不用文件名参数就不用 尽量不要让用户可控 平行用户的权限 管理员的权限 操作权限 禁止传入参数类似于这种 .. ,/ ,\ 检查传入的参数,做出限制,停止程序往下执行
1.文件包含漏洞:(1) 本地文件包含: 

(2) 远程文件包含: (3) 文件包含截断: %00截断(php版本小于5.3) 问号截断(问号后面相当于请求的参数,伪截断) 英文(.) 反斜杠(/) 截断
2.文件读取(下载)漏洞:搜索关键函数: file_get_contents() ,highlight_file() ,fopen() ,read file() ,fread() ,fgetss() , fgets() ,parse_ini_file() ,show_source() ,file() 等
3.文件上传漏洞:搜索关键函数: move_uploaded_file() 接着看调用这个函数的代码是否存在为限制上传格式或者可以绕过。
(1) 未过滤或本地过滤:服务器端未过滤,直接上传PHP格式的文件即可利用。 (2) 黑名单扩展名过滤: 
不被允许的文件格式.php ,但是我们可以上传文件名为1.php (注意后面有一个空格) (3) 文件头 content-type 验证绕过: (4) 防范: 4.文件删除漏洞:搜索关键函数: Metinfo的任意文件删除漏洞: 
$action = delete 即可删除.sql 的文件,如果文件不是sql 直接删除提交的文件名
target.com/recovery.php?&action=delete&filename=../../index.php
b.代码执行漏洞1.代码执行函数:搜索关键函数: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() ');【√】 2.动态函数执行:动态函数后门: 1 2 3 | <>
$_GET [ 'a' ]( $_GET [ 'b' ]);
>
|

3.命令执行函数:搜索关键函数:system() , exec() , shell_exec() , passthru() ,pcntl_exec() , popen() ,proc_open() (1) popen 和proc_open() : 1 2 3 |
popen( 'whoami >> /Users/bingdaojueai/Desktop/1.txt' , 'r' );
>
|
所在路径就会出现一个1.txt 里面的内容为命令执行后的结果 (2) 反引号命令执行: echo whoami ; 直接就可以执行命令 双引号和单引号的区别: 1 2 3 | $a = 1
echo ' $a ' output:1
echo ' $a ' output: $a
|
双引号时,可以直接解析变量,造成代码执行漏洞,过狗绕过。 c.变量覆盖漏洞1.函数使用不当: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 )
2.$$变量覆盖:

d.逻辑漏洞需要思考的问题: 程序是否可以重复安装 修改密码是否存在越权修改其他用户密码 找回密码验证码是否可以暴力破解 cookie是否可以预测 验证存在绕过
1.等于与存在判断绕过:(1) in_array() : 比较之前会自动转换类型 

(2)is_numeric() :当传入参数为hex时 直接通过并返回true 并且MYSQL可以直接使用hex编码代替字符串明文 可以二次注入 并且可能造成XSS漏洞 (3)双等于== 和三等于=== : 2.账户体系中的越权问题:(1) 未exit /return /die : 1 2 3 4 5 6 7 | <>
if ( file_exists ('install.lock)){
header( 'Location:xxx.com' );
//exit();
}
echo 'test' ;
>
|
test 依旧会被输出,替换成安装流程,PHP依旧会进行。 (2) 支付漏洞: 客户端修改单价 客户端修改总价和购买数量 服务端未校验严格 重复发包利用时间差: 1 2 3 4 5 6 7 | <>
if (check_money( $price )){
//Do something
//花费几秒
$money = $money - $price ;
}
>
|
可能导致漏洞函数: str_replace() 
1 2 3 4 5 6 7 | <>
$a = addslashes ( $_GET [ 'a' ]);
$b = addslashes ( $_GET [ 'b' ]);
echo '$a $b ' ;
$c = str_replace ( $a , '' , $b );
echo trim( $c );
>
|

e.会话认证漏洞f.二次漏洞1.类型:

2.技巧:(1) 钻GPC等转义的空子: (2)字符串问题:
|