外链论坛

 找回密码
 立即注册
搜索
查看: 19|回复: 0

PHP弱类型你真的懂了吗?

[复制链接]

3011

主题

155

回帖

9923万

积分

论坛元老

Rank: 8Rank: 8

积分
99239081
发表于 2024-10-4 16:59:06 | 显示全部楼层 |阅读模式

文案源自仙桥六号部队

在一次渗透测试中,因为甲方守护做的比较好,并发掘什么漏洞,在即将结束的时候,我还是大的突破。于是我又进行了一波仔细的信息搜集,发掘系统中存在phpList,顿时,我眼前一亮——我记得以前看到过phplist的关联漏洞。随即

起始搜索phplist的历史漏洞,经过我的一通操作,最后确定phplist的版本为3.5.0,漏洞为弱类型漏洞,利用弱类型漏洞登录进去,之后就一切顺利了。

因为在客户设备上做的渗透,截图神马的都······下面我在本机上搭建了一个环境,对phplist3.5.0弱类型漏洞进行一下复现。1复现过程

phpList 3.5.0版本存在的安全漏洞编号是CVE-2020-5847,该漏洞源于程序正确处理开头为0e之后所有为数字字符的哈希值。远程攻击者可利用该漏洞绕过管理员账户的身份验证。

首要下载phpList 3.5.0-RC1,而后解压找到这个目录:

将这个目录拷贝到网站目录下,并重命名。修改config/config.php配置文件,设置要连接的数据库和账户秘码同期创立phplistdb数据库。拜访http://127.0.0.1/phplist/admin/;接下来初始化安装,设置管理员的账号秘码这儿秘码要设置成 sha256 后以0e开头的字符串,如TyNOQHUS。咱们再次拜访后台,以秘码 34250003024812进行登录,其sha256后是以0e开头。“TyNOQHUS——hash :0e66298694359207596086558843543959518835691168370379069085300385”“34250003024812——hash:0e46289032038065916139621039085883773413820991920706299695051332”登录成功,漏洞验证成功:下面还是详细分析一下漏洞处的代码。验证管理员登录的PHP文件为:“phpListAdminAuthentication.php”登录时,秘码传入其中,经过if判断后,能够看到$encryptedPass秘码sha256后的值)是运用==来判断和数据库中的值是不是同样,即$encryptedPass == $passwordDB。PHP弱类型比较,就会导致0exxxxx == 0eyyyyy(会把每一个以”0e”开头的哈希值都解释为0),详细代码如下图:2什么是PHP弱类型首要先说一下,什么是强类型和弱类型?语言一般被分为强类型和弱类型两种。强类型指的是强制数据类型的语言,换句话说,一个变量一旦被定义了成某个类型,倘若不经过强制类型转换,这个变量就始终是这个类型。在变量运用之前,必须声明变量的类型和名叫作,且不经强制转换,不准许两种区别类型的变量互相操作。而弱类型能够随意转换变量的类型。PHP作为最受欢迎的开源脚本语言,越来越多的应用于Web研发行业同期PHP属于弱类型语言,即定义变量的时候不消声明它是什么类型。弱类型确实给程序员书写代码带来了很大的便利,然则在安全行业,特性既漏洞,这些特性在代码里面经常便是漏洞最容易显现地区PHP官方给出了类型比较表,表格表示了 PHP 类型比较运算符在松散和严格比较时的功效松散比较:严格比较:总结一下PHP弱类型产生漏洞的原理:

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0e”开头的哈希值都解释为0,因此倘若两个区别秘码经过哈希以后,其哈希值都是以”0e”开头的,那样PHP将会认为她们相同,都是0。

区别类型的变量进行比较的时候就会存在变量转换的问题,在转换之后就有可能会存在弱类型问题。例如需要将GET是POST的参数转换为int类型,是两个变量不匹配的时候,PHP会自动地进行变量转换。然则PHP是一个弱类型的语言,引起在进行类型转换的时候就会产生弱类型关联的漏洞。

函数转换出错时导致的弱类型问题,例如:strcmp函数参数str1不为预期的String类型时(例如数组,),在PHP 5.3版本之前将返回-1,5.3之后的版本将返回NULL。

经过以上方式能够产生秘码重置、绕过管理员账户的身份验证、注入、cookie伪造等弱类型漏洞。有些CTF试题会利用其弱类型进行设置有些如MD5碰撞、十六进制转换等问题。下面经过有些漏洞实例来进行说明。3CVE-2014-0166(WordPress Cookie伪造) 在wordpress-3.8.2的补丁中有以下代码:而在wordpress-3.8.1的相对应的PHP代码是这般的:经过对比咱们自然把所有的关注点放到!=与!==上来。再看php manual中给出的例子:<?php var_dump(0 == "a"); // 0 == 0 -> true var_dump("1" == "01"); // 1 == 1 -> true var_dump("10" == "1e1"); // 10 == 10 -> truevar_dump(100 == "1e2"); // 100 == 100 -> true?>字符串在与数字比较前会自动转换为数字,因此0=="a"了。回到wordpress的验证代码上来。先生成按照用户名($username)、秘码($pass_frag)、cookie有效期 ($expiration)、wp-config.php中的key($key)四个信息计算出对应的$hash, 而后用cookie中取得的$hmac值与之进行比较($hmac != $hash ),从而验证cookie有效性。cookie的格式是这般的:wordpress_hashofurl=username|expiration|hmac咱们掌控的变量有$username和$expiration,其中$username需要固定。于是咱们能够经过掌控cookie中的$expiration去改变$hash的值,而后将cookie中的$hmac设置为0。只要持续改变$expiration,找到满足$hash=="0"的$hash,就成功伪造了有效的cookie。4

HDwiki sql注入

在/control/list.php中,代码如下:分析代码可知,从GET里得到$doctype,即$doctype = $this->get[2],接着进入一个switch语句。咱们看到后面直接将$doctype带入SQL语句了:$count=$this->db->fetch_total(focus,"type=$doctype");只要这个switch语句不影响$doctype的值,后面就能注入了。咱们看到case 2和case 3的结果都不会改变$doctype的值,但倘若进入default是会将$doctype改为1。这儿就犯了一个“弱类型”的错误,当一个字符串和一个数字比较的时候,是会先将字符串强制类型转换后再与数字比较。因此我传入doctype是2xxxx的时候,实质上是会进入case 2而不是default。出了switch语句后,doctype的值还是2xxxx,而不是2。因此之后的:$count=$this->db->fetch_total(focus,"type=$doctype");$doctype带入SQL语句导致注入。

5

CTF中的利用《MD5碰撞》:<?php if (isset($_GET[Username]) && isset($_GET[password])) {$logined = true; $Username = $_GET[Username]; $password = $_GET[password]; if (!ctype_alpha($Username)) {$logined = false;}if (!is_numeric($password) ) {$logined = false;} if (md5($Username) != md5($password)) {$logined = false;} if ($logined){ echo "successful"; }else{ echo "login failed!"; } } ?>这个题目的意思是,输入一个数字和一个字符串,并且让她们的MD5值相同,才能够得到successful。0e在比较的时候会将其视做为科学计数法,因此无论0e后面是什么,0的多少次方还是0。因此咱们只需要输入一个数字和字符串,进行MD5加密之后都为0e,就可得出答案。md5(240610708) == md5(QNKCDZO)成功绕过。《起名字真难》:<?phpfunction noother_says_correct($number){ $one = ord(1); $nine = ord(9); for ($i = 0; $i < strlen($number); $i++) { $digit = ord($number{$i});if ( ($digit >= $one) && ($digit <= $nine) ) { return false; } } return $number == 54975581388;}$flag=*******;if(noother_says_correct($_GET[key])) echo $flag;elseecho access denied;?>题目大致的意思便是,输入一串key,key不能够是数字的形式,然则需求与数字54975581388相等,才能够拿到flag。看完题目就晓得需求字符串和数字进行比较,因此$number == 54975581388;看到这就想到了弱类型,54975581388与之匹配的十六进制的字符串是0xccccccccc。全不是数字,自然就绕过了,得到flag。6结语看到这儿相信大众都对PHP弱类型比较认识了,当然还有非常多其他的漏洞实例,这儿就不一一列举了。下面列举有些以0e开头的字符串的md5的hash值:

s214587387a:

0e848240448830537924465865611904;

s1502113478a:

0e861580163291561247404381396064;

s1091221200a:

0e940624217856561557816327384675;

s1665632922a:

0e731198061491163073197128363787;

s1885207154a:

0e509367213418206700842008763514;

s1836677006a:

0e481036490867661113260034900752;

s1665632922a:

0e731198061491163073197128363787;

s878926199a:

0e545993274517709034328855841020;

QLTHNDT:

0e405967825401955372549139051580;

QNKCDZO:

0e830400451993494058024219903391;

EEIZDOI:

0e782601363539291779881938479162;

TUFEPMC:

0e839407194569345277863905212547;

UTIPEZQ:

0e382098788231234954670291303879;

UYXFLOI:

0e552539585246568817348686838809;

IHKFRNS:

0e256160682445802696926137988570;

240610708:

0e462097431906509019562988736854;

314282422:

0e990995504821699494520356953734;

571579406:

0e972379832854295224118025748221;

903251147:

0e174510503823932942361353209384;

1110242161:

0e435874558488625891324861198103;

1320830526:

0e912095958985483346995414060832;

1586264293:

0e622743671155995737639662718498;

感谢阅读,下次再见!

 侵权请私聊公众号删文

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|外链论坛 ( 非经营性网站 )|网站地图

GMT+8, 2024-11-5 18:33 , Processed in 0.066528 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.