Let's look at the
source code of the service .
A list of all available user IDs can be obtained at
/data
.
If there is an id, then the data can be obtained using a request to the address
/data/id
.
To access the data, the service requires a token for authentication. We have an available
token , but it has expired, and the service no longer accepts it.
Let's see in the code
how these tokens are generated . The token is obtained by encrypting JSON like
{ “userId” : “id”, expireDate: “date”}
and then encoding it to base64. The service uses RSA for encryption, and the public key can be obtained by requesting the address
/key
.
Let's make a query: e = 30593, n = 66043. Because n small enough, then we can easily calculate the private key.
To do this, decompose n into simple factors: 211 * 313.
Calculate
the Euler function of n: φ (n) = (211 - 1) (313 - 1) = 65520.
We obtain d = e-1 (mod φ (n)) = 257.
The inverse element of the module can be calculated using the
advanced Euclidean algorithm .
Having calculated the private key, we will decipher the token available to us.
We get the following JSON:
{"userId":"448f0a79-e2d8-4ccd-9009-53858914dcaa","expireDate":"2018-12-06T14:38:00.898026+00:00"}
Note that the
service is enough for the user with the given userId to exist and expireDate to be less than the current time on the server.
That is, knowing userId, we can generate a new valid token.
To do this, take expireDate large enough to pass the test — for example,
{"userId":"448f0a79-e2d8-4ccd-9009-53858914dcaa","expireDate":"2100-01-01T12:00:00.000000+00:00"}
.
We encrypt our new token with a public key.
Making a request to
/data
, we find out that the user has created messages with identifiers from 1 to 4.
Let's go through them all.
Among them is a wonderful phrase: the
New Year is knocking on the door, open to him soon! .