ctfshow Web入门[命令执行] web56-77 Writeup
剩下来的命令执行
有一些 open_basedir 和 disable_functions 的绕过
web56
过滤了字母和数字
根据上一题, 只能使用 .
执行 PHP 的缓存文件
web57
提示 flag 在 36.php 中
发现 $
没被过滤, 当时想的是类似 $$
$@
$!
的指令, 然后 ++
--
这样子, 本地测试发现都不好构造36
hint 如下
|
|
双小括号的介绍 http://c.biancheng.net/view/2480.html
|
|
$(())
的默认值是0 ,因为里面没有任何东西, 对0取反得到-1, 取反的结果需要用另一对$(())
包裹住
这里的-1有点特殊, 因为类似 $((1 1))
的命令是错误的 (没有运算符号), 而两个-1并在一起 $((-1 -1))
会让 shell 认为是 $((-1-1))
即-1减去1, 然后得到-2
|
|
36的取反结果是-37, 就是说我们需要通过-1来构造出-37, 然后再取反一次
|
|
访问得到 flag
|
|
web58
命令执行的函数都被 ban 了, 但是 file_get_contents()
还能用
然后看到了 index 里的 highlight_file(__FILE__)
, 也能够读取 flag
payload 如下
|
|
之前的无参数读取文件在这里也能用
web59-65
同上
或者配合伪协议进行文件包含, eval 在这里比较灵活, 方法很多
web66
flag 换了个位置
|
|
其实只要题目源码能看得到, highlight_file()
就一直能用…
web67
print_r()
被过滤了, 换成 var_dump()
或者 var_export()
scandir()
返回的是数组, 其实就算被过滤了也可以加下标 echo 输出或者写个循环
web68
都被过滤了, 换成文件包含, 盲猜一个 /flag.txt
scandir()
没有被过滤, 严谨一点列目录再读取也可以
web69-70
同上
web71
index.php 附件
感觉漏了个 ob_start()
就是说将脚本输出的内容发送到缓冲区, 然后通过 ob_get_contents()
获取缓冲区内容, ob_end_clean()
清除并关闭缓冲区, 最后通过 preg_replace()
过滤输出
简单来说就是我们 eval 返回的输出内容被过滤了, 大小写字母和数字会被替换成 ?
测试了一下发现如果语句执行错误, 会显示原来的内容
没有被过滤
当语句执行成功后才被过滤
也就是说过滤的操作是在我们当前的命令执行完以后再进行的
我们可以通过 die()
exit()
让程序终止, 不再继续往下执行
web72
/flag.txt 提示不存在
列目录发现被限制了
考察的是 open_basedir
和 disable_function
的绕过
https://www.v0n.top/2020/07/10/open_basedir绕过/
https://www.anquanke.com/post/id/208451
使用 scandir() + glob://
列目录, 不过 glob:// 协议还是有限制, 子目录就不能列了
|
|
flag 在 /flag0.txt 内, 但是受限于 open_basedir 和 disable_functions, 常规的文件读取和文件包含都不起作用
于是尝试 bypass disable_functions
其中一个 exp
|
|
https://github.com/mm0r1/exploits
我用的是安全客里的 exp, 注意 url 编码
执行失败, 报错显示 str_repeat()
被禁用了
发现是这两处调用了这个函数
本质上是把 A
重复79遍, 干脆手工替换
又失败了, 这次是 chr()
被禁用
查阅 PHP 官方手册发现可以使用 sprintf('%c', $var)
的形式替代 chr($var)
https://www.php.net/manual/zh/function.sprintf.php
替换之
执行成功
查看 /flag0.txt 得到 flag
web73
/flagc.txt
竟然可以直接包含了…
web74
scandir()
被 ban 了
换成 DirectoryIterator
|
|
然后 include 读取 flag
web75
DirectoryIterator + glob:// 列目录
flag 在 /flag36.txt, include 包含失败, 存在 open_basedir 限制
hint 提示是 mysql 弱口令连接, 用 load_file()
读文件…(???)
|
|
读文件
web76
/flag36d.txt
同上
web77
提示是 php 7.4
response 头显示 X-Powered-By: PHP/7.4.9
strlen()
被禁用. 三种 UAF exp 都不能用, 在上面安全客的文章里找了一会
FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP 的 FFI 扩展就是一个让你在 PHP 里调用 C 代码的技术。
尝试一下 FFI 扩展
cat /flag36x.txt > /var/www/flag.txt
读不出来
换成 readflag 下载下来发现是个 ELF 文件
于是用 readflag 读取 /flag36.txt