关于PHP二次传参


在很多CTF比赛里面,经常出现如下代码(以下代码也为后面例题源码):

$a=$_GET['cmd'];
	if (preg_match("/system/i", $a))
{
	echo 'isset flag!!';
	die();
}
	eval($a); 

先不考虑其他绕过取反,异或等等绕过方式,纯粹的从二次传参出发,playload应该如下:

?cmd=\$_GET[a] (\$_GET[b])&b=system&b=ls 

这里我们采用system(dir)的命令在本地运行:
在这里插入图片描述
很显然,这里可以绕过死亡die从而执行命令

问题1:虽然是二次传参传给了cmd,但是为什么可以绕过那么正则表达式呢?

我们改下源码看看:
这里增加了一个 echo $a,这样更方便我们清楚传进去$a的值,很显然,虽然这里我想用二次传参,但是这里没有传进去,$_GET[shell]在这里仅仅是一个字符串

在这里插入图片描述

问题2:那么为什么在后面,$_GET[shell]又可以进行传参了呢?

这里应该是由于eval存在的原因,eval执行$_GET[shell],并且可以命令执行传入进来的字符串

问题3:既然可以把传入进来的字符串命令执行,那为什么不直接用一个$_GET然后执行所有呢?

而是?cmd=$_GET[a] ($_GET[b])&b=system&b=ls ,我们在看一下效果:
在这里插入图片描述

没有执行命令,至于为什么没有执行,我猜测是因为传进来的数值依然是当成了字符串
比如:?cmd=$_GET[shell];&shell=system(‘dir’);
最后还是被当成了字符串:eval(‘system(“dir”);’);,eval一个字符串,自然也得不到一个输出
为了更好的证实一下我的猜想,我们修改一下代码看看:
在这里插入图片描述
果然,传进去的system(‘dir’);被当成了字符串输出了。
为了避免被当成字符串的现象,所以我们才会采用多次传参的方法,具体原因我认为应该是由于()的存在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值