In the process of identifying and exploiting vulnerabilities, it is sometimes necessary to resort to Out of Band (OOB) techniques in order to exfiltrate information through DNS resolutions or HTTP requests. To address this kind of situation the faster and simpler solution can be the use of a Burp Collaborator instance or a online service like requestbin.net, but this has a big disadvantage: both are services hosted by a third party. Local instances of Burp Collaborator or requestbin can be deployed but they are heavy and poorly customizable or adaptable. To suply this need during a RedTeam operation a tool (Arecibo) with an easy API was developed.

0x01 – Introduction

Arecibo is a small tool written in python with following capabilities:

Detection of incoming HTTP requests (à la Requestbin)

Configuration of HTML, server headers and status code from the server

Upload & Download files

Detection of subdomains resolutions (DNS exfiltration)

Dynamic resolution (127.0.0.1.ip.XXXX resolves to 127.0.0.1, 10.1.1.10.ip.XXXX resolves to 10.1.1.10, etc.)

Internally it is composed of two parts, on one hand a python script that interacts with PowerDNS through a “backend pipe” and on the other hand the scripts that act as API (Flask + SQLite3) that allows to add new functionalities easily.

0x02 – DNS interactions

In the first instance, an identification token must be generated via Arecibo API to proceed with the exfiltration of data through DNS:

curl localhost:5000/generatedns {"htoken": "3144bd59af63b2ff98b303f3c0eb8f62"}

Using this token a domain such as ABCDEF.3144bd59af63b2ff98b303f3c0eb8f62.x.DOMAIN.ORG can be built, where “ABCDEF” is any string that you want to exfiltrate to Arecibo. Once this domain is resolved, we can see the registered string:

curl localhost:5000/hitsdns/3144bd59af63b2ff98b303f3c0eb8f62 {"hits": [["3144bd59af63b2ff98b303f3c0eb8f62", 1541002657.242613, "ABCDEF"]]}

Through the endpoint “hitsdns” we obtain all resolutions associated with the token that we had previously generated, including the exfiltrated information and the timestamp from when it was sent. On the other hand, for dynamic resolution of IPs you only need to use the prefix X.X.X.X.ip.domain.org:

PS> nslookup 192.10.10.1.ip.domain.org Servidor: X Address: X Respuesta no autoritativa: Nombre: 192.10.10.1.ip.domain.org Address: 192.10.10.1

0x03 – HTTP interactions

If you simply want to collect the content (GET, POST) and the headers sent, you can generate a token analogously to what was done with DNS:

curl localhost:5000/generatehttp {"htoken": "69afaccfe767fc9c37e00dcea8a5b236"}

HTTP requests must be made against the endpoint /h/TOKEN:

curl https://localhost:5000/h/2aa88ba02cbc0d6b72213fc117ae03dc It works!

To recover the info:

curl https://localhost:5000/hitshttp/2aa88ba02cbc0d6b72213fc117ae03dc {"hits": [{"get": {}, "timestamp": 1541592259.541545, "headers": {"X-Real-Ip": "X", "Connection": "close", "Host": "X", "Accept": "*/*", "User-Agent": "curl/7.55.1"}, "htoken": "2aa88ba02cbc0d6b72213fc117ae03dc", "post": {}, "ip_address": "X"}]}

If you want the server with the HTTP request to respond with an arbitrary content, specific headers or a specific status code must be configured with a POST request to the endpoint /generatehttp:

curl https://localhost:5000/generatehttp -H "Content-Type: application/json" --data '{"body":"SGVsbG8gd29ybGQhIAo=", "headers":{"Server":"PWNED", "X-Dummy-Header": "ka0labs"}, "status" : 504}' {"htoken": "5b296af97512af80615932e2f56360fe"}

This way we are indicating the content (encoded in base64, when it is decoded), the header Server will be “PWNED” and will add an additional header “X-Dummy-Header”, and the status code is 504:

curl https://localhost:5000/h/5b296af97512af80615932e2f56360fe -v * Trying x... * TCP_NODELAY set * Connected to x (x) port 80 (#0) > GET /h/5b296af97512af80615932e2f56360fe HTTP/1.1 > Host: x > User-Agent: curl/7.55.1 > Accept: */* > < HTTP/1.1 504 GATEWAY TIMEOUT < Content-Type: text/html; charset=utf-8 < Content-Length: 14 < Connection: keep-alive < X-Dummy-Header: ka0labs < Server: PWNED < Date: Wed, 07 Nov 2018 12:18:33 GMT < Hello world! * Connection #0 to host x left intact

0x04 – File transfer

The upload of files is trivial:

By supplying the token we proceed to download the uploaded file:

curl localhost:5000/download/36981274bdb9cc833472681caeb82337 root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ...

0x05 – Installing and configuring Arecibo for exfiltration

As mentioned at the beginning, it is necessary to have installed pdns (packages pdns and pdns-backend-pipe) and the modules flask and flask_restful for python. The ideal situation is to deploy the API in the local interface and use an NGINX as a reverse proxy to handle authentication and security. Once these requirements are met, the process would be:

1. Modify the configuration of arecibo-dns-backend.py

2. Assign execution permissions to arecibo-dns-backend.py (chmod + x)

3. Edit the pdns.conf file (its location can vary between distributions):

setuid=1001 setgid=1001 launch=pipe pipe-command=/your/path/arecibo-dns-backend.py

(changing the setuid / setgid by the user that will be used to run the service, which will be the same used for the API)

4. Execute arecibo-api.py and pdns_server (the location can change according to distribution)

If everything goes fine:

Note: the server must be configured as Authoritative DNS

Arecibo is up for exfiltration

0x06 – Conclusions

Arecibo is a lightweight tool that brings together the features of requestbin, file.io, xip.io, etc. in a single tool, allowing its easy deployment. It has the advantages of being able to operate easily through its API, so it is a very good alternative to use in penetration tests.

You can download Arecibo from our GitHub.