Capture The Coin Writeup
https://capturethecoin.org/
Last updated
https://capturethecoin.org/
Last updated
My team: Kubertu stayed at top #6
My personal work stayed at top #10
Our prize
Question:
We found a mnemonic for a wallet with a note saying there is a hidden transaction:
Can you find the exact amount transferred on the BTC Testnet network?Once you're strong enough, save the world:
Problems:
This seed is generated from BIP-44
We need to find exact amount transferred ?! I was confused as well. So, as I understood one mnemonic gives thousand of addresses. In order to find the exact address has transferred the money, the fastest way to do is automate things.
Methods:
Use this online generator to get a list of addresses derived from BIP-44 https://iancoleman.io/bip39/
Later, we have a list of BIP-44 addresses
Write a automatic script by using blockcypher API
4. The first address has 1000000 n2cceZi8jjMxTtmP7oVzX2ADt4jL6qcdhQ
but it's not a right one
5. Keep on scanning, we found 179362 mygH814iJuKrg7tCY2fspCCpxtU3jrzDsd
. Seemly, this account has a balance. Let's check them out on blockchain explorer. https://www.blockchain.com/btctest/address/mygH814iJuKrg7tCY2fspCCpxtU3jrzDsd
6. Total Received 0.00179362 BTC
Question:
Someone sent us an Android malware sample saying that it stole all their BTC coins. Can you extract the evil address where all the money is sent?
https://drive.google.com/file/d/19AkEBgguBdzpRcdYWFC_ArAGVd8Sbylg/view?usp=sharing
Problems:
Is the evil address hard-coded?
Is the evil address called from arbitrary servers?
Is the evil address is hidden somewhere at the first created?
Analyze:
Is the evil address called from arbitrary servers?
Download the apk file and install it on an android phone. By using Burp Suite we can tamper its requests and see what's it calling in and out. Nothing found!
Is the evil address hard-coded?
Download the apk file and using dex2jar
to decompress the file to java file, then drag them onto the jdgui
to have a pretty human-reading format.
After hours of reading the code. I've found:
it uses Kotlin
It will target those Android phones which are installed com.madeup.wallet.app"
Then using regex
to find the victim address
The evil address is encrypted and write them to log :D
Answer:
Connect the phone to the PC
Run adb logcat | grep "asdf"
Open the app
Question:
Can you cause the ethereum contract below to self destruct?
Cause the contract at 0x8fb994E4F056c659CF96f9cAFdC4dd6F2cD402F8 to selfdestruct itself.
Problems:
Contract using selfdestruct
Contract using delegatecall
To execute the function selfdestruct
we have to become an owner
delegatecall
is calling to an arbitrary number/address ??!!
Answer:
Paraphrased from the solidity docs:
“Delegatecall is identical to a message call apart from the fact that the code at the target address is executed in the context of the calling contract and
msg.sender
andmsg.value
do not change their values.This means that a contract can dynamically load code from a different address at runtime. Storage, current address and balance still refer to the calling contract, only the code is taken from the called address.”
This low-level function has been very useful as it’s the backbone for implementing Libraries and modularizing code. However it opens up the doors to vulnerabilities as essentially your contract is allowing anyone to do whatever they want with their state.
Thanks to this drawback of delegatecall
. I created an attack smart contract
1. Add address 0x8fb994E4F056c659CF96f9cAFdC4dd6F2cD402F8 to Jackpot smart contract.
2. Deploy Checker smart contract which has fallback function.
3. Add our smart contract address to function hackerme
. The delegatecall
will call our smart contract with an arbitrary function which also means it will trigger the fallback function. Bravo! we soon will become the owner of Jackpot smart contract.
4. We become an owner
5. Execute destroyme()
function (I had to increase gas limit to 300000).
6. The contract is killed.
Your goal is to recognize a flaw in a particular implementation of a digital currency client, that utilizes CryptoNote key/transaction model, and use it to get the tracking key of the node running this client. Setup
The node that you are targeting is misconfigured; it's error log is publicly accessible via a RPC endpoint. What is relevant for this challenge are log entries created by the function that checks every transaction that passes through the node.
You construct and broadcast a series of invalid transactions. These transactions are recored in txs.json . Many other fields that would be present in a real transaction are omitted for brevity.
Althought the broadcasted transactions are invalid, with this particular node you can see error messages mentioning these transactions appearing in the node's aforementioned error log. These log entries are recorded in err_log.json.
Using this information, find the tracking key of the node owner. This tracking key is the flag for the challenge. The flag must be submitted in hex format. Technical details
Appendix
It's important to note that the node operator's funds are still safe since the spending key is not stored on the node or used for transaction scanning. But now you can set up your own tracking node and watch every transaction that is sent to the node operator, defeating the unlinkable payments model.```
We have 2 files, transactions and their error log:
The CryptoNode use Elliptic-curve Diffie–Hellman(ECDH) to establish a common secret between client and server, the elliptic-curve is brainpoolP160r1(RFC - https://tools.ietf.org/html/rfc5639), so we know value of p, A, B, base point (x,y), q
Curve-ID: brainpoolP160r1
In order to understand the basic idea behind our attacks, you just need to know that an elliptic curve E in cryptography is a set of points over a finite field satisfying the following equation: E: y^2 = x^3 + ax + b
You can read more from https://en.wikipedia.org/wiki/Elliptic-curve_cryptography
According to the CryptoNode whitepaper, we know the destination key is "P = Hs(rA)G + B" and one-time public key is "P' = Hs(aR)G + bG". But to simplify the challenge, the destination key is P=rA, P'=aR and the tracking key is a
P = rA
P' = aR
R = rG => P' = a(rG)
G is a base point, that belong to the curve(brainpoolP160r1). We need to find the tracking key a(a part of private key).
Reading through the transaction log txs.json, we can get x, y (It's a 160-bit curve, so a point on the curve is a pair of 160-bit numbers. A point on the curve is serialized as follows: 0xXXXXYYYY, where XXXX is a 160-bit hexadecimal number corresponding to the x-coordinate of the point and YYYY is another 160-bit number in hex corresponding to the y-coordinate of the point). The first 20 bytes of the transaction is X, the last 20 bytes is Y. Now we use SageMath to check these points - They belong to the curve?.
After checking, all of them do not belong to the defined curve. Look like the attacker sent 22 invalid points(outside of the defined curve) to the server. The invalid point could belong to a different curve E' (different B), which consists of a very small number of elements(Invalid curve attacks).
Let’s call this new curve E′. E′: y^2 ≡ x^3 + A*x + B' (mod P) B' ≠ B
We have 22 points in the txs.json, so we can compute B' with the expression:
B' = (Y^2 - X^3 - A*X) mod p
B' = [214056964304889, 221864837895040, 227922420544393, 241972569596889, 8356763387106, 28159690006704, 9516820837131, 165209032884639, 168449704989074, 60673558959867, 101581735758527, 159237028241252, 40242026678833, 103670189236856, 262646877055792, 240332779594647, 239871262924756, 193672526341504, 269060903799201, 187321463214601, 185801876971391, 256736902157449]
These new curve’s order has a small prime divisor r will ensure there exists a subgroup of 𝔼′ of small order r. As the discrete logarithm(https://en.wikipedia.org/wiki/Discrete_logarithm) is now in the subgroup of |r| generated by G ∈ 𝔼′, the result will only have r possible values. If we send the invalid point P' to the server, the server computes secret sP'. The secret can have only small possible values. If we are able to learn the result sP'(from err_log.json), we then also learn s1 = s mod (small order).
This will leak k mod r. Repeating this for new curves and new r values will create a system of linear congruences which can be solved with the Chinese Remainder Theorem, we can find out the final value of k.
a = k ≡ X (mod r)
Using the result in err_log.json, we can compute the discrete logarithm of G1` and the order of G`.
K mod order(G`) = discrete_log(G1`)
Finally, We get the secrect with the Chinese Remainder Theorem(CRT)
The secret:
0xdec1a551f1edc014ba5edefc042019
Question & Answer:
Code:
Question & Answer