!c99Shell v. 1.0 pre-release build #16!

Software: Apache/2.2.3 (CentOS). PHP/5.1.6 

uname -a: Linux mx-ll-110-164-51-230.static.3bb.co.th 2.6.18-194.el5PAE #1 SMP Fri Apr 2 15:37:44
EDT 2010 i686
 

uid=48(apache) gid=48(apache) groups=48(apache) 

Safe-mode: OFF (not secure)

/usr/share/doc/m2crypto-0.16/demo/medusa/   drwxr-xr-x
Free 50.88 GB of 127.8 GB (39.81%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     status_handler.py (7.4 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# -*- Mode: Python; tab-width: 4 -*-

VERSION_STRING = "$Id: status_handler.py 299 2005-06-09 17:32:28Z heikki $"

#            
# medusa status extension
#

import string
import time
import re

import asyncore
import http_server
import medusa_gif
import producers
from counter import counter

START_TIME = long(time.time())

class status_extension:
    hit_counter = counter()

    def __init__ (self, objects, statusdir='/status', allow_emergency_debug=0):
        self.objects = objects
        self.statusdir = statusdir
        self.allow_emergency_debug = allow_emergency_debug
        # We use /status instead of statusdir here because it's too
        # hard to pass statusdir to the logger, who makes the HREF
        # to the object dir.  We don't need the security-through-
        # obscurity here in any case, because the id is obscurity enough
        self.hyper_regex = re.compile('/status/object/([0-9]+)/.*')
        self.hyper_objects = []
        for object in objects:
            self.register_hyper_object (object)

    def __repr__ (self):
        return '<Status Extension (%s hits) at %x>' % (
            self.hit_counter,
            id(self)
            )

    def match (self, request):
        path, params, query, fragment = request.split_uri()
        # For reasons explained above, we don't use statusdir for /object
        return (path[:len(self.statusdir)] == self.statusdir or
                path[:len("/status/object/")] == '/status/object/')

    # Possible Targets:
    # /status
    # /status/channel_list
    # /status/medusa.gif

    # can we have 'clickable' objects?
    # [yes, we can use id(x) and do a linear search]

    # Dynamic producers:
    # HTTP/1.0: we must close the channel, because it's dynamic output
    # HTTP/1.1: we can use the chunked transfer-encoding, and leave
    #   it open.

    def handle_request (self, request):
        [path, params, query, fragment] = request.split_uri()
        self.hit_counter.increment()
        if path == self.statusdir:          # and not a subdirectory
            up_time = string.join (english_time (long(time.time()) - START_TIME))
            request['Content-Type'] = 'text/html'
            request.push (
                '<html>'
                '<title>Medusa Status Reports</title>'
                '<body bgcolor="#ffffff">'
                '<h1>Medusa Status Reports</h1>'
                '<b>Up:</b> %s' % up_time
                )
            for i in range(len(self.objects)):
                request.push (self.objects[i].status())
                request.push ('<hr>\r\n')
            request.push (
                '<p><a href="%s/channel_list">Channel List</a>'
                '<hr>'
                '<img src="%s/medusa.gif" align=right width=%d height=%d>'
                '</body></html>' % (
                    self.statusdir,
                    self.statusdir,
                    medusa_gif.width,
                    medusa_gif.height
                    )
                )
            request.done()
        elif path == self.statusdir + '/channel_list':
            request['Content-Type'] = 'text/html'
            request.push ('<html><body>')
            request.push(channel_list_producer(self.statusdir))
            request.push (
                '<hr>'
                '<img src="%s/medusa.gif" align=right width=%d height=%d>' % (
                    self.statusdir,
                    medusa_gif.width, 
                    medusa_gif.height
                    ) +
                '</body></html>'
                )
            request.done()

        elif path == self.statusdir + '/medusa.gif':
            request['Content-Type'] = 'image/gif'
            request['Content-Length'] = len(medusa_gif.data)
            request.push (medusa_gif.data)
            request.done()

        elif path == self.statusdir + '/close_zombies':
            message = (
                '<h2>Closing all zombie http client connections...</h2>'
                '<p><a href="%s">Back to the status page</a>' % self.statusdir
                )
            request['Content-Type'] = 'text/html'
            request['Content-Length'] = len (message)
            request.push (message)
            now = int (time.time())
            for channel in asyncore.socket_map.keys():
                if channel.__class__ == http_server.http_channel:
                    if channel != request.channel:
                        if (now - channel.creation_time) > channel.zombie_timeout:
                            channel.close()
            request.done()

        # Emergency Debug Mode
        # If a server is running away from you, don't KILL it!
        # Move all the AF_INET server ports and perform an autopsy...
        # [disabled by default to protect the innocent]
        elif self.allow_emergency_debug and path == self.statusdir + '/emergency_debug':
            request.push ('<html>Moving All Servers...</html>')
            request.done()
            for channel in asyncore.socket_map.keys():
                if channel.accepting:
                    if type(channel.addr) is type(()):
                        ip, port = channel.addr
                        channel.socket.close()
                        channel.del_channel()
                        channel.addr = (ip, port+10000)
                        fam, typ = channel.family_and_type
                        channel.create_socket (fam, typ)
                        channel.set_reuse_addr()
                        channel.bind (channel.addr)
                        channel.listen(5)

        else:
            m = self.hyper_regex.match (path)
            if m:
                oid = string.atoi (m.group (1))
                for object in self.hyper_objects:
                    if id (object) == oid:
                        if hasattr (object, 'hyper_respond'):
                            object.hyper_respond (self, path, request)
            else:
                request.error (404)
                return

    def status (self):
        return producers.simple_producer (
            '<li>Status Extension <b>Hits</b> : %s' % self.hit_counter
            )

    def register_hyper_object (self, object):
        if not object in self.hyper_objects:
            self.hyper_objects.append (object)

import logger

class logger_for_status (logger.tail_logger):

    def status (self):
        return 'Last %d log entries for: %s' % (
            len (self.messages),
            html_repr (self)
            )

    def hyper_respond (self, sh, path, request):
        request['Content-Type'] = 'text/plain'
        messages = self.messages[:]
        messages.reverse()
        request.push (lines_producer (messages))
        request.done()

class lines_producer:
    def __init__ (self, lines):
        self.lines = lines

    def ready (self):
        return len(self.lines)

    def more (self):
        if self.lines:
            chunk = self.lines[:50]
            self.lines = self.lines[50:]
            return string.join (chunk, '\r\n') + '\r\n'
        else:
            return ''

class channel_list_producer (lines_producer):
    def __init__ (self, statusdir):
        channel_reprs = map (
            lambda x: '&lt;' + repr(x)[1:-1] + '&gt;',
            asyncore.socket_map.values()
            )
        channel_reprs.sort()
        lines_producer.__init__ (
            self,
            ['<h1>Active Channel List</h1>',
             '<pre>'
             ] + channel_reprs + [
                 '</pre>',
                 '<p><a href="%s">Status Report</a>' % statusdir
                 ]
            )


# this really needs a full-blown quoter...
def sanitize (s):
    if '<' in s:
        s = string.join (string.split (s, '<'), '&lt;')
    if '>' in s:
        s = string.join (string.split (s, '>'), '&gt;')
    return s

def html_repr (object):
    so = sanitize (repr (object))
    if hasattr (object, 'hyper_respond'):
        return '<a href="/status/object/%d/">%s</a>' % (id (object), so)
    else:
        return so

def html_reprs (list, front='', back=''):
    reprs = map (
        lambda x,f=front,b=back: '%s%s%s' % (f,x,b),
        map (lambda x: sanitize (html_repr(x)), list)
        )
    reprs.sort()
    return reprs

# for example, tera, giga, mega, kilo
# p_d (n, (1024, 1024, 1024, 1024))
# smallest divider goes first - for example
# minutes, hours, days
# p_d (n, (60, 60, 24))

def progressive_divide (n, parts):
    result = []
    for part in parts:
        n, rem = divmod (n, part)
        result.append (rem)
    result.append (n)
    return result

# b,k,m,g,t
def split_by_units (n, units, dividers, format_string):
    divs = progressive_divide (n, dividers)
    result = []
    for i in range(len(units)):
        if divs[i]:
            result.append (format_string % (divs[i], units[i]))
    result.reverse()
    if not result:
        return [format_string % (0, units[0])]
    else:
        return result

def english_bytes (n):
    return split_by_units (
        n,
        ('','K','M','G','T'),
        (1024, 1024, 1024, 1024, 1024),
        '%d %sB'
        )

def english_time (n):
    return split_by_units (
        n,
        ('secs', 'mins', 'hours', 'days', 'weeks', 'years'),
        (         60,     60,      24,     7,       52),
        '%d %s'
        )

:: Command execute ::

Enter:
 
Select:
 

:: Shadow's tricks :D ::

Useful Commands
 
Warning. Kernel may be alerted using higher levels
Kernel Info:

:: Preddy's tricks :D ::

Php Safe-Mode Bypass (Read Files)

File:

eg: /etc/passwd

Php Safe-Mode Bypass (List Directories):

Dir:

eg: /etc/

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c999shell v. 1.0 pre-release build #16 Modded by Shadow & Preddy | RootShell Security Group | r57 c99 shell | Generation time: 0.0087 ]--