# Fly Off The Handle

{% hint style="info" %}
I ran `zeek fly.zeek` to generate all the files in tmp/.

However, I then deleted the flag.zeek file. See if you can recover the flag string.
{% endhint %}

```c
@load ./lookup
@load ./flag

global GLOBAL::n: count = 0;
global GLOBAL::fh: file;
global GLOBAL::pain_level: count = 1000;

srand(double_to_count(time_to_double(current_time())));
local winner = rand(pain_level);
print winner;

while (n < pain_level) {
  if (mkdir("tmp/")) {
    fh = open(fmt("tmp/%s", n));
    if (n == winner) {
      for (char in flag) {
        write_file(fh, fmt("%s.", ascii_map[char] + n));
      }
    } else {
      for (char in flag) {
        write_file(fh, fmt("%s.", rand(93) + 32 + n));
      }
    }
    close(fh);
  } else {
    ;
  }
  n += 1;
}
```

Hmm so we don't have the flag string. We have some 1000 files in directories which contain numbers nicely delimited by decimals. So some string **was** used to compute a file that wasn't created using a randomizing function, the rest use the lookup table and a random offset we can't reverse.

Ok lets reverse every file back into strings on the assumption that is was the **winner** one.

So lets read the file in using the input framework.

```c
Input::add_event([$source=fmt("tmp/%s", n),
                          $name=fmt("tmp_%s", n),
                          $reader=Input::READER_RAW,
                          $want_record=F,
                          $fields=FileLine,
                          $ev=file_line]);

```

We get an event from we can hook into that will gives us the line in the file. Brute force some string manipulations and reverse the look table.

```c
event file_line(description: Input::EventDescription, tpe: Input::Event, s: string) {
    local parts = split_string(s, /\./)[:-1];
    local nn = to_count(split_string1(description$name, /_/)[1]);
    local msg: string="";

    for(el in parts) {
        local idx = to_count(parts[el]) - nn;
        if(idx in rev_ascii_map) {
            msg += rev_ascii_map[idx];
        }
    }
}
```

Putting it all together

```c
module fly;

@load base/frameworks/input
@load ./lookup
# @load ./flag

redef exit_only_after_terminate = F;
global rev_ascii_map: table[count] of string = {};

type FileLine: record {
    s: string;
};

event file_line(description: Input::EventDescription, tpe: Input::Event, s: string) {
    local parts = split_string(s, /\./)[:-1];
    local nn = to_count(split_string1(description$name, /_/)[1]);
    local msg: string="";

    for(el in parts) {
        local idx = to_count(parts[el]) - nn;
        if(idx in rev_ascii_map) {
            msg += rev_ascii_map[idx];
        }
    }

    if (/flag/i in msg) {
        print fmt("n=%s flag=%s", nn, msg);
    }
}

function run() {

    local n: count = 0;
    local pain_level: count = 1000;

    while (n < pain_level) {
        Input::add_event([$source=fmt("tmp/%s", n),
                          $name=fmt("tmp_%s", n),
                          $reader=Input::READER_RAW,
                          $want_record=F,
                          $fields=FileLine,
                          $ev=file_line]);

        n += 1;
    }
}

event zeek_init() {
    # Probably a better way but I just brute forced reversed the lookup table
    for(el in ascii_map){
        rev_ascii_map[ascii_map[el]] = el;
    }
    run();
}
```

You end up getting a fair amount of string output, but this is a CTF and your looking for flags right. So a quick case insensitive search for flag and voila.&#x20;

```
n=705 flag=3s..AWildFlagAppeared..3Sx[ylmnop::GLOBAL::
```

{% hint style="success" %}
The solution!

The `::GLOBAL::` being in the string threw me off

```
3s..AWildFlagAppeared..3Sx[ylmnop::GLOBAL::
```

{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eephillip.gitbook.io/zw2020-ctf-writeup/writeup/fly-off-the-handle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
