Skip to content

Commit

Permalink
docker-onion-nmap first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
milesrichardson committed Oct 23, 2017
0 parents commit 514514e
Show file tree
Hide file tree
Showing 17 changed files with 314 additions and 0 deletions.
39 changes: 39 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM alpine:edge

ENV PROXYCHAINS_CONF=/etc/proxychains.conf \
TOR_CONF=/etc/torrc.default \
TOR_LOG_DIR=/var/log/s6/tor \
DNSMASQ_CONF=/etc/dnsmasq.conf \
DNSMASQ_LOG_DIR=/var/log/s6/dnsmasq

RUN echo '@edge http://dl-cdn.alpinelinux.org/alpine/edge/main' >> \
/etc/apk/repositories && \
echo '@edge http://dl-cdn.alpinelinux.org/alpine/edge/community' >> \
/etc/apk/repositories && \
apk --no-cache add --update \
dnsmasq \
openssl \
proxychains-ng \
s6 \
curl \
nmap \
nmap-scripts \
nmap-doc \
nmap-nping \
nmap-ncat \
tor@edge && \
rm -rf /var/cache/apk/*

COPY etc /etc/
COPY run.sh bin /custom/bin/

RUN chmod +x /custom/bin/* && \
mkdir -p "$TOR_LOG_DIR" "$DNSMASQ_LOG_DIR" && \
chown tor $TOR_CONF && \
chmod 0644 $PROXYCHAINS_CONF && \
chmod 0755 \
/etc/s6/*/log/run \
/etc/s6/*/run

ENV PATH="/custom/bin:${PATH}"
ENTRYPOINT ["/custom/bin/run.sh"]
137 changes: 137 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
## docker-onion-nmap

Use nmap to scan hidden "onion" services on the Tor network. Minimal image
based on alpine, using proxychains to wrap nmap. Tor and dnsmasq are run
as daemons via s6, and proxychains wraps nmap to use the Tor SOCKS proxy on port 9050, which is configured to use the dnsmasq DNS server on port 9053.

### Example:

``` bash
$ docker run --rm -it milesrichardson/onion-nmap -p 80,443 facebookcorewwwi.onion
[tor_wait] Wait for Tor to boot... (might take a while)
[tor_wait] Done. Tor booted.
[nmap onion] nmap -p 80,443 facebookcorewwwi.onion
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.12

Starting Nmap 7.60 ( https://nmap.org ) at 2017-10-23 16:17 UTC
[proxychains] Dynamic chain ... 127.0.0.1:9050 ... facebookcorewwwi.onion:443 ... OK
[proxychains] Dynamic chain ... 127.0.0.1:9050 ... facebookcorewwwi.onion:80 ... OK
Nmap scan report for facebookcorewwwi.onion (224.0.0.1)
Host is up (2.7s latency).

PORT STATE SERVICE
80/tcp open http
443/tcp open https

Nmap done: 1 IP address (1 host up) scanned in 3.58 seconds
```

### How it works:

When the container boots, it launches Tor and dnsmasq as daemons. The `tor_wait`
script then waits for the Tor SOCKS proxy to be up before executing your command.

### Arguments:

By default, args to `docker run` are passed to [/custom/bin/nmap](/custom/bin/nmap)
which calls nmap with args `-sT -PN -n "$@"` necessary for it to work over Tor ([via explainshell.com](https://explainshell.com/explain?cmd=nmap+-sT+-PN+-n)).

For example, this:

``` bash
docker run --rm -it milesrichardson/onion-nmap -p 80,443 facebookcorewwwi.onion
```

will be executed as:

``` sh
proxychains4 -f /etc/proxychains.conf /usr/bin/nmap -sT -PN -n -p 80,443 facebookcorewwwi.onion
```

In addition to the custom script for `nmap`, custom wrapper scripts for `curl`
and `nc` exist to wrap them in proxychains, at [/custom/bin/curl](/custom/bin/curl)
and [/custom/bin/nc](/custom/bin/nc). To call them, simply specify `curl` or `nc`
as the first argument to `docker run`. For example:

``` bash
docker run --rm -it milesrichardson/onion-nmap nc -z 80 facebookcorewwwi.onion
```

will be executed as:

``` bash
proxychains4 -f /etc/proxychains.conf /usr/bin/nc -z 80 facebookcorewwwi.onion
```

and

``` bash
docker run --rm -it milesrichardson/onion-nmap curl -I https://facebookcorewwwi.onion
```

will be executed as:

```
proxychains4 -f /etc/proxychains.conf /usr/bin/curl -I https://facebookcorewwwi.onion
```

If you want to call any other command, including the original `/usr/bin/nmap` or
`/usr/bin/nc` or `/usr/bin/curl` you can specify it as the first argument to docker run, e.g.:

``` bash
docker run --rm -it milesrichardson/onion-nmap /usr/bin/curl -x socks4h://localhost:9050 https://facebookcorewwwi.onion
```

### Environment variables:

There is only one environment variable: `DEBUG_LEVEL`. If you set it to
anything other than `0`, more debugging info will be printed (specifically,
the attempted to connections to Tor while waiting for it to boot). Example:

``` bash
$ docker run -e DEBUG_LEVEL=1 --rm -it milesrichardson/onion-nmap -p 80,443 facebookcorewwwi.onion
[tor_wait] Wait for Tor to boot... (might take a while)
[tor_wait retry 0] Check socket is open on localhost:9050...
[tor_wait retry 0] Socket OPEN on localhost:9050
[tor_wait retry 0] Check SOCKS proxy is up on localhost:9050 (timeout 2 )...
[tor_wait retry 0] SOCKS proxy DOWN on localhost:9050, try again...
[tor_wait retry 1] Check socket is open on localhost:9050...
[tor_wait retry 1] Socket OPEN on localhost:9050
[tor_wait retry 1] Check SOCKS proxy is up on localhost:9050 (timeout 4 )...
[tor_wait retry 1] SOCKS proxy DOWN on localhost:9050, try again...
[tor_wait retry 2] Check socket is open on localhost:9050...
[tor_wait retry 2] Socket OPEN on localhost:9050
[tor_wait retry 2] Check SOCKS proxy is up on localhost:9050 (timeout 6 )...
[tor_wait retry 2] SOCKS proxy UP on localhost:9050
[tor_wait] Done. Tor booted.
[nmap onion] nmap -p 80,443 facebookcorewwwi.onion
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.12

Starting Nmap 7.60 ( https://nmap.org ) at 2017-10-23 16:34 UTC
[proxychains] Dynamic chain ... 127.0.0.1:9050 ... facebookcorewwwi.onion:443 ... OK
[proxychains] Dynamic chain ... 127.0.0.1:9050 ... facebookcorewwwi.onion:80 ... OK
Nmap scan report for facebookcorewwwi.onion (224.0.0.1)
Host is up (2.8s latency).

PORT STATE SERVICE
80/tcp open http
443/tcp open https

Nmap done: 1 IP address (1 host up) scanned in 4.05 seconds
```

### Notes:

- No UDP available over Tor
- Tor can take 10-20 seconds to boot. If this is untenable, another option is to run the proxy in its own container, or run it as the main process and then run "exec" to call commands like nmap

### gr33tz:

- [@jessfraz](https://github.com/jessfraz) [tor-proxy](https://github.com/jessfraz/dockerfiles/tree/master/tor-proxy)
- [@zuazo](https://github.com/zuazo) [alpine-tor-docker](https://github.com/zuazo/alpine-tor-docker)
- [shellhacks](https://www.shellhacks.com/anonymous-port-scanning-nmap-tor-proxychains/)
- [crypto-rebels.de](https://www.crypto-rebels.de/scanhidden.html)
5 changes: 5 additions & 0 deletions bin/curl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

proxychains4 -f /etc/proxychains.conf /usr/bin/curl "$@"

exit $?
5 changes: 5 additions & 0 deletions bin/nc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

proxychains4 -f /etc/proxychains.conf /usr/bin/nc "$@"

exit $?
5 changes: 5 additions & 0 deletions bin/nmap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

proxychains4 -f /etc/proxychains.conf /usr/bin/nmap -sT -PN -n "$@"

exit $?
6 changes: 6 additions & 0 deletions bin/tor_boot
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

set -e

s6-svscan /etc/s6 > /dev/null 2>&1 &
tor_wait
44 changes: 44 additions & 0 deletions bin/tor_wait
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh

set -e

DEBUG_LEVEL=${DEBUG_LEVEL-0}

counter=0

socket_open() {
echo "[tor_wait retry $counter] Check socket is open on localhost:9050..."
/usr/bin/nc -z localhost 9050 \
&& { echo "[tor_wait retry $counter] Socket OPEN on localhost:9050" ; sleep 1 ; return 0 ; } \
|| { echo "[tor_wait retry $counter] Socket CLOSED on localhost:9050, try again..." ; return 1 ; }
}

proxy_up() {
echo "[tor_wait retry $counter] Check SOCKS proxy is up on localhost:9050 (timeout $(($((counter+1))*2)) )..."
/usr/bin/curl --max-time $(($((counter+1))*2)) -s -f -I -x socks4h://localhost:9050 http://ipinfo.io/json \
>/dev/null 2>&1 \
&& { echo "[tor_wait retry $counter] SOCKS proxy UP on localhost:9050" ; return 0 ; } \
|| { echo "[tor_wait retry $counter] SOCKS proxy DOWN on localhost:9050, try again..." ; return 1 ; }
}

is_ready() {
if test "$DEBUG_LEVEL" -eq 0 ; then
socket_open >/dev/null 2>&1 && proxy_up >/dev/null 2>&1 && return 0 || return 1
else
socket_open && proxy_up && return 0 || return 1
fi
}

echo "[tor_wait] Wait for Tor to boot... (might take a while)"
while true
do
is_ready && { \
test $counter -eq 0 && { break ; } || { echo "[tor_wait] Done. Tor booted." ; break ; } ; \
}

counter=$((counter+1))
sleep 0.5
done

# Use Tor for all DNS queries:
echo 'nameserver 127.0.0.1' > /etc/resolv.conf
6 changes: 6 additions & 0 deletions etc/dnsmasq.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
no-resolv
server=127.0.0.1#9053
user=root
interface=lo
bind-interfaces
cache-size=1024
12 changes: 12 additions & 0 deletions etc/proxychains.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
dynamic_chain
proxy_dns

remote_dns_subnet 224

tcp_read_time_out 15000
tcp_connect_time_out 8000

localnet 127.0.0.0/255.0.0.0

[ProxyList]
socks4 127.0.0.1 9050
4 changes: 4 additions & 0 deletions etc/s6/dnsmasq/log/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

exec 2>&1
exec s6-log "$DNSMASQ_LOG_DIR"
3 changes: 3 additions & 0 deletions etc/s6/dnsmasq/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

exec dnsmasq -C "$DNSMASQ_CONF"
4 changes: 4 additions & 0 deletions etc/s6/tor/log/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

exec 2>&1
exec s6-log "$TOR_LOG_DIR"
3 changes: 3 additions & 0 deletions etc/s6/tor/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

exec s6-setuidgid tor tor --defaults-torrc "$TOR_CONF"
4 changes: 4 additions & 0 deletions etc/torrc.default
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SocksPort 0.0.0.0:9050
Log debug stderr
DataDirectory /var/lib/tor
DNSPort 0.0.0.0:9053
35 changes: 35 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/sh

export PATH="/custom/bin:$PATH"

arg_in_path() {
which "$1" >/dev/null 2>&1 && return 0
return 1
}

arg_is_cmd() {
test -x "$1" && return 0 || return 1
}

arg_is_executable() {
if arg_in_path "$1" ; then
return 0
elif arg_is_cmd "$1" ; then
return 0
else
return 1
fi
}

tor_boot

if test -z "$1" ; then
echo "No arguments given to run, launching /bin/sh..."
exec /bin/sh
elif arg_is_executable "$1" ; then
echo "[nmap onion]" "$@"
exec "$@"
else
echo "[nmap onion] nmap" "$@"
exec "nmap" "$@"
fi
Empty file added service/start.sh
Empty file.
2 changes: 2 additions & 0 deletions service/tor/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
tor

0 comments on commit 514514e

Please sign in to comment.