Level 6 – shop

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:

shop full text

As the good boy I am, I register myself filling the REGISTRATION form.

register

Now, I can LOGIN into the shop.

login

Once logged, I can see the OPERATIONS MENU.

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:

product

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:

http://ctf.rs-labs.com:82/shop_c8f828cc0374f4b1e2187599055ecde2/?op=productos&tipo=%3C%3D34&Submit=SEE+PRODUCTS

And with «Expensive» selected, like this:

http://ctf.rs-labs.com:82/shop_c8f828cc0374f4b1e2187599055ecde2/?op=productos&tipo=%3E%3D36&Submit=SEE+PRODUCTS

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:

http://ctf.rs-labs.com:82/shop_c8f828cc0374f4b1e2187599055ecde2/?op=productos&tipo=%3E%3D0&Submit=SEE+PRODUCTS

«tipo>=0» does the trick. I get all the products (the omitted one included).

tip1

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?

http://ctf.rs-labs.com:82/shop_c8f828cc0374f4b1e2187599055ecde2/?op=productos&tipo=%3E%3D0&Submit=SEE+PRODUCTS&debug=1

Yes! I get this list:

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:

http://ctf.rs-labs.com:82/shop_c8f828cc0374f4b1e2187599055ecde2/?op=busqueda&nombre=*&tipo=%3C%3D34&Submit=FIND

At the server LDAP query, «nombre» is substituted with «cn» field and «tipo» with «ctfPrice» field. The query must be something like [1]:

(& (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 [1], 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 [1] 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 [1] turns into:

(& (cn=*) (| (objectClass=*) ) (| (cn=*) (ctfPrice<=34) ) )

Which means:

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:

tip2

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 [1] 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:

http://www.openldap.org/software/man.cgi?query=slapd.replog&sektion=5&apropos=0&manpath=OpenLDAP+2.0-Release

The right syntax to set an attribute value should be:

<attributetype>: <value1>

So I need to add a single line:

ctfCash: 34000

(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:

?op=registro&subop=procesar&username=m2000&clearpassword=mypass&nombrecompleto=miguel&tlf=1%0A%0DctfCash%3a%2035000&Submit=Send

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:

35000

Got it! :-)

cash

My injection worked as expected.

The final step is to buy the prized product:

solved

The flag: «LD4p_1nj3ct10N_rlZzzz«

Share on RedditShare on FacebookTweet about this on TwitterShare on LinkedIn

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Antes de enviar el formulario: