设为首页 收藏本站
查看: 669|回复: 0

[经验分享] php函数漏洞原理解析

[复制链接]
发表于 2018-12-11 12:38:26 | 显示全部楼层 |阅读模式
  PHP是世界上最好的语言,是的,php在世界上养活了两类人,一类是编写php代码的人,一类是从事安全×××的这类人,因为在php中存在着有漏洞的函数。
在一定条件作用下,这些函数没有按着函数发明者的意愿去解析。
在ctf的web世界中也算待了几个月了,对学习当中的遇到的有问题的函数略做一下总结。
  md5()函数

定义:Md5()函数计算字符串的MD5散列
  问题1:经过MD5()函数处理的字符串散列如果出现0e开头的,在被php处理的时候会被认为等于0。
源码:


  代码功能:判断get方法传入的参数的MD5的hash字符串是否相等,并且是在两参数值不相等的情况下。
测试结果:

  原理分析:
当两个字符串被MD5加密的时候,会产生以0e开头的哈希值。Php进行判断的时候0e…会被看成科学计数法,0的n次方都是等于零。所以这两个字符串被md5()加密后都等于零。
var_dump(0 == 0e123456)

问题2:处理数组的时候返回为null
源码:


  测试:

解析:
如果unset变量存在请求参数当中,便会出现销毁变量实现绕过的现象。就如这里,通过$$符号,$key=abc;$$key=$abc;最后unset()函数便会变成unset($abc),将原来定义的$abc[‘a’]=true给销毁。
  extract()函数

定义用法:
extract() 函数从数组中将变量导入到当前的符号表。
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
EXTR_OVERWRITE - 默认。如果有冲突,则覆盖已有的变量。
EXTR_SKIP - 如果有冲突,不覆盖已有的变量。
EXTR_PREFIX_SAME - 如果有冲突,在变量名前加上前缀 prefix。
EXTR_PREFIX_ALL - 给所有变量名加上前缀 prefix。
EXTR_PREFIX_INVALID - 仅在不合法或数字变量名前加上前缀 prefix。
EXTR_IF_EXISTS - 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。
EXTR_PREFIX_IF_EXISTS - 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。
EXTR_REFS - 将变量作为引用提取。导入的变量仍然引用了数组参数的值。
这个函数的重点就是默认将已经有的变量给覆盖掉
  存在问题;将原来的变量覆盖,进行绕过
  源码:

    $a = 'yaun';  
extract($_GET);
if($auth == 1){  
echo "private!";  
} else{  
echo "public!";  
}  
  测试:

  问题解析:当我传递a=1的时候,extract()函数发现有原来的变量,于是将原来变量的值覆盖掉,变成a=1,在进行if条件语句的判断。
  parse_str()函数

定义用法:
parse_str() 函数用于把查询字符串解析到变量中,如果没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量。 极度不建议 在没有 array参数的情况下使用此函数,并且在 PHP 7.2 中将废弃不设置参数的行为。此函数没有返回值。
  源码:

  if(empty($_GET['id'])){
show_source(__FILE__);
die();
}else{
include('flag.php');
$a = "http://blog.运维网.com/12332766";
$id = $_GET['id'];
@parse_str($id);
if($a[0] == 'yaun'){
echo "yes is flag";
}else{
exit('其实很简单,其实并不难');
}
}
  测试:

问题解析:
当传递参数id=a[]=yaun的时候,经过parse_str()函数的处理将a变成变量。但是原来有同名的变量,于是就将原来的变量覆盖掉,同时覆盖的还有变量的值。

  变量覆盖拓展:php中遇到$$的时候也会出现变量覆盖的情况。详情请到:http://blog.运维网.com/12332766/2120800。
  strcmp()函数

定义用法:
Strcmp(string1,string2)函数比较两个字符串
  返回值:
0 - 如果两个字符串相等
0 - 如果 string1 大于 string2
  问题:处理数组的时候返回null
  源码“


$a="yaun";
$pass=$_GET['pass'];
if(strcmp($a, $pass) == 0){
echo "成功";
}else{
echo "失败";
}
  测试:

问题解析:
传递数组的时候,函数没有办法比较数组,返回null,php语言本身就是弱类型的语言,null==0 在数值上相等。但是在类型上不等。

  is_numeric()函数

定义用法:
is_numeric() 函数用于检测变量是否为数字或数字字符串。
如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE
  问题1:传递十六进制的话,会让检测无效。
源码:

$a=$_GET['num'];
if(is_numeric($a)){
echo "您输入的是数字";
}else{
echo "请输入合法字符";
}
  测试:
输入一串查询语句转换过得十六进制

成功绕过函数的检测
问题解析:这个函数不仅能够检测十进制,同时还认为十六进制也是合法的。于是就可以构造十六进制的语句进行绕过此函数。

  preg_match()函数

定义用法:
Preg_match()函数匹配正则表达式。
  返回值:
返回 pattern 的匹配次数。 它的值将是 0 次(不匹配)或 1 次,因为 preg_match() 在第一次匹配后 将会停止搜索。如果发生错误preg_match()返回 FALSE。
问题:如果在进行正则表达式匹配的时候,没有限制字符串的开始和结束(^ 和 $),则可以存在绕过的问题
源码:

$ip=$_GET['ip'];
if(!preg_match("/(\d+)\.(\d+)\.(\d+)\.(\d+)/",$ip)) {
die('error');
} else {
echo "this is flag";
}
  测试:
输入一个不符合匹配规则的字符串,依然返回flag

问题解析:
因为这个函数在执行匹配规则的时候没有说明是以什么开头或者结尾,所以只需要在这个字符串中存在规定的字符,其他的字符也可以添加上去进行绕过。
  in_array()函数

定义用法:
in_array(search,array) 函数搜索数组中是否存在指定的值。
  返回值:
如果给定的值 search 存在于数组 array 中则返回 true。如果没有在数组中找到参数,函数返回 false。

$array=[0,1,2,'3'];  
var_dump(in_array('abc', $array));
var_dump(in_array('1bc', $array));
  测试:

问题分析:
可以看到上面的情况返回的都是true,因为’abc’会转换为0,’1bc’转换为1。
在所有php认为是int的地方输入string,都会被强制转换
  unserialize()函数
具体使用方法见另一篇博客:http://blog.运维网.com/12332766/2121394
  strpos()函数

定义用法:
strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写)。
注释:strpos() 函数是区分大小写的。
注释:该函数是二进制安全的。
  语法:
strpos(string,find,start)   string 必须,规定被搜索的字符串;find    必须,规定查找的字符串;start 可选,规定开始搜索的位置。
返回值:
返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。注释: 字符串位置从 0 开始,不是从 1 开始
源码:

if(strpos($_GET['password'],'abc') == 0 ){
echo '123';
}
else{
echo '456';
}
  传递一个数组进去测试,使得返回结果是123

可以看到我们输入的并不符合要求,但是还是给了123的输出。
问题解析:
这个函数也是只解析string类型的字符串,给他个数组就不知道如何解析,于是就返回为null。Null==0!
  strlen()函数

定义用法:
strlen() 函数返回字符串的长度
  语法:
strlen(string) string-必须,规定要检查的字符串。
  源码:

if(strlen($_GET['password']) == 0  ){
echo '1233';
}else{
echo '4566';
}
  测试:
传递一个数组,使得返回为1233

问题分析:
这个函数也是只解析string类型的字符串,给他个数组就不知道如何解析,于是就返回为null。Null==0!
  此博客作为个人笔记,若有带来错误之处请谅解!




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-650122-1-1.html 上篇帖子: 分享一个PHP抽奖算法 下篇帖子: PHP的错误处理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表