Last active
January 29, 2024 08:07
-
-
Save pirate/b33bad004c8e17618b4c6ebe7d973377 to your computer and use it in GitHub Desktop.
Remote control a Docker container from another container in the same network using netcat, ssh, or pure python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Three ways to control a docker container remotely from another docker container or host: Python, SSH, or ncat/nc/socat. | |
# | |
# Useful if you have two containers in a Docker Compose project and you want | |
# container1 to be able to run commands in container2 without having to share /var/run/docker.sock | |
# | |
# Further Reading: https://www.revshells.com/#bind | |
### 1. Using pure Python, the cleanest option | |
# supports dbus/x11/etc as it doesnt spawn a new login shell, correctly handles exiting after finished commands without hacky workarounds | |
# Server: Open a socket on 0.0.0.0:2222 and run the received text in a subprocess, feed output line-by-line in realtime and close the socket on exit | |
docker run -p 2222:2222 python:3.12 python3 -c 'exec(""" | |
import socket as s | |
import subprocess as sp | |
s1 = s.socket(s.AF_INET, s.SOCK_STREAM) | |
s1.setsockopt(s.SOL_SOCKET, s.SO_REUSEADDR, 1) | |
s1.bind(("0.0.0.0", 2222)) | |
s1.listen(1) | |
print("Listening on 0.0.0.0:2222", flush=True) | |
conn, addr = s1.accept() | |
while True: | |
cmd = conn.recv(1024).decode() | |
if not cmd: | |
conn, addr = s1.accept() | |
continue | |
print(cmd, flush=True) | |
with sp.Popen(cmd, shell=True, stdout=sp.PIPE, stderr=sp.STDOUT, stdin=sp.PIPE, bufsize=1, universal_newlines=True) as p: | |
for line in p.stdout: | |
print(line.strip(), flush=True) | |
conn.sendall(line.encode("utf-8")) | |
conn.close() | |
conn, addr = s1.accept() | |
""")' | |
# Client: simply pipe a command into netcat and it'll run on the server, it will close automatically on exit | |
echo whoami | netcat 127.0.0.1 2222 | |
### 2. Using SSH, listens on port 2222 for connections to root@container_ip with an empty password | |
# hacky, spawns a new login shell in the container for each client command, so dbus/x11/etc wont work | |
# Server: install sshd, set root password to emptystring, allow root ssh login with empty pass, start sshd server | |
docker run -it -p 2222:22 ubuntu:22.04 /bin/bash -c "\ | |
apt-get update -qq; \ | |
apt-get install -y openssh-server; \ | |
mkdir /var/run/sshd; \ | |
printf '%s\n' 'root:U6aMy0wojraho' | chpasswd -e; \ | |
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config; \ | |
echo 'PermitEmptyPasswords yes' >> /etc/ssh/sshd_config; \ | |
echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config; \ | |
sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd; \ | |
/usr/sbin/sshd -D" | |
# Client: connect to server on 2222 with an empty password and run whoami, printing result stdout/stderr on client machine | |
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -q -p 2222 [email protected] /bin/bash -c 'whoami' | |
### 3. Using ncat, listens on port 2222 for netcat connections | |
# hackier, but it supports dbus/x11/etc as it doesnt spawn a new login shell for each command run by the client | |
# Server: install ncat (not nc or netcat, because we want --sh-exec), open ncat server listening on 2222 that runs each command with /bin/bash | |
docker run -it -p 2222:22 ubuntu:22.04 /bin/bash -c "\ | |
apt-get update -qq; \ | |
apt-get install -y ncat; \ | |
ncat -lk 22 --sh-exec /bin/bash | |
" | |
# Client: open a netcat tunnel to 127.0.0.1:2222, pass in "whoami" command + magic string to watch for on completion, loop looking for magic string and close pipe on match or timeout | |
while read -r i; do | |
echo "$i"; | |
if [[ "$i" == "DONEDONEDONE" ]]; then | |
break; | |
fi; | |
done < <(echo "whoami; echo DONEDONEDONE" | timeout 10 netcat 127.0.0.1 2222) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment