0x01 漏洞预警
OpenEMR是OpenEMR社区的一套开源的医疗管理系统。该系统可用于医疗实践管理、电子医疗记录、处方书写和医疗帐单申请。 OpenEMR 5.0.2之前版本中的interface/forms/eye_mag/save.php文件存在SQL注入漏洞。该漏洞源于基于数据库的应用缺少对外部输入SQL语句的验证。攻击者可利用该漏洞执行非法SQL命令。
0x02 漏洞分析
查看版本diff:OpenEMR <5.0.2
存在两处sql注入漏洞
发现是由于sql语句直接拼接造成得sql注入
1 | $sql = "DELETE from categories_to_documents where document_id IN (SELECT id from documents where documents.url like '%" . $filename . "')"; |
这里直接将$filename
传入sql语句,没有进行任何过滤。
下载cms 5.0.17进行查看
1 | $filename = $pid."_".$encounter.".pdf"; |
可以看到我们可以控制encounter
参数从而造成sql注入漏洞
本文主要回顾一下防御方法
1 | $sql = "DELETE from categories_to_documents where document_id IN (SELECT id from documents where documents.url like ?)"; |
在这里使用了参数化查询方法防止sql注入sqlQuery($sql, ['%'.$filename]);
跟入sqlQuery函数
发现使用了mysqli_fetch_array() 函数
语法
mysqli_fetch_array(result,resulttype);参数 描述
result 必需。规定由 mysqli_query()、mysqli_store_result() 或 mysqli_use_result() 返回的结果集标识符。
resulttype 可选。规定应该产生哪种类型的数组。可以是以下值中的一个:
MYSQLI_ASSOC 数字数组
MYSQLI_NUM 关联数组
MYSQLI_BOTH
这里的$link是查询数据库的sql语句 $statement是传入的filename
参数,规定查询字符串。
在执行参数化查询的时候,服务器把sql语句发送到数据库,数据库编译sql语句放入缓存池中,等服务器执行execute
时,传入数据库的sql注入语句不进行编译,而是找到之前在缓存池的sql模板,传参,执行,所以sql注入语句只会被当作参数处理。
参考: