php特性靶场

 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;
    }
} 

由代码可知我们所传入的参数中不能有数字但又要使intval($num)=1

intval() 的返回值是整型,1或者0 作用于数组时当数组为空,返回值是0,不为空则为1

所以我们可以使用数组进行绕过正则表达式也就是说我们不按规定去传一个数组而不是字符串就会返回false从而不会进入if语句,达到绕过的效果

输入:?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参数既要绕过第一个if语句也应该满足第二个if语句这样才能输出flag

由第一个if语句可知我们不能直接传入4467这个数由第二个if语句中intval函数可知

intval($num, 0) 表示将变量 $num 转换为整数,根据 $num 的前缀来确定进制。如果转换后的整数值等于 4476,则可以尝试找到适合的前缀和进制

因此符合intval($num, 0)==4476 条件的输入方式有很多种可以通过进制转换 例:?num=0x117c

或者在数字后面加上字母或者加上小数(因为intval()函数只取整数部分且如果没有前缀会默认是十进制)

输入:?num=4476.0 或 ?num=4476a 或 ?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';
} 

由源代码可知此题需要得到一个名为cmd的参数

第一个大的if语句条件是要满足正则匹配(意思就是要在你传入的参数中匹配到正则表达式中的东西)

preg_match('/^php$/im', $a)此部分中 /i 表示匹配的时候不区分大小写 /m 表示多行匹配 ^$符号表示匹配每一行的开头结尾

第一个if的嵌套if语句条件preg_match('/^php$/i', $a)

对比以上两行代码可知第二个if条件中没有了 /m 不能进行多行匹配因此我们可以在传入的参数中第一行没有php第二行有只要符合这种形式均能得到flag(在url中换行符为%0A因为不区分大小写所以对PHP的写法没有要求)

输入:?cmd=php%0A123

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);
    }
} 

此题和web90唯一的差别就是

web90 $num === "4476"

web92 $num==4476

全等比较 (===) 不会进行类型转换,而相等比较 (==) 会进行类型转换

因此在web92中4476.0不行

其它与web90的方法没有区别

输入:?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);
    }
} 

看到第一个条件是首先排除不能直接让参数等于4476

然后将第二三个条件结合起来看发现也不能通过其他进制的方法(因为不能有大小写字母)

如果考虑十进制且intval()函数只取整数部分所以我们可以通过在4476后加上小数部分来得到flag

输入:?num=4476.1 或 ?num=010574

web94

<?php

include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==="4476"){
        die("no1 no no!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("no2 no no!");
    }
    if(!strpos($num, "0")){
        die("no3 no no!");
    }
    if(intval($num,0)===4476){
        echo $flag;
    }
} 

通过对代码的大致观察我们发现此关代码和上一关的区别是存在

strpos() 函数此函数用于在字符串中查找一个子串的第一次出现位置。如果找到了子串,则返回子串在字符串中的位置(索引)否则返回 false又因为在这行代码之前有!表示对结果取反所以说我们的参数中必须含有0但是需要注意的是我们的0不能出现在首位否则返回的位置可能为0取反条件为真就无法得到flag因此我们可以在八进制数010574基础上做处理可以在开头加上换行符%0a或空格

另一种方法:当我们仔细观察这段代码发现是全等比较因此我们可以输入4476.0来绕过

输入:?num=4476.0或+010574或%20010574(其中%20是空格的url编码)

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;
    }
} 

根据对代码的解释我们可知我们要想得到flag传入的参数需要满足

相等比较不能等于4476且不能含有英文字母或小数点,要含有0且在首位不能是0

由上可得

输入?num= 010574或%0a010574

web96

 <?php

highlight_file(__FILE__);

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

由源代码可知我们需要传入参数u且u不能等于flag.php

highlight_file($_GET['u']由这行代码可知它会高亮显示参数u

的值所指的文件

但是我们又不能直接传入flag.php所以我们可以在flag.php之前加上当前目录./

即传入的值为./flag.php,或者也可以传入flag.php文件的绝对路径

输入:?u=./flag.php或D:\phpStudy\WWW\phptx\web96\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的值不同但是他们的md5加密结果必须完全相同

所以我们想到了使用两个不同的数组来绕过因为md5函数对于数组不能处理如果输入数组会返回空NULL

另一种方法:若两个字符经MD5加密后的值为 0exxxxx形式就会被认为是科学计数法,且表示的是0*10的xxxx次方则还是零都是相等的

下列的字符串的MD5值都是0e开头的:

QNKCDZO

240610708

s878926199a

s155964671a

s214587387a

s214587387a

输出:?a[]=1&b[]=2或a[]=QNKCDZO&b[]=240610708

web98

<?php

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';由这段代码可知如果存在get传参则get所传的参数会被post参数覆盖

$_GET['flag'] == 'flag' ? $_GET = &$_COOKIE : 'flag'; 
$_GET['flag'] == 'flag' ? $_GET = &$_SERVER : 'flag';

这两行代码对最后flag的输出没有影响因为最后源代码的显示主要看get参数HTTP_FLAG=flag是否成立

highlight_file($_GET['HTTP_FLAG'] == 'flag' ? $flag : __FILE__);

但是我们不能直接get传参HTTP_FLAG=flag因为如果get传参存在的话就会被post覆盖所以我们可以get传参任意一个数(随便传但是必须有)然后再post传参HTTP_FLAG=flag覆盖get所传参数的值便可以显示flag

get输入:flag=flag(随便输) post输入:HTTP_FLAG=flag

web100

<?php

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");
        }
    }
} 

以上代码表示只有$v0=1且v2中不能含有分号v3要有分号

$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);在这段代码中只需要v1有数字即可因为赋值操作的优先级大于and

eval("$v2('ctfshow')$v3");这段代码会执行括号里的内容因此我们可以利用括号中的$v2('ctfshow')$v3来构造可以输出flag的函数

//flag in class ctfshow;由题目中的注释可知flag在ctfshow中因此我们只需要输出ctfshow即可

get传参传入?v1=1&v2=var_dump($ctfshow)/*&v3=*/;       /*....*/是注释符

var_dump()是PHP中的一个函数,用于输出一个或多个表达式的结构信息,包括表达式的类型和值。它通常用于调试目的,可以帮助开发者理解变量的内容和结构。var_dump()函数可以接受多个参数,每个参数都会被输出。对于数组和对象,它会递归地展开值,并通过缩进显示其结构

输入:?v1=1&v2=var_dump($ctfshow)/*&v3=*/;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值