From f84b9ac8b25e0fa112769b88e9bc6e434691b074 Mon Sep 17 00:00:00 2001 From: Arek Maruszczak <38382850+TheArqsz@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:34:04 +0100 Subject: [PATCH] =?UTF-8?q?Added=20working=20and=20tested=20base=20for=20i?= =?UTF-8?q?mpacket,=20smbserver=20and=20fixed=20an=20is=E2=80=A6=20(#23)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added working and tested base for impacket, smbserver and fixed an issue in lib * Added impacket's smbserver to tools.json --- lib/install.sh | 2 +- lib/run.sh | 64 ++++++---- tools.json | 3 + tools/impacket-smbserver/.dockerignore | 4 + tools/impacket-smbserver/Dockerfile | 34 ++++++ tools/impacket-smbserver/README.md | 155 +++++++++++++++++++++++++ tools/impacket-smbserver/pre-run.sh | 16 +++ tools/impacket-smbserver/test.sh | 14 +++ 8 files changed, 267 insertions(+), 25 deletions(-) create mode 100644 tools/impacket-smbserver/.dockerignore create mode 100644 tools/impacket-smbserver/Dockerfile create mode 100644 tools/impacket-smbserver/README.md create mode 100644 tools/impacket-smbserver/pre-run.sh create mode 100644 tools/impacket-smbserver/test.sh diff --git a/lib/install.sh b/lib/install.sh index 537176a..762ff18 100755 --- a/lib/install.sh +++ b/lib/install.sh @@ -69,6 +69,6 @@ $CURRENT_TOOL() { EOM # If config file exists and tool is there, but the user forces reinstallation, add it once more elif grep "$CURRENT_TOOL()" $HOME/.c4p_config &>/dev/null && [ "$FORCE_INSTALL" -eq "1" ]; then - perl -i -p0e "s;$CURRENT_TOOL\(.*\{\n.*\n\};$CURRENT_TOOL() {\n $LIB_PATH/run.sh $CURRENT_TOOL \"\$\@\"\n\};" /home/arek/.c4p_config + perl -i -p0e "s;$CURRENT_TOOL\(.*\{\n.*\n\};$CURRENT_TOOL() {\n $LIB_PATH/run.sh $CURRENT_TOOL \"\\$@\"\n\};" /home/arek/.c4p_config fi fi \ No newline at end of file diff --git a/lib/run.sh b/lib/run.sh index e7f00e4..d58141e 100755 --- a/lib/run.sh +++ b/lib/run.sh @@ -6,14 +6,14 @@ ALL_TOOLS_PATH="$(dirname $LIB_PATH)/tools" CURRENT_TOOL=$1 source "$LIB_PATH/logging.sh" -if [ -z $CURRENT_TOOL ]; then +if [ -z "$CURRENT_TOOL" ]; then echo "Tool not specified. Pass it as an argument." exit 1 fi CURRENT_TOOL_PATH="$ALL_TOOLS_PATH/$CURRENT_TOOL" -if ! [ -d $CURRENT_TOOL_PATH ]; then +if ! [ -d "$CURRENT_TOOL_PATH" ]; then echo "Tool $CURRENT_TOOL doesn't exist - exiting" exit 1 fi @@ -22,7 +22,23 @@ CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-docker} CONTAINER_NAME=c4p-$CURRENT_TOOL CONTAINER_IMAGE=containers4pentesters/$CURRENT_TOOL:latest HOME=${HOME:-/tmp} -DOCKER_NETWORK_TYPE=${DOCKER_NETWORK_TYPE:-host} + +MACHINE_TYPE="unkown" +case "$(uname -s)" in + Linux*) MACHINE_TYPE=Linux;; + Darwin*) MACHINE_TYPE=Mac;; +esac + +if [ "$MACHINE_TYPE" == "Linux" ]; then + log_debug "You are running on Linux-based system. Using 'host' networking or the one you specified" + DOCKER_NETWORK_TYPE=${DOCKER_NETWORK_TYPE:-host} +elif [ "$MACHINE_TYPE" == "Mac" ]; then + log_warn "You are running on MacOS or other Darwin-based system. 'host' networking is not supported - using 'bridge' or the one you specified" + DOCKER_NETWORK_TYPE=${DOCKER_NETWORK_TYPE:-bridge} +else + DOCKER_NETWORK_TYPE=${DOCKER_NETWORK_TYPE:-bridge} +fi + if [ -f "$CURRENT_TOOL_PATH/pre-run.sh" ]; then . "$CURRENT_TOOL_PATH/pre-run.sh" @@ -30,27 +46,27 @@ fi if [ "$DEBIAN_FRONTEND" = "noninteractive" ]; then $CONTAINER_RUNTIME run \ - -t --rm --name $CONTAINER_NAME \ - --network $DOCKER_NETWORK_TYPE \ - --user `id -u`:`id -g` \ - --volume "$HOME":"$HOME" \ - --volume "$WORKING_C4P_DIR":"$WORKING_C4P_DIR" \ - --volume /tmp:/tmp \ - --volume /dev:/dev \ - --workdir "$WORKING_C4P_DIR" \ - -e HOME=$HOME \ - $DOCKER_OPTIONS $CONTAINER_IMAGE "${@:2}" + -t --rm --name $CONTAINER_NAME \ + --network $DOCKER_NETWORK_TYPE \ + --user `id -u`:`id -g` \ + --volume "$HOME":"$HOME" \ + --volume "$WORKING_C4P_DIR":"$WORKING_C4P_DIR" \ + --volume /tmp:/tmp \ + --volume /dev:/dev \ + --workdir "$WORKING_C4P_DIR" \ + -e HOME=$HOME \ + $DOCKER_OPTIONS $CONTAINER_IMAGE "${@:2}" else $CONTAINER_RUNTIME run \ - -it --rm --name $CONTAINER_NAME \ - --network $DOCKER_NETWORK_TYPE \ - --user `id -u`:`id -g` \ - --volume "$HOME":"$HOME" \ - --volume "$WORKING_C4P_DIR":"$WORKING_C4P_DIR" \ - --volume /tmp:/tmp \ - --volume /dev:/dev \ - --workdir "$WORKING_C4P_DIR" \ - -e HOME="$HOME" \ - -e TERM=$TERM \ - $DOCKER_OPTIONS $CONTAINER_IMAGE "${@:2}" + -it --rm --name $CONTAINER_NAME \ + --network $DOCKER_NETWORK_TYPE \ + --user `id -u`:`id -g` \ + --volume "$HOME":"$HOME" \ + --volume "$WORKING_C4P_DIR":"$WORKING_C4P_DIR" \ + --volume /tmp:/tmp \ + --volume /dev:/dev \ + --workdir "$WORKING_C4P_DIR" \ + -e HOME="$HOME" \ + -e TERM=$TERM \ + $DOCKER_OPTIONS $CONTAINER_IMAGE "${@:2}" fi \ No newline at end of file diff --git a/tools.json b/tools.json index e10ec67..6c97ba1 100644 --- a/tools.json +++ b/tools.json @@ -68,6 +68,9 @@ }, { "tool_name": "apktool" + }, + { + "tool_name": "impacket-smbserver" } ] } \ No newline at end of file diff --git a/tools/impacket-smbserver/.dockerignore b/tools/impacket-smbserver/.dockerignore new file mode 100644 index 0000000..ca78123 --- /dev/null +++ b/tools/impacket-smbserver/.dockerignore @@ -0,0 +1,4 @@ +install.sh +run.sh +test.sh +README.md \ No newline at end of file diff --git a/tools/impacket-smbserver/Dockerfile b/tools/impacket-smbserver/Dockerfile new file mode 100644 index 0000000..74b6c63 --- /dev/null +++ b/tools/impacket-smbserver/Dockerfile @@ -0,0 +1,34 @@ +FROM debian:bullseye-slim as build + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt update \ + && apt install -y \ + wget \ + build-essential \ + python3-dev \ + python3-venv \ + libssl-dev \ + cargo \ + unzip \ + && rm -rf /var/cache/apt/* + +WORKDIR /src + +ARG IMPACKET_VERSION=0_11_0 + +RUN wget https://github.com/fortra/impacket/archive/refs/tags/impacket_${IMPACKET_VERSION}.zip -O /src/impacket.zip && \ + unzip /src/impacket.zip && mv impacket-impacket_${IMPACKET_VERSION} impacket + +RUN python3 -m venv /src/impacket/venv && \ + /src/impacket/venv/bin/pip install /src/impacket/ + +WORKDIR /src/impacket + +FROM gcr.io/distroless/python3 +LABEL org.opencontainers.image.authors="Arqsz" + +COPY --from=build /src/impacket /src/impacket + +ENV PATH="/src/impacket/venv/bin:$PATH" + +ENTRYPOINT ["/src/impacket/venv/bin/smbserver.py"] \ No newline at end of file diff --git a/tools/impacket-smbserver/README.md b/tools/impacket-smbserver/README.md new file mode 100644 index 0000000..03360ec --- /dev/null +++ b/tools/impacket-smbserver/README.md @@ -0,0 +1,155 @@ +# Containerized impacket's smbserver + +## Basic info + +- **Current version**: 0.11.0 +- **Source**: https://github.com/fortra/impacket/archive/refs/tags/impacket_0_11_0.zip + +## Use indepentendly to [containers4pentesters](https://github.com/TheArqsz/containers4pentesters) project + +### CLI + +Use in CLI directly as a pull from the DockerHub: + +```bash +docker pull containers4pentesters/impacket-smbserver +docker run -it --rm --name impacket-smbserver \ + --user `id -u`:`id -g` \ + --volume "$HOME":"$HOME" \ + --volume "$(pwd)":"$(pwd)" \ + --volume /tmp:/tmp \ + -e HOME="$HOME" \ + -e TERM=$TERM \ + --network host containers4pentesters/impacket-smbserver \ + --help +``` + +or as a build (with [containers4pentesters](https://github.com/TheArqsz/containers4pentesters) repository cloned): + +```bash +docker build -q -t containers4pentesters/impacket-smbserver:latest /opt/containers4pentesters/tools/impacket-smbserver/ +docker run -it --rm --name impacket-smbserver \ + --user `id -u`:`id -g` \ + --volume "$HOME":"$HOME" \ + --volume "$(pwd)":"$(pwd)" \ + --volume /tmp:/tmp \ + -e HOME="$HOME" \ + -e TERM=$TERM \ + --network host containers4pentesters/impacket-smbserver:latest \ + --help +``` + +### As a script + +You can create a script `/usr/local/bin/impacket-smbserver` with given content (pulling from the DockerHub): + +```bash +#!/usr/bin/env bash + +docker pull -q containers4pentesters/impacket-smbserver:latest +docker run -it --rm --name impacket-smbserver \ + --user `id -u`:`id -g` \ + --volume "$HOME":"$HOME" \ + --volume "$(pwd)":"$(pwd)" \ + --volume /tmp:/tmp \ + -e HOME="$HOME" \ + -e TERM=$TERM \ + --network host containers4pentesters/impacket-smbserver \ + "$@" +``` + +or as a build process (with [containers4pentesters](https://github.com/TheArqsz/containers4pentesters) repository cloned): + +```bash +#!/usr/bin/env bash + +docker build -q -t containers4pentesters/impacket-smbserver:latest /opt/containers4pentesters/tools/impacket-smbserver/ +docker run -it --rm --name impacket-smbserver \ + --user `id -u`:`id -g` \ + --volume "$HOME":"$HOME" \ + --volume "$(pwd)":"$(pwd)" \ + --volume /tmp:/tmp \ + -e HOME="$HOME" \ + -e TERM=$TERM \ + --network host containers4pentesters/impacket-smbserver \ + "$@" +``` + +You can use the script as if it was a native tool + +> This example assumes usage of port **445/tcp** (you need to have root rights) + +*Server:* +```console +$ mkdir /tmp/smbserver-test +$ echo 1234 > /tmp/smbserver-test/myfile.txt +$ sudo su +$ id +uid=0(root) gid=0(root) groups=0(root) +$ /usr/local/bin/impacket-smbserver -smb2support -username user -password pass TMP /tmp/smbserver-test/ +[xxxx/xx/xx xx:xx:xx][INFO] You are using host network - exposing all ports +Impacket v0.11.0 - Copyright 2023 Fortra + +[*] Config file parsed +... +``` + +*Client:* +```console +$ smbclient //localhost/TMP --user user --password pass +Try "help" to get a list of possible commands. +smb: \> dir + myfile.txt AN 5 xxx xxx x xx:xx:xx 2024 +``` + +## Known issues + +### `Permission denied` when starting the smbserver + +```python +Traceback (most recent call last): + File "/src/impacket/venv/bin/smbserver.py", line 71, in + server = smbserver.SimpleSMBServer(listenAddress=options.interface_address, listenPort=int(options.port)) + File "/src/impacket/venv/lib/python3.9/site-packages/impacket/smbserver.py", line 4870, in __init__ + self.__server = SMBSERVER((listenAddress, listenPort), config_parser=self.__smbConfig) + File "/src/impacket/venv/lib/python3.9/site-packages/impacket/smbserver.py", line 3965, in __init__ + socketserver.TCPServer.__init__(self, server_address, handler_class) + File "/usr/lib/python3.9/socketserver.py", line 452, in __init__ + self.server_bind() + File "/usr/lib/python3.9/socketserver.py", line 466, in server_bind + self.socket.bind(self.server_address) +PermissionError: [Errno 13] Permission denied +``` + +This issue occurs because low privileged user has no rights to use TCP ports under 1024 (which 445 definitely is). By default, smbserver uses port 445/tcp. + +There are 3 solutions: +- You can change the default port: +```console +$ impacket-smbserver -port 1445 TMP /tmp +[YYYY/MM/DD HH:mm:SS][INFO] You are using host network - exposing all ports +Impacket v0.11.0 - Copyright 2023 Fortra + +[*] Config file parsed +``` + +- You should start the impacket-smbserver as a root user (it will use port 445/tcp): +```console +$ sudo su +$ impacket-smbserver TMP /tmp +[YYYY/MM/DD HH:mm:SS][INFO] You are using host network - exposing all ports +Impacket v0.11.0 - Copyright 2023 Fortra + +[*] Config file parsed +``` + +> If you want to use it through c4p project, you can copy .c4p_config yourself or simply run the c4p installation one more time + +- You can change docker's network type and the TCP port to a number above 1024: +```console +$ DOCKER_NETWORK_TYPE=bridge SMB_PORT=1445 impacket-smbserver TMP /tmp +[YYYY/MM/DD HH:mm:SS][WARN] Exposing port 1445/tcp as a port 445/tcp from the container +Impacket v0.11.0 - Copyright 2023 Fortra + +[*] Config file parsed +``` \ No newline at end of file diff --git a/tools/impacket-smbserver/pre-run.sh b/tools/impacket-smbserver/pre-run.sh new file mode 100644 index 0000000..7402fa6 --- /dev/null +++ b/tools/impacket-smbserver/pre-run.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# This setting is valid only for 'bridge' type network. +# On 'host' type you can use any native port you want. +SMB_PORT=${SMB_PORT:-1445} + +if [ "$DOCKER_NETWORK_TYPE" == "host" ]; then + log_info "You are using host network - exposing all ports" +else + if [[ $DOCKER_OPTIONS =~ '--publish '|'-p ' ]]; then + log_info "It seems that you want to expose some ports - using your configuration" + else + log_warn "Exposing port $SMB_PORT/tcp as a port 445/tcp from the container" + DOCKER_OPTIONS="$DOCKER_OPTIONS --publish $SMB_PORT:445" + fi +fi \ No newline at end of file diff --git a/tools/impacket-smbserver/test.sh b/tools/impacket-smbserver/test.sh new file mode 100644 index 0000000..135e983 --- /dev/null +++ b/tools/impacket-smbserver/test.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +SCRIPT_PATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +TOOLS_PATH="$(dirname $SCRIPT_PATH)" +LIB_PATH="$(dirname $TOOLS_PATH)/lib" +CURRENT_TOOL=$(basename $SCRIPT_PATH) +verify_if_installed=${1:-} + +source "$LIB_PATH/test.sh" + +command_output=$(bash $LIB_PATH/run.sh $CURRENT_TOOL --help) +pattern="usage: smbserver.py" + +test_tool "$CURRENT_TOOL" "$command_output" "$pattern" "$verify_if_installed" \ No newline at end of file