Okay, let's break some of it down:
How come this is possible? Apparently, the input from the GET variable password seems to be evaluated as PHP. This can be caused by eval(), but also preg_match() where the 'e' flag is set.
(And other functions too, but in cases like these, most likely the above.)
How could the actual code look like?This is just a pseudo-file based on the information shared,
<?php
$username = $_GET['user'];
$password = $_GET['password'];
@eval($password. ";");
// This is a valid query: ${@print(md5(1))}
// Which equals: eval(${@print(md5(1))});
?>
The interesting part of this is that we can evaluate input as PHP with e.g., ${@print(md5(1))} and the URI may look like this:
http://example.tld/path/script.php?user=1&password=${@print(md5(1))}
So, what's up with the ${@print(md5(1))} ?It seems overly completicated, as print(md5(1)) could've possibly achieved the same, depending on filters and WAF's in use.
Furthermore, the @ only disables any error output, meaning you will only make it harder for yourself.
You may not even need the ${PHP code} , perhaps you may.
Why can't you use <?php phpinfo(); ?> ?Because you would receive an error like this:
Parse error: syntax error, unexpected '<' in /var/www/script.php(5) : eval()'d code on line 1
(not exactly like that of course.)
Why don't you get an error like that?Because error_reporting(0); is set or display_errors is Off.
Why doesn't system() work?Because A) The website has a filter or WAF in place blocking, removing, changing, etc., such requests or simply just the word system() in the URL (GET-requests) passed to varibles.
B) Perhaps because your syntax is incorrect. There can be multiple reasons, of them being that you don't encapsulate input in the system() variable with quotes or apostrophes. (i.e., system('ls') or system("ls"), you can also use base64_decode() to decode input in base64.)
What would error occurs when you just write "ls" like system(ls) ?
Notice: Use of undefined constant ls - assumed 'ls' in /var/www/script.php(5) : eval()'d code on line 1
See:
http://php.net/manual/en/function.system.phpWhy is there no output when the syntax is wrong?
Return Values: Returns the last line of the command output on success, and FALSE on failure.
What other commands can you use to execute code? exec();
passthru();
backticks, e.g., $var=`ls`;print($var)
fopen() (Requires that allow_url_fopen() is enabled for remote connections to other servers.)
include(), include_once(), require(), require_once() (These requires allow_url_include() is enabled for remote connections too.)
What can we tell from these results?Here some result
1. ${@system(ls)} (It is fine)
2. ${@system(ls /etc)} :
<script language="javascript">document.location="default.html";</script>
3. ${@print(iamhere)} (It print out fine)
4. ${@system(i am here)}:
<hr>Query was empty
1. You can use system()
2. The syntax is wrong (sorry, but it is).
3. You can use print()
4. See 2
What should you look out for when using ' and " ?In case magic_quotes is enabled, then apostrophes ' and quotes " will have a backslash prepended so they look like this \' and this \" , meaning if you send: print(system('ls')), it will become print(system(\'ls\')) which is wrong and will therefore fail.
How do you circumvent this? One way is to make the code like this:
print(base64_decode($_GET[cmd]))
(You can always add e.g., system() later on between print() and base64_decode().)
The query would then look like this to test it:
http://example.tld/script.php?user=1&password=print(base64_decode($_GET['cmd']))&cmd=VGhpcyBpcyBhIHRlc3Qgb2Ygc3BlY2lhbCBjaGFyYWN0ZXJzOiAnIC8gXCA+IDwgPyA9ICkgKCA
Where the base64 is of course a connect-back shell home to me

Joke, the above Base64 represents:
This is a test of special characters: ' / \ > < ? = ) (
What should you be aware of too?Besides magic_quotes, max_execution_time() but also Safe Mode where chroots can be enabled (so you won't have that many commands available to play with, including visible directories), and of course the Suhosin patch which hardens PHP a little bit too.
Is there a limit / max input of characters in GET-requests? Yes, typically 1024 or 2048 characters, sometimes 4096. (This depends on the webserver and can be read (and changed) in the source.
As you can see, there's a lot to know about web application security when it comes to to overcoming most challenges, but I'm glad you took the time to read this reply

It took a little while to write, as I was testing the examples I wrote as well, just to make sure they actually work
