由XCTF-favorite_number引发的PHP 数组问题与URL编码引出的编码问题

这个ctf题有很多大佬的WP就不写了

第一个比较是数组的强等于 但是由要求两个数组的第一个元素不等
WP的payload

stuff[4294967296]=admin&stuff[1]=user&num=123

讨论PHP数组问题(数字索引数组)

实验环境:
WINDOWS10,PHPstudy(Apache2.4.39,php5.5.9nts)

在 PHP 中,有三种数组类型:
• 索引数组 - 带有数字索引的数组
• 关联数组 - 带有指定键的数组
• 多维数组 - 包含一个或多个数组的数组

$bb = array("1" => "banana", "0" => "apple");
$bb是索引数组,即使0被双引号包含
//array(2) { [1]=> string(6) "banana" [0]=> string(5) "apple" }

为什么是4294967296?

$arr[-4] = '-4';
$arr[4294967302] = "llllllllla";
$arr[4294967301] = "llllllllls";
$arr[4294967300] = "llllllllle";
$arr[4294967299] = "llllllllld";
$arr[4294967298] = "lllllllllf";
$arr[4294967297] = "lllllllllg";
$arr[4294967299] = "lllllllllh";
$arr[6442450945] = "lllllllllh";
$arr[6442450944] = "lllllllllh";
$arr[6442450943] = "lllllllllh";
$arr[6442450942] = "lllllllllh";
$arr[6442450941] = "lllllllllh";
$arr[42949645353457298] = "llllllllkkkkkkkkkkkl";
$arr[15] = '1';
$arr[0] = 'oooooooooooooooooo';
$arr[1844674407370855161] = '1844674407370855161';
$arr[1844674407370855162] = '1844674407370855162aaaa';
$arr[1844674407370855163] = '1844674407370855169afffffaaa';
$arr[66666] = 't';
$arr[-3] = 'ttttgggg';
$arr[-2] = 'tttt';
$arr[4294967295] = 'te';
$arr[9223372036854775807] = 'tes';
$arr[9223372036854775808] = 'testppp';
$arr[9223372036854775809] = 'testppdddp';
$arr[0] = 'ttttgggggggg';
echo "</br>";
foreach ($arr as $key => $value) {
  
    echo "{$key} => {$value} ";
echo "</br>";
    
}

上面数组的输出结果

-4 => -4
6 => llllllllla
5 => llllllllls
4 => llllllllle
3 => lllllllllh
2 => lllllllllf
1 => lllllllllg  //说明4294967296为0
-2147483647 => lllllllllh
-2147483648 => lllllllllh
2147483647 => lllllllllh
2147483646 => lllllllllh
2147483645 => lllllllllh
-1836738928 => llllllllkkkkkkkkkkkl
15 => 1
0 => testppdddp
-1718086912 => 1844674407370855169afffffaaa
66666 => t
-3 => ttttgggg
-2 => tttt
-1 => te

//foreach打印
Array ( 
[-4] => -4 
[6] => llllllllla
 [5] => llllllllls 
 [4] => llllllllle 
 [3] => lllllllllh
  [2] => lllllllllf 
  [1] => lllllllllg
   [-2147483647] => lllllllllh
    [-2147483648] => lllllllllh 
    [2147483647] => lllllllllh 
    [2147483646] => lllllllllh 
    [2147483645] => lllllllllh 
    [-1836738928] => llllllllkkkkkkkkkkkl 
    [15] => 1 
    [0] => testppdddp
    [-1718086912] => 1844674407370855169afffffaaa 
    [66666] => t 
    [-3] => ttttgggg 
    [-2] => tttt 
    [-1] => te )
1111 1111 1111 1111 1111 1111 1111 111 //2147483647 31位
1000 0000 0000 0000 0000 0000 0000 0000//2147483648 32位
1000 0000 0000 0000 0000 0000 0000 0000 0//4294967296 33位

1100110011001100110011001100110011001100110000001001011111010//1844674407370855162
1000000000000000000000000000000000000000000000000000000000000001//9223372036854775809

上面是几个特殊数字的二进制


0---2147483647            下标0~2147483647
2147483648---4294967296   下标-2147483648~0
4294967296---6442450943   下标 0~2147483647

说明下一个溢出为0的数字是:8589934592

未指定下标时,即arr[]="aaa";
默认"aaa"的下标为arr数组下标的最大值+1
即打印时会把aaa的键指定为当前数组最大下标+1
当2147483647和[]同时存在时,即
arr[]="bbb";
arr[2147483647]="ccc";
Cannot add element to the array as the next element is already occupied in
然后使用print_r($arr)打印时,显示[2147483647] => ccc

==比较时 只比较两个数组中的键及其对应键的值,是否完全相同
===比较时,不仅在==的基础上,而且还与两个数组定义时每个元素的顺序有关,如果相同才完全相等

如果定义数组时键重复了,先定义key=a,再定义key=b,那么最后的数组中key的值为b

题目本地模拟

但是我在本地实验的时候却和题目的效果不一样??
在这里插入图片描述
虽然将大数认为0,但是 下标为0时却相等。

然后我又BURP进行POST尝试???大数没有变,而且 sthff[0] 确实不等于admin
在这里插入图片描述
不知道是什么问题???是环境吗????

这里注意!!
num的长度为8 说明它把结尾的\r\n\r\n也读了。。。为下文做铺垫嘿嘿

下面按照我们的实验。。。。将下标改为8589934592
成功!!
在这里插入图片描述

URL编码与其他编码方式

首先,POST与GET方式(其他类型暂且忽略)

前端的POST与GEt

在写前端的时候我们都用过表单提交,表单提交关注最多的是:methtod:GET和POST方法
enctype:application/x-www-form-urlencoded、multipart/form-data、text/plain
1.application/x-www-form-urlencoded在发送前编码所有字符(默认)(空格被编码为’+’,特殊字符被编码为ASCII十六进制字符)
2.multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
3. text/plain 空格转换为 “+” 加号,但不对特殊字符编码。

参考链接:为什么上传文件的表单需要设置enctype=“multipart/form-data”

在一个提交一个参数和上传一个文件的表单中

<form action="xxx" method="未知" enctype="未知">
<input type="text" name="name">
<input type="file" name="file"/>
<input type="submit" value="submit" name="submit">
</form>
  1. enctype=application/x-www-form-urlencoded
    1.method=’get’
因为是get请求,所以只有头部没有正文。
请求的链接为/xxx?name=hello+world.&file=temp.png&submit=submit,
可以看到表单的信息已经被编码到URL中了。
注意两点:
"hello world"被编码为%22hello+world%22,特殊字符和空格都被编码
type='file'提交的文件内容并没有被提交, //内容没有提交
只是把文件名编码到了URL中

2 .method=’post’ 编码后的表单内容作为post请求的正文内容

与get请求相比,
只是把name=hello+world.&file=temp.png&submit=submit放在了正文中,
其他没有区别了
注意两点:
"hello world"被编码为%22hello+world%22,特殊字符和空格都被编码
type='file'提交的文件内容并没有被提交,//内容·没有提交
只是把文件名编码到了正文中

在这里插入图片描述
2.enctype='multipart/form-data'

  • method=get: 结果和实验一一模一样,说明get和multipart/form-data配合无效,只是普通的提交。
  • method=post: 文件上传成功,参数也上传成功
  • 在这里插入图片描述

后端的POST与GET数据接收

GET

  • 在已知URL参数的情况下,我们可以根据自身情况采用$_GET来获取相应的参数信息($_GET['name'])
  • $_REQUEST: $_REQUEST["参数"] 具有$_POST["参数"] $_GET["参数"]的功能,但是$_REQUEST["参数"]比较慢。 通过post和get方法提交的所有数据都可以通过$_REQUEST数组["参数"]获得
  • 在未知的情况下,$_SERVER['QUERY_STRING']或者$_SERVER["REQUEST_URI"]
    在这里插入图片描述
    在这里插入图片描述

POST

  • $_POST、$_REQUEST。。。。只能接收Content-Type: application/x-www-form-urlencoded提交的数据
  • file_get_contents("php://input")、$GLOBALS['HTTP_RAW_POST_DATA']。。。。 php://input和 $HTTP_RAW_POST_DATA 都不能用于 enctype="multipart/form-data" 对于未指定 Content-Type 的POST数据,则可以使用$GLOBALS['HTTP_RAW_POST_DATA']和file_get_contents(“php://input”);来获取原始数据
  • enctype="multipart/form-data"类型用$_FILES['file']['tmp_name']来获取文件
<?php
echo var_export($_FILES,true);
echo file_get_contents($_FILES['file']['tmp_name']);
$path = "./".$_FILES['file']['name'];
echo "<br>"."储存路径:".$path."</br>";
copy($_FILES['file']['tmp_name'], $path);
?>

$_FILES是一个二维数组。第一个键是表单中的name属性

<input type="file" name="file"/>

第二个键属性参考下图,有name\type\tmp_name\size\error
在这里插入图片描述

  • 对于一个enctype="multipart/form-data"类型中的参数怎么提取暂时还不知道,emmmm。如下的第一个参数。第二个用$_FILES
    -在这里插入图片描述

URL编码正题

来看一下对GET和POST参数的提取
在这里插入图片描述
红色是POST内容。蓝色是GET内容。不同函数的提取,然后都是用echo回显。但是效果却不同,那么到底怎么回事呢??
在这里插入图片描述
在这里插入图片描述

到底在哪里进行URL编解码

下一篇博客:
URL编码及其其他编码问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值