您的位置:首页 > 编程语言 > PHP开发

php安全代码审计小结

2014-06-05 08:35 369 查看
文章仅为一段时间整理的php安全代码审计笔记总结,一个分析框架,没有实例化分析。一、工具篇编辑器(notepad++,editplus,UE等等,看个人习惯)TommSearch(字符串检索) || grepHttpProtocolDebugger(http协议调试器)Fiddler(分析包,改包)Seay PHP代码审计工具(php-code-audit分析辅助)几个有趣的项目dvwa(代码审计测试平台)phpmvsphp security audit checkPHP Vulnerability Hunter二、函数篇addslashed()添加反斜杠stripslashed()去掉反斜杠get_magic_quotes_gpc() 判断是否开启gpcexpode(".",$array)分割成数组is_numeric()判断是否为数字sizeof()判断长度trim() 去除字符串开头和末尾的空格或其他字符system() 输出并返回最后一行shell结果。exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。EscapeShellCmd(),把一个字符串中所有可能瞒过Shell而去执行另外一个命令的字符转义。这些字符在Shell中是有特殊含义的,象分号(;),重定向(>)和从文件读入 (<)等。EscapeShellArg() 。在给定的字符串两边加上单引号,并把字符串中的单引号转义,这样这个字符串就可以安全地作为命令的参数。用popen()函数打开进程上面的方法只能简单地执行命令,却不能与命令交互。但有些时候必须向命令输入一些东西,如在增加Linux的系统用户时,要调用su来把当前用户换到root才行,而su命令必须要在命令行上输入root的密码。这种情况下,用上面提到的方法显然是不行的。popen ()函数打开一个进程管道来执行给定的命令,返回一个文件句柄。既然返回的是一个文件句柄,那么就可以对它读和写了。在PHP3中,对这种句柄只能做单一 的操作模式,要么写,要么读;从PHP4开始,可以同时读和写了。除非这个句柄是以一种模式(读或写)打开的,否则必须调用pclose()函数来关闭 它。例子1:/* PHP中如何增加一个系统用户下面是一段例程,增加一个名字为james的用户,root密码是 verygood。仅供参考*/$sucommand = "su --login root --command";$useradd = "useradd ";$rootpasswd = "verygood";$user = "james";$user_add = sprintf("%s "%s %s"",$sucommand,$useradd,$user);$fp = @popen($user_add,"w");@fputs($fp,$rootpasswd);@pclose($fp);require在被包含文件有错误代码时将不再往下执行include在被包含文件有错误代码时仍然往下执行htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。预定义的字符是:& (和号) 成为 &" (双引号) 成为 "' (单引号) 成为 '< (小于) 成为 <> (大于) 成为 >move_uploaded_file() 函数将上传的文件移动到新位置。extract() 函数从数组中把变量导入到当前的符号表中。对于数组中的每个元素,键名用于变量名,键值用于变量值。第二个参数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。本函数返回成功设置的变量数目。语法extract(array,extract_rules,prefix)parse_str() 函数把查询字符串解析到变量中. (常见于变量覆盖漏洞)语法parse_str(string,array)参数 描述string 必需。规定要解析的字符串。array 可选。规定存储变量的数组名称。该参数指示变量存储到数组中。针对变量指定攻击不使用foreach遍历$_GET变量,改用$_GET[(index)]eval() 函数把字符串按照 PHP 代码来计算。该字符串必须是合法的 PHP 代码,且必须以分号结尾。如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。preg_replace 执行一个正则表达式的搜索和替换/e参数执行代码三、漏洞篇-----------------------------------------------[1].Sql-Injection留意:cookie及x-forward-for,宽字节,报错注射等挖掘漏洞参考变量$_GET[""],$_POST[""],$_COOKIE[""], $SERVER[""]数据库操作函数mysql_query()数字型注入防范:1.is_numeric() ctype_digit() intval()2.str_length()确定长度字符型注入防范:1.mysql_real_escape_string()2.数据库查询语句前加@防爆错3.str_length()确定长度-----------------------------------------------[2].Command-Execution函数:system(),passthru(),popen(),exec()数据库操作函数:exec,system,popen,passthru,proc_open,shell_exec执行命令管道符 % | >测试如0 | dir c:|| 双竖线的作用,前面语句执行错误则执行后面语句如xx"+||+whoami+||+echo-----------------------------------------------[3].File-Inclusion函数:include(),require(),include_once(),require_once()远程文件包含漏洞要求allow_url_fopen() allow_url_include() file_get_contents()绕过:zlib://和ogg://5.2.0之后版本data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+ //@eval(file_get_contents('php://input')); //POST phpinfo();配合%00截断,新版本自动转义\0-----------------------------------------------[4].CSRFCSRF防范策略1>验证http-referer字段安全性低,易被伪造2>在请求地址中添加token并验证token可在用户登录后存放在session中,每次请求时将token从session中取出,去请求的token对比以防范CSRFGET方式:http://url/?=token如果一个网站接受请求地方比较多,则在每次页面加载时遍历整个dom树,在dom中每个a和form标签后加入token但在动态页面加载后产生的html代码,则需要以硬编码的形式手工添加这种方式安全性弱点在于,如在论坛等交互比较频繁的地方hacker可构造环境盗取token并进而构造csrf攻击故手工关闭referer3>在HTTP头中自定义属性并进行验证。通过XMLHttpRequest类。通常用于Ajax方法对页面局部的异步刷新但适应性一般,对已有的网站架构局限性较大-----------------------------------------------[5].XSS(Cross Site Script)反射型与存储型控制$_GET,$_POST,$_COOKIE 各种传入的变量使用htmlspecialchars()函数进行基础过滤结合CSRF实现自动化利用-----------------------------------------------[6].File_Upload函数:move_uploaded_file()变量:$_FILESphp文件上传利用form表单进行文件上传时必须为post使用multipart/form-data才能完整的传递文件数据php利用$_FILES系统函数的相关参数与函数move_upload_file函数来实例把由$_FILES全局变量生成的临时文件移动到指定目录完成文件的上传$_FILES['files']['name']客户端文件的原名称$_FILES['files']['type']文件的MIME类型$_FILES['files']['size']已上传文件的大小$_FILES['files']['tmp_name']储存的临时文件名,一般为系统默认$_FILES['files']['error']该文件上传到相关的错误代码防范方式:1>判断MIME TYPE文件类型如$_FILES['files']['type']=="image/jpeg",判断文件大小,如$_FILES['files']['size']<10000 && $_FILES['files']['size']>1002>指定上传文件名,如依赖时间生成hash(time).jpg等方式3>根据文件后缀名判断文件如file_ext=substr($filename,$strrpos($filename,'.')+1);注意是否可能有双扩展名,二次上传突破等逻辑问题4>服务器尝试渲染文件等方式判断是否为图片5>不依赖于客户端js脚本限制上传文件类型6>白名单规则apache服务器常见上传安全问题1>配合.htaccess利用上传AllOverride ALL 允许子规则覆盖父规则.htaccess添加AddType Application/x-httpd-php .jpg2>文件名解析漏洞*.php.123在.htaccess添加AddHandler php5-script .php,文件名中包含php扩展名可以php脚本执行,如x.php.jpg.php3 .php4扩展名
四、配置篇1>关注漏洞信息,及时更新版本2>php.ini httpd.conf .htaccess文件配置1)safe_mode相关配置2)register_globals关闭3)open_basedir配置,防范目录遍历4)allow_url_fopen关闭5)disable_functions配置6)magic_quotes_gpc打开7)error_reporting=E_ALL & ~E_NOTICE8)display_errors=Off避免攻击者获取更多信息9)expose_php=Off隐藏版本信息3>最小化服务器其他账户权限4>第三方安全加固软件安装5>调用第三方安全防护文件,配置php.iniinclude_path=".:/php/includes"auto_pretend_file="anti-inj.php"auto_appent_file=五、思路篇刚开始练习审计时,拿到一套源码,马上做的事情就是,丢到工具里,去扫敏感的函数,然后去一个一个的回溯它,找到入口点。但是,这样审计很浪费时间,每次都要在回溯过程中,不断的去寻找源码中定义的一些通用函数。由于不了解整个源码的流程,导致在找这些通用函数的过 程中浪费了很多的时间与精力。所以,我重新调整了我的审计流程。在拿到源码之后,先从它开始的地方(一般是根目录下的index文件)按照执行的顺序去读代码,一直到它的初始化内容, 和基本功能实现完毕为止。这样,可以明确的了解整套源码的结构,哪一种函数文件放在哪个文件夹下;知道通用函数放在哪个文件中。这对我们在之后阅读“疑似”有问题的代码时,有很好的帮助,例如,在看到一个通用函数时,我们可以快速的切换到通用函数文件,查找这个函数的实现代码。注:此处引用修改唐门三少文章《PHP代码审计学习总结》六、小结代码审计一如逆向工程,均需要耐心与细心。此外,关注漏洞发布平台上最新漏洞并跟踪加以分析也是一个很快提升自己能力的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php安全 代码审计