CTF中PHP相关题目考点总结(上) 您所在的位置:网站首页 安全知识教育总结内容有哪些题目 CTF中PHP相关题目考点总结(上)

CTF中PHP相关题目考点总结(上)

2024-07-17 10:40| 来源: 网络整理| 查看: 265

本篇文章主要总结了我在写ctfshow题目中遇到的关于PHP的考点。因为只总结知识点和考点会比较空洞,也不容易理解,所以我都是通过题目来总结考点,这样的话比较容易理解。

PHP函数特性相关0x01

考点一:intval函数传入非空数组时会返回1 详情可以查一下PHP手册。【https://www.php.net/manual/zh/function.intval.php】 考点二:preg_match()只能处理字符串,当传入的是数组时将会返回false,详情也可以查一下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; } }

例题分析:

分析上面的代码可以看出,正则匹配0-9,匹配到则返回true,直接die,但是由于preg_match()只能处理字符串,当传入的是数组时将会返回false,从而绕过死亡函数。由于之前没怎么了解过intval函数,所以我直接选择查阅php手册【https://www.php.net/manual/zh/function.intval.php】查阅后发现 **intval()**函数用于获取变量的整数值。**intval()**函数通过使用指定的进制 base 转换(默认是十进制),返回变量var的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。也就是说,当给intval()函数传入一个非空的数组时,intval()函数将会返回1,结合我们preg_match()传入数组返回false的特性,这道题的payload就很清楚了。

payload: ?num[]=1 0x02

考点一:PHP比较运算符 ===在进行比较的时候,会先判断两种字符串的类型是否相等,再比较值是否相等。

考点二:intval($value,$base)当base为0时,会检测value的格式来决定使用的进制。

例题:

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

例题分析:

如下图所示,通过查询php手册,我们发现,intval($value,$base)当base为0时,会检测value的格式来决定使用的进制,所以我们可以通过把4476转换成16进制,经过base为0的intval函数处理,会识别16进制的4476,从而返回flag,又因为===在进行比较的时候,会先判断两种字符串的类型是否相等,再比较值是否相等,所以由于字符串类型不同会返回false,从而绕过死亡函数。

图片.png

payload: ?num=?num=0x117c 0x03

考点一:strpos()函数查找字符串在另一字符串中第一次出现的位置并返回

考点二:intval($value,$base)当base为0时,会检测value的格式来决定使用的进制。

例题:

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")){ #strpos()函数查找字符串在另一字符串中第一次出现的位置并返回。 die("no no no!"); } if(intval($num,0)===4476){ echo $flag; } }

例题分析:

这道题目如果我们可以用八进制的4476来绕过,那么会有一个问题,因为八进制需要开头指定为0,而strpos()会匹配到数字0返回0,!0也就是1从而执行死亡函数,所以我们可以在八进制前面加一个空格,这样strpos()会返回1,所以我们把4476转换为8进制10574后,前面再加一个空格即可。

payload如下:

?num= 010574 0x04

考点一:PHP比较运算符 ===在进行比较的时候,会先判断两种字符串的类型是否相等,再比较值是否相等。

考点二:在PHP强比较中变量a、b两个值不一样,要求两者md5值相同时的绕过方法。

考点三:PHP中md5函数处理数组类型会返回falsefalse的特性。

例题:

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类型,从代码我们可以得知,要求a、b两个值不一样但是需要这两个值得md5值一样,因此强比较类型,我们可以利用md5函数处理数组类型会返回false的特性,从而利用false=false来绕过。我之前写过一篇总结相关知识点的文章链接如下:https://www.freebuf.com/articles/web/321300.html

payload:

a[]=1&b[]=2 0x05

考点一:in_array ()函数的作用是 检查数组中是否存在某个值,而当in_array()函数没设置第三个参数时进行的比较是弱比较。

考点二:file_put_contents()函数的作用是将一个字符串写入文件。如果写入的字符串和文件名可控则可能导致任意文件上传漏洞。

例题:

$allow = array(); #创建空数组 for ($i=36; $i < 0x36d; $i++) { array_push($allow, rand(1,$i)); #在1-$i之间随机生成一个整数,添加到数组$allow尾部 } if(isset($_GET['n']) && in_array($_GET['n'], $allow)){ file_put_contents($_GET['n'], $_POST['content']); }

例题分析:

由于之前不怎么了解in_array()函数所以直接查了PHP手册https://www.php.net/manual/zh/function.in-array.php,发现这题在使用in_array()函数时并没有设置第三个参数为TRUE,所以此时in_array函数进行的比较是==的弱类型比较。也就是会先进行强制转换成相同类型,再比较两者的值是否相等,所以当我们传入1.php时会强制转换成数字1,而数字1正好在 range(1,24)数组中,当随机生成的数字正好是1时就可以绕过 in_array()函数判断,导致任意文件上传漏洞。多试几次,直到不报错的那一次,说明成功传入一句话。之后访问1.php 再通过再通过post传入1=system('ls');即可查看目录,再访问这个flag36d.php,即post: 1=system('cat flag36d.php');即可在网页源码中看到flag。

payload:

?n=1.php post: content= #写入一句话 0x06

考点一:**is_numeric()**函数用于检测变量是否为数字或数字字符串,如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE。

考点二:php有运算的优先级,而且&& > = > and

例题:

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

例题分析:

**is_numeric()**函数用于检测变量是否为数字或数字字符串,如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE。看到最后eval,肯定是需要命令执行,这需要$v2传入命令,$v3需要;结尾,但这么一来is_numeric一处理就变成了

$vo = $v1 and FALSE and FAlse

但php有运算的优先级,也就是&&> = > and

按照运算优先级,先执行=也就是赋值给$a为true,false就被忽略了,思路也就有了,payload为

?v1=1&v2=system("tac ctfshow.php")&v3=; or ?v1=1&v2=var_dump($ctfshow)&v3=; #var_dump() 函数用于输出变量的相关信息,这里用来获取ctfshow类中变量的相关信息。从而获得flag

得到$flag_is_1ce376300x2d8dc70x2d4b870x2d9f0e0x2d1eea5dada15;,其中0x2d需要替换成-,然而一共35位还少了一位,最后一位需要爆破获得。

0x07

考点一:is_numeric() 函数用于检测变量是否为数字或数字字符串,如果指定的变量是数字和数字字符串则返回true,否则返回false。如果字符串中含有一个e代表科学计数法,也可返回true

考点二:call_user_func() 函数用于调用方法或者变量,第一个参数是被调用的函数,第二个是调用的函数的参数。

考点三:file_put_contents()函数的作用是将一个字符串写入文件。如果写入的字符串和文件名可控则可能导致任意文件上传漏洞。

考点四:通过file_put_contents()函数配合php://协议以base64编码的形式写入webshell。

例题:

说明:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有