php 弱类型问题

php 是一门简单而强大的语言,提供了很多 Web 适用的语言特性,其中就包括了变量弱类型,在弱类型机制下,你能够给一个变量赋任意类型的值。

php 的 8 种变量类型


标准类型:布尔 boolen,整型 integer,浮点 float,字符 string

复杂类型:数组 array,对象 object

特殊类型:资源 resource

但由于 php 在定义变量时并不需要像 C++ 语言那样去定义其变量类型,因此在一些 CTF web 题目中,经常会碰到一些源码是 php 的题目,我们可以通过分析代码,结合 php 弱类型问题去尝试绕过。比如:

下面是C++的:

int i = 100;

下面是PHP的:

$i = 100;

操作之相等比较:== 与 ===


在进行相等比较时:

== 会先把两个变量的类型变成相同后再比较,而 === 会先判断两个变量的类型是否相同,再去比较。( php 有个内置函数 gettype 可以查看变量类型,settype 可以设置变量类型)

如果比较一个 int 型(数字)$a 和一个字符串 $b,如果 $b 是以数字开头,如: $a = "1", $b = "1admin" ,那么判断时就会把 $b 当做 1 去和 $a 比较; 如果 $b 不是以数字开头,如 $a = "1", $b = "admin1" ,那么就会把 $b 当做 0 去和 $a 比较。

可以看下面的代码示例:

函数之 empty 和 isset


  • 1)变量为:0,"0", null, '', false,array() 时,使用 empty 函数,返回的都为 true
  • 2)变量未定义或者为 null 时,isset 函数返回的为 false ,其他都为 true

函数之 md5


部分字符串由于使用 md5 加密后会变成 0e 开头的字符串,然后使用 == 判断时就容易绕过

题目大意是要输入一个字符串和数字类型,并且他们的 md5 值相等,就可以成功执行下一步语句。

那么可以通过一批已公开的 md5 开头是 0e 的字符串去绕过,下面给大家列一些可以用的 md5 值:

QNKCDZO 0e830400451993494058024219903391 s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974117254469 s214587387a 0e848240448830537924465865611904 s214587387a 0e848240448830537924465865611904 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675 s1885207154a 0e509367213418206700842008763514

纯数字类:

240610708 0e462097431906509019562988736854 314282422 0e990995504821699494520356953734 571579406 0e972379832854295224118025748221 903251147 0e174510503823932942361353209384 1110242161 0e435874558488625891324861198103 1320830526 0e912095958985483346995414060832 1586264293 0e622743671155995737639662718498 2302756269 0e250566888497473798724426794462 2427435592 0e067696952328669732475498472343 2653531602 0e877487522341544758028810610885 3293867441 0e471001201303602543921144570260 3295421201 0e703870333002232681239618856220 3465814713 0e258631645650999664521705537122 3524854780 0e507419062489887827087815735195 3908336290 0e807624498959190415881248245271 4011627063 0e485805687034439905938362701775 4775635065 0e998212089946640967599450361168 4790555361 0e643442214660994430134492464512 5432453531 0e512318699085881630861890526097 5579679820 0e877622011730221803461740184915 5585393579 0e664357355382305805992765337023 6376552501 0e165886706997482187870215578015 7124129977 0e500007361044747804682122060876 7197546197 0e915188576072469101457315675502 7656486157 0e451569119711843337267091732412

纯字母类:

QLTHNDT 0e405967825401955372549139051580 QNKCDZO 0e830400451993494058024219903391 EEIZDOI 0e782601363539291779881938479162 TUFEPMC 0e839407194569345277863905212547 UTIPEZQ 0e382098788231234954670291303879 UYXFLOI 0e552539585246568817348686838809 IHKFRNS 0e256160682445802696926137988570 PJNPDWY 0e291529052894702774557631701704 ABJIHVY 0e755264355178451322893275696586 DQWRASX 0e742373665639232907775599582643 DYAXWCA 0e424759758842488633464374063001 GEGHBXL 0e248776895502908863709684713578 GGHMVOE 0e362766013028313274586933780773 GZECLQZ 0e537612333747236407713628225676 NWWKITQ 0e763082070976038347657360817689 NOOPCJF 0e818888003657176127862245791911 MAUXXQC 0e478478466848439040434801845361 MMHUWUV 0e701732711630150438129209816536

PHP手册中的 md5() 函数的描述是 string md5 ( string \$str [, bool $raw_output = false ] ) ,md5() 中需要的是一个 string 类型的参数。但是当你传递一个 array 时,md5() 不会报错,只是会无法正确地求出 array 的 md5 值,这样就会导致任意 2 个 array 的 md5 值都会相等。

函数之 strcmp 漏洞绕过( php -v < 5.3 )


strcmp 是比较两个字符串,如果 str1 < str2 则返回 <0 如果 str1 大于 str2 返回 >0 如果两者相等则返回 0

我们是不知道 $password 的值的,题目要求 strcmp 判断的接受的值和 $password 必需相等,strcmp 传入的期望类型是字符串类型,如果传入的是个数组会怎么样呢

我们传入 password[]=xxx 可以绕过,是因为函数接受到了不符合的类型,将发生错误,但是还是判断其相等

payload: password[]=xxx

函数之 in_array() 和 array_search()


在 PHP 手册中,in_array() 函数的解释是 bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) ,如果 strict 参数没有提供,那么 in_array 就会使用松散比较来判断 $needle 是否在 $haystack 中。当 strince 的值为 true 时,in_array() 会比较 needls 的类型和 haystack 中的类型是否相同。

array_search() 函数在数组中搜索某个键值,并返回对应的键名。官方手册对 array_search 的介绍: mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] ) 其中 $needle,$haystack 必需,$strict 可选 函数判断 $haystack 中的值是存在 $needle,存在则返回该值的键值第三个参数默认为 false ,如果设置为 true 则会进行严格过滤

函数之 switch 问题


如果 switch 是数字类型的 case 的判断时,switch 会将参数转换为 int 类型。

总结


上面所述的 php 弱类型可能只是一部分,在打 CTF 过程中,可能更多,但问题都在于对函数的使用不够规范,对变量的类型没有完全校验(可使用内置的 settype, gettype 函数多校验或者规范),这是强大的 php 语言引起的“不足”问题,而在企业使用 php 开发中一般不会涉及到这方面的漏洞问题,通常可能仅仅是判断不充分而导致的逻辑问题,希望大家可以共同补充探讨。

参考:

php 弱类型总结:

http://www.cnblogs.com/Mrsm1th/p/6745532.html

0e开头MD5 python生成脚本 PHP哈希弱类型:

http://blog.csdn.net/kalbertlee/article/details/70213392

原文发布于微信公众号 - 信安之路(xazlsec)

原文发表时间:2017-11-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学 Web 前端

01 - JavaSE之基础及面向对象

byte(-128 ~ 127) short(-32768 ~ 32767) int(-2147483648 ~ 2147483647)

17640
来自专栏互联网技术栈

JVM解读-方法区

方法区,Method Area, 对于习惯在HotSpot虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为“永久代”(Permanent Genera...

42040
来自专栏猿人谷

Java初学者需掌握的30个概念

基本概念:       1.OOP中唯一关心的是对象的接口是什么,就像计算机的销售商她不管电源内部结构 是怎样的,他只关系能否给你提供电就行了,也就是只要知道c...

180100
来自专栏C/C++基础

认识初始化

初始化是编码过程中的重要操作,往往由于被忽略,导致使用未初始化的变量(或内存区域),将程序置于不确定的状态,产生各种bug,严重影响的程序的健壮性。正确地理解和...

7410
来自专栏LanceToBigData

异常处理升级版

其实前面就写了一篇异常处理的文章,但是那个文章实在是感觉太详细了,不太好复习。所以今天我就再写一篇这样就更好复习了。 一、异常概述   在我们日常生活中,有时会...

21290
来自专栏锦小年的博客

python学习笔记4.2-python高级之迭代器

迭代是Python中最强有力的特性之一,同时对编程人员来说,也是最难理解的一种用法。其实从高层次来看,迭代就是一种处理序列中元素的方式。通过自定义迭代对象可以...

227100
来自专栏程序生活

Python itertools的使用简介无限迭代器chain方法

用*放在一个可迭代对象前面可以将对象拆分成多个单元素,比如first=[['1','2','3','4','4'],['2','4','2']],如果把*放在f...

7810
来自专栏蜕变

Python 数据类型

Python主要数据类型包括list(列表)、tuple(元组)、dict(字典)和set(集合)等对象,下面逐一介绍这些Python数据类型。

9000
来自专栏JetpropelledSnake

Python入门之迭代器/生成器/yield的表达方式/面向过程编程

 本章内容     迭代器     面向过程编程       一、什么是迭代       二、什么是迭代器       三、迭代器演示和举例       四、生...

30690
来自专栏Python爬虫实战

Python数据类型之字典(上)

之前系列文章介绍了Python简单数据类型和序列数据类型,本文来学习一种新的映射数据类型:字典。

9310

扫码关注云+社区

领取腾讯云代金券