PHP特性靶场(web89~web103)

文章探讨了在Web开发中如何通过理解代码逻辑和利用特定技巧,如数组操作、字符编码、正则表达式绕过、进制转换等,绕过预设的条件检查,成功获取flag。涉及到了诸如intval函数、字符串处理、字符编码识别等技术细节。
摘要由CSDN通过智能技术生成

1.web89

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

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

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

输入:?num[]=1

回车如图:

屏幕截图 2024-02-02 215314

2.web90

由代码可知传入的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

如图:

屏幕截图 2024-02-01 121856

3.web91

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

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

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

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

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

注意:在url中不要存在空格,因为在某些情况下,将空格字符(ASCII码为32)直接包含在URL中可能会导致问题。这是因为空格字符在URL中具有特殊的含义,用于分隔URL中的不同组件(例如路径、查询参数等)。

解的flag如图:

屏幕截图 2024-02-01 122006

4.web92

此题和web90唯一的差别就是

web90 $num === "4476"

web92 $num==4476

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

因此在web92中4476.0不行

其它与web90的方法没有区别

如图:

屏幕截图 2024-02-01 122210

5.web93

源码中共有三个过滤条件

我的解题思路:

if($num==4476){
    die("no no no!");
  }

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

if(preg_match("/[a-z]/i", $num)){
    die("no no no!");
  }
  if(intval($num,0)==4476){
    echo $flag;
  }else{
    echo intval($num,0);
  }

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

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

如图:

屏幕截图 2024-02-01 155011

也可以使用另一种方法换用八进制010574

6.web94

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

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

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

分别如图:

屏幕截图 2024-02-01 164933

屏幕截图 2024-02-01 163246

7.web95

源代码解析及思路

<?php
​
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if($num==4476)//判断num是否等于4476;可以进行类型转换
    {
        die("no no no!");
    }
    if(preg_match("/[a-z]|\./i", $num))//用于判断在num中是否存在英文字母或小数点
    {
        die("no no no!!");
    }
    if(!strpos($num, "0"))//详解见web94解释
    {
        die("no no no!!!");
    }
    if(intval($num,0)===4476)//全等比较,无法进行类型转换
    {
        echo $flag;
    }
}

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

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

由上可得

num= 0101574num=%0a010574

如图:

屏幕截图 2024-02-01 170019

8.web96

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

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

的值所指的文件

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

即传入的值为./flag.php

如图:

屏幕截图 2024-02-01 172503

或者也可以传入flag.php文件的绝对路径(flag.php文件的绝对路径的获取方法可以传入除了flag.php以外的其它任意值因为不存在所以会报错)如图:

屏幕截图 2024-02-01 174216

然后我们就可以知道当前目录的路径(图中黑色加粗部分就是)在此基础上加上文件名flag.php即为此文件的绝对路径

如图:

屏幕截图 2024-02-01 173853

9.web97

屏幕截图 2024-02-01 222406

由代码可知此题是post传参要求满足a和b的值不同但是他们的md5加密结果必须完全相同

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

例:a[]=1&b[]=0

如图:

屏幕截图 2024-02-02 124544

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

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

QNKCDZO

240610708

s878926199a

s155964671a

s214587387a

s214587387a 如图:

屏幕截图 2024-02-02 141614

10.web98

由代码可知这段代码主要使用了三目运算符? :来进行条件判断和赋值操作

$_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

如图:

屏幕截图 2024-02-02 142718

11.web99

代码解析:

  <?php
​
highlight_file(__FILE__);
$allow = array();//定义一个名为allow的空数组
for ($i=36; $i < 0x36d; $i++) { 
    array_push($allow, rand(1,$i));
}//这是一个循环 i的范围是36~876(0x36d十进制是877)在这段代码中 rand(1, $i) 生成一个介于 1 和 $i 之间的随机整数 然后array_push() 函数将这个随机数添加到 $allow 数组中
​
if(isset($_GET['n']) && in_array($_GET['n'], $allow))//条件是get传参 参数n存在并且n的值再数组allow中存在
{
    file_put_contents($_GET['n'], $_POST['content']);//把content的值写入文件n 如果n不存在就新建文件n (注意:n和content均为参数且n是get传参content是post传参)
}
​
?> 

由以上代码可知我们可以在当前目录新建一个文件并且在文件中写入任意的东西但是前提是传入n的值再随机数的数组中存在

因为数字随机生成的范围依次是:1~36;1~37;1~38;1~39 ···

所以我们可以猜测概率较大的数字比如:1,2,3 ···

因为可以新建文件并且可以在新建的文件中写入任意东西所以我们首先想到的就是新建php文件写入一句话木马这样就可以通过蚁剑连接来获取flag

(in_array()此函数一般情况下会把 "1.php" 视为数字 1,2.php同理

操作如图:

屏幕截图 2024-02-02 180722

屏幕截图 2024-02-02 180704

屏幕截图 2024-02-02 180811

屏幕截图 2024-02-02 180823

也可以得到文件名后直接在页面访问 如图:

屏幕截图 2024-02-02 180847

12.web100

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=*/;

回车即可如图:

屏幕截图 2024-02-02 202324

13.web101

由代码可知这关和web100关的区别是禁用了许多符号这就说明我们无法使用注释来像上一关那样输出ctfshow

但是我们可以利用函数把类反射出来,就像是赋值一样这样直接输出这个反射类就能得到原来的类

输入:?v1=1&v2=echo new ReflectionClass&v3=;

ReflectionClass 是 PHP 中的一个内置类,用于获取类的反射信息

echo new ReflectionClass('ctfshow') 表示输出ctfshow的反射

如图:

屏幕截图 2024-02-02 210934

根据以上题目所得到的flag可知此题的为flag{You have successfully completed web101}

14.web102

call_user_func(callback,parameter ) //是一个回调函数

第一个参数 callback 是被调用的回调函数(一般为闭包函数)其余参数是回调函数的参数

v2从第三位开始所有的值作为v1函数的参数)把v3作为文件名传入既然往进写文件那就可以写一个php的一句话木马或者是命令执行那一句话木马如何只作为数字并且经过函数又正常执行呢那一定是16进制和hex2bin

本来以为这样就可以了但是这里0x在is_numeric面前根本通不过

而且hex2bin也不允许有0x所以这里还得再加一层base64给文件内容进行base64加密然后v3利用php://filter/write=convert.base64-decode/resource伪协议把命令写进去,所以最终输入:

get:?v2=cc504438395948526859794171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post: v1=hex2bin

回车然后

访问1.php后查看源代码获得flag

操作依次如图:

屏幕截图 2024-02-02 214323

屏幕截图 2024-02-02 214627

15.web103

103关的话加了一个php的过滤但是不起作用所以和web102一样

如图:

屏幕截图 2024-02-02 215056

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值