From 63a66a9c122acef7621c552cad1f7d455251f008 Mon Sep 17 00:00:00 2001 From: SkyperTHC Date: Wed, 13 Dec 2023 16:23:45 +0000 Subject: [PATCH] gsexecio --- ChangeLog | 7 +++- Makefile | 6 ++- config/etc/sf/sf.conf | 8 ++++ config/etc/ssh/banner_example | 2 + contrib/db-sync.sh | 4 +- contrib/sfwg | 2 +- docker-compose.yml | 3 +- guest/Dockerfile | 31 ++++++++-------- guest/fs-root/etc/zsh_command_not_found | 19 ++++++++-- guest/fs-root/sf/bin/gsexecio | 33 ++++++++++++++++- guest/fs-root/sf/bin/str2mnemonic | 49 +++++++++++++++++++++++++ host/fs-root/bin/docker_sshd.sh | 5 +++ host/fs-root/bin/segfaultsh | 18 ++++++++- host/fs-root/etc/ssh/sshd_config | 2 +- host/mk_sshd.sh | 1 + provision/init-linux.sh | 4 ++ router/init.sh | 1 - sfbin/banhammer.sh | 40 ++++++++++++++++++++ sfbin/funcs_admin.sh | 14 +++++-- sfbin/sf | 5 ++- 20 files changed, 220 insertions(+), 34 deletions(-) create mode 100644 config/etc/ssh/banner_example create mode 100755 guest/fs-root/sf/bin/str2mnemonic create mode 100755 sfbin/banhammer.sh diff --git a/ChangeLog b/ChangeLog index a693a6c..a2660ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -0.5.0 - 2023-11-00 +0.5.2 - 2023-12-00 + * Kali 2023.4 + * SSHD Banner + +0.5.0 - 2023-11-29 + * Configurable access to external storage (SF_USER_FS_EXT=) * Configurable access to /dev/kvm * Reverse Port via curl sf/port * Token via curl sf/set -dtoken= diff --git a/Makefile b/Makefile index 2fb2a76..a4cc1ca 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VER := 0.5.0rc1 +VER := 0.5.2a1 all: make -C router @@ -49,6 +49,8 @@ FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/geoiphn" FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/gssec" FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/gsexec" FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/gsexecio" +FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/d" +FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/str2mnemonic" FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/thcssh" FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/transfer" FILES_GUEST += "segfault-$(VER)/guest/fs-root/sf/bin/asn" @@ -141,6 +143,7 @@ FILES_CONFIG += "segfault-$(VER)/config/etc/loginmsg-new.sh-example" FILES_CONFIG += "segfault-$(VER)/config/etc/loginmsg-all.sh-example" FILES_CONFIG += "segfault-$(VER)/config/etc/logoutmsg-all.sh-example" FILES_CONFIG += "segfault-$(VER)/config/etc/logpipe/config.yaml" +FILES_CONFIG += "segfault-$(VER)/config/etc/ssh/banner_example" FILES_ROOT += "segfault-$(VER)/Makefile" FILES_ROOT += "segfault-$(VER)/ChangeLog" @@ -153,6 +156,7 @@ FILES_ROOT += "segfault-$(VER)/sfbin/funcs_redis.sh" FILES_ROOT += "segfault-$(VER)/sfbin/funcs_admin.sh" FILES_ROOT += "segfault-$(VER)/sfbin/funcs_net.sh" FILES_ROOT += "segfault-$(VER)/sfbin/sf" +FILES_ROOT += "segfault-$(VER)/sfbin/banhammer.sh" FILES_CLEANER += "segfault-$(VER)/tools/cg/Dockerfile" FILES_CLEANER += "segfault-$(VER)/tools/cg/go.mod" diff --git a/config/etc/sf/sf.conf b/config/etc/sf/sf.conf index 724b883..d141a11 100644 --- a/config/etc/sf/sf.conf +++ b/config/etc/sf/sf.conf @@ -45,6 +45,14 @@ #SF_USER_FS_SIZE= # =128m, xfs only, Not set=unlimited #SF_USER_FS_INODE= # =16384, xfs only, Not set=unlimited +#SF_USER_FS_EXT= # Mount /sf/data/ext/NAME to /DST, Example ="foobar:/nonsec:ro" + # You may want to add a quota to any external share: + # 1. Pick a new prjid below 1,000,000 + # xfs_quota -x -c 'report /sf/data' + # 2. Add PrjId and quota: + # xfs_quota -x -c 'project -s -p /sf/data/ext/foobar 9999999' + # docker exec sf-encfsd xfs_quota -x -c 'limit -p ihard=16777216 bhard=512g 9999999' + #SF_USER_DEV_KVM= # =1 to allow access to /dev/kvm (Warning: User can DoS PHY) #SF_ALLOW_SRC_TOR= # =1 to allow connections from TOR #SF_USER_IMMUNE= # =1 to not ban user by lgban diff --git a/config/etc/ssh/banner_example b/config/etc/ssh/banner_example new file mode 100644 index 0000000..fc71fa3 --- /dev/null +++ b/config/etc/ssh/banner_example @@ -0,0 +1,2 @@ +# Rename this file to banner and remove this line +https://thc.org/abuse diff --git a/contrib/db-sync.sh b/contrib/db-sync.sh index 4b9318e..c1bb4c5 100755 --- a/contrib/db-sync.sh +++ b/contrib/db-sync.sh @@ -12,7 +12,7 @@ while [[ $i -gt 0 ]]; do ((i--)) h="${HOSTS[$i]}" echo "#${i} Syncing ${h} DOWN" - rsync -ral "${h}":/sf/config/db/banned "${h}":/sf/config/db/token "${h}":/sf/config/db/limits . + rsync -ral "${h}":/sf/config/db/banned "${h}":/sf/config/db/private "${h}":/sf/config/db/token "${h}":/sf/config/db/limits . done echo "==[DOWN done. Press Enter to start UP]==================================================" @@ -20,6 +20,6 @@ read i=0 for h in "${HOSTS[@]}"; do echo "#$i Syncing ${h} UP" - rsync -ral banned token limits "${h}":'/sf/config/db' + rsync -ral banned private token limits "${h}":'/sf/config/db' ((i++)) done diff --git a/contrib/sfwg b/contrib/sfwg index edea74f..6fbd3a4 100755 --- a/contrib/sfwg +++ b/contrib/sfwg @@ -209,7 +209,7 @@ wg_up() [[ $(sysctl -n net.ipv4.ip_forward) -eq 0 ]] && sysctl -q -w net.ipv4.ip_forward=1 [[ $(sysctl -n net.ipv6.conf.all.forwarding) -eq 0 ]] && sysctl -q -w net.ipv6.conf.all.forwarding=1 - ip link del "${WG_DEV}" &>/dev/null + ip link del "${WG_DEV:?}" &>/dev/null ip link add "${WG_DEV}" type wireguard || return 255 fn="/dev/shm/private.$$" diff --git a/docker-compose.yml b/docker-compose.yml index 2e86286..d27d6ee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -646,6 +646,7 @@ services: volumes: - "${SF_BASEDIR:-.}/config:/config/host" - "${SF_BASEDIR:-.}/data/share:/sf/share:ro" + - "${SF_BASEDIR:-.}/data/ext:/sf/ext:ro" - "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro" - "${SF_SHMDIR:-/dev/shm/sf}/run:/sf/run" - "${SF_SHMDIR:-/dev/shm/sf}/encfs-sec/www-root:/sec/www-root:slave" @@ -654,7 +655,7 @@ services: - "/var/run/docker.sock:/var/run/docker.sock" - "/var/lib/lxcfs:/var/lib/lxcfs:ro" - "${SF_SHMDIR:-/dev/shm/sf}/run/redis/sock:/redis-sock" - #- /research/segfault/host/fs-root/bin/segfaultsh:/bin/segfaultsh:ro # FIXME-TESTING + # - /research/segfault/host/fs-root/bin/segfaultsh:/bin/segfaultsh:ro # FIXME-TESTING # - /research/segfault/host:/host:ro # FIXME-TESTING sshd debug nginx: diff --git a/guest/Dockerfile b/guest/Dockerfile index ed63fb4..d7407e4 100644 --- a/guest/Dockerfile +++ b/guest/Dockerfile @@ -216,7 +216,7 @@ RUN /pkg-install.sh LARGE apt-get install -y --no-install-recommends \ mono-mcs \ mono-devel \ most \ - mycli \ + `### mycli ### yanked from Kali.2023.4` \ mypager \ nfs-common \ neofetch \ @@ -320,7 +320,7 @@ RUN /pkg-install.sh HUGE apt-get install -y --no-install-recommends \ cloud-image-utils \ debootstrap \ libguestfs-tools \ - qemu-efi \ + `qemu-efi ### yanked from Kali2023.4` \ qemu-efi-arm \ qemu-system \ qemu-user \ @@ -362,7 +362,7 @@ RUN /pkg-install.sh GUI bash -c '{ cd /tmp \ && echo "deb https://packages.microsoft.com/repos/vscode stable main" | tee /etc/apt/sources.list.d/microsoft.list \ && apt-get update; }' \ && /pkg-install.sh GUI apt-get install -y --no-install-recommends \ - `###alacritty - Not available in stable release` \ + alacritty \ aqemu \ awesome \ brave-browser \ @@ -402,14 +402,14 @@ RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \ code || { [ $(uname -m) != x86_64 ] && true; } RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \ `### xpra ### Using Xpra repo instead` \ - libavformat59 \ - libavif15 \ + libavformat60 \ + libavif16 \ libjs-jquery-ui \ `###libprocps8 ### yanked from Kali` \ libqrencode4 \ libxres1 \ libxtst6 \ - libswscale6 \ + libswscale7 \ libturbojpeg0 \ gir1.2-gtk-3.0 \ python3-cairo \ @@ -442,13 +442,13 @@ RUN /pkg-install.sh GUI apt-get install -y --no-install-recommends \ # && rm -f /var/lib/apt/lists/xpra*; }' ### 2023-07: beta is badly synced ### E: Failed to fetch https://xpra.org/beta/bookworm/main/binary-amd64/Packages.gz File has unexpected size (41831 != 39348). Mirror sync in progress? [IP: 78.129.163.65 443] -RUN /pkg-install.sh GUI bash -c '{ : \ - && wget -O "/usr/share/keyrings/xpra.asc" https://xpra.org/xpra-2023.asc \ - && wget -O "/etc/apt/sources.list.d/xpra.sources" https://raw.githubusercontent.com/Xpra-org/xpra/master/packaging/repos/bookworm/xpra.sources \ - && apt-get update \ - && pkg=("xpra" "xpra-x11" "xpra-html5") \ - && apt-get install -y --no-install-recommends "${pkg[@]}" \ - && rm -f /var/lib/apt/lists/xpra*; }' +# RUN /pkg-install.sh GUI bash -c '{ : \ +# && wget -O "/usr/share/keyrings/xpra.asc" https://xpra.org/xpra-2023.asc \ +# && wget -O "/etc/apt/sources.list.d/xpra.sources" https://raw.githubusercontent.com/Xpra-org/xpra/master/packaging/repos/bookworm/xpra.sources \ +# && apt-get update \ +# && pkg=("xpra" "xpra-x11" "xpra-html5") \ +# && apt-get install -y --no-install-recommends "${pkg[@]}" \ +# && rm -f /var/lib/apt/lists/xpra*; }' ### x86_64 only RUN /pkg-install.sh GUI bash -c '{ [[ $HOSTTYPE != x86_64 ]] && exit 0; cd /usr/lib \ && curl -sf https://download-installer.cdn.mozilla.net/pub/firefox/releases/108.0.1/linux-x86_64/en-US/firefox-108.0.1.tar.bz2 | tar xfvj - \ @@ -795,7 +795,7 @@ RUN /pkg-install.sh LARGE apt-get install -y --no-install-recommends \ RUN /pkg-install.sh HACK ghbin ekzhang/bore '%arch:aarch64=arm%-unknown-linux' \ && pipx install git+https://github.com/bluet/proxybroker2.git \ && /pkg-install.sh HACK pipx install pwncat-cs \ - && /pkg-install.sh HACK ghbin praetorian-inc/noseyparker 'linux-' noseyparker \ + && /pkg-install.sh HACK ghbin praetorian-inc/noseyparker 'linux-' noseyparkerπpkt \ && /pkg-install.sh HACK bin 'https://gitlab.com/api/v4/projects/33695681/packages/generic/nrich/latest/nrich_latest_amd64.deb' `# x86_64 only` \ && /pkg-install.sh HACK bin 'https://github.com/RustScan/RustScan/releases/download/2.0.1/rustscan_2.0.1_amd64.deb' `# x86_64 only` \ && /pkg-install.sh HACK ghbin hueristiq/xurlfind3r 'linux_%arch:x86_64=amd64:aarch64=arm64%' xurlfind3r @@ -808,7 +808,8 @@ RUN /pkg-install.sh HACK bash -c '{ wget -O "/usr/bin/favfreak.py" https://raw. && wget -O /usr/share/wordlists/meg/openredirects "https://raw.githubusercontent.com/tomnomnom/meg/master/lists/openredirects" \ && wget -O /usr/share/wordlists/meg/configfiles "https://raw.githubusercontent.com/tomnomnom/meg/master/lists/configfiles" \ && wget -O /usr/share/wordlists/meg/crlfinjection "https://raw.githubusercontent.com/tomnomnom/meg/master/lists/crlfinjection"; }' -RUN /pkg-install.sh DEV ghbin helix-editor/helix '-%arch%-linux.tar.xz' hx +RUN /pkg-install.sh DEV ghbin helix-editor/helix '-%arch%-linux.tar.xz' hx \ + && /pkg-install.sh DEV ghbin dandavison/delta '_%arch1%.deb' RUN sed 's/deb-src.*//' -i /etc/apt/sources.list \ && apt-get autoremove -y \ && apt-get update diff --git a/guest/fs-root/etc/zsh_command_not_found b/guest/fs-root/etc/zsh_command_not_found index bf6fced..bf4dd5a 100644 --- a/guest/fs-root/etc/zsh_command_not_found +++ b/guest/fs-root/etc/zsh_command_not_found @@ -16,11 +16,22 @@ function cnf_preexec() { local cmd local is_nospace - - [ -n "$cnf_once" ] && return - typeset -g cnf_once="1" + local s cmd="$1" + # Dont deal with ultra long commands + [[ ${#cmd} -gt 1024 ]] && return + # Dont deal with multi-lines + [[ "$cmd" == *$'\n'* ]] && return + # Check if we are tracking this command already + [[ $cnf_last == $cmd ]] && return + typeset -g cnf_last="$cmd" + + cmd="${cmd#"${cmd%%[^[:space:]]*}"}" # remove leading whitespace characters + # Dont deal with function definitions: contains "()" and no " " before + s="${cmd%%\(\)*}" + [[ $s != $cmd ]] && [[ "$s" != *" "* ]] && return + # Remove any variable like in `FOO=blah duf` # Test: # X="FOO BAR" Y="hello world" Z=mememe id @@ -59,7 +70,7 @@ function cnf_preexec() { function cnf_precmd() { cnf_ret=$? - unset cnf_once + unset cnf_last echo -en "\e[0m" (($cnf_ret)) && [ -n "$cnf_command" ] && { whence -- "${cnf_command}" >& /dev/null || diff --git a/guest/fs-root/sf/bin/gsexecio b/guest/fs-root/sf/bin/gsexecio index 9c8f3ac..a2ac9fd 100755 --- a/guest/fs-root/sf/bin/gsexecio +++ b/guest/fs-root/sf/bin/gsexecio @@ -1,11 +1,42 @@ #! /usr/bin/env bash +# Known problems: +# - OpenWRT's broken? kill -9 $PPID but the parent's parent only detects EOF on STDOUT after 10 second timeout. + { [[ -n $SF_BINDIR ]] && source "${SF_BINDIR}/funcs.sh"; } || source "/sf/bin/funcs.sh" [[ $# -lt 1 ]] && { echo -e >&2 "${CY}ERROR${CN}: gsexecio SECRET /dev/null | sed -un '/stty raw -echo/,$p'|tail +3 + # local IFS="" + # - stty is not always available. This poses a problem because we can not disable echo on the TTY and the entire + # script with be replied back to us. Solution is to add an ENDMARKER and use 'sed -un' to ignore all output until + # ENDMARKER (end of script) is reached. + # Old: { echo -e "stty raw -echo\nexec cat | exec bash; stty +echo"; sleep 3; cat; echo -e "\n:;kill -9 \$PPID";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/stty raw -echo/,$p'|tail +3 + # - The "echo sleep 2; cat;" triggers the remote bash to first wait 2 seconds before executing whatserver.sh + # and thus allowing the bash to read all the script into its input buffer (because when stty does not exist we + # must wait for bash to reply the entire script back to us before creating output or the output will + # get mangled. + # Old: { echo "sleep 2"; cat; } | { echo -e "exec cat | exec bash"; cat; echo -e '\n:;kill -9 $PPID;';} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/:;kill -9 $PPID/,$p' | tail +2 + # - We can not pipe the commands into bash because that would cause output mangling (bash starts execting before EOF.) + # Old: { echo -e 'dd bs=1 count='"${#s}" 2>/dev/null' | bash; kill -9 $$'; echo "$s";} | gs-netcat -Ii -s "$1" 2>/dev/null + # - Expand diretly into bash -c will make our script show in remote's process list + # Old: { echo -e 'exec bash -c "$(dd bs=1 count='"${#s} 2>/dev/null)"'"'; echo "$s";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/####ENDMARKER/,$p' | tail +2 + + # Right deep into the bash tool kit: + # - we dont want that the entire script shows in 'ps' output. Thus read into variable 's' and then + # double eval + # bash -c 'IFS="" s="$(/dev/null) eval eval "\$s"'"'"; echo "$s";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/####ENDMARKER/,$p' | tail +2 + # Understanding the quote-escape, turn ' into '"'"' + # { echo 'exec bash -c '"'"'IFS="" s=$(dd bs=1 count='"${#s}"' 2>/dev/null) eval eval "\$s"'"'"; echo "$s";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/####ENDMARKER/,$p' | tail +2 + # { echo 'exec bash -c ' IFS="" s=$(dd bs=1 count="${#s}" 2>/dev/null) eval eval "\$s"'; echo "$s";} | gs-netcat -Ii -s "$1" 2>/dev/null | sed -un '/####ENDMARKER/,$p' | tail +2 } + gsexecio "$1" + diff --git a/guest/fs-root/sf/bin/str2mnemonic b/guest/fs-root/sf/bin/str2mnemonic new file mode 100755 index 0000000..755bf5c --- /dev/null +++ b/guest/fs-root/sf/bin/str2mnemonic @@ -0,0 +1,49 @@ +# /usr/bin/env bash + +BINDIR="$(cd "$(dirname "${0}")" || exit; pwd)" + +ERREXIT() { + local code=$1 + shift 1 + echo -e >&2 "[ERROR] $*" + exit "$code" +} + +usage() { + echo -e "Create a Mnemonic from 'string'" + echo -e "Usage: ${0%/*} [number of words in mnemonic] string ..." + exit 255 +} + +findfn() { + local fn + for fn in "$@"; do + [[ ! -f "$fn" ]] && continue + echo "$fn" + return + done + return 1 # ERROR +} + +[[ $# -lt 2 ]] && usage + +amount=$1 +shift 1 +NUM=$(echo "$*" | md5sum) +NUM=${NUM%% *} +NUM=$((16#${NUM:0:15})) + +fn=$(findfn "${BINDIR}/english.txt" "/sf/share/english.txt" "/usr/share/english.txt" "/etc/english.txt") || ERREXIT 255 "List of 2000 words (english.txt) not found." +readarray -t english <"$fn" +unset fn + +# Create a amount number of words from NUM: + +while [[ $amount -gt 0 ]]; do + ((amount--)) + m=$((NUM % ${#english[@]})) + fn+="${english[$m]}" + NUM=$((NUM / ${#english[@]})) +done + +echo "$fn" \ No newline at end of file diff --git a/host/fs-root/bin/docker_sshd.sh b/host/fs-root/bin/docker_sshd.sh index 69610b6..3675615 100755 --- a/host/fs-root/bin/docker_sshd.sh +++ b/host/fs-root/bin/docker_sshd.sh @@ -182,6 +182,9 @@ done LXCFS_STR=$str } +# Find out if the host has /dev/kvm +docker run --rm --device=/dev/kvm sf-host true && SF_HAS_DEV_KVM=1 + # SSHD resets the environment variables. The environment variables relevant to the guest # are stored in a file here and then read by `segfaultsh'. # Edit 'segfaultsh' and add them to 'docker run --env' to pass any of these @@ -201,7 +204,9 @@ SF_SHMDIR=\"${SF_SHMDIR}\" SF_RAND_OFS=\"$RANDOM\" SF_HM_SIZE_LG=\"$SF_HM_SIZE_LG\" SF_BACKING_FS=\"$SF_BACKING_FS\" +SF_HAS_DEV_KVM=\"$SF_HAS_DEV_KVM\" SF_NS_NET=\"$(readlink /proc/self/ns/net)\" + LXCFS_ARGS=($LXCFS_STR) SF_FQDN=\"${SF_FQDN}\"" >/dev/shm/env.txt diff --git a/host/fs-root/bin/segfaultsh b/host/fs-root/bin/segfaultsh index c2366d4..0da1b65 100755 --- a/host/fs-root/bin/segfaultsh +++ b/host/fs-root/bin/segfaultsh @@ -617,6 +617,11 @@ load_limits() { local prefix local is_need_update_token + local str + local name + local dst + local arr + local IFS # Set the default values. # No default for ROOT_FS limit. Should be set in sf.conf or if not set # then root is mounted read-only @@ -726,7 +731,18 @@ load_limits() DOCKER_ARGS+=("--oom-score-adj=${SF_USER_OOM_SCORE}") DOCKER_ARGS+=("--blkio-weight=${SF_USER_BLKIO_WEIGHT}") - [[ -n $SF_USER_DEV_KVM ]] && [[ -e /dev/kvm ]] && DOCKER_ARGS+=("--device=/dev/kvm") + [[ -n $SF_USER_DEV_KVM ]] && [[ -n $SF_HAS_DEV_KVM ]] && DOCKER_ARGS+=("--device=/dev/kvm") + + # Mount external filesystem into LG (for android builders who dont need encryption but high IO) + [[ -n $SF_USER_FS_EXT ]] && { + IFS=: read -ra arr <<<"$SF_USER_FS_EXT" + + name=${arr[0]//[^a-z0-9A-Z]} + dst=${arr[1]//[^a-z0-9A-Z\/]} + str=${arr[2]//[^a-z,]} + [[ -n $str ]] && str=":${str}" + [[ -n $name ]] && [[ -n $dst ]] && [[ -e "/sf/ext/${name}" ]] && DOCKER_ARGS+=("-v${SF_BASEDIR}/data/ext/${name}:${dst}${str}") + } if [[ -z $SF_USER_ROOT_FS_SIZE ]]; then DOCKER_ARGS+=("--read-only") diff --git a/host/fs-root/etc/ssh/sshd_config b/host/fs-root/etc/ssh/sshd_config index deb4cd0..fe70a76 100644 --- a/host/fs-root/etc/ssh/sshd_config +++ b/host/fs-root/etc/ssh/sshd_config @@ -126,7 +126,7 @@ MaxStartups 128:10:1024 #VersionAddendum none # no default banner path -#Banner none +Banner /config/host/etc/ssh/banner # override default of no subsystems Subsystem sftp /usr/lib/ssh/sftp-server diff --git a/host/mk_sshd.sh b/host/mk_sshd.sh index f4063a1..047a7e1 100755 --- a/host/mk_sshd.sh +++ b/host/mk_sshd.sh @@ -23,6 +23,7 @@ SRCDIR="/tmp/openssh-9.2p1" } cd "$SRCDIR" ./configure --prefix=/usr --sysconfdir=/etc/ssh --with-libs=-lcap \ + --without-zlib-version-check \ --disable-utmp \ --disable-wtmp \ --disable-utmpx \ diff --git a/provision/init-linux.sh b/provision/init-linux.sh index 5150a3a..b9f943b 100755 --- a/provision/init-linux.sh +++ b/provision/init-linux.sh @@ -288,6 +288,10 @@ journalctl --vacuum-time=10d sed 's/rotate 4/rotate 2/' -i /etc/logrotate.conf sed 's/rotate 4/rotate 2\n\tsize 64M\n\tminsize 128k/' -i /etc/logrotate.d/rsyslog +sed 's|.*-/var/log/syslog$|\$outchannel mysyslog,/var/log/syslog,1048576\n*.*;kern.none,auth,authpriv.none :omfile:$mysyslog|' -i /etc/rsyslog.d/50-default.conf +sed 's|.*-/var/log/kern.log$|\$outchannel mykern,/var/log/kern.log,1048576\n*.*;kern.none,auth,authpriv.none :omfile:$mykern|' -i /etc/rsyslog.d/50-default.conf +systemctl restart rsyslog.service + # NOTE: Only needed if source is mounted into vmbox (for testing) [[ "$(stat -c %G /research/segfault 2>/dev/null)" == "vboxsf" ]] && usermod -a -G vboxsf "${SF_HOST_USER}" diff --git a/router/init.sh b/router/init.sh index 7575976..3aa6007 100755 --- a/router/init.sh +++ b/router/init.sh @@ -325,7 +325,6 @@ ipt_direct() ipset_add_domain http.kali.org # SF is direct (otherwise a user can inflate root-server-per-IP-limit) - ipset_add_domain teso.segfault.net ipset_add_domain lsd.segfault.net ipset_add_domain 8lgm.segfault.net ipset_add_domain adm.segfault.net diff --git a/sfbin/banhammer.sh b/sfbin/banhammer.sh new file mode 100755 index 0000000..de76864 --- /dev/null +++ b/sfbin/banhammer.sh @@ -0,0 +1,40 @@ +#! /usr/bin/env bash + +source /sf/sfbin/funcs_admin.sh >/dev/null || exit + +do_ban() { + echo "[$(date '+%F %H:%M:%S' -u)] Banning $2 [$1]. See /sf/config/db/user/${2}/syscop-ps.txt" + [[ -n $SF_DEBUG ]] && { + lgwall "$2" "$3" + return + } + lgban "$2" "$3" +} + +run_ban() { + local interval + local rx_fn="/sf/config/db/private/${1}" + local msg_fn="/sf/config/db/private/${2}" + local regex + local reason="${rx_fn%.txt}" + reason="${reason##*rx_}" + while :; do + source "$rx_fn" || { sleep 60; continue; } + for lg in $(lgx "$regex" skiptoken); do + if [[ -f "$msg_fn" ]]; then + do_ban "$reason" "$lg" "$(<"$msg_fn"))" + else + do_ban "$reason" "$lg" "You got banned. Contact a SysCop to discuss [ERROR: $msg_fn]." + fi + done + sleep "${interval:-360}" + done +} + +run_ban rx_dos.txt banmsg_dos.txt & +run_ban rx_egress.txt banmsg_egress.txt & +run_ban rx_exhaust.txt banmsg_exhaust.txt & + +# CTRL-c here will also send a SIGINTR to all child processes (and kill them) +echo "Banhammer started. Press CTRL-c to stop." +read diff --git a/sfbin/funcs_admin.sh b/sfbin/funcs_admin.sh index 1d10fa0..6bc811d 100644 --- a/sfbin/funcs_admin.sh +++ b/sfbin/funcs_admin.sh @@ -114,7 +114,7 @@ _sfcg_forall() skip_token="$1" set -o noglob - IFS=$'\n' arr=($(docker ps --format "{{.Names}}" --filter 'name=^lg-')) + IFS=$'\n' arr=($(docker ps --format "{{.Names}}" --filter 'name=^lg-' 2>/dev/null)) for l in "${arr[@]}"; do ts=2147483647 @@ -139,7 +139,7 @@ _sfcg_psarr() found=0 [[ -z $match ]] && found=1 # empty string => Show all - IFS= str=$(docker top "${lglid}" -e -o pid,bsdtime,rss,start_time,comm,cmd) + IFS= str=$(docker top "${lglid}" -e -o pid,bsdtime,rss,start_time,comm,cmd 2>/dev/null) [[ -n $str ]] && [[ -n $match ]] && [[ "$str" =~ $match ]] && found=1 echo "$str" @@ -221,6 +221,7 @@ lgwall() # This local pid local cid + local fn [[ -z $2 ]] && { echo >&2 "lgwall LID [message]"; return; } cid=$(docker inspect --format='{{.Id}}' "$1") || return pid=$(<"/var/run/containerd/io.containerd.runtime.v2.task/moby/${cid}/init.pid") || return @@ -436,6 +437,8 @@ lgdf() local dst local IFS local blocks + local fn + local info _sf_init @@ -460,7 +463,12 @@ lgdf() perctt=${_sfquota["${l}-inode-perctt"]} pin=$(printf '% 3u.%02u\n' $((perctt / 100)) $((perctt % 100))) str="${psz} " - echo "${blocks} ${str:0:5}% ${pin}% ${l}" + info="${l}" + fn="${_sf_dbdir}/user/${l}/hostname" + [[ -f "$fn" ]] && info+=" $(<"$fn")" + fn="${_sf_dbdir}/user/${l}/token" + [[ -f "$fn" ]] && info+=" [$(<"$fn")]" + echo "${blocks} ${str:0:5}% ${pin}% ${info}" done _sf_deinit diff --git a/sfbin/sf b/sfbin/sf index 55e13f6..8698f22 100755 --- a/sfbin/sf +++ b/sfbin/sf @@ -160,9 +160,10 @@ export SF_GUEST_MTU=$((SF_HOST_MTU - 80)) [[ ! -d "${SF_DATADIR}/user" ]] && mkdir -p "${SF_DATADIR}/user" [[ ! -d "${SF_DATADIR}/share" ]] && mkdir -p "${SF_DATADIR}/share" -[[ ! -f "${SF_DATADIR}/share/GeoLite2-City.mmdb" ]] && { +[[ ! -f "${SF_DATADIR}/share/GeoLite2-City.mmdb" ]] && [[ "${MAXMIND_KEY,,}" != "skip" ]] && { WARN "Not found: data/share/GeoLite2-City.mmdb" - echo -e "Try \`curl 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=${MAXMIND_KEY:?}&suffix=tar.gz' | tar xfvz - --strip-components=1 --no-anchored -C '${SF_DATADIR}/share/' 'GeoLite2-City.mmdb'\`." + echo -e "Try \`curl 'https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=${MAXMIND_KEY:-KEY-NOT-SET}&suffix=tar.gz' | tar xfvz - --strip-components=1 --no-anchored -C '${SF_DATADIR}/share/' 'GeoLite2-City.mmdb'\`." + echo -e "Try ${CDC}MAXMIND_KEY=skip${CN} to disable. This will also disable limits by GEOIP and disable user tools like geoip and geoiphn." } [[ ! -f "${SF_DATADIR}/share/tor-exit-nodes.txt" ]] && {