Immunify ETH ESCAPE CTF Writeup
Immunify ETH ESCAPE CTF Writeup
During devcon 7 in bangok, I participated in ETH ESCAPE ctf organized by immunify. It was my first experience, playing an on-site ctf with time restriction. In this, contest the time was 50min. I did really bad, so this is me trying to review and solve some of the challenges after the contest.
Check all the problems and solutions in my github.
Sekai
This was an easy challenge that required some knowledge about how mappings are stored in the evm.
We have to find the key stored in keys[0xdead]
in the constructor to unlockSekai()
and solve the challenge.
In order to do this, we need to retrieve the slot where the key is saved. In the evm, mappings
are stored at slot keccak256(abi.encode(x, y))
being y
the slot of the mapping
variable keys
which in this case is 1 and x
the key of the mapping 0xdead
.
Solution:
function test_Sekai() public {
bytes32 slot = keccak256(abi.encode(uint256(0xdead), uint256(1)));
sekai.unlockSekai(uint256(slot));
assertEq(sekai.isKeyFound(), true);
}
Curve Validator
In order to solve this challenge we need to have a basic understanding of what are elliptic curves and how we can perform point addition.
https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/
The elliptic curve is setup with some constants A
and B
and a finite field p
.
The formula of the elliptic curve is y**2 = x**3 + ax + b mod p
. If that equation resolves,
then we have a point P(x,y)
on the curve.
In order to pass validate(x2,y2)
we have to ensure that the points passed are on the
curve and also the point addition of P(W0x, W0y) + Q(x2, y2) = R(X[0], y3)
.
https://www.rareskills.io/post/elliptic-curve-addition
At this point, we have points P
and R
(as we can deduct y3
from X[0]
), all we have
to do is a bit of magic to find out x2
.
The point addition formula for elliptic curves rearanged for x2 is as follow:
x**2 = λ**2 -x1 - x3 mod p
λ = y3 + y1 / x3 - x1 mod p
Solution:
function test_CurveValidator() public {
assert(p%4 == 3);
uint256 x1 = W0x;
uint256 y1 = W0y;
uint256 x3 = X[0];
uint256 y3 = modExp((x3**3 + A*x3 + B), (p + 1) / 4, p);
uint256 lambda = ((y3 + y1) * modInverse((p - (x1 - x3)))) % p;
uint x2 = (lambda * lambda - x1 - x3) % p;
uint y2 = modExp((x2**3 + A*x2 + B), (p + 1) / 4, p);
curveValidator.validate(x2, y2);
assertEq(curveValidator.isSolved(), true);
}
Curve Validator Plus
TODO: