您好,欢迎访问一九零五行业门户网

代码审计入门总结

0x00 简介 之前看了seay写的php代码审计的书,全部浏览了一遍,作为一个代码审计小白,希望向一些和我一样的小白的人提供一下我的收获,以及一个整体的框架和常见漏洞函数。这也算是这本书的一个学习笔记吧,可以结合我捋顺的思路来看这本书。: )
0x01 整体 学习代码审计的目标是能够独立完成对一个cms的代码安全监测。其通用的思路有:
通读全文代码,从功能函数代码开始阅读,例如 include 文件夹下的 common_fun.php ,或者有类似关键字的文件。 看配置文件,带有 config 关键字的文件,找到mysql.class.php文件的connect()函数,查看在数据库连接时是否出现漏洞。 继续跟读首页文件, index.php ,了解程序运作时调用了哪些函数和文件 以index.php文件作为标线,一层一层去扩展阅读所包含的文件,了解其功能,之后进入其功能文件夹的首页文件,进行扩展阅读。 0x02 各种洞洞 a.文件操作漏洞 能不用文件名参数就不用 尽量不要让用户可控 平行用户的权限 管理员的权限 操作权限 禁止传入参数类似于这种 .. , / , \ 检查传入的参数,做出限制,停止程序往下执行 1.文件包含漏洞: (1) 本地文件包含:
一般存在于模块加载,模板加载,cache调用 包括函数: include()/include_once() , require()/require_once() 寻找可控变量
(2) 远程文件包含:
前提条件: allow_url_include = on 出现频率不如本地包含 (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) 黑名单扩展名过滤:
限制不够全面:iis默认支持解析 .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)) 。 4.文件删除漏洞: 搜索关键函数:
unlink() 利用回溯变量的方式 老版本下的 session_destroy() ,可以删除文件,现已基本被修复。 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.动态函数执行: 动态函数后门:
#!php
3.命令执行函数: 搜索关键函数: system() , exec() , shell_exec() , passthru() , pcntl_exec() , popen() , proc_open()
(1) popen 和 proc_open() :
#!php> /users/bingdaojueai/desktop/1.txt', 'r' ); ?>
所在路径就会出现一个1.txt 里面的内容为命令执行后的结果
(2) 反引号命令执行:
echo whoami ; 直接就可以执行命令
双引号和单引号的区别:
#!php$a = 1echo $a output:1echo ' $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)双等于 == 和三等于 === :
双等于会在变量比较时,进行类转换,与 in_array() 是一样的问题。 三等于是 type 和 value 的双重比较,相比之下更加安全。 2.账户体系中的越权问题: 水平越权: a用户能够以b用户的身份,进行b用户的全部权限操作。前提a用户和b用户拥有相同的权限。 垂直越权: a用户能够以c用户的身份,进行c用户的全部权限操作,前提c用户比a用户拥有更高的权限。 (1) 未 exit / return / die :
#!php
test 依旧会被输出,替换成安装流程,php依旧会进行。
(2) 支付漏洞:
客户端修改单价 客户端修改总价和购买数量 服务端未校验严格 重复发包利用时间差:
#!php
可能导致漏洞函数: str_replace()
#!php
e.会话认证漏洞 cookie验证:没有使用session验证,将信息直接保存在cookie中
找到传入sql语句的参数的传递过程 回溯变量到最原始的函数 看它保存在cookie的算法 是否可逆 和md5比起 sha1更安全 解密sha1的网站更少 限制一个用户只能同时在一个ip上登录 审计代码时,查看登录处代码
f.二次漏洞 1.类型: 不是逻辑问题,是可信问题。 业务逻辑复杂度,与二次漏洞触发率 成正比。 购物车 / 订单 / 引用数据 / 文章编辑 / 草稿 ==> sql注入 / xss
2.技巧: (1) 钻gpc等转义的空子:
不受gpc保护的 $_server 变量: php5以后,$_server取到的header不再受gpc影响,就算开启特殊字符也不会被转义,存在注入 编码问题转换:
gbk的宽字节注入: %df ' 单引号自动被转义成(%5c),同时 %df 与 %5c 连在一起组合成 運 字单引号依然在,成功闭合。【php与mysql交互过程中发生的编码转换问题】 mb_convert_encoding() :
#!php
(2)字符串问题:
利用报错,找到敏感信息 字符串截断:
%00空字符截断:【php版本小于5.3】
#!php
iconv函数字符编码转换截断:【对php版本有要求】
#!phpchr(128)—chr(255)可以截断字符
php:// 输入输出流:
#!php1.php?file=php://filter/convert.base64-encode(内容被base64编码)/resource=example.txt(远程文件)
php代码解析标签:
…?> : php3.0.4版本后可用 : asp标签,需要asp_tags=on,默认是off 正则表达式:
没有使用^ 和 $ 限定匹配开始位置: 特殊字符未转义: 报错注入:
windows findfirstfile 利用: 若要搜索12345.txt文件,可使用 1 ,因为单独一个只是代表了一个字符,两个代表多个字符。
0x03 end 自己走上安全这条路既是兴趣也是偶然,选择白盒完全是因为喜欢php,毕竟是初识代码审计,seay的书确实帮了我不少,抱作者大腿 (我是萌妹纸) ,希望这篇文章能够帮助像我一样小白的人,花了两天总结的,如果有什么缺陷也等着大家指出。
不会开发的谈审计都是耍流氓! :)
其它类似信息

推荐信息