This screenshot, as rendered in Firefox, doesn’t shows all the text (maybe the web designer must enlarge the iframe container) :-P
Let’s do it:
As the good boy I am, I register myself filling the REGISTRATION form.
Now, I can LOGIN into the shop.
Once logged, I can see the OPERATIONS MENU.
I can see cheap or expensive products, find or buy products, see my cash left and logout from the shop. My start cash is 100€ and if I take a look into expensive products, I find this one:
OMFG!!! 31337€!!! I have no enough money to buy it. :-(
Well, come on!
When I click on “SEE PRODUCTS” button with “Cheap” selected, the URL looks like:
And with “Expensive” selected, like this:
On %3C%3D is ‘< =‘ url-encoded, and %3E%3D is ‘>=‘ url-encoded
Do you see something weird here? The value 35 is missing in both requests!
Trying this request:
“tipo>=0” does the trick. I get all the products (the omitted one included).
It’s a tip: “Try to activate DEBUG mode“, hum!
DEBUG mode in the browser?
DEBUG mode in the shop?
DEBUG mode into my brain?
Let’s try the second one: how can I to activate DEBUG mode in the shop? Looking at page’s source code doesn’t solve anything… What about a debug parameter into the request?
Yes! I get this list:
Aha! It’s a LDAP database!
Things turns clear. I need to do a LDAP injection to get more information. The URL when I click on “FIND” button using “*” as a wildcard, looks like:
At the server LDAP query, “nombre” is substituted with “cn” field and “tipo” with “ctfPrice” field. The query must be something like :
(& (cn=*) (ctfPrice<=34) )
Translating it to natural language:
Get all products that have ANY name AND whose prices are LESS or EQUAL to 34
If I change “< =34” for “=*” I get all products that have ANY name AND ANY price ;-) But with that information I don’t get anything useful. Looking at query , I need to inject something through the “nombre” or “tipo” attribute trying to get the whole LDAP tree.
I’ve chosen to do the injection through “nombre“.
Due to all products belong to ctfShopProduct objectClass, I’ll try to get all the objectClass classes. But I need to separate the ctfPrice from the AND condition at query  in order to the ctfPrice restriction doesn’t disturb my new query.
So, I tried this injection:
?op=busqueda&nombre=*) (|(objectClass%3d*)) (|(cn%3d*&tipo=<%3D34)&Submit=FIND&debug=1
This way, the query  turns into:
(& (cn=*) (| (objectClass=*) ) (| (cn=*) (ctfPrice<=34) ) )
Get objects whose (name is ANY) AND (whose objectClass is ANY) AND ( (whose name is ANY) OR (whose ctfPrice is LESS or EQUAL to 34) )
The ctfPrice AND restriction has been converted to an OR. :-)
Here is what I get:
Nice! Isn’t it?
I’ve got all classes in database.
The hidden “Tip 2” and “Tip 3” give me an important clue and some information: the ctfCash field for objectClass person (or ctfShopUser) is my new goal. I know that the code is calling ldapadd (ldapadd is a tool that comes with OpenLDAP package and used to add or modify registers into the LDAP database).
At this point anyone can cheat trying to guess the password of some registered users with enough cash and, logged with that user, buy the prized solution to this game. (Some users, like me, when registering themselves, have used their names as password too).
The request to get those users would be:
?op=busqueda&nombre=*) (%26(objectClass%3dperson)(ctfCash%3e%3d31337)) (|(cn%3d*&tipo=%3c%3D34)&Submit=FIND&debug=1
The query  looks like:
(& (cn=*) (& (objectClass=person) (ctfCash>=31337) ) (| (cn=*) (ctfPrize<=34) ) )
But it isn’t the goal of this game. The real goal is to get enough cash within our own user account.
Looking at ldapadd man page, this tool takes its input from command line or from a file. It’s obvious that in our case the input is taken from a file.
How and where can I alter the information into that file? ctfCash is probably set to a default value of 100 euros if not specified.
Our account is created filling the registration form. This is a good place where I can try to increase my cash.
The contents of the file that ldapadd reads should conform the rules specified here:
The right syntax to set an attribute value should be:
So I need to add a single line:
(or any quantity greater than 31337: the prize of the solution)
I can take advantage of the fact that, when we’re registering ourselves, the information provided is written into the file that will be read for ldapadd later on. I’ve used the phone field for this purpose but it’s perfectly possible to use full name field too.
The injection that do the magic is:
I’m injecting this:
\n (newline character) ctfCash: 35000
And if I login with my new user and take a look at my cash available:
Got it! :-)
My injection worked as expected.
The final step is to buy the prized product:
The flag: “LD4p_1nj3ct10N_rlZzzz“