Points: 496
Category: Web


“We will never make the same mistakes again, we challenge you to read our messages and earn some BTCs!” – DPR


In this web challenge we’re presented with a website in TOR network. To access it we can use Tor Browser and torify for command line tools like curl:

The website consists of two pages:

1) Login panel:

2) Registration panel at /register that turns out to be disabled…

Testing for common vulnerabilities like SQL Injection does not provide anything useful.
Let’s take a look at headers:

The interesting thing here is the PHP version, let’s try to find some vulnerabilities.
Searching for php 7.0.8 vulnerability in google leads us to something very interesting:

More about this vulnerability:

Quick test:

Excellent! We crashed the application!

Now let’s setup amazon instance with Tinyproxy and set it to redirect traffic to local Apache server. The requests are made with HTTPS, so we’ll also need a domain (free from No-IP) and SSL certificate (also free from Let’s Encrypt)

After successfully setting up our server let’s see what requests are being sent:

Now we can take a look at /var/log/apache2/access.log on our server and see:

/d90cdc7988b15060c1896126cee2eae9/hiddenservice_ws.php is a valid path in challenge website, but when called with GET it only returns an empty page. Let’s now create a file /d90cdc7988b15060c1896126cee2eae9/hiddenservice_ws.php in our webserver and see what requests are coming from challenge’s server:

After making request with Proxy header once again we can see the contents of request in request.log:

Turns out hiddenservice_ws.php serves SOAP API, and the query itself is used to generate captcha word. Fun fact – the original Silk Road was tracked down by leaky captcha (at least FBI claims so…), more about it: https://krebsonsecurity.com/2014/09/dread-pirate-sunk-by-leaky-captcha/ – nice try Ekoparty ;).
Now with our proxy hack we can:

  • See server queries,
  • Send valid queries to real API,
  • Respond with our own, changed response.

Knowing this we can try to login to the service. Sending the above request to real hiddenservice_ws.php returns the following output:

Let’s now change our script to pretend to be a server and make it send this response back:

Next request we got:

Again – we send it to the real server and check the response:

Let’s change it a little – replace


so that we always pass captcha validation and put it in our fake SOAP server:

The next request our fake server received from web server:

That’s the request for public key – seems like some encryption will take place. Let’s download the key from the real SOAP server and save it for later use:

Now let’s generate our own key pair for forged communication with webpage:

Let’s proceed and create fake response to getPublicKey, this time with our own key and proceed with authentication process:

Next request:

Those strings are base64 encoded and after decoding they look like some random data – let’s try to decrypt it with our private key:

Sending the query to SOAP api shows us the correct response format:

We assume that the data is encrypted using SOAP API’s private key, and the webpage uses public key it received from API to decrypt. Let’s give it a try and write our response in the format we received above, then encrypt it using our private key:

We have constructed another correct response to our fake SOAP server, let’s add it to our script:

Next request our fake API gets:

Nice – seems like we passed the authentication. Sending the query to the real API with username encrypted with server’s public key shows us another correct response format:

Decrypting the message with server’s public key gives:

It’s some structure containing user details serialized using standard PHP serialize method

Again – let’s encrypt it with our private key and add another condition to our fake SOAP script. One last request and…

No new SOAP request were made and we received Location header telling us to refresh the page. Let’s set the received PHPSESSID cookie in our browser and open the challenge’s webpage – this time without Proxy header, so the real API is being called for remaining communication. Great, we’re logged in as admin! Unfortunately, we can’t see any flags. We spent some time trying to change getUserDetails response, but the solution was much simpler – we only needed to login as DPR user (we take it from challenge description, it’s the name of original Silk Road founder) and set high level (10000000) in checkCredentialsResponse. Then voilà – flag appears in user messages: