CTF中常见的黑魔法

本文也可以说是常见php特性考察的总结

1.sha1和md5

要求变量原值不同但md5或sha1相同的情况下

1.0e开头的全部相等(==判断)

240610708 和 QNKCDZO md5值类型相似,但并不相同,在”==”相等操作符的运算下,结果返回了true.

Md5和sha1一样

2.利用数组绕过(===判断)

Md5和sha1对一个数组进行加密将返回NULL;而NULL===NULL返回true,所以可绕过判断。

2.strcmp函数的绕过

strcmp 的参数只能是字符串,当我们传入数组时就会返回NULL,而判断使用的是==,NULL==0是 bool(true)的

代码测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
error_reporting(0);
$flag="{sadd44484878}";
if(isset($_GET['password']))


if (strcmp($_GET['password'],$flag)==0)

die('Flag: '.$flag);

else
print 'Invalid password';

?>

get 传参 password[] 数组,成功打出flag

sCEdxI.png

3.Ereg匹配

定义和用途

ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。

1.数组绕过

ereg是处理字符串,传入数组之后,ereg是返回NULL

2.%00截断绕过== 的比较

测试环境: php5.3版本,php7不行

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

error_reporting(0);

*//$test=$_POST['a'];*

if( ereg("c",$_GET['a'])== false)

{

echo 'failure';

}

else

{

echo 'success';

}

sCEhMq.png

加入%00,可以发现后面的c被截断了

sCE5LV.png

4.PHP弱类型比较

  1. == :弱等于。在比较前会先把两种字符串类型转成相同的再进行比较。简单的说,它不会比较变量类型,只比较值。至于怎么转换后续会再赘述。

  2. === :强等于。在比较前会先判断两种字符串类型是否相同再进行比较,如果类型不同直接返回不相等。既比较值也比较类型。

当要比较的两种字符串的类型相同时,== 和 === 是相等的。

PHP转换规则

  • 若一个数字和一个字符串进行比较或者进行运算时,PHP会把字符串转换成数字再进行比较。若字符串以数字开头,则取开头数字作为转换结果,不能转换为数字的字符串(例如”aaa”是不能转换为数字的字符串,而”123”或”123aa”就是可以转换为数字的字符串)或null,则转换为0;例如:
1
2
3
4
5
 var_dump(12=="12")                                   // true
var_dump(12=="12aa") //true
var_dump( "admin"==0) //true
var_dump(false==""==0==NULL) //true
1234
  • 布尔值true和任意字符串都弱相等。例如:
1
var_dump(true=="hyuf")                   //true
  • 数字和“e”开头加上数字的字符串(例如”1e123”)会当作科学计数法去比较;
  • 0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0;
  • 当字符串被当作一个数值来处理时,如果该字符串没有包含’.’,‘e’,’E’并且其数值在整形的范围之内,该字符串作为int来取值,其他所有情况下都被作为float来取值,并且字符串开始部分决定它的取值,开始部分为数字,则其值就是开始的数字,否则,其值为0。

5.extract变量覆盖漏洞

直接看题

sCVpdO.png

extract()函数用法:

extract() 函数从数组中将变量导入到当前的符号表。

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

该函数返回成功设置的变量数目。

如果当前符号表中有于数组键值变量名相同的,那么用数组键值的变量覆盖

trim()函数

trim() 函数移除字符串两侧的空白字符或其他预定义字符。

ltrim() - 移除字符串左侧的空白字符或其他预定义字符

rtrim() - 移除字符串右侧的空白字符或其他预定义字符

我们本题利用extract()函数的变量覆盖漏洞原理构造payload

漏洞产生原因:extract()函数当只有一个参数时,默认的第二参数是:EXTR_OVERWRITE,如果有变量发生冲突,则覆盖已有的变量。

代码审计需要满足两个条件:1. if(isset($a)) == 》 TRUE

             2. if($a==$c) == 》 TRUE

构造payload:

1
2
3
4
5
6
7
8
9
//利用extract()函数变量覆盖漏洞+php伪协议

http://123.206.87.240:9009/1.php?a=999&b=data://,999

//利用file_get_content()函数返回字符串+php弱类型(null == "string" ==》 true)

http://123.206.87.240:9009/1.php?a=
http://123.206.87.240:9009/1.php?a=&b=
http://123.206.87.240:9009/1.php?a=&c=

属于菜鸡的注释: 当file_get_connents 读入的不是一个文件是,返回的是false ,也就是 NULL

所以我们可以不对 b变量进行赋值或者随意赋值,只要a 是 NULL 就行,如果要想让a 不是NULL 我们就可以利用php伪协议 data,这里不能使用 php://input 是因为 它限定的是GET方式传参

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2021-2023 Wh1tecell
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~