An information disclosure vulnerability exists in the findhostd authentication functionality of Synology DSM 6.2.3 25426 DS120j. Using an application (e.g. Synology Assistant) can lead to information disclosure of administrator credentials. An attacker can sniff network traffic to trigger this vulnerability.
Synology DSM 6.2.3 25426-2 DS120j
https://www.synology.com/en-global/dsm
8.0 - CVSS:3.0/AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-319 - Cleartext Transmission of Sensitive Information
Synology DiskStation Manager (DSM) is the Linux-based operating system for every Synology NAS.
For easy configuration and setup of different Synology NAS’s running Synology DSM, tools such as the Synology Assistant are provided: https://www.synology.com/en-us/releaseNote/Assistant. This tool (and perhaps others) interact with Synology NAS’s by communicating over UDP port 9997, 9998, and 9999 to the findhostd
daemon.
Avoiding diving too deeply into the protocol, there are certain commands that can be sent to findhostd
that require authentication via pam_unix.so
. In the case of Synology Assistant, there is a Memory Test
command that requires this, but based on the fact that there’s three cross-references of the pam_authentication
codepath we’re concerned with, we surmise that there are other tools or binaries that also perform vulnerable actions. Let us now examine the packet sent upon trying to perform a Memory Test
from Synology Assistant:
0000 12 34 56 78 53 59 4e 4f a4 04 00 00 02 01 a6 04 .4VxSYNO........
0010 78 00 00 00 01 04 0c 00 00 00 19 11 30 30 3a 31 x...........00:1
0020 31 3a 33 32 3a 62 38 3a 63 33 3a 35 38 2a 10 76 1:32:b8:c3:58*.v
0030 6e 73 6e 48 50 34 50 75 55 37 55 42 30 65 6e 4a nsnHP4PuU7UB0enJ
0040 05 61 64 6d 69 6e c2 04 5a 61 00 00 7c 11 31 31 .admin..Za..|.11
0050 3a 65 30 3a 34 63 3a 33 36 3a 30 30 3a 32 63 :e0:4c:36:00:2c
Not too complicated, findhostd
’s protocol is a simple tlv. Breaking it down to the individual elements:
buf = ''"
#magic bytes
buf+= "\x12\x34\x56\x78SYNO"
# not sure, but required
buf+= '\xa4" [1]
buf+= "\x04" [2]
buf+= "\x00\x00\x02\x01' [3]
# not sure, but required
buf+= '\xa6\x04'
buf+= '\x78\x00\x00\x00'
# not sure, but required
buf+= '\x01\x04'
buf+='\x0c\x00\x00\x00'
# dst mac addr 00:11:32:b8:c3:58
buf+= '\x19\x11\x30\x30\x3a\x31\x31\x3a\x33\x32\x3a\x62\x38\x3a\x63\x33\x3a\x35\x38'
# password ???
buf+= '\x2a\x10'
buf+= 'vnsnHP4PuU7UB0en' [4]
# username (admin)
buf+= '\x4a\x05\x61\x64\x6d\x69\x6e'
#src mac addr 11:e0:4c:36:00:2c
buf+=' \x7c\x11\x31\x31\x3a\x65\x30\x3a\x34\x63\x3a\x33\x36\x3a\x30\x30\x3a\x31\x62'
As an example of a singular tlv, we see a uint8_t type
at [1], a uint8_t len
at [2], and then the value at [3]. Each given type
correspond to a different parameter is usually only an integer (which must be length 4) or a string. In examining the previously mentioned authentication opcodes, we quickly see that type \x4a
is passed as the username, whilst type \x2a
is passed as an obfuscated password of some sort, the text input to generate the bytes at [4] was ‘password’. Looking back at the authentication codepath, we quickly see a singular function which handles this decoding process:
=>0x7f7bb62e28 : stp x29, x30, [sp, #-64]! //start of MatrixDecode(input,output)
0x7f7bb62e2c : mov x29, sp
0x7f7bb62e30 : stp x19, x20, [sp, #16]
0x7f7bb62e34 : stp x21, x22, [sp, #32]
0x7f7bb62e38 : stp x23, x24, [sp, #48]
0x7f7bb62e3c : cbz x0, 0x7f7bb62f94
***********************************************************************************
#0 0x0000007f7bb62e28: (0x7f7bb5f000 0x7f7bb6a000 0xb000 0x0 /usr/lib/libfindhost.so.1)
#1 0x000000000040c000: (0x400000 0x40f000 0xf000 0x0 /usr/syno/bin/findhostd)
***********************************************************************************
[-.-]> x/1s $x0
0x7ff3acb1d4: "vnsnHP4PuU7UB0en"
[^.^]> x/1s $x1
0x7ff3ac9198: ""
[o.o]> fin
Run till exit from #0 0x0000007f7bb62e28 in ?? ()
[^.^]> x/1s 0x7ff3ac9198
0x7ff3ac9198: "password"
The name of the function essentially gives up the vulnerability, the word “Decode” is always fun when it deals with credentials. Giving a quick run-through to verify that the entire MatrixDecode
and MatrixEncode
process is in fact entirely hard coded and has no secrets:
7f7bb62ed0 e4f047f9 ldr x4, [x7, #0xfe0] {mapc2d@GOT} [1]
7f7bb62ed4 62004039 ldrb w2, [x3] [2]
7f7bb62ed8 66f05f38 ldurb w6, [x3, #-0x1]
7f7bb62edc 82686238 ldrb w2, [x4, x2] [3]
7f7bb62ee0 84686638 ldrb w4, [x4, x6]
7f7bb62ee4 8218022a orr w2, w4, w2, lsl #0x6
7f7bb62ee8 414c1432 orr w1, w2, #0xfffff000
7f7bb62eec 82fe5f37 tbnz w2, #0xb, 0x7f7bb62ebc
7f7bb62ef0 4000621e scvtf d0, w2
7f7bb62ef4 63080091 add x3, x3, #0x2
7f7bb62ef8 7f0000eb cmp x3, x0 [4]
7f7bb62efc a08400fc str d0, [x5], #0x8 [5]
7f7bb62f00 81feff54 b.ne 0x7f7bb62ed0
At [1], we load in a hard coded matrix (just 0x100 hardcoded bytes) that we then index into at [3] with bytes taken directly from a pointer in our input buffer, x3
at [2]. After performing basic operations on these sets of bytes, we then store it into a different matrix at [5], and continue to do so until x3
reaches the end of our input buffer at [4].
After this, another reversible matrix operation occurs, but with a different hardcoded matrix:
7f7bb62f04 a10000f0 adrp x1, 0x7f7bb79000
7f7bb62f08 e20318aa mov x2, x24
7f7bb62f0c e00313aa mov x0, x19 // transformed buffer
7f7bb62f10 21cc47f9 ldr x1, [x1, #0xf98] {pmti64@GOT}
7f7bb62f14 210040f9 ldr x1, [x1]
7f7bb62f18 6efcff97 bl MatrixMultiply
7f7bb62f1c 6105005c ldr d1, 0x7f7bb62fc8
7f7bb62f20 03230091 add x3, x24, #0x8
7f7bb62f24 020080d2 mov x2, #0
After performing a MatrixMultiply
with a transformed version of the input buffer and a hardcoded matrix, the output buffer can be read as the decoded password.
A few other things to note for understanding the totality of this vulnerability, in order to get to MatrixDecode
, the user account authenticating must be a part of the admin
group. Also, because this is pam_authentication
, this password must be the plaintext of the actual account’s normal unix password. Furthermore, the library functions used by Synology Assistant to send this authentication message are broadcast to 255.255.255.255, so one doesn’t even need to perform a MITM attack, one simply needs to be able to receive broadcast traffic from the device authenticating in order to gain an administrative credential.
2020-10-21 - Vendor Disclosure
2021-02-25 - Public Release
Discovered by Lilith >_> and Claudio Bozzato of Cisco Talos.
This vulnerability has not been disclosed and cannot be viewed at this time.