返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >CTF——PHP语言弱类型详解
  • 760
分享到

CTF——PHP语言弱类型详解

php开发语言 2023-10-10 06:10:02 760人浏览 八月长安
摘要

一、PHP语言弱类型简介 第一次打CTF比赛,关于php语言弱类型这块了解的还不够,所以写一篇笔记学习一下。 强类型是两个不同类型的变量不能用同一块内存存储弱类型是两个不同的类型的变量可以用同一块内存

一、PHP语言弱类型简介

第一次打CTF比赛,关于php语言弱类型这块了解的还不够,所以写一篇笔记学习一下。

  • 强类型是两个不同类型的变量不能用同一块内存存储
  • 弱类型是两个不同的类型的变量可以用同一块内存存储
  • PHP语言是弱类型的,简单来说就是数据类型可以被忽视的语言,类型可以一个变量赋不同数据类型的值
    PHP里面也有一些强语言类型相关的强制定义数据类型的结构方法,比如PHP里面的== 和 ===的区别,==是松散比较,只比较值,不比较数据类型。
    例1:

例2:

   $c='123abc';    $d=123;    if($c==$d){        echo "不比较数据类型";    }    else echo "比较数据类型";    //输出为不比较数据类型    $c='123abc';    $d=123;    if($c===$d){        echo "不比较数据类型";    }    else echo "比较数据类型";    //输出为比较数据类型

但是,php 内核的开发者原本是想让程序员借由这种不需要声明的体系,更加高效的开发,所以在几乎所有内置函数以及基本结构中使用了很多松散的比较和转换,防止程序中的变量因为程序员的不规范而频繁的报错,然而这却带来了安全问题。

二、类型转换问题

1、比较操作符

  • ===在进行比较的时候,会先判断两种字符串的类型是否相等,再比较。
  • ==在进行比较的时候,会先将字符串类型转化成相同,再比较。
  • 如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行
    例1 Hash比较缺陷:
"0e132456789"=="0e7124511451155" //true"0e123456abc"=="0e1DDDada"  //false"0e1abc"=="0"     //true在进行比较运算时,如果遇到了 0e\d + 这种字符串,就会将这种字符串解析为科学计数法。如果不满足 0e\d + 这种模式,就会当作字符串进行比较,所以不会相等。

例二 十六进制转换:

"0x1e240"=="123456"     //true"0x1e240"==123456       //true"0x1e240"=="1e240"      //false当其中的一个字符串是 0x 开头的时候,PHP 会将此字符串解析成为十进制然后再进行比较。

2、类型转换问题
当一个字符串当作一个数值来取值,其结果和类型如下:如果该字符串没有包含’.’,’e’,’E’ 并且其数值值在整形的范围之内该字符串被当作 int 来取值,其他所有情况下都被作为 float 来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,也就是字符串开头否则其值为 0。
例一:

    $test=1 + "10.5";    var_dump($test);//float(11.5)    $test=1+'-1.3e3';    var_dump($test);//float(-1299)    $test=1+"bob-1.3e3";    var_dump($test);//int(1)    $test=1+"2admin";    var_dump($test);//int(3)    $test=1+"admin2";    var_dump($test);//int(1)  

intval () 函数:intval () 转换的时候,会将从字符串的开始进行转换知道遇到一个非数字的字符。即使出现无法转换的字符串,intval () 不会报错而是返回 0。
例二:

    var_dump(intval('2'));  // int(2)    var_dump(intval('3abcd'));   // int(3)    var_dump(intval('abcd'));//      int(0)

3、bool欺骗
当存在 JSON_decode 和 unserialize 的时候,部分结构会被解释成 bool 类型

    $json_str = '{"user":true,"pass":true}';    $data = json_decode($json_str,true);    var_dump($json_str['ss']); //输出为 string(1) "{" 因为并不是字符串    if ($data['user'] == 'admin' && $data['pass']=='secirity')    {        print_r('logined in as bool'."\n");    }    //输出为logined in as bool

unserialize示例代码

 $unserialize_str = 'a:2:{s:4:"user";b:1;s:4:"pass";b:1;}';    $data_unserialize = unserialize($unserialize_str);    var_dump($data_unserialize['user']);//bool(true)     if ($data_unserialize['user'] == 'admin' && $data_unserialize['pass']=='secirity')    {        print_r('logined in unserialize'."\n");    }    //输出结果为logined in unserialize

4、数字转换问题

    var_dump("1" == 0.9999999999999999);//false    var_dump("1" == 0.99999999999999999);//true

int 和 intval在转换数字的时候都是低的,小于等于的整数部分

print((int)'0.9999999999999');//0print((int)'1.8');//1intval 还有个尽力模式,就是转换所有数字直到遇到非数字为止

5、绕过函数问题
0x01.MD5(),sha1()
这个函数用于对字符串进行MD5加密
函数格式:md5(要加密的字符串,规定的输出格式)

绕过方法
通过传入数组去绕过,这两个函数不能处理数组数据,md5还有一个加密的问题

示例代码:

error

'; else if (md5($_GET['name']) === md5($_GET['passwd'])) die('Flag: '.$flag); else echo '

Invalid passwd.

';}else echo '

Login first!

';?>

测试效果如下
在这里插入图片描述SHA-1绕过也是一样。
0x02.md5加密相等问题
关于md5还有个科学计数法的问题,
绕过方式
php在处理0e开头,后接的字符都为数字的的字符串的时候,会将整个字符串解析为科学计数法,当有另一个0e开头的字符串和这个进行对比时,php会都当作0来处理
示例代码如下:

这里我们传入一个md5编码后开头是0e的字符串,网上找了一个,aabC9RqS,效果为:
在这里插入图片描述

0x03.strcmp()
这个函数的作用是比较两个字符串并且区分大小写
当字符串1大于字符串2就返回>0,当字符串1小于字符串2就返回<0,相等则返回0
函数格式: strcmp(第一个需要比较的字符串,第二个需要比较的字符串)

绕过方式
通过传入数组去绕过,该函数处理数组时会发生错误,strcmp会返回结果0,导致绕过

测试代码

在这里插入图片描述

0x04.json_decode()
这个函数用于解码json格式的字符串

函数格式 json_decode(需要解码的字符串)

绕过方式
当有不同类型的数据时,该函数会转换为同一类型比较,这里会把原有的数据的数据类型转换为和传入数据的数据类型相同

测试代码

flag == $flag) {        echo "233";    }    else {        echo "haha";    }}else{     echo "hahaha";}?>

这里要传入一个json格式的字符,字符要用json格式去编写,这里设定名称为flag,传入json格式字符为{“flag”:0},为什么这里传入的值要是0呢?这里当我们传入数字时,它会转化为同一类型进行比较(这里关键点在于,要把字符转换为数字有效,因为字符转换为数字会出问题,字符会被转为0),这里字符被转为0,我们传入的参数为0,所以相等:
在这里插入图片描述

0x05.switch函数
绕过方式
switch选择的时候,处理的变量会被强转为int类型

这个函数一般用于根据多个条件选择执行不同动作,和if…. else相似

函数格式
switch(表达式,通常是变量)
{
case xxxx1:
当条件符合xxxx1时执行的代码
break;
case xxxx2:
当条件符合xxxx2时执行的代码
break;
….
}
这里的问题在于switch选择的时候,处理的变量会被强转为int类型

这里当我们输入字符串时,会被强转为int类型的
当我们输入字符串4abcdesdf的时候,这个 a 就 会 被 强 转 为 i n t 类 型 , 使 a就会被强转为int类型,使 aint使a的值为4
0x06.in_array函数
函数格式 in_array(需要在数组内搜索的数值,被搜索的数组,一个可选参数,设置TURE检查数据和数组值类型是否相同)

绕过方式
这个函数的作用是检查数组中是否存在某个值,当没有最后的检测参数为true时,默认为松散比较,导致弱类型,传入不同数据类型来绕过

关键就在于这个最后的检查的参数,如果没有这个参数的话,就会使用松散比较来判断

这里如果没有设置检查参数为ture的话,会进行松散比较,数据类型不同的话,会进行适当的类型转换,这里aaa被转换为int类型,被转换为0,匹配失败,但是1aa 在转换时被转换为1,匹配成功
0x07.array_search()函数
绕过方式
1.传入不同数据类型来绕过,没有最后的检测参数为true时,默认为松散比较,导致弱类型
2.当数据类型不同会先把原有数据的数据类型的进行转换,导致弱类型的产生

该函数的作用是在数组中搜索某个键值,并返回键名
函数格式 array_search(要搜索的键值,被搜索的数组,设置TURE检查数据和数组值类型是否相同)

这个函数有两个问题
第一个:

和前面in_array一样,当没有设定检测参数为true时,会进行松散比较,会把数据类型进行转换,然后执行

第二个:

在这里插入图片描述

0x08.intval()函数
该函数用于获取变量的整数值

函数格式 intval(要转换的参数,指定转换需要的进制)

绕过方法:
该函数处理本身不能处理的字符串时并不会报错,直接返回0,当函数内有其他的操作时,会把字符串这些转为数字类型再操作,而且在处理一些特殊数据的时候会有不同的处理结果

echo intval('+25'); //25echo '
'; echo intval('-25');//-25echo '
'; echo intval(025);//21echo '
'; echo intval('025');//25echo '
'; echo intval(1e10);//1410065408echo '
'; echo intval('1e10');//1echo '
'; echo intval(0x1A);//26echo '
'; echo intval(25000000);//25000000echo '
'; echo intval(250000000000000000000);//2007498752echo '
';echo intval('420000000000000000000');//2147483647echo '
';echo intval(25, 8);//25echo '
';echo intval('0x42');//0echo '
';echo intval(array());//0echo '
';echo intval(array('aaa', 'abb'));//1echo '
';echo intval('aaa', 8);//0echo '
';echo intval('fgh');//0echo '
';echo intval('1e10'+8);//1410065416echo '
';echo intval('0x2000'+8);//8200?>

0x09.is_numeric函数
这个函数用于检测变量是否只由数字组成,否则返回false
函数格式is_numeric(目标字符)

绕过方法
当传入数字开头,字母在后的字符串时,参数可以绕过某些检测,从而进行到下一步,而php处理不同字符串时又会把两个字符串转换到同一类型去处理

2010) {    echo $a;}?>

这个代码里需要传入一个参数,参数要求大于2010又不能是数字,如果数字就会中途中断从而无法输出变量a里的内容,这里我们输入一个2020a的字符串,输入后由于不是纯数字,执行到下一步,又因为php在处理数据对比时会将两个数据转换为同一类型的,从而达到绕过效果,传入2010a即可;
0x10. strpos函数
strpos函数用于查找目标字符在字符串中出现的第一次的位置

函数格式:strpos(字符串,目标字符)

绕过方法
strpos在处理数组时直接返回null,而没有返回false,导致问题发生

这里通过数组的形式去传入一个数字,首先绕过第一道检测,然后在第二处strpos检测时,通过数组去绕过,直接返回null,从而绕过。

0x11.strlen函数 + intval函数

让你传一个值,这个值长度要小于4,又要比500000大,你要如何处理?

 500000){    echo file_get_contents('flag');}}绕过方法:5e5因为在strlen()函数的判断中,5e5被认为是字符串,长度为3,但是当他跟数字比较或者进行数学运算的时候,会被当成科学计数法,转成数字,也就是5乘以10的5次方,也就是500000,500000+1,自然是比500000大的

来源地址:https://blog.csdn.net/nobugnomoney/article/details/124944096

--结束END--

本文标题: CTF——PHP语言弱类型详解

本文链接: https://lsjlt.com/news/426812.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • CTF——PHP语言弱类型详解
    一、PHP语言弱类型简介 第一次打CTF比赛,关于php语言弱类型这块了解的还不够,所以写一篇笔记学习一下。 强类型是两个不同类型的变量不能用同一块内存存储弱类型是两个不同的类型的变量可以用同一块内存...
    99+
    2023-10-10
    php 开发语言
  • Python是强类型语言还是弱类型语言
    本篇内容主要讲解“Python是强类型语言还是弱类型语言”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python是强类型语言还是弱类型语言”吧!1、动静类型与强弱类型很多读者应该都熟悉动态类型...
    99+
    2023-06-16
  • p84 CTF夺旗-PHP弱类型&异或取反&序列化&RCE
    数据来源 文章参考 本课重点: 案例1:PHP-相关总结知识点-后期复现案例2:PHP-弱类型对比绕过测试-常考点案例3:PHP-正则preg_match绕过-常考点案例4:PHP-命令执行RCE变异绕过-常考点案例5:PHP-反序列化考...
    99+
    2023-09-05
    php 开发语言
  • javascript是弱类型语言的原因是什么
    本篇内容主要讲解“javascript是弱类型语言的原因是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript是弱类型语言的原因是什么”吧!在...
    99+
    2024-04-02
  • 弱类型语言javascript开发中的示例分析
    这篇文章主要介绍了弱类型语言javascript开发中的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。测试1: (未声明变量自动提升...
    99+
    2024-04-02
  • php弱类型比较及绕过
    title: php弱类型比较以及绕过 date: 2022-11-20 12 :14 :36 tags: php categories: 学习笔记 author: Abyssaler PHP中的...
    99+
    2023-09-28
    php 开发语言 数据库
  • Go语言类型详解:基本类型有哪些?
    Go语言类型详解:基本类型有哪些? 作为一门静态类型的编程语言,Go语言中拥有丰富的基本类型,这些类型为程序员提供了灵活性和效率。本文将详细介绍Go语言中常见的基本类型,并附上相应的代...
    99+
    2024-04-02
  • PHP 高级特性解析:深入了解动态类型和弱类型
    php动态类型允许变量在运行时确定其类型,提供灵活性和弱类型比较不同类型表达式。实际案例包括表单数据处理、数组处理和数据库查询。注意事项包括匹配比较类型、使用严格比较运算符和类型标注。通...
    99+
    2024-05-08
    php 弱类型
  • C语言:自定义类型详解
    目录一、结构体1.结构体变量的定义及初始化2.结构体内存对齐3.为什么要内存对齐呢?二、位段1.什么是位段2.位段的内存分配三、枚举1.枚举的定义2.枚举的优点四、联合(共用体)1....
    99+
    2024-04-02
  • Go语言之嵌入类型详解
    一、什么是嵌入类型 先看如下代码: type user struct { name string email string } type admin struct ...
    99+
    2024-04-02
  • Go语言的数据类型详解
    标题:Go语言的数据类型详解 在Go语言中,数据类型是非常重要的概念。Go语言提供了丰富的数据类型,包括基本数据类型、复合数据类型和自定义数据类型。本文将详细介绍Go语言中常用的数据类...
    99+
    2024-03-04
    数据类型 go语言 详解 键值对
  • 弱类型语言javascript中a,b运算的示例分析
    小编给大家分享一下弱类型语言javascript中a,b运算的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体如下:下...
    99+
    2024-04-02
  • Go语言文档解读:time.Duration类型详解
    Go语言文档解读:time.Duration类型详解时间是计算机编程中一个非常常见的概念,而在Go语言中,time包提供了丰富的时间处理函数和类型。其中,time.Duration类型是Go中用于表示持续时间的一个重要类型。本文将详细解读t...
    99+
    2023-11-04
    Go语言 timeDuration 类型详解
  • R语言中的因子类型详解
    一、Factor函数 #函数factor可以把一个向量编码为一个因子,其一般形式为: #factor(x,levels=sort(unique(x),na.last=TRUE),...
    99+
    2024-04-02
  • R语言数据类型深入详解
    R语言用来存储数据的对象包括: 向量, 因子, 数组, 矩阵, 数据框, 时间序列(ts)以及列表 意义介绍 1. 向量(一维数据): 只能存放同一类型的数据 语法: c(dat...
    99+
    2024-04-02
  • C语言中自定义类型详解
    目录结构大小offsetof结构体对齐规则存在原因总结结构大小 我们先随便给出一个结构体,为了计算他的大小,我给出完整的打印方案: typedef struct num { cha...
    99+
    2024-04-02
  • 详解Go语言中的数据类型及类型转换
    目录1、基本数据类型2、基础数据类型转换3、基本数据类型转为字符串4、strconv的使用5、字符串转为基础类型1、基本数据类型 数据类型有很多,先研究一下基础的,例如:布尔型、数字...
    99+
    2024-04-02
  • Go语言文档解读:encoding/json.Encoder类型详解
    在 Go 语言中, encoding/json 包是用于处理 JSON(JavaScript Object Notation)格式的数据的标准库。在这个库中,提供了一个 Encoder 类型,它可以将 Go 语言中的结构体或是其它数据类型编...
    99+
    2023-11-03
    Go语言 encoding/json Encoder类型
  • Go语言数据类型详解:基本数据类型概述
    go 语言提供了以下基本数据类型:bool:布尔型int:有符号整数uint:无符号整数float:浮点数complex:复数型byte:字符型string:字符串 Go 语言数据类型...
    99+
    2024-04-03
    数据类型 go语言
  • C语言光标信息CONSOLE_CURSOR_INFO类型详解
    光标信息的结构体类型 typedef struct _CONSOLE_CURSOR_INFO { DWORD dwSize; BOOL bVisible; ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作