# Window of Opportunity (rev500)Original writeup, with sources: [here](https://github.com/numinit/CTF/blob/master/SwampCTF-2018/rev/window-of-opportunity-500/window-of-opportunity.md)
$ nc chal1.swampctf.com 1313
No user input. After some reverse engineering, it turns out that it mmaps a region of memory +rwx and generates an access token.The token is generated based on the current time and used to decrypt a bunch of x86 instructions, which it then jumps to.If you generate the right token, you get the flag.
An equation for the token is:
    (((tv.tv_sec & 0xFFC) << 16) - 0x14C437BE) ^ ((tv.tv_sec & 0xF0) << 8) | ((tv.tv_sec & 0xFFC) << 8) | ((tv.tv_sec >> 8) << 24) | tv.tv_sec & 0xFC;
There is an upper bound of 2^16 potential tokens. The search space is way smaller considering the crazy equation to make the token.
Considering that, it's sat solver time. Let's explore the space of tokens with z3: [source here](https://github.com/numinit/CTF/blob/master/SwampCTF-2018/rev/window-of-opportunity-500/window_solve.py). Run it with `python window_solve.py | tee timestamps`.
Now that we have all the possible timestamps after the current one, we need to test them.Let's write a [LD_PRELOAD](http://www.goldsborough.me/c/low-level/kernel/2016/08/29/16-48-53-the_-ld_preload-_trick/) shared librarythat can mock `gettimeofday()`.
```c/* gcc -shared -fPIC -Os -opreload.so preload.c */
#include <stdlib.h>#include <sys/time.h>#include <unistd.h>#include <signal.h>
int gettimeofday(struct timeval *tv, struct timezone *tz) {    const char *timestamp_str = getenv("TS");    unsigned long int timestamp = timestamp_str ? strtoul(timestamp_str, NULL, 10) : 0;    tv->tv_sec = timestamp;    tv->tv_usec = 0;}
unsigned int sleep(unsigned int seconds) {    // Just pretend we slept for that many seconds to move things along.    return seconds;}```
So, we can rename the provided `OS.BIN` to `window` and run it like `TS=1522400279 LD_PRELOAD="$(realpath preload.so)" ./window` to mock the timestamp.
With a bunch of timestamps in hand, I wrote a bash script to run the binary a bunch of times to look for any output other than `NOT AUTHORIZED`.
```sh(    cat timestamps |        sort -n |        while read line; do            ts="$(echo "$line" | cut -d, -f1)"            tk="$(echo "$line" | cut -d, -f2)"            echo -n "$ts,$tk,"            TS="$ts" LD_PRELOAD="$(realpath preload.so)" timeout 5 ./window 2>&1 | grep 'NOT AUTHORIZED'        done) | tee results```
It found a few. Manually reviewed them, and the one with key `0xff4fdc56` said "ACCESS GRANTED." Nice!
```> RUN "V:\OS\GETFLG.BIN" WITH KEY "0xff4fdc56"ACCESS GRANTEDRUNNING ...```
Now we have the correct key, which makes coming up with z3 constraints way easier.We just have to minimize `timestamp` with the constraints `timestamp > time.time()` (i.e. it's in the future) and `token == 0xff4fdc56`.We also need to account for server/client clock difference and repeatedly run netcat when the "window of opportunity" presents itself. [Source here](https://github.com/numinit/CTF/blob/master/SwampCTF-2018/rev/window-of-opportunity-500/window_connect.py).
Wait a while, and then...
```> RUN "V:\OS\GETFLG.BIN" WITH KEY "0xff4fdc56"ACCESS GRANTEDRUNNING ...PERFORMING CHECKSUM ..... PASSEDLOADING DATA SECTION ..... LOADED
V:\OS\GETFLG.BIN > HELPLISTGET [ID]SET [ID] [CONTENT]CREATE [CONTENT]EXIT
V:\OS\GETFLG.BIN > LISTFLAG # |         DATE CREATED      |      LAST MODIFIED        |-------+---------------------------+---------------------------+1      | 2018-03-19T18:32:02+00:00 | 2018-03-29T04:56:40+00:00 |
V:\OS\GETFLG.BIN > GET 1FLAG 1: flag{y0ur_t1m3_t0_sh1ne_is_N0W}```