Revert libssh2 branch, for now.

$ svn merge -r r33518:r33513 .

and removed added scripts to the script.db.

The branch needs further refinement/testing for Windows and Mac before merging
into the trunk. There is also the latent EOF bug which is giving performance
issues.

Further work on the branch will continue in Devin's latest branch:

/nmap-exp/devin/nmap-libssh2
This commit is contained in:
batrick 2014-08-18 03:12:00 +00:00
parent 3702d44201
commit de27812fe4
14 changed files with 27 additions and 1092 deletions

View file

@ -50,7 +50,7 @@ export CFLAGS = $(CXXFLAGS)
# CFLAGS = $(DEFS) $(INCLS)
STATIC =
LDFLAGS = @LDFLAGS@ $(DBGFLAGS) $(STATIC)
LIBS = @LIBNBASE_LIBS@ @LIBNSOCK_LIBS@ @LIBPCRE_LIBS@ @LIBPCAP_LIBS@ $(OPENSSL_LIBS) libnetutil/libnetutil.a @LIBDNET_LIBS@ @LIBLUA_LIBS@ @LIBLINEAR_LIBS@ @LIBSSH2_LIBS@ @LIBS@
LIBS = @LIBNBASE_LIBS@ @LIBNSOCK_LIBS@ @LIBPCRE_LIBS@ @LIBPCAP_LIBS@ $(OPENSSL_LIBS) libnetutil/libnetutil.a @LIBDNET_LIBS@ @LIBLUA_LIBS@ @LIBLINEAR_LIBS@ @LIBS@
OPENSSL_LIBS = @OPENSSL_LIBS@
# LIBS = -lefence @LIBS@
# LIBS = -lrmalloc @LIBS@
@ -89,11 +89,6 @@ ifneq (@LIBLUA_LIBS@,)
NSE_SRC=nse_main.cc nse_utility.cc nse_nsock.cc nse_dnet.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_binlib.cc nse_bit.cc nse_lpeg.cc
NSE_HDRS=nse_main.h nse_utility.h nse_nsock.h nse_dnet.h nse_fs.h nse_nmaplib.h nse_debug.h nse_pcrelib.h nse_binlib.h nse_bit.h nse_lpeg.h
NSE_OBJS=nse_main.o nse_utility.o nse_nsock.o nse_dnet.o nse_fs.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_binlib.o nse_bit.o nse_lpeg.o
ifneq (@LIBSSH2_LIBS@,)
NSE_SRC+=nse_libssh2.cc
NSE_HDRS+=nse_libssh2.h
NSE_OBJS+=nse_libssh2.o
endif
ifneq (@OPENSSL_LIBS@,)
NSE_SRC+=nse_openssl.cc nse_ssl_cert.cc
NSE_HDRS+=nse_openssl.h nse_ssl_cert.h

59
aclocal.m4 vendored
View file

@ -1,4 +1,4 @@
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
@ -11,9 +11,8 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
# nls.m4 serial 5 (gettext-0.18)
dnl Copyright (C) 1995-2003, 2005-2006, 2008-2013 Free Software Foundation,
dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@ -45,12 +44,14 @@ AC_DEFUN([AM_NLS],
AC_SUBST([USE_NLS])
])
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009,
# 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 2
# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# ---------------------------------------------------------------------------
@ -79,7 +80,7 @@ AC_DEFUN([AM_PATH_PYTHON],
dnl Find a Python interpreter. Python versions prior to 2.0 are not
dnl supported. (2.0 was released on October 16, 2000).
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
[python python2 python3 python3.2 python3.1 python3.0 python2.7 dnl
python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
AC_ARG_VAR([PYTHON], [the Python interpreter])
@ -95,11 +96,10 @@ AC_DEFUN([AM_PATH_PYTHON],
dnl A version check is needed.
if test -n "$PYTHON"; then
# If the user set $PYTHON, use it and don't search something else.
AC_MSG_CHECKING([whether $PYTHON version is >= $1])
AC_MSG_CHECKING([whether $PYTHON version >= $1])
AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([Python interpreter is too old])])
[AC_MSG_RESULT(yes)],
[AC_MSG_ERROR(too old)])
am_display_PYTHON=$PYTHON
else
# Otherwise, try each interpreter until we find one that satisfies
@ -148,25 +148,6 @@ AC_DEFUN([AM_PATH_PYTHON],
[am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
# Just factor out some code duplication.
am_python_setup_sysconfig="\
import sys
# Prefer sysconfig over distutils.sysconfig, for better compatibility
# with python 3.x. See automake bug#10227.
try:
import sysconfig
except ImportError:
can_use_sysconfig = 0
else:
can_use_sysconfig = 1
# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
# <https://github.com/pypa/virtualenv/issues/118>
try:
from platform import python_implementation
if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
can_use_sysconfig = 0
except ImportError:
pass"
dnl Set up 4 directories:
@ -183,14 +164,7 @@ except ImportError:
else
am_py_prefix=$prefix
fi
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null`
case $am_cv_python_pythondir in
$am_py_prefix*)
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
@ -225,14 +199,7 @@ sys.stdout.write(sitedir)"`
else
am_py_exec_prefix=$exec_prefix
fi
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null`
case $am_cv_python_pyexecdir in
$am_py_exec_prefix*)
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
@ -280,12 +247,14 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
sys.exit(sys.hexversion < minverhex)"
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 1
# AM_RUN_LOG(COMMAND)
# -------------------
# Run COMMAND, save the exit status in ac_status, and log it.

183
configure vendored
View file

@ -661,7 +661,6 @@ DNET_BUILD
DNET_DEPENDS
LIBDNETDIR
LIBDNET_LIBS
LIBSSH2_LIBS
PCRE_DIST_CLEAN
PCRE_CLEAN
PCRE_BUILD
@ -782,7 +781,6 @@ with_nping
with_openssl
with_libpcap
with_libpcre
with_libssh2
with_libdnet
with_liblua
with_liblinear
@ -1441,7 +1439,6 @@ Optional Packages:
--with-libpcre=DIR Use an existing (compiled) pcre lib from DIR/include
and DIR/lib.
--with-libpcre=included Always use the version included with Nmap
--with-libssh2=DIR Use speficic copy of libssh2
--with-libdnet=DIR Use an existing (compiled) dnet lib from DIR/include
and DIR/lib. This is NOT RECOMMENDED because we have
made many important fixes to our included libdnet,
@ -5466,8 +5463,8 @@ if test "$with_ndiff" != "no"; then
if test -n "$PYTHON"; then
# If the user set $PYTHON, use it and don't search something else.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 2.4" >&5
$as_echo_n "checking whether $PYTHON version is >= 2.4... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 2.4" >&5
$as_echo_n "checking whether $PYTHON version >= 2.4... " >&6; }
prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
# because we need at least 4 digits for the hex conversion.
@ -5485,9 +5482,7 @@ sys.exit(sys.hexversion < minverhex)"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "Python interpreter is too old" "$LINENO" 5
as_fn_error $? "too old" "$LINENO" 5
fi
am_display_PYTHON=$PYTHON
else
@ -5499,7 +5494,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
$as_echo_n "(cached) " >&6
else
for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
for am_cv_pathless_PYTHON in python python2 python3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
test "$am_cv_pathless_PYTHON" = none && break
prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
@ -5615,25 +5610,6 @@ $as_echo "$am_cv_python_platform" >&6; }
PYTHON_PLATFORM=$am_cv_python_platform
# Just factor out some code duplication.
am_python_setup_sysconfig="\
import sys
# Prefer sysconfig over distutils.sysconfig, for better compatibility
# with python 3.x. See automake bug#10227.
try:
import sysconfig
except ImportError:
can_use_sysconfig = 0
else:
can_use_sysconfig = 1
# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
# <https://github.com/pypa/virtualenv/issues/118>
try:
from platform import python_implementation
if python_implementation() == 'CPython' and sys.version[:3] == '2.7':
can_use_sysconfig = 0
except ImportError:
pass"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5
@ -5647,14 +5623,7 @@ else
else
am_py_prefix=$prefix
fi
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null`
case $am_cv_python_pythondir in
$am_py_prefix*)
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
@ -5691,14 +5660,7 @@ else
else
am_py_exec_prefix=$exec_prefix
fi
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null`
case $am_cv_python_pyexecdir in
$am_py_exec_prefix*)
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
@ -5770,8 +5732,8 @@ if test "$with_zenmap" != "no"; then
if test -n "$PYTHON"; then
# If the user set $PYTHON, use it and don't search something else.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 2.4" >&5
$as_echo_n "checking whether $PYTHON version is >= 2.4... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 2.4" >&5
$as_echo_n "checking whether $PYTHON version >= 2.4... " >&6; }
prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
# because we need at least 4 digits for the hex conversion.
@ -5789,9 +5751,7 @@ sys.exit(sys.hexversion < minverhex)"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "Python interpreter is too old" "$LINENO" 5
as_fn_error $? "too old" "$LINENO" 5
fi
am_display_PYTHON=$PYTHON
else
@ -5803,7 +5763,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
$as_echo_n "(cached) " >&6
else
for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
for am_cv_pathless_PYTHON in python python2 python3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
test "$am_cv_pathless_PYTHON" = none && break
prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
@ -5919,25 +5879,6 @@ $as_echo "$am_cv_python_platform" >&6; }
PYTHON_PLATFORM=$am_cv_python_platform
# Just factor out some code duplication.
am_python_setup_sysconfig="\
import sys
# Prefer sysconfig over distutils.sysconfig, for better compatibility
# with python 3.x. See automake bug#10227.
try:
import sysconfig
except ImportError:
can_use_sysconfig = 0
else:
can_use_sysconfig = 1
# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
# <https://github.com/pypa/virtualenv/issues/118>
try:
from platform import python_implementation
if python_implementation() == 'CPython' and sys.version[:3] == '2.7':
can_use_sysconfig = 0
except ImportError:
pass"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5
@ -5951,14 +5892,7 @@ else
else
am_py_prefix=$prefix
fi
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null`
case $am_cv_python_pythondir in
$am_py_prefix*)
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
@ -5995,14 +5929,7 @@ else
else
am_py_exec_prefix=$exec_prefix
fi
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null`
case $am_cv_python_pyexecdir in
$am_py_exec_prefix*)
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
@ -6740,92 +6667,6 @@ fi
have_libssh2=no
# Check whether --with-libssh2 was given.
if test "${with_libssh2+set}" = set; then :
withval=$with_libssh2; case "$with_libssh2" in
yes)
have_libssh2=yes
;;
included)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"Libssh2 is not included with Nmap. Will try to find system version\"" >&5
$as_echo "$as_me: WARNING: \"Libssh2 is not included with Nmap. Will try to find system version\"" >&2;}
;;
*)
have_libssh2=yes
CPPFLAGS="-I$with_libssh2/include $CPPFLAGS"
LDFLAGS="-L$with_libssh2/lib $LDFLAGS"
;;
esac
fi
if test $have_libssh2 != yes; then
for ac_header in libssh2.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "libssh2.h" "ac_cv_header_libssh2_h" "$ac_includes_default"
if test "x$ac_cv_header_libssh2_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBSSH2_H 1
_ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libssh2_version in -lssh2" >&5
$as_echo_n "checking for libssh2_version in -lssh2... " >&6; }
if ${ac_cv_lib_ssh2_libssh2_version+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lssh2 -lm $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char libssh2_version ();
int
main ()
{
return libssh2_version ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_ssh2_libssh2_version=yes
else
ac_cv_lib_ssh2_libssh2_version=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssh2_libssh2_version" >&5
$as_echo "$ac_cv_lib_ssh2_libssh2_version" >&6; }
if test "x$ac_cv_lib_ssh2_libssh2_version" = xyes; then :
have_libssh2=yes; break
fi
fi
done
fi
LIBSSH2_LIBS=
if test $have_libssh2 = yes; then
LIBSSH2_LIBS="-lssh2"
$as_echo "#define HAVE_LIBSSH2 1" >>confdefs.h
fi
have_dnet=no
requested_included_dnet=no
LIBDNETDIR=libdnet-stripped

View file

@ -509,38 +509,6 @@ AC_SUBST(PCRE_BUILD)
AC_SUBST(PCRE_CLEAN)
AC_SUBST(PCRE_DIST_CLEAN)
have_libssh2=no
AC_ARG_WITH(libssh2,
AC_HELP_STRING([--with-libssh2=DIR], [Use speficic copy of libssh2]),
[ case "$with_libssh2" in
yes)
have_libssh2=yes
;;
included)
AC_MSG_WARN("Libssh2 is not included with Nmap. Will try to find system version")
;;
*)
have_libssh2=yes
CPPFLAGS="-I$with_libssh2/include $CPPFLAGS"
LDFLAGS="-L$with_libssh2/lib $LDFLAGS"
;;
esac]
)
if test $have_libssh2 != yes; then
AC_CHECK_HEADERS([libssh2.h],
AC_CHECK_LIB(ssh2, libssh2_version, [have_libssh2=yes; break],, [-lm])
)
fi
LIBSSH2_LIBS=
if test $have_libssh2 = yes; then
LIBSSH2_LIBS="-lssh2"
AC_DEFINE(HAVE_LIBSSH2)
fi
AC_SUBST(LIBSSH2_LIBS)
have_dnet=no
requested_included_dnet=no
LIBDNETDIR=libdnet-stripped

View file

@ -175,8 +175,6 @@
#undef HAVE_PCRE_H
#undef HAVE_LIBSSH2
#undef HAVE_PCRE_PCRE_H
#undef BSD_NETWORKING

View file

@ -1,463 +0,0 @@
/* Binding for the libssh2 library. Note that there is not a one-to-one correspondance
* between functions in libssh2 and the binding.
* Currently, during the ssh2 handshake, a call to nsock.recieve may result in an EOF
* error. This appears to only occur when stressing the ssh server (ie during a brute
* force attempt) or while behind a restrictive firewall/IDS.
* by Devin Bjelland
*/
extern "C" {
#include "lua.h"
#include "lauxlib.h"
}
#include "nse_debug.h"
#include "nse_nsock.h"
#include "nse_utility.h"
#include <libssh2.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
enum {
SSH2_UDATA = lua_upvalueindex(1)
};
struct ssh_userdata {
int sp[2];
LIBSSH2_SESSION *session;
};
static int ssh_error (lua_State *L, LIBSSH2_SESSION *session, const char *msg)
{
char *errmsg;
libssh2_session_last_error(session, &errmsg, NULL, 0);
return nseU_safeerror(L, "%s: %s", msg, errmsg);
}
static int finish_send (lua_State *L)
{
if (lua_toboolean(L, -2)) {
return 0;
} else {
return lua_error(L); /* uses idx 6 */
}
}
static int finish_read (lua_State *L)
{
struct ssh_userdata *sshu = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
if (lua_toboolean(L, -2)) {
size_t n = 0;
size_t l;
lua_getuservalue(L, 1);
lua_getfield(L, -1, "sp_buff");
lua_pushvalue(L, 3);
lua_concat(L, 2);
const char *data = lua_tolstring(L, -1, &l);
lua_pushliteral(L, "");
lua_setfield(L, 4, "sp_buff");
while (n < l) {
int rc = write(sshu->sp[1], data+n, l-n);
if(rc == -1 && errno != EAGAIN) {
luaL_error(L, "Writing to socket pair: %s", strerror(errno));
} else if(rc == -1 && errno == EAGAIN) {
lua_pushlstring(L, data+n, l-n);
lua_setfield(L, 4, "sp_buff");
break;
} else {
n += rc;
}
}
return 0;
} else {
return lua_error(L); /* uses idx 6 */
}
}
static int filter (lua_State *L)
{
int rc;
char data[4096];
struct ssh_userdata *sshu = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
lua_getuservalue(L, 1);
lua_getfield(L, -1, "sock");
lua_replace(L, -2);
rc = read(sshu->sp[1], data, sizeof(data));
if (rc > 0) {
//write data to nsock socket
lua_getfield(L, -1, "send");
lua_insert(L, -2); /* swap */
lua_pushlstring(L, data, rc);
lua_callk(L, 2, 2, 0, finish_send);
return finish_send(L);
} else if (rc == -1 && errno != EAGAIN) {
luaL_error(L, "%s", strerror(errno));
}
lua_getfield(L, -1, "receive");
lua_insert(L, -2); /* swap */
lua_callk(L, 1, 2, 0, finish_read);
return finish_read(L);
}
static int do_session_handshake (lua_State *L)
{
int rc;
struct ssh_userdata *sshu;
assert(lua_gettop(L) == 4);
sshu = (struct ssh_userdata *) nseU_checkudata(L, 3, SSH2_UDATA, "ssh2");
while((rc = libssh2_session_handshake(sshu->session, sshu->sp[0])) == LIBSSH2_ERROR_EAGAIN) {
luaL_getmetafield(L, 3, "filter");
lua_pushvalue(L, 3);
lua_callk(L, 1, 0, 0, do_session_handshake);
}
if (rc)
luaL_error(L, "Unable to complete libssh2 handshake.");
lua_pushvalue(L, 3);
return 1;
}
static int finish_session_open (lua_State *L) {
assert(lua_gettop(L) == 6);
if (lua_toboolean(L, -2)) {
lua_pop(L, 2);
return do_session_handshake(L);
} else {
return lua_error(L);
}
}
/* Creates libssh2 session, connects to hostname:port and tries to perform a
* ssh handshake on socket. Returns ssh_state on success
*
* session_open(hostname, port)
*/
static int l_session_open(lua_State *L) {
int rc;
luaL_checkint(L, 2);
lua_settop(L, 2);
ssh_userdata *state = (ssh_userdata *)lua_newuserdata(L, sizeof(ssh_userdata)); /* index 3 */
assert(lua_gettop(L) == 3);
state->session = NULL;
state->sp[0] = -1;
state->sp[1] = -1;
lua_pushvalue(L, lua_upvalueindex(1)); /* metatable */
lua_setmetatable(L, 3);
lua_newtable(L);
lua_setuservalue(L, 3);
lua_getuservalue(L, 3); /* index 4 */
assert(lua_gettop(L) == 4);
state->session = libssh2_session_init();
libssh2_session_set_blocking(state->session, 0);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, state->sp) == -1) {
return nseU_safeerror(L, "trying to create socketpair");
}
rc = fcntl(state->sp[1], F_GETFD);
if (rc == -1)
return nseU_safeerror(L, "%s", strerror(errno));
rc |= O_NONBLOCK;
rc = fcntl(state->sp[1], F_SETFL, rc);
if (rc == -1)
return nseU_safeerror(L, "%s", strerror(errno));
lua_getglobal(L, "nmap");
lua_getfield(L, -1, "new_socket");
lua_replace(L, -2);
lua_call(L, 0, 1);
lua_setfield(L, 4, "sock");
lua_pushliteral(L, "");
lua_setfield(L, 4, "sp_buff");
assert(lua_gettop(L) == 4);
lua_getfield(L, 4, "sock");
lua_getfield(L, -1, "connect");
lua_insert(L, -2); /* swap */
lua_pushvalue(L, 1);
lua_pushvalue(L, 2);
lua_callk(L, 3, 2, 3, finish_session_open);
return finish_session_open(L);
}
/* Returns the SHA1 or MD5 hostkey hash of provided session or nil if it is not available
*
*/
static int l_hostkey_hash(lua_State *L) {
static int hash_option[] = {LIBSSH2_HOSTKEY_HASH_MD5, LIBSSH2_HOSTKEY_HASH_SHA1};
static int hash_length[] = {16, 20};
static const char *hashes[] = {"md5", "sha1", NULL};
luaL_Buffer B;
struct ssh_userdata *state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
int type = luaL_checkoption(L, 2, "sha1", hashes);
const unsigned char *hash = (const unsigned char *) libssh2_hostkey_hash(state->session, hash_option[type]);
if (hash == NULL)
return nseU_safeerror(L, "could not get hostkey hash");
luaL_buffinit(L, &B);
for (int i = 0; i < hash_length[type]; i++) {
char byte[3]; /* with space for NUL */
snprintf(byte, sizeof(byte), "%02X", (unsigned int) hash[i]);
if (i)
luaL_addchar(&B, ':');
luaL_addlstring(&B, byte, 2);
}
luaL_pushresult(&B);
return 1;
}
static int l_set_timeout(lua_State *L) {
struct ssh_userdata *state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
long timeout = luaL_checklong(L, 2);
libssh2_session_set_timeout(state->session, timeout);
return 0;
}
/* Return list of supported authenication methods
*
*/
static int l_userauth_list(lua_State *L) {
struct ssh_userdata *state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
const char *username = luaL_checkstring(L, 2);
char *auth_list;
while((auth_list = libssh2_userauth_list(state->session, username, lua_rawlen(L, 2))) == NULL && libssh2_session_last_errno(state->session) == LIBSSH2_ERROR_EAGAIN) {
luaL_getmetafield(L, 1, "filter");
lua_pushvalue(L, 1);
lua_callk(L, 1, 0, 0, l_userauth_list);
}
if(auth_list) {
const char *auth = strtok(auth_list, ",");
lua_newtable(L);
do {
lua_pushstring(L, auth);
lua_rawseti(L, -2, lua_rawlen(L, -2)+1);
} while((auth = strtok(NULL, ",")));
libssh2_free(state->session, (void *)auth_list);
} else if (libssh2_userauth_authenticated(state->session)) {
lua_pushliteral(L, "none_auth");
} else {
return ssh_error(L, state->session, "userauth_list");
}
return 1;
}
static int l_userauth_publickey(lua_State *L) {
int rc;
const char *username, *private_key_file, *passphrase, *public_key_file;
struct ssh_userdata *state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
username = luaL_checkstring(L, 2);
private_key_file = luaL_checkstring(L, 3);
if (lua_isstring(L, 4)) {
passphrase = lua_tostring(L, 4);
}
else {
passphrase = NULL;
}
if (lua_isstring(L, 5)) {
public_key_file = lua_tostring(L, 5);
}
else {
public_key_file = NULL;
}
while ((rc = libssh2_userauth_publickey_fromfile(state->session, username, public_key_file, private_key_file, passphrase)) == LIBSSH2_ERROR_EAGAIN) {
luaL_getmetafield(L, 1, "filter");
lua_pushvalue(L, 1);
lua_callk(L, 1, 0, 0, l_userauth_publickey);
}
if(rc == 0) {
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
}
return 1;
}
static int l_read_publickey(lua_State *L) {
FILE *fd;
char c;
const char* publickeyfile = luaL_checkstring(L, 1);
luaL_Buffer publickey_data;
fd = fopen(publickeyfile, "r");
if (!fd) {
luaL_error(L, "Error reading file");
}
luaL_buffinit(L, &publickey_data);
while(fread(&c, 1, 1, fd) && '\r' && c != '\n' && c != ' ') continue;
while(fread(&c, 1, 1, fd) && '\r' && c != '\n' && c != ' ') {
luaL_addchar (&publickey_data, c);
}
fclose(fd);
lua_getglobal(L, "require");
lua_pushstring(L, "base64");
lua_call(L, 1, 1);
lua_getfield(L, -1, "dec");
luaL_pushresult(&publickey_data);
lua_call(L, 1, 1);
return 1;
}
static int publickey_canauth_cb(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract) {
return 0;
}
static int l_publickey_canauth(lua_State *L) {
char *errmsg;
int errlen;
int rc;
const char *username;
unsigned const char *publickey_data;
size_t len;
struct ssh_userdata *state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
username = luaL_checkstring(L, 2);
if (lua_isstring(L, 3)) {
publickey_data = (unsigned const char*) lua_tolstring(L, 3, &len);
} else {
luaL_error(L, "Invalid public key");
}
while ((rc = libssh2_userauth_publickey(state->session, username, publickey_data, len, &publickey_canauth_cb, NULL)) == LIBSSH2_ERROR_EAGAIN) {
luaL_getmetafield(L, 1, "filter");
lua_pushvalue(L, 1);
lua_callk(L, 1, 0, 0, l_publickey_canauth);
}
libssh2_session_last_error(state->session, &errmsg, &errlen, 0);
if(rc == LIBSSH2_ERROR_ALLOC || rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) {
lua_pushboolean(L, 1);
//Username/PublicKey combination invalid
} else if(rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED) {
lua_pushboolean(L, 0);
} else {
luaL_error(L, "Invalid Publickey");
}
return 1;
}
/* Attempts to authenticate session with provided username and password
* returns true on success and false otherwise
*
* userauth_password(state, username, password)
*/
static int l_userauth_password(lua_State *L) {
int rc;
const char *username, *password;
struct ssh_userdata *state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
username = luaL_checkstring(L, 2);
password = luaL_checkstring(L, 3);
while((rc = libssh2_userauth_password(state->session, username, password)) == LIBSSH2_ERROR_EAGAIN) {
luaL_getmetafield(L, 1, "filter");
lua_pushvalue(L, 1);
lua_callk(L, 1, 0, 0, l_userauth_password);
}
if(rc == 0) {
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
}
return 1;
}
static int l_session_close(lua_State *L) {
struct ssh_userdata *state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
int rc;
while ((rc = libssh2_session_disconnect(state->session, "Normal Shutdown")) == LIBSSH2_ERROR_EAGAIN) {
luaL_getmetafield(L, 1, "filter");
lua_pushvalue(L, 1);
lua_callk(L, 1, 0, 0, l_session_close);
}
if (rc < 0)
luaL_error(L, "unable to disconnect session");
if (libssh2_session_free(state->session) < 0) {
luaL_error(L, "unable to free session");
}
return 0;
}
static const struct luaL_Reg libssh2 [] = {
{"session_open", l_session_open},
{"hostkey_hash", l_hostkey_hash},
{"set_timeout", l_set_timeout},
{"userauth_list", l_userauth_list},
{"userauth_publickey", l_userauth_publickey},
{"read_publickey", l_read_publickey},
{"publickey_canauth", l_publickey_canauth},
{"userauth_password", l_userauth_password},
{"session_close", l_session_close},
{NULL, NULL}
};
static int gc (lua_State *L)
{
struct ssh_userdata *sshu = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2");
if (sshu) {
lua_pushvalue(L, lua_upvalueindex(1));
lua_getfield(L, -1, "session_close");
lua_insert(L, -2); /* swap */
lua_pcall(L, 1, 0, 0); /* if an error occurs, don't do anything */
}
close(sshu->sp[0]);
close(sshu->sp[1]);
return 0;
}
int luaopen_libssh2 (lua_State *L) {
lua_settop(L, 0); /* clear the stack */
luaL_newlibtable(L, libssh2);
lua_newtable(L); /* ssh2 session metatable */
lua_pushvalue(L, -1);
lua_pushcclosure(L, gc, 1);
lua_setfield(L, -2, "__gc");
lua_pushvalue(L, -1);
lua_pushcclosure(L, filter, 1);
lua_setfield(L, -2, "filter");
luaL_setfuncs(L, libssh2, 1);
if(libssh2_init(0) != 0) {
luaL_error(L, "unable to open libssh2");
}
return 1;
}

View file

@ -1,8 +0,0 @@
#ifndef LIBSSH2
#define LIBSSH2
#define LIBSSH2LIBNAME "libssh2"
LUALIB_API int luaopen_libssh2 (lua_State *L);
#endif

View file

@ -20,7 +20,6 @@
#include "nse_openssl.h"
#include "nse_debug.h"
#include "nse_lpeg.h"
#include "nse_libssh2.h"
#define NSE_MAIN "NSE_MAIN" /* the main function */
@ -546,9 +545,6 @@ static void set_nmap_libraries (lua_State *L)
{BITLIBNAME, luaopen_bit},
{LFSLIBNAME, luaopen_lfs},
{LPEGLIBNAME, luaopen_lpeg},
#ifdef HAVE_LIBSSH2
{LIBSSH2LIBNAME, luaopen_libssh2},
#endif
#ifdef HAVE_OPENSSL
{OPENSSLLIBNAME, luaopen_openssl},
#endif

View file

@ -1,71 +0,0 @@
--
-- Provides a binding for the libssh2 library.
--
-- SSH2 is a complex protocol and libssh2 simplifies many tasks involved in
-- interacting with ssh servers. This module provides bindings for some of the
-- most commonly used libssh2 functions.
--
-- For perfomance reasons, the modules reuses the NSE's existing nsock socket
-- pool. In order to accomplish this, libssh2 is a given a unix socket pair
-- instead of a network socket. As a result, this library is *nix only at the
-- current time.
--
-- @author Devin Bjelland
-- @copyright same as Nmap
module "libssh2"
--- Creates libssh2 session and performs handshake
-- @param host Host to connect to.
-- @param port Port to connect to.
-- @return session or nil on failure
function session_open(host, port)
--- Returns SHA1 or MD5 hostkey hash of session
-- @param session Connected libssh2 session.
-- @param hashtype (optional) "sha1" or "md5" (sha1 is default)
-- @return hostkey hash of server
function hostkey_hash(session, hashtype)
--- Sets timeout of libssh2 session
-- @param session Connected libssh2 session.
-- @param timeout Timeout for session in milliseconds.
function set_timeout(session, timeout)
--- Returns list of authentication methods supported by the server
-- @param session Connected libssh2 session.
-- @return List of supported authentication methods/
function userauth_list(session)
--- Attempts to authenicate libssh2 session using provided credentials
-- @param username Username to authenicate as.
-- @param password Password to authenicate with.
-- @return true/false, depending on success
function userauth_password(session, username, password)
--- Attempts to authenticate libssh2 session using provided publickey
-- @param session Connected libssh2 session
-- @param username Username to authenicate as
-- @param privatekeyfile File containing privatekey
-- @param passphrase Passphrase for privatekey
-- @param publickeyfile File containing publickey. Not necessary if libssh2 is
-- compiled against OpenSSL
-- @return true/false, depending on success
function userauth_publickey(session, username, privatekeyfile, passphrase publickeyfile)
--- Read publickey from id_*.pub type key file
-- @param publickeyfile File containing publickey
-- @return string containing raw key data
function read_publickey(publickeyfile)
--- Checks to see if ssh server accepts public key for authentication as given user.
-- This doesn't require the private key as it doesn't finish authenticating.
-- @param session Connected libssh2 session
-- @param username Username to authenicate as
-- @param publickeydata String containing raw publickey blob
-- @return true/false, depending on whether user can authenticate with given key
function publickey_canauth(session, username, publickeydata)
--- Gracefully closes connected libssh2 session
-- @param session Connected libssh2 session
function session_close(session)

View file

@ -112,12 +112,6 @@ fetch_host_key = function(host, port)
end
end
--- Returns key fingerprint in hexadecimal
fingerprint = function( hostkey )
local fingerprint = openssl.md5(hostkey)
return stdnse.tohex(fingerprint,{separator=":",group=2})
end
--- Format a key fingerprint in hexadecimal.
-- @param fingerprint Key fingerprint.
-- @param algorithm Key algorithm.

View file

@ -433,7 +433,6 @@ Entry { filename = "socks-auth-info.nse", categories = { "default", "discovery",
Entry { filename = "socks-brute.nse", categories = { "brute", "intrusive", } }
Entry { filename = "socks-open-proxy.nse", categories = { "default", "discovery", "external", "safe", } }
Entry { filename = "ssh-hostkey.nse", categories = { "default", "discovery", "safe", } }
Entry { filename = "ssh-vuln-hostkey.nse", categories = { "default", "discovery", "safe", } }
Entry { filename = "ssh2-enum-algos.nse", categories = { "discovery", "safe", } }
Entry { filename = "sshv1.nse", categories = { "default", "safe", } }
Entry { filename = "ssl-ccs-injection.nse", categories = { "safe", "vuln", } }

View file

@ -1,37 +0,0 @@
local shortport = require "shortport"
local stdnse = require "stdnse"
local libssh2 = stdnse.silent_require "libssh2"
description = [[
Returns authenication methods a ssh server supports.
]]
---
-- @usage
-- nmap -p 22 --script ssh-auth-methods --script-args="ssh.user=<username>" <target>
--
-- @output
-- 22/tcp open ssh syn-ack
-- | ssh-auth-methods:
-- | Supported authentication methods:
-- | publickey
-- |_ password
author = "Devin Bjelland"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
local username = stdnse.get_script_args("ssh.user") or stdnse.generate_random_string(5)
portrule = shortport.port_or_service(22, 'ssh')
categories = {"safe"}
action = function (host, port)
local result = stdnse.output_table()
local session = libssh2.session_open(host, port.number)
local authmethods = libssh2.userauth_list(session, username)
result["Supported authentication methods"] = authmethods
return result
end

View file

@ -1,118 +0,0 @@
local shortport = require "shortport"
local stdnse = require "stdnse"
local brute = require "brute"
local libssh2 = stdnse.silent_require "libssh2"
description = [[
Performs brute-force password guessing against ssh servers.
]]
---
-- @usage
-- nmap -p 22 --script ssh-brute --script-args userdb=users.lst,passdb=pass.lst \
-- --script-args ssh-brute.timeout=4s <target>
--
-- @output
-- 22/ssh open ssh
-- | ssh-brute:
-- | Accounts
-- | username:password
-- | Statistics
-- |_ Performed 32 guesses in 25 seconds.
--
-- @args ssh-brute.timeout Connection timeout (default: "5s")
author = "Devin Bjelland"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {'brute', 'intrusive'}
portrule = shortport.port_or_service(22, 'ssh')
local arg_timeout = stdnse.get_script_args(SCRIPT_NAME .. ".timeout") or "5s"
Driver = {
new = function(self, host, port, options)
stdnse.debug(2, "creating brute driver")
local o = {}
setmetatable(o, self)
self.__index = self
o.host = host
o.port = port
o.options = options
return o
end,
connect = function (self)
stdnse.debug(2, "connecting to %s:%d", self.host.ip, self.port.number)
local status, session, err = pcall(libssh2.session_open, self.host, self.port.number)
if not status then
stdnse.debug(2, "libssh2 error: %s", session)
local err = brute.Error:new(session)
err:setAbort(true)
return false, err
elseif not session then
stdnse.debug(2, "failure to connect: %s", err);
local err = brute.Error:new(err)
err:setAbort(true)
return false, err
else
self.ssh_session = session
libssh2.set_timeout(self.ssh_session, self.options.ssh_timeout)
return true
end
end,
disconnect = function(self)
stdnse.debug(2, "disconnecting from %s:%d", self.host.ip, self.port.number);
local status, err = pcall(libssh2.session_close, self.ssh_session)
if not status then
stdnse.debug(2, "libssh2 error: %s", ok)
end
end,
login = function(self, username, password)
stdnse.verbose(2, "Trying username/password pair: %s:%s", username, password)
local status, ok = pcall(libssh2.userauth_password, self.ssh_session, username, password)
if not status then
stdnse.debug(2, "libssh2 error: %s", ok)
return false, brute.Error:new(ok)
elseif not ok then
stdnse.debug(2, "login failed for %s:%s", username, password)
return false, brute.Error:new("login failed")
else
stdnse.verbose(1, "Found working Credentials: %s:%s", username, password)
return true, brute.Account:new(username, password, "OPEN")
end
end,
}
password_auth_allowed = function (host, port)
local status, ssh_session = pcall(libssh2.session_open, host, port.number)
if status and ssh_session then
local status, methods = pcall(libssh2.userauth_list, ssh_session, "root")
if status then
for _, value in pairs(methods) do
if value == "password" then
return true
end
end
end
end
return false
end
action = function (host, port)
local timems = stdnse.parse_timespec(arg_timeout) --todo: use this!
local ssh_timeout = 1000 * timems
if password_auth_allowed(host, port) then
local options = {ssh_timeout = ssh_timeout}
local engine = brute.Engine:new(Driver, host, port, options)
engine.options.script_name = SCRIPT_NAME
local _, result = engine:start()
return result
else
return "Password authenication not allowed"
end
end

View file

@ -1,128 +0,0 @@
local shortport = require "shortport"
local ssh2 = require "ssh2"
local ssh1 = require "ssh1"
local stdnse = require "stdnse"
local io = require "io"
local string = require "string"
local table = require "table"
description = [[
Checks if ssh server has a predictable hostkey by checking it against a list of fingerprints
generated by HD Moore. You have to download these hostkeys separately and specify their directory
as the fingerprintdir variable. The keys are available at http://itsecurity.net/debian_ssh_scan_v4.tar.bz2. Additionally, you can specify a file ssh hostkey fingerprints, one per line, and the scripts will report if the hostkey matches one of the provided fingerprints.
]]
---
-- @usage
-- nmap -p 22 --script ssh-vuln-hostkey \
-- --script-args fingerprintdir=<directory with vulnerable fingerprints> <target>
--
-- @output
--
-- 22/tcp open ssh syn-ack
-- | ssh-vuln-hostkey:
-- | Weak hostkeys:
-- |_ 2048 6d:cd:2a:8b:dc:3e:e0:92:00:47:59:16:8c:8b:17:70 (RSA)
--
--
-- @usage
-- -- nmap -p 22 --script ssh-vuln-hostkey \
-- --script-args fingerprintfile=<file with fingerprints to check for> <target>
--
-- @output
--
-- 22/tcp open ssh syn-ack
-- | ssh-vuln-hostkey:
-- | Listed hostkeys:
-- |_ 2048 6d:cd:2a:8b:dc:3e:e0:92:00:47:59:16:8c:8b:17:70 (RSA)
--
-- @args fingerprintdir Directory containing vulnerable fingerprints
-- @args fingerprintfile File containing fingerprints to check against
--
author = "Devin Bjelland"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"safe","default","discovery"}
dependencies = {"ssh-hostkey"}
portrule = shortport.port_or_service(22, 'ssh')
local fingerprintdir = stdnse.get_script_args("fingerprintdir")
local fingerprintfile = stdnse.get_script_args("fingerprintfile")
action = function (host, port)
local key
local keys = {}
local r = stdnse.output_table()
local w = {}
local listed_hostkeys = {}
local found_listed_key
local found_weak_key
if nmap.registry.sshhostkey and nmap.registry.sshhostkey[host.ip] then
keys = nmap.registgry.sshhostkey[host.ip]
else
key = ssh2.fetch_host_key( host, port, "ssh-rsa" )
if key then table.insert( keys, key ) end
key = ssh2.fetch_host_key( host, port, "ssh-dss" )
if key then table.insert( keys, key ) end
end
for _,key in ipairs(keys) do
local fingerprint = stdnse.tohex(key.fingerprint)
stdnse.debug("fingerprint: " .. fingerprint)
if fingerprintdir then
if key.key_type == "ssh-rsa" then
for line in io.lines(fingerprintdir .. "ssh_rsa_" .. key.bits .. "_keys.txt") do
local stripped_line = string.gsub(line, "-.*", "")
if stripped_line == fingerprint then
found_weak_key = true
stdnse.verbose("Found weak hostkey: " .. ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
table.insert(w, ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
end
end
elseif key.key_type == "ssh-dss" and key.bits == "1024" then
for line in io.lines(fingerprintdir .. "ssh_dsa_1024_keys.txt", "r") do
local stripped_line = string.gsub(line, "-.*", "")
if stripped_line == fingerprint then
found_weak_key = true
stdnse.verbose("Found weak hostkey: " .. ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
table.insert(w, ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
end
end
end
end
if fingerprintfile then
for line in io.lines(fingerprintfile) do
local stripped_line = string.gsub(line, ":", "")
if stripped_line == fingerprint then
found_listed_key = true
table.insert(listed_hostkeys, ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
stdnse.verbose("Found hostkey on list:" .. ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
end
end
end
end
if not found_weak_key then
w = "No weak hostkeys found"
end
if not found_listed_key then
list_hostkey = "No listed hostkeys found"
end
if fingerprintdir then
r["Weak hostkeys"] = w
end
if fingerprintfile then
r["Listed hostkeys"] = listed_hostkeys
end
return r
end