Synopsis
A heap-based buffer overflow vulnerability exists in Ivanti Avalanche prior to 6.4.3.
A message sent to Avalanche's WLAvalancheService.exe on TCP port 1777 has the following structure:
// be = big-endian
strut msg
{
preamble pre;
hp hdrpay;
};
struct preamble
{
be32 MsgSize; // size of hp + 16
be32 HdrSize; // size of hp.hdr
be32 PayloadSize; // size of hp.payload
be32 unk:24;
be32 em:8; // encryption method
};
// header + payload
struct hp
{
MuProperty hdr[]; // hdr as array of MuProperty structure(s)
// h.cmd
// - REQ_REGISTER (18)
// - RSP_REGISTER (19)
// - REQ_AUTH_DEVICE_KEY (28)
// - RSP_AUTH_DEVICE_KEY (29)
// - REQ_AUTH_AGENT_KEY (30)
// - RSP_AUTH_AGENT_KEY (31)
// - REQ_FILE_UPLOAD (10)
// - RSP_FILE_UPLOAD (11)
// - REQ_FILE_UPLOAD_CONT (12)
// - RSP_FILE_UPLOAD_CONT (13)
// - ...
MuProperty payload[]; // payload as array of MuProperty structure(s)
byte pad[]; // zero-padded to 16-byte boundary
};
struct MuProperty
{
be32 type; // property type, valid: 1-9, 100-102
be32 NameSize;
be32 ValueSize;
byte name[NameSize]; // property name
byte value[ValueSize]; // property value
// format depends on @type
// 3 - hex string
// 9 - list of decimal strings separated by ;
// 100-102 - list of tokens separated by ;
};WLAvalancheService.exe allows upload of a large amount of file data via multiple RSP_FILE_UPLOAD / RSP_FILE_UPLOAD_CONT messages from the client. Each message carries a block of compressed file data in the 'p.parcel' property in the message payload, which is limited to a certain size as preamble.MsgSize has a maximum size (i.e., 0x200000).
The compressed and decompressed sizes of a file block are specified in the 'p.parcel.cmp' and 'p.parcel.info' properties, respectively. The last file block transferred is indicated by the 'p.eof' property set to a non-zero value.
WLAvalancheService.exe calculates the decompressed size for all file blocks by adding the decompressed size in each RSP_FILE_UPLOAD / RSP_FILE_UPLOAD_CONT message and allocates a buffer of that size to store the decompressed file data:
// WLAvalancheService.exe v6.4.2.0
[...]
.text:004C4715 foreach_file_upload_msg: ; CODE XREF: sub_4C4650+E6↓j
.text:004C4715 mov eax, [ebp+inmsg]
.text:004C4718 mov ecx, [eax+INMSG.pNext]
.text:004C471E mov [ebp+inmsg], ecx
.text:004C4721
.text:004C4721 loc_4C4721: ; CODE XREF: sub_4C4650+C3↑j
.text:004C4721 cmp [ebp+inmsg], 0
.text:004C4725 jz short loc_4C4738
.text:004C4727 mov edx, [ebp+inmsg]
.text:004C472A mov eax, [ebp+TotalDecompressedSize]
.text:004C472D add eax, [edx+INMSG.DecompressedSize] ; int32 overflow
.text:004C4733 mov [ebp+TotalDecompressedSize], eax
.text:004C4736 jmp short foreach_file_upload_msg
.text:004C4738 ; ---------------------------------------------------------------------------
.text:004C4738
.text:004C4738 loc_4C4738: ; CODE XREF: sub_4C4650+D5↑j
.text:004C4738 mov ecx, [ebp+TotalDecompressedSize]
.text:004C473B push ecx
.text:004C473C call operator new(uint)
.text:004C4741 add esp, 4
.text:004C4744 mov [ebp+var_74], eax
.text:004C4747 mov edx, [ebp+var_74]
.text:004C474A mov [ebp+pbDecompressedBuf], edx
[...]
.text:004C47E5 lea eax, [ebp+pbDecompressedMsg]
.text:004C47E8 push eax
.text:004C47E9 mov ecx, [ebp+pSession]
.text:004C47EF mov edx, [ecx+SESS.field_1BB4]
.text:004C47F5 push edx
.text:004C47F6 mov eax, [ebp+inmsg]
.text:004C47F9 push eax
.text:004C47FA mov ecx, [ebp+pSession]
.text:004C4800 call decompress_msg ; return true/false
.text:004C4805 mov byte ptr [ebp+var_64], al
.text:004C4808 mov ecx, [ebp+var_64]
.text:004C480B and ecx, 0FFh
.text:004C4811 test ecx, ecx
.text:004C4813 jz short err_4C4886
.text:004C4815 cmp [ebp+pbDecompressedMsg], 0
.text:004C4819 jz short copy_input_data
.text:004C481B mov edx, [ebp+inmsg]
.text:004C481E mov ecx, [edx+INMSG.DecompressedSize]
.text:004C4824 mov esi, [ebp+pbDecompressedMsg]
.text:004C4827 mov edi, [ebp+pbDecompressedBuf]
.text:004C482A add edi, [ebp+offset]
.text:004C482D mov eax, ecx
.text:004C482F shr ecx, 2
.text:004C4832 rep movsd ; copy decompressed data to small
.text:004C4832 ; heap buf -> heap overflow
.text:004C4834 mov ecx, eax
.text:004C4836 and ecx, 3
.text:004C4839 rep movsb
[...]An unauthenticated remote attacker can specify a large decompressed size in multiple RSP_FILE_UPLOAD / RSP_FILE_UPLOAD_CONT messages to cause an int32 overflow in the total decompressed size for all file blocks. This can result in a heap-based buffer overflow when decompressed data is copied to a small heap-based buffer.
Solution
Upgrade to version 6.4.3 or later.
Additional References
https://forums.ivanti.com/s/article/Avalanche-6-4-3-Security-Hardening-and-CVEs-addressed?language=en_UShttps://www.ivanti.com/blog/security-update-for-ivanti-avalanche
Disclosure Timeline
All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.
Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.
For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.
If you have questions or corrections about this advisory, please email [email protected]