Cette version du service Knock Knock utilise l'opttion SSL de Ncat (NetCat du package Nmap) et un serveur SSH pour l'ouverture de session final. Il ne se content pas d'ouvrir un port. De plus tout les ports par défaut sont fermés et ouvert un à un. De plus Ncat n'autorise qu'une connexion et uniquement au client.





0x01. KK.CONF


#
# Configuration
#

# Key to validate session
KEY1="Ca5f523dFFE46C_fa0a96d6dfFb2B95FD058230B87afec6e"
KEY2="144d7Dcc8AeC89b58D710+8Fa7ffe75Cc1d1ADA33d113368"
KEY3="5AaddF32BFA3B63De2F16dfaDE50B=ebBaBbcE60DDe3aFb7"

# SSH reference file 
CONF_SSHD_REF="kk.ssh.conf.ref"
CONF_SSHD="kk.ssh.conf"

# SSH daemon + SSH conf file
DAEMON="/usr/sbin/sshd -D -d -e -f "$CONF_SSHD""
DAEMON_PROCNAME="sshd"
CLIENT="/usr/bin/ssh"

# Time to wait before considering a SSH client
WAIT_FOR_SSH_CLIENT=30

# Log file
LOG="kk.log"

# Port to send data for next sessions
PORT_CONF="50000"

# Session port range
MIN_PORT1=5    # 59999 >= port1 >= 50000 
MIN_PORT2=5    # 59999 >= port2 >= 50000 
MIN_PORT3=5    # 59999 >= port3 >= 50000 
MIN_PORTSSH=5  # 59999 >= portssh >= 50000 


#
# Programs path
#
iptables=/sbin/iptables
ncat=/usr/bin/ncat



0x02. KK.SSH.CONF.REF


Port %PORT%

Protocol 2

UsePrivilegeSeparation yes

KeyRegenerationInterval 3600
ServerKeyBits 1024

SyslogFacility AUTH
LogLevel INFO

StrictModes yes

PubkeyAuthentication yes

IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no

PermitEmptyPasswords no

ChallengeResponseAuthentication no

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes

AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

UsePAM yes



0x03. KK.SERVER.SH


 
#!/bin/bash
 
#
# Configuration
#
source kk.conf
 
# Assume iptables rule is OK, print only ncat result
# Allow only for client and port
open_listen()
{
  client="$1"
  port="$2"
 
  sleep 1
  ( ${iptables} -I INPUT -p tcp -s $client --dport $port -j ACCEPT ) >/dev/null 2>&1
  ${ncat} --allow $client --ssl -lp $port
}
 
# Delete iptables rule with port and IP
close_port()
{
  client="$1"
  port="$2"
  ( $iptables -D INPUT -p tcp -s $client --dport $port -j ACCEPT ) >/dev/null 2>&1
}
 
# This function may be overwritten to use another daemon
# You should bind a crypted shell (cryptcat?) on port
# SSH is "naturally" protected, audited and make crypted traffic
configure_server()
{
  client="$1"
  port="$2"
  ( ${iptables} -D INPUT -p tcp -s $client --dport $port -j ACCEPT ) >/dev/null 2>&1
  ( ${iptables} -I INPUT -p tcp -s $client --dport $port -j ACCEPT ) >/dev/null 2>&1
  cat "$CONF_SSHD_REF"|sed "s/%PORT%/$port/1" > "$CONF_SSHD"
  $DAEMON >"$LOG" 2>&1 &
  sleep $WAIT_FOR_SSH_CLIENT
  while true
  do
    w | grep "$client" >/dev/null 2>&1 && sleep 1.5 || break
    sleep 1
  done
  killall "$DAEMON_PROCNAME" >>"$LOG" 2>&1
}
 
# Be a daemon
while true
do
  # At first generate random port for sessions
  PORTS="$MIN_PORT1$(((RANDOM%8000)+2000));$MIN_PORT2$(((RANDOM%8000)+2000));$MIN_PORT3$(((RANDOM%8000)+2000));$MIN_PORTSSH$(((RANDOM%8000)+2000))"
 
  # Separate knock knock session and daemon port
  PORT1=$(echo $PORTS|cut -d';' -f1)
  PORT2=$(echo $PORTS|cut -d';' -f2)
  PORT3=$(echo $PORTS|cut -d';' -f3)
  PORTDAEMON=$(echo $PORTS|cut -d';' -f4)
 
  # Display used ports
  echo -e "\\n[+] Listening PORTS : $PORTS"
 
  # Allow connection to get session configuration
  $iptables -I INPUT -p tcp --dport $PORT_CONF -j ACCEPT
  CLIENT=$(echo $PORTS|ncat -v --ssl -lp $PORT_CONF 2>&1|grep 'Connection from '|head -n1|awk '{ print $4 }'|cut -d'.' -f1,2,3,4)
  echo "[-] New client : $CLIENT"
  $iptables -D INPUT -p tcp --dport $PORT_CONF -j ACCEPT
  [ -z "$CLIENT" ] && continue
 
  # Open 1st session...
  echo -ne "\\n[+] Listening on $PORT1 ..."
  res1=$(open_listen "$CLIENT" "$PORT1")
  # ...get and compare key #1...
  if [ "$res1" = "$KEY1" ]; then
    echo "OK!"
    close_port "$CLIENT" "$PORT1"
    echo -ne "[+] Listening on $PORT2 ..."
    res2=$(open_listen "$CLIENT" "$PORT2")
    if [ "$res2" = "$KEY2" ]; then
      echo "OK!"
      close_port "$CLIENT" "$PORT2"
      echo -ne "[+] Listening on $PORT3 ..."
      res3=$(open_listen "$CLIENT" "$PORT3")
      if [ "$res3" = "$KEY3" ]; then
        # ...if all keys are OK, then run daemon
        echo "OK!"
        close_port "$CLIENT" "$PORT3"
        echo -e "\\n[+] Opening session for $CLIENT"
        configure_server "$CLIENT" "$PORTDAEMON"
        close_port "$CLIENT" "$PORTDAEMON"
      else
        echo "Failed."
      fi
    else
      echo "Failed."
    fi
  else
    echo "Failed."
  fi
done
 




0x04. KK.CLIENT.SH


 
#!/bin/sh
 
 
#
# Connect on host and via ssh user 
#
user="$1"
host="$2"
 
 
#
# Configuration
#
source kk.conf
 
 
#
# Get port sequence
#
PORTS=$(echo |ncat --ssl $host $PORT_CONF)
 
echo -e "\\n[-] Got ports: $PORTS"
 
PORT1=$(echo $PORTS|cut -d';' -f1)
PORT2=$(echo $PORTS|cut -d';' -f2)
PORT3=$(echo $PORTS|cut -d';' -f3)
PORTSSH=$(echo $PORTS|cut -d';' -f4)
 
 
#
# Function to open port one by one, exit if fail
#
toctoc()
{
  hst="$1"
  prt="$2"
  key="$3"
  iky="$4"
  [ $# -eq 5 ] && wit="$5"
  sleep $wit ; echo "$key"|ncat --ssl $hst $prt ; err=$?
  [ "$err" = "0" ] && printf "\\n[v] Door #$iky (%-5s) : Open!" "$prt"
  [ "$err" = "1" ] && printf "\\n[x] Door #$iky (%-5s) : Closed." "$prt"
  [ "$err" != "0" ] && exit $err
}
 
#
# Make the sequence
#
toctoc "$host" "$PORT1" "$KEY1" 1 $WAIT_BETWEEN_TWO_SEQUENCE
toctoc "$host" "$PORT2" "$KEY2" 2 $WAIT_BETWEEN_TWO_SEQUENCE
toctoc "$host" "$PORT3" "$KEY3" 3 $WAIT_BETWEEN_TWO_SEQUENCE
 
# If we are always in script, then all sequence are done.
# We are able to open SSH session
printf "\\n\\n[-] Got session from knockknock server\\n\\n"
# Wait for SSH loading
sleep $WAIT_SSH_TO_BE_READY
# And then connect
ssh "$user"@"$host" -p "$PORTSSH"
# Print some return
printf "\\n\\n"
 



   =>   Écrit par : Nicolas, le 04 août 2015


 
Mots clés :  
  network 
  
  ssh 
  
  security 
    >   Articles connexes :

GitVuln



HTTP Server, tell me who you are ?


Discuter avec un serveur web *apparement* muet ? Voici comment faire...

Socket SSH


Cet article décrit comment faire un système de "mot de passe maitre" pour SSH, afin de ne taper que le mot de passe des clés, et de manière à ce qu'on n'ait pas à le retaper à chaque connexion au même serveur.

/tmp et /var/log en noexec sur macOS



Durcissement de Windows



6235197