IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> PHP 黑魔法 -> 正文阅读

[PHP知识库]PHP 黑魔法

PHP 黑魔法

弱比较

若字符串以数字开头,则取开头数字作为转换结果,若无则输出0

<?php 
echo "---------------- 弱比较黑魔法 -------------------------";
echo "<br>";echo "<br>";
if (1 == "1abc") {
	if (0 == "abc") {
		if ("0e132456789" == "0e7124511451155") {
			#常见于md5弱比较绕过
			echo "两个'=='的弱比较成功";
		}
	}
}

md5(),sha1()

md5()是不能处理数组的,md5(数组)会返回null,两个null相等绕过
sha1()也是同理

<?php 
echo "---------------- md5(),sha1()黑魔法 -------------------------";
echo "<br>";echo "<br>";
if (md5($md5_bug1[]=1) === md5($md5_bug2[]=1)){
	if (sha1($md5_bug1[]=1) === sha1($md5_bug2[]=1)){
		echo "md5传入数组绕过成功";
	}
}

转换

php会自动进行转换,比如16进制,科学计数法等,有时也用这点绕过

<?php 
echo "---------------- 转换黑魔法 -------------------------";
echo "<br>";echo "<br>";
echo "0x1e240 自动转换10进制:",0x1e240;
echo "<br>";
echo "123456 十进制数:",123456;
echo "<br>";
echo "1e240 科学计数法自动转换:",1e240;
---------------- 转换黑魔法 -------------------------<br><br>0x1e240 自动转换10进制:123456<br>123456 十进制数:123456<br>1e240 科学计数法自动转换:1.0E+240

strcmp()

int strcmp ( string $str1 , string $str2 )
参数 str1第一个字符串。str2第二个字符串。
如果 str1 小于 str2 返回 < 0;
如果 str1 大于 str2 返回 > 0;
如果两者相等,返回 0。

strcmp()函数只有在相等的情况下返回0。
php在5.3版本之前若传入的是一个非字符串类型数据,比如数组和对象,则会报错,但在报错的同时会返回0,那么我们传入一个数组,它会返回NULL,而判断使用了== ,但是NULL==0是bool(true),这样就成功绕过。

<?php
echo "---------------- strcmp()黑魔法 -------------------------";
echo "<br>";echo "<br>";
$strcmp_bug[]=1;
if (@strcmp($strcmp_bug, "you_don't_know_this_string") == 0){
	echo "strcmp()数组黑魔法绕过成功";
}

例:

<?php
    $password="***************"
     if(isset($_POST['password'])){
        if (strcmp($_POST['password'], $password) == 0) {
            echo "Right!!!login success";
            exit();
        } else {
            echo "Wrong password..";
        }
?>

只要我们$_POST[‘password’]是一个数组或者一个object即可

password[]=admin

intval()

intval()转换的时候,会将从字符串的开始进行转换直到遇到一个非数字的字符。
即使出现无法转换的字符串,intval()不会报错而是返回0。
注:
在科学计数法字符串转换为数字时,如果 E 后面的数小于某个值会弄成 double 类型,再强制转换为 int 类型时可能会有奇妙的结果,测试发现某变量为 1e-1000 时已经可以触发这个漏洞绕过两个检查,使得某变量既大于 0 又不大于 0。

例如:

var_dump((int)('1e-1000')>0);
var_dump('1e-1000'>0);

结果

Command line code:1:
bool(true)
Command line code:1:
bool(false)

再如:

var_dump((int)('1e-10')>0);
var_dump('1e-10'>0);

结果

Command line code:1:
bool(true)
Command line code:1:
bool(true)
<?php
echo " ---------------- intval()黑魔法 -------------------------";
echo "<br>";echo "<br>";
echo "2 的intval()转换结果:",intval('2');
echo "<br>";
echo "3abcd 的intval()转换结果:",intval('3abcd');
echo "<br>";
echo "abcd 的intval()转换结果:",intval('abcd'); 
echo "<br>";echo "<br>";
$intval_bug = '1e-1000';
if ((int)($intval_bug) > 0) {
	if ($intval_bug <= 0) {
		echo "intval()转换问题绕过成功";
	}
}

ereg()

字符串对比解析,ereg函数存在NULL截断漏洞,当ereg读取字符串string时,如果遇到了%00,后面的字符串就不会被解析。
注:这里的%00是需要urldecode才可以截断的,这是url终止符,且**%00长度是1**不是3

<?php
echo "---------------- ereg()黑魔法 -------------------------";
echo "<br>";echo "<br>";
$input = urldecode('1e8%00*-*');
// echo strlen($input); #7
if (isset($input)){
	if (@ereg ("^[a-zA-Z0-9]+$",$input) === FALSE){
		echo $input;
        echo '输入只能是数字和字母!';
    }
	else{
		echo "ereg()%00截断绕过成功";   
	}
}

例:

<?php
if (isset ($_GET['password'])) {
   if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
   {
       echo '<p>You password must be alphanumeric</p>';
   }
   else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
   {
       if (strpos ($_GET['password'], '*-*') !== FALSE)
       {
           die('Flag: ' . $flag);
       }
       else
       {
           echo('<p>*-* have not been found</p>');
       }
   }
   else
   {
       echo '<p>Invalid password</p>';
   }
}
?>

ereg函数存在NULL截断漏洞,可以%00截断,则不会读取后面的内容,可以绕过输入*-*
大小和长度限制可以利用科学计数法

?password=1e8%00*-*

is_numeric()

如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE,注意浮点型返回 1,即 TRUE。

当有两个is_numeric判断并用and连接时,and后面的is_numeric可以绕过
16进制也可以绕过is_numeric()检验,可以用来绕过sql注入里的过滤

<?php
echo "---------------- is_numeric()黑魔法 -------------------------";
echo "<br>";echo "<br>";
$is_numeric1 = "0123";
$is_numeric2 = "abc";
$c=is_numeric($is_numeric1) and is_numeric($is_numeric2);

if ($c) {
	if (is_numeric('    +.1234e5678')) {
		echo "is_numeric()连用漏洞绕过";
		# 这样也能绕过检测……
	}
}

switch()

当switch没有break时可以继续往下执行。
这里也有自动转换,比如$switch_bug = a,会当0执行,=1a,会当1执行……

<?php
echo "---------------- switch()黑魔法 -------------------------";
echo "<br>";echo "<br>";
@$switch_bug = 0;
if (isset ( $switch_bug )) {
	switch ($switch_bug) {
 		case 0 :
 				echo '你已经运行到了case0';
 				echo "<br>";
 		case 1 :
 				echo '你已经运行到了case1';
 				echo "<br>";
 		case 2 :
 				echo '你已经运行到了case2';
 				echo "<br>";
 				echo "switch()没有break连续运行绕过成功";
 				break;
 		default :
 				echo "1";
 				break;
 }
}

array_search()

用到了PHP弱类型的一个特性,当一个整形和一个其他类型行比较的时候,会先把其他类型intval再比。
当检索中带入字符串,比如”sky”,会intval(‘sky’)==0,从而致使数字数组也可以查询成功

<?php
echo "---------------- array_search()黑魔法 -------------------------";
echo "<br>";echo "<br>";
$array_search=[1,0];
$eee = @array_search("XMAN", $array_search);
if($eee){
	echo "array_search()检索字符串绕过成功";
}

json_deconde()

json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

json_decode接受一个JSON格式的字符串并且把它转换为PHP变量 ,当该参数$assoc为TRUE时,将返回array,否则返回object。

<?php
echo "---------------- json_decode()黑魔法 -------------------------";
echo "<br>";echo "<br>";
$v3=0;
$input = '{"key":0001}';
$b=json_decode(@$input);
if($var = $b === NULL){
        ($var === true)?$v3=1:NULL;
        if ($v3) {
        	echo "json_decode()函数漏洞绕过成功";
        }
    }
?>

Extract()

该函数使用数组键名作为变量名,使用数组键值作为变量值。但是当变量中有同名的元素时,该函数默认将原有的值给覆盖掉。这就造成了变量覆盖漏洞。

<?php
$a = 1;    //原变量值为1
$b = array('a' => '3');
extract($b);    //经过extract()函数对$b处理后
echo $a;    //输出结果为3
?>

例题:

"extract($_GET);
if(isset($a))
{
$content=trim(file_get_contents($flag));//file_get_contents—将整个文件读入一个字符串
if($a==$content)                             //trim—去除字符串首尾处的空白字符(或者其他字符)
{ echo'flag{**********}'; }
else
{ echo'这不是flag啊'; }
}"

题目使用了**extract($_GET)接收了GET请求中的数据,并将键名和键值转换为变量名和变量的值,然后再进行两个if 的条件判断,所以可以使用GET提交参数和值,利用extract()**对变量进行覆盖,从而满足各个条件。

?a=&content= 或者可以利用file_get_contents()可以读取只读流:php://input构造Payload

int_array()绕过(使用不设第三个参数的情况下)

bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
说明:在 haystack 中搜索 needle,如果没有设置 strict 则使用 宽松 的比较。如果第三个参数 strict 的值为 true,则 in_array 函数还会检查 needle 的 类型 是否和 haystack 中的相同。

in_array 函数存在第三个参数 strict,它用来标记函数在对两元素进行比较时是否采用 严格比较,类似 == 和 === 区别,in_array 函数默认采用 宽松 比较,即不比较类型,只比较值是否相等。
例如:in_array(0, array('s'))会返回 TRUE,这是因为因为 in_array 函数没有使用第三个参数,而默认进行了 宽松 比较,即等同于 0 == ‘s’ ,而为什么0 == ‘s’,可参照下表:

img

filter_var()(仅对FILTER_VALIDATE_URL)

filter_var() 要求传入参数符合url规定,函数通过指定的过滤器过滤一个变量。 如果成功,则返回被过滤的数据。如果失败,则返回 FALSE。
FILTER_VALIDATE_URL:把值作为 URL 来验证。

mixed filter_var ( mixed ``$variable` `[, int ``$filter` `= FILTER_DEFAULT [, mixed ``$options` `]] )

参数:

$variable 待过滤的变量,必须,如果不是字符串,PHP会自动依据转换规则,将其转为字符串。

$filter 过滤使用的过滤器ID,可选

$option 一个选项的关联数组,或者按位区分的标示。如果过滤器接受选项,可以通过数组的 “flags” 位去提供这些标示。

返回值:如果通过验证,返回过滤后的数据,否则返回false。

FILTER_VALIDATE_URL 过滤器来判断是否是一个合法的url。

例题:

// index.php
<?php 
$url = $_GET['url'];
if(isset($url) && filter_var($url, FILTER_VALIDATE_URL)){
    $site_info = parse_url($url);
    if(preg_match('/sec-redclub.com$/',$site_info['host'])){
        exec('curl "'.$site_info['host'].'"', $result);
        echo "<center><h1>You have curl {$site_info['host']} successfully!</h1></center>
              <center><textarea rows='20' cols='90'>";
        echo implode(' ', $result);
    }
    else{
        die("<center><h1>Error: Host not allowed</h1></center>");
    }

}
else{
    echo "<center><h1>Just curl sec-redclub.com!</h1></center><br>
          <center><h3>For example:?url=http://sec-redclub.com</h3></center>";
}

?>

构造符合函数要求的URL即可,又因为题目正则匹配了要求以sec-redclub.com结尾,构造如下:

?url=0://xxx.com;sec-redclub.com ?url=http://xxx.com()sec-redclub.com ()里换成@&?/,:#这些任意一个均可

.htmlentitier()

在写PHP代码时,不能在字符串中直接写实体字符,因此需要一个将HTML特殊字符转换成实体字符的函数 htmlentities()。
注:htmlentities() 并不能转换所有的特殊字符,是转换除了空格之外的特殊字符,且单引号和双引号需要单独控制(通过第二个参数)。第2个参数取值有3种,分别如下:

  • ENT_COMPAT(默认值):只转换双引号。
  • ENT_QUOTES:两种引号都转换。
  • ENT_NOQUOTES:两种引号都不转换。

img

ec-redclub.com结尾,构造如下:

?url=0://xxx.com;sec-redclub.com ?url=http://xxx.com()sec-redclub.com ()里换成@&?/,:#这些任意一个均可

.htmlentitier()

在写PHP代码时,不能在字符串中直接写实体字符,因此需要一个将HTML特殊字符转换成实体字符的函数 htmlentities()。
注:htmlentities() 并不能转换所有的特殊字符,是转换除了空格之外的特殊字符,且单引号和双引号需要单独控制(通过第二个参数)。第2个参数取值有3种,分别如下:

  • ENT_COMPAT(默认值):只转换双引号。
  • ENT_QUOTES:两种引号都转换。
  • ENT_NOQUOTES:两种引号都不转换。

[外链图片转存中…(img-sbCaExxz-1632206471123)]

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:21:05  更:2021-09-24 10:21:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:40:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码