Git Product home page Git Product logo

certainly's Introduction

certainly

Certainly is a offensive security toolkit to capture large amounts of traffic in various network protocols in bitflip and typosquat scenarios. The tool was built to support research on these topics, originally presented at BlackHat USA 2024.

How it works

Built-in protocols

  • DNS
  • HTTP(S)
  • IMAP(S)
  • SMTP(S)

DNS

The core functionality of certainly revolves around the DNS server. It is designed to act as the authoritative name server for a number of apex domains, answering to any DNS questions around the zones with a response pointing to its own IP address while logging any and all requests coming its way. Certainly is trying to play nice and to not to break anything longer than necessary, because of this reason all the answers have TTL of one second.

HTTP

When certainly receives a HTTP request, it first checks if the requested resource is something that it should apply an injection template on. If so, certainly will copy the request headers to a new proxied request towards the upstream (legit, non-bitflippped / non-typosquatted) domain, copy the response headers to the response sent to the victim while replacing the response body according to the template rules.

If injection template is not configured for the resource, certainly will instead respond with HTTP 307 (Temporary redirect) to the upstream target with the full request URI intact.

HTTPS

HTTPS works similarly to HTTP, but in case certainly doesn't have a valid TLS certificate to present to the client, it will hold the TCP connection after the ClientHello in TLS handshake while fetching the certificate client requested in the TLS SNI. Certainly will try to priorize getting wildcard certificates for all subdomains in order to not to exhaust CA limits as well as to speed up the transaction when receiving a new connection. This behavior is very important as especially in the bitflips the targeted subdomains are far and between and not doing so will risk losing valuable data.

IMAP(S)

Certainly will initiate the authentication sequence and log the user credentials as well as potential shared secret in case of CRAM-MD5, after which it will disconnect the user.

SMTP(S)

Certainly will kindly accept all email sent towards it and proceed delivering it to the log files.

Core features

DNS

  • Full authoritative DNS server support. Just point the nameserver addresses at your domain registrar of choice towards Certainly instance.
  • CNAMEs to randomly generated UUID subdomains of the configured "main domain" in order to be able to track client behavior per-requester basis. This is omitted for CNAME requests against the "main domain" subdomains in order to prevent infinite loops. A record answers for these CNAMEs are also appended to the answer to lower the necessary network traffic.
  • DNS based ACME challenge solver to support wildcard TLS certificate generation.
  • Custom DNS records to present
  • Configurable protocol(s) to listen; udp, tcp or both

HTTPS

  • Holding the TLS handshake in ClientHello phase while fetching the certificate to present in the background. This typically takes under 5 seconds.
  • Optional upstream check for existence of a domain record before answering. If the upstream (sub)domain doesn't exist, certainly will proceed answering with NXDOMAIN as well.
  • Injection templating based on request uri regexes. Templates have couple of keyword variables that will be replaced: CERTAINLY_UPSTREAM that will be replaced by the full response body of the upstream request, and CERTAINLY_HASH that will be replaced by a UUID generated for the orignal connection.
  • Injection template filtering by a list of regexes. There's a lot of noise in the web today, and we saw a lot of random sweep scans hitting us with predetermined paths that we're better off by just ignoring.
  • A custom route for /callback/* that will just simply answer with 204 No Content instead of the default behavior of doing a temporary redirect. This is to catch and log potential callbacks from injected JavaScript resources without disturbing the intended behavior of the web application too much.

Output

  • Default output format of JSONLines to feed in to your data analysis platform; ELK, Splunk, mad grep oneliners; whatever your prefer.
  • Extensible notification framework for sending automated notifications. Currently only supports Slack.

Installation on Linux

For this documentation we're using /path/to/install/certainly as the example installation directory.

1) Create a user and installation path for Certainly

Create the application and the injection template directories

sudo mkdir -p /path/to/install/certainly/templates

Set up a system user and group to run Certainly

sudo useradd --system --user-group certainly

Set the ownership and permissions for the user to access the filesystem path.

sudo chown -R certainly:certainly /path/to/install/certainly
sudo chmod -R ug+w /path/to/install/certainly

2) Fetch the application and the example configuration

Certainly can be fetched by either go install or downloading and unarchiving a pre-built binary to your file system location of choice.

Using go install

go install github.com/happycakefriends/certainly@latest

Move the certainly binary to the installation path (not necessary, but streamlines this documentation). The installation directory for Go binaries can vary based on your configuration, but the default directory location is $HOME/go/bin/

When using this method, you will also need to download the latest config.cfg manually:

curl -L https://raw.githubusercontent.com/happycakefriends/certainly/main/config.cfg -o /path/to/install/certainly/config.cfg

Downloading a pre-built binary

Head over to releases page to download the latest pre-built release for your platform of choice.

Unarchive the contents of the release archive to /path/to/install/certainly

3) Edit the certainly configuration file

Open /path/to/install/certainly/config.cfg in your favorite text editor and change the configuration values according to your needs.

4) Set capabilities to allow binding to privileged ports

Allow certainly to bind to necessary ports

sudo setcap 'cap_net_bind_service=+ep' /path/to/install/certainly/certainly

5) Create a systemd service

sudo touch /etc/systemd/system/certainly.service
sudo chmod 644 /etc/systemd/system/certainly.service

Open the newly created systemd service definition file with your favorite text editor and change the paths accordingly.

[Unit]
Description=Certainly
StartLimitIntervalSec=30
StartLimitBurst=5
After=syslog.target network.target

[Service]
Type=simple
WorkingDirectory=/path/to/install/certainly
User=certainly
ExecStart=/path/to/install/certainly/certainly
TimeoutStartSec=30
Restart=on-failure

[Install]
WantedBy=multi-user.target

Reload the service configurations

sudo systemctl daemon-reload

6) Start the systemd service

Start the service

sudo systemctl start certainly

(Optionally) set it up to automatically start when OS is booted

sudo systemctl enable certainly

7) Setting Up DNS Configuration with Certainly

  1. Choose and Configure a master domains for DNS Management

    Begin by selecting a master domain, which we'll refer to as grandma.tld, and configure it to be hosted by your DNS provider. Create and point ns1.grandma.tld and ns2.grandma.tld to the IP address of your VPS (Virtual Private Server) that is going to host Certainly. This setup allows you to easily manage DNS records—if the IP address changes, you only need to update these two records.

  2. Select a Primary Domain for Your Setup

    Choose a default_domain for your configuration, referred to here as the Mother Domain. This domain will serve as the default domain for all DNS responses. So it should be a domain you own and can control. We'll call it mom.tld. Since this is the domain that will be used with a uuid for any CNAME lookup performed on any of the bitflip/typo domains, it might be a good idea to have a domain name thats similar to you targets domain. or if your runnings loots of different target domains on the same box, use one that has no connection to the targets, being sneaky is a win here.

    Update your configuration file with the following:

    • Add the IP address of your VPS. to the config using ip=1.2.3.4
    • Set the Mother Domain (example mom.tld) as the default_domain=
    • Include any custom DNS entries. (Certainly in a fully functional Nameserver so add whatever you like here, maybe a custom txt record to indicate that you are a good person?)
    • Specify the domains you intend to point to the vps to capture and respond to in the [ns] domains section. As seen in the example below.
  3. Point Domains to Your Nameservers

    After updating the configuration file and ensuring your VPS is operational, change the nameserver of the domains you want to manage to ns1.grandma.tld and ns2.grandma.tld using your DNS provider. This action ensures that all DNS requests for these domains are captured and managed by the custom DNS server in your certainly setup.

Here are some guides from popular domains providers as a inspiration how to perform this step:

https://docs.gandi.net/en/domain_names/common_operations/changing_nameservers.html#nameservers

https://www.godaddy.com/help/edit-my-domain-nameservers-664

  1. Configure Rewrites and TLS Settings

    To keep stealth, provide a seamless experience for any connecting clients and to utilize Certainly's injection capabilities, you should configure the [rewrites] section of your configuration file. Here’s what you need to do:

    • Add Rewrite Rules: Specify domain matching pairs. Example "coogle.com" = "google.com" as seen in this example, any connection to the hosted flip domain (coogle.com) will be redirected using a 307 to the real (google.com). Since we are delivering the client to the real domain there isnt any Denial of Service event happening and the connecting client will happily continue its flow.

    • Enable Stealth Mode (Optional): If you prefer to operate in stealth mode, set tls_upstream_check = true. This setting forces Certainly to before issuing any certificates or responding to any DNS request to verify the existence of the matching target subdomain before responding to requests.

    • Set Up TLS Filters: Use the tls_filters setting to drop any incoming TLS requests that match any predefined regex patterns. This is particularly useful for filtering out noise and whilefocusing on specific subdomains. For example: maybe you only want to catch some sweet api requests and dont care about common fuzz domains or www, then a simple filter like this might be in handy:

tls_filters = [
'www|ns1|ns2|hostmaster|mail|owa|ssl|webmail|smtp'
]

Resulting in a dropped client connection and a logged entry "msg":"http: TLS handshake error from 1.2.3.4: certificate is not allowed for server name blahwww.subdomain.target.tld: decision func: not allowed due to tls filter configuration"}

##Enable Stealth Mode (Optional) Note: Enabling the tls_upstream_check = true feature may cause you to miss some subdomain flips or typo hits. For example login.target.tld might exists upstream, while lkgin.target.tld most likely does not.

Client performs a host lookup:
Host mx.coogle.com

Certainly performs:
Host mx.google.com and receives "not found: 3 (NXDOMAIN)"
Since the upstream subdomain doesn't exist, Certainly will drop the session.

Example of tls_upstream_check = true feature with a Valid Upstream Domain:

Client performs a lookup for:
Host mail.coogle.com

Certainly performs:
Host mail.google.com and receives "mail.google.com has address 142.250.74.101"

Since the upstream domain exists, a response will be delivered to the client using Certainly's IP.
If an HTTP/S TCP connection is made, Certainly will hold the session, generate a wildcard certificate for `*.coogle.com`, and release the session once the certificate is in place.

To sum the features and getting started settings, here is a example of a config file, where we used real world domains for the ease of understanding, and has nothing to do with the real targets used.

Example Configuration

[General]
ip = "1.2.3.4"
tls_upstream_check = false
tls_filters = [
  'ns1|ns2|hostmaster|mail|owa|ssl|webmail|smtp',
  # 'www\.',
  "third_regex"
]

[ns]
port = "53"
protocol = "both4"
default_domain = "mom.tld"
domains = [
  "mom.tld",
  "c  oogle.com",
  "woogle.com",
  "amazkn.com",
  "gordpress.com",
]
nsname = "ns.mom.tld"
nsadmin = "admin.mom.tld"
records = [
  # Any static records go here in zone file format
  "ns.mom.tld. A 1.2.3.4",
  "ns.mom.tld. NS ns.mom.tld.",
]

[rewrites]
  "coogle.com" = "google.com"
  "woogle.com" = "google.com"
  "amazkn.com" = "amazon.com"
  "gordpress.com" = "wordpress.com"

certainly's People

Contributors

joohoi avatar stokfredrik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

certainly's Issues

Config returned for certificate has nil cache

Every 10 minutes I get this message:
{"level":"error","time":"2024-08-26T21:23:06.970Z","msg":"unable to get configuration to manage certificate; unable to renew","identifiers":["example.com"],"error":"config returned for certificate [example.com] has nil cache; expected 0xc0000acf80 (this one)"}

(replaced my domain with example.com).

I believe the root issue is here: joohoi/acme-dns#337. Is it possible to fix this upstream?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.