How to use PHP to fake shell acces
(This tutorial copyright Carl van Tonder <simplyw00x> February 2006 All rights reserved)
Requirements:
**Server that allows system() [try it and see] [Frihost does]
**Server with PHP (DUH!)
**Basic knowlede of command-line. Windows here and linux here
**About 5 minutes
Skill level:
**Easy (Copy-and-Paste)
Don't get me wrong, free webhosting is great. It's free for a start...
One of my less favourite things about free webshosting, however, is the lack of shell access. Shell access, for the uninitiated, is basically where you have a command prompt and you can enter commands and have them run on the server. It's basically the same as sitting at the server and opening up a terminal window. Shell access opens up new cans of awesome. Want to delete the directory foo and all recursively delete its contents, including subfolders? This could take minutes or hours using FTP or cPanel, but with Shell access it's as easy as rm-rf foo.
Now, as I said earlier, no free hosts and few cheap ones have shell access. This is a bad thing. As you may have guessed from the subtle title, however, this is not the end of the story. Read on!
My favouritest function in PHP at the moment has to be system(). What system() does is tells the PHP interpreter to execute a command. It then returns the output. How useful is that? Then, based on this and some nifty $_GET skullduggery, we have a basic command line. w00t.
This does exactly what it looks like; grabs a command from $_GET, executes it and then bungs the output in some <pre> tags. Note the use of $_SERVER[PHP_SELF] instead of a static name to ensure that you cann call this file anything you like. Deadly, and deadly simple. It is, however, not ideal. For a start, no errors are displayed. The way around this is to, instead of executing the command and directly displaying the output, instead redirecting the output and the errors to a text file, displaying the text file and then deleting it. We'll also use a read-only textarea to make it look a bit more like a shell:
Replace the <pre> tags and the bit between them with the above, and marvel at the error-reporting glory. Try and ls a non-existent directory to prove this. So, what else could we add? Well, one of the most confusing things whilst working in a shell is knowing what directory you're in, and what the directories above you are. Also, some unscrupulous webhosts (*cough*Frihost*cough*) will not let you cd to directories above home, or in some cases even public_html. So, a breadcrumb-esque directory structure seems to be in order:
Looks complicated; really isn't. First, it splits the $DOCUMENT_ROOT (forward-thinking PHPers may want to use $_SYSTEM[DOCUMENT_ROOT] instead) into an array, with each element containing a directory name. Then, it bungs 'Root' out and starts a for loop where it prints each parent directory. Sharp observers will have noticed that that entire block of code is equivalent to echo $DOCUMENT_ROOT;, but this method is more useful on two levels. Firstly, it's longer and hence will help make your code look more impressive, and second it will be built upon in the next step.
That next step is that we'd quite like just to be able to click on these directories and the it'd cd to them. How rare!
I hope by now you're beginning to see how things are falling together. Basically, we $_GET the $work_dir and then change to it. If $_GET[work_dir] is blank, we change to the document root. The [color=green]for loop outputs links instead of text, and that's about it for changes.
So, that's it for that. The full and final file (orignally by Martin Geisler, www.gimpster.com with modifications by me) is located here and is ready to run right off the bat. Bear in mind that this can be used to bork your entire website, however, so it would be wise to put it in a password-protected directory (using .htaccess) or something.
Carl van Tonder.
(This tutorial copyright Carl van Tonder <simplyw00x> February 2006 All rights reserved)
Requirements:
**Server that allows system() [try it and see] [Frihost does]
**Server with PHP (DUH!)
**Basic knowlede of command-line. Windows here and linux here
**About 5 minutes
Skill level:
**Easy (Copy-and-Paste)
Don't get me wrong, free webhosting is great. It's free for a start...
One of my less favourite things about free webshosting, however, is the lack of shell access. Shell access, for the uninitiated, is basically where you have a command prompt and you can enter commands and have them run on the server. It's basically the same as sitting at the server and opening up a terminal window. Shell access opens up new cans of awesome. Want to delete the directory foo and all recursively delete its contents, including subfolders? This could take minutes or hours using FTP or cPanel, but with Shell access it's as easy as rm-rf foo.
Now, as I said earlier, no free hosts and few cheap ones have shell access. This is a bad thing. As you may have guessed from the subtle title, however, this is not the end of the story. Read on!
My favouritest function in PHP at the moment has to be system(). What system() does is tells the PHP interpreter to execute a command. It then returns the output. How useful is that? Then, based on this and some nifty $_GET skullduggery, we have a basic command line. w00t.
| Code: |
| <form action="<?php echo $_SERVER[PHP_SELF]; ?>" method="GET">
<input name="cmd" value="<?php print $_GET['cmd']; ?>"> <input type="submit"> </form> <br> <pre> <?php system($_GET['cmd']); ?> </pre> |
This does exactly what it looks like; grabs a command from $_GET, executes it and then bungs the output in some <pre> tags. Note the use of $_SERVER[PHP_SELF] instead of a static name to ensure that you cann call this file anything you like. Deadly, and deadly simple. It is, however, not ideal. For a start, no errors are displayed. The way around this is to, instead of executing the command and directly displaying the output, instead redirecting the output and the errors to a text file, displaying the text file and then deleting it. We'll also use a read-only textarea to make it look a bit more like a shell:
| Code: |
| <textarea cols="80" rows="20" readonly>
<?php $command = $_GET[cmd]; if ($command) { system($command . " 1> /tmp/output.txt 2>&1; cat /tmp/output.txt; rm /tmp/output.txt"); } ?> </textarea> |
Replace the <pre> tags and the bit between them with the above, and marvel at the error-reporting glory. Try and ls a non-existent directory to prove this. So, what else could we add? Well, one of the most confusing things whilst working in a shell is knowing what directory you're in, and what the directories above you are. Also, some unscrupulous webhosts (*cough*Frihost*cough*) will not let you cd to directories above home, or in some cases even public_html. So, a breadcrumb-esque directory structure seems to be in order:
| Code: |
| <p>Current working directory: <b><?php
$work_dir_splitted = explode("/", substr($DOCUMENT_ROOT, 1)); echo "Root/"; if ($work_dir_splitted[0] == "") { } else { for ($i = 0; $i < count($work_dir_splitted); $i++) { echo "$work_dir_splitted[$i]/"; } } ?></b></p> |
Looks complicated; really isn't. First, it splits the $DOCUMENT_ROOT (forward-thinking PHPers may want to use $_SYSTEM[DOCUMENT_ROOT] instead) into an array, with each element containing a directory name. Then, it bungs 'Root' out and starts a for loop where it prints each parent directory. Sharp observers will have noticed that that entire block of code is equivalent to echo $DOCUMENT_ROOT;, but this method is more useful on two levels. Firstly, it's longer and hence will help make your code look more impressive, and second it will be built upon in the next step.
That next step is that we'd quite like just to be able to click on these directories and the it'd cd to them. How rare!
| Code: |
| <?php
$work_dir = $_GET[work_dir]; /* First we check if there has been asked for a working directory. */ if (isset($work_dir)) { /* A workdir has been asked for - we chdir to that dir. */ chdir($work_dir); $work_dir = exec("pwd"); } else { /* No work_dir - we chdir to $DOCUMENT_ROOT */ chdir($DOCUMENT_ROOT); $work_dir = $DOCUMENT_ROOT; } ?> <p>Current working directory: <b><?php $work_dir_splitted = explode("/", substr($work_dir, 1)); echo "<a href=\"".$_SERVER['PHP_SELF']."?work_dir=" . urlencode($url) . "/&command=" . urlencode($command) . "\">Root</a>/"; if ($work_dir_splitted[0] == "") { } else { for ($i = 0; $i < count($work_dir_splitted); $i++) { $url .= "/".$work_dir_splitted[$i]; echo "<a href=\"".$_SERVER['PHP_SELF']."?work_dir=" . urlencode($url) . "&command=" . urlencode($command) . "\">$work_dir_splitted[$i]</a>/"; } } ?></b></p> |
I hope by now you're beginning to see how things are falling together. Basically, we $_GET the $work_dir and then change to it. If $_GET[work_dir] is blank, we change to the document root. The [color=green]for loop outputs links instead of text, and that's about it for changes.
So, that's it for that. The full and final file (orignally by Martin Geisler, www.gimpster.com with modifications by me) is located here and is ready to run right off the bat. Bear in mind that this can be used to bork your entire website, however, so it would be wise to put it in a password-protected directory (using .htaccess) or something.
Carl van Tonder.
