I went hunting for vulnerable PHP code to use as an example and my first acquisition was a collection of scripts that wouldn't function correctly.  It had several different pieces, all supposedly vulnerable, but only one of the pieces actually worked.  In my second attempt at finding vulnerable code, I came across WackoPicko.  According to the description:

"WackoPicko is a website that contains known vulnerabilities. It was first used for the paper Why Johnny Can't Pentest: An Analysis of Black-box Web Vulnerability Scanners"

In the end, I didn't get exactly what I wanted and my frustration with "free" code not performing up to my level of expectation lead me down a path which is equally amusing.

No need to scan with Nmap, we already know what we're after:

After a quick run through of the links, I head over to the registration page and I setup an account:

When we login, we are greeted with:

I attempt to upload a shell using the image upload function:

When the upload is finished, I attempt to see the specifics of what was uploaded and how:

It's obvious that "something" was uploaded.  I pull the source and I find:

I realize the input fields for the upload are part of the naming process.  I need to rework that to our advantage.  

When I view what was uploaded, I see that our shell is intact although it looks like garbage when viewed here:

Starting over:

Now, we're looking good:

When we view the /upload directory, we see:

Setting up our handler:

When we execute the shell, we catch our session in Metasploit.  No need to move further down that path.  Our goal is to exploit this application, not the server.

Moving on to XSS:

Pretty basic stuff. 

When we hit Submit:

We have XSS.  

Looking for SQL Injection:

When we hit Create Account:

It really doesn't get much easier than that.  In fact, I'm not even sure how that happened.  I could dig into the code but I choose to move on.

Now here's where things start going down hill.  There are a number of possible angles to this application and when I attempt to inject using either PHP or SQL into other areas of the site, I run into walls.  So much so that I go back to the instructions and I see that there are indeed vulnerabilities where I'm poking.  Not only that, HOW I'm poking "should" work but it does not.  

At that point, I head in the opposite direction and I decide to write vulnerable pieces for this application.

The site has a built-in password tester which calls "grep" and we should be able to inject into the PHP but what we inject ends up in the variable and does NOT break the statement.  Maybe that has something to do with the version of PHP or I don't know what but I can't get it to do what it's supposed to do.

Then I think -- what would it take to create a form that takes input -- input I can break into?  

Our form:

And when we post:

Taking the variable directly from the form and inserting it directly into our command.

When we run it with good intentions:

We get:

And when we run it with bad intentions:

We get:

This is not the only method to inject code, we can use any number of methods.  Another for your pleasure:

And we get:

Somewhat satisfied, I move on to another area of the site that's supposed to be vulnerable to SQL Injection but the same issue occurs and I, again, decide to write vulnerable code which allows us to SQL Inject.

My ability to write PHP is one dimensional and while I tried incorporate what was written for this application, I couldn't get it to work.  More to the point, I gave up.  I abandon the original code and I write up a simple page that makes a connection to the SQL server and queries the existing database while creating an injection point.

In retrospect, this is blind SQL injection.  Not because I'm clever but because I didn't include SQL errors into the output.  More on that later.

Our code looks like this:

Querying for a known title:

We get:

Attempting SQL Injection:

When I hit Submit:

Not what I was expecting but even though I wrote the query, I'm not thinking about it.

Attempt #2:

We hit Submit:

Now that's what I was expecting.  

I realize we're working with two different languages:  PHP and MySQL.  

Attempt #3 which injects on both:

We hit Submit:

Now we're cooking!

Still not thinking with 100% of my brain though and just mindlessly poking:

We hit Submit:

Not the desired outcome.

Moving into SQL to query directly on the database:

It makes a lot more sense when you can see where you're inserting characters as opposed to just blindly inserting random characters.  We need to open, close, and terminate appropriately.  

Looking at this example helps to understand the problem when we're attempting to use:  ' or '1'='1

While that works in some cases, it doesn't here because:

We fail to close off the statement.  Now that we can see where this goes wrong, we head back to our form:

This time, we close off the statement with the ending single quote and we terminate the PHP with the #.

We hit Submit:

And we get what we're expecting.

Previously, our attempts we were injecting blindly but if we add error output:

I've included the query statement from the form along with any error message from SQL.  Now when we inject:

We hit Submit:

And we get an error which allows us to see what we're injecting and where we're injecting.  

This went off in a direction I wasn't expecting and it did not provide the example I needed but it's given me some ideas for that Vuln server I will create.... some day....