mirror of
https://github.com/nmap/nmap.git
synced 2025-12-19 22:19:02 +00:00
Merged libssh2-integration branch
This commit is contained in:
@@ -52,6 +52,7 @@ STATIC =
|
|||||||
LDFLAGS = @LDFLAGS@ $(DBGFLAGS) $(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@ @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@
|
OPENSSL_LIBS = @OPENSSL_LIBS@
|
||||||
|
LIBS += -lssh2 #Just for now
|
||||||
# LIBS = -lefence @LIBS@
|
# LIBS = -lefence @LIBS@
|
||||||
# LIBS = -lrmalloc @LIBS@
|
# LIBS = -lrmalloc @LIBS@
|
||||||
INSTALL = @INSTALL@
|
INSTALL = @INSTALL@
|
||||||
@@ -86,9 +87,9 @@ UNINSTALLZENMAP=@UNINSTALLZENMAP@
|
|||||||
UNINSTALLNPING=@UNINSTALLNPING@
|
UNINSTALLNPING=@UNINSTALLNPING@
|
||||||
|
|
||||||
ifneq (@LIBLUA_LIBS@,)
|
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_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_libssh2.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_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_libssh2.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
|
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 nse_libssh2.o
|
||||||
ifneq (@OPENSSL_LIBS@,)
|
ifneq (@OPENSSL_LIBS@,)
|
||||||
NSE_SRC+=nse_openssl.cc nse_ssl_cert.cc
|
NSE_SRC+=nse_openssl.cc nse_ssl_cert.cc
|
||||||
NSE_HDRS+=nse_openssl.h nse_ssl_cert.h
|
NSE_HDRS+=nse_openssl.h nse_ssl_cert.h
|
||||||
|
|||||||
64
aclocal.m4
vendored
64
aclocal.m4
vendored
@@ -1,8 +1,7 @@
|
|||||||
# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
|
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
|
||||||
# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
|
|
||||||
# Inc.
|
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
# with or without modifications, as long as this notice is preserved.
|
# with or without modifications, as long as this notice is preserved.
|
||||||
@@ -12,8 +11,9 @@
|
|||||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
# PARTICULAR PURPOSE.
|
# 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)
|
# nls.m4 serial 5 (gettext-0.18)
|
||||||
dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
|
dnl Copyright (C) 1995-2003, 2005-2006, 2008-2013 Free Software Foundation,
|
||||||
dnl Inc.
|
dnl Inc.
|
||||||
dnl This file is free software; the Free Software Foundation
|
dnl This file is free software; the Free Software Foundation
|
||||||
dnl gives unlimited permission to copy and/or distribute it,
|
dnl gives unlimited permission to copy and/or distribute it,
|
||||||
@@ -45,14 +45,12 @@ AC_DEFUN([AM_NLS],
|
|||||||
AC_SUBST([USE_NLS])
|
AC_SUBST([USE_NLS])
|
||||||
])
|
])
|
||||||
|
|
||||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009,
|
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||||
# 2011 Free Software Foundation, Inc.
|
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
# with or without modifications, as long as this notice is preserved.
|
# 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])
|
# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -81,7 +79,7 @@ AC_DEFUN([AM_PATH_PYTHON],
|
|||||||
dnl Find a Python interpreter. Python versions prior to 2.0 are not
|
dnl Find a Python interpreter. Python versions prior to 2.0 are not
|
||||||
dnl supported. (2.0 was released on October 16, 2000).
|
dnl supported. (2.0 was released on October 16, 2000).
|
||||||
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
|
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
|
||||||
[python python2 python3 python3.2 python3.1 python3.0 python2.7 dnl
|
[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
|
||||||
python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
|
python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
|
||||||
|
|
||||||
AC_ARG_VAR([PYTHON], [the Python interpreter])
|
AC_ARG_VAR([PYTHON], [the Python interpreter])
|
||||||
@@ -97,10 +95,11 @@ AC_DEFUN([AM_PATH_PYTHON],
|
|||||||
dnl A version check is needed.
|
dnl A version check is needed.
|
||||||
if test -n "$PYTHON"; then
|
if test -n "$PYTHON"; then
|
||||||
# If the user set $PYTHON, use it and don't search something else.
|
# If the user set $PYTHON, use it and don't search something else.
|
||||||
AC_MSG_CHECKING([whether $PYTHON version >= $1])
|
AC_MSG_CHECKING([whether $PYTHON version is >= $1])
|
||||||
AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
|
AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
|
||||||
[AC_MSG_RESULT(yes)],
|
[AC_MSG_RESULT([yes])],
|
||||||
[AC_MSG_ERROR(too old)])
|
[AC_MSG_RESULT([no])
|
||||||
|
AC_MSG_ERROR([Python interpreter is too old])])
|
||||||
am_display_PYTHON=$PYTHON
|
am_display_PYTHON=$PYTHON
|
||||||
else
|
else
|
||||||
# Otherwise, try each interpreter until we find one that satisfies
|
# Otherwise, try each interpreter until we find one that satisfies
|
||||||
@@ -149,6 +148,25 @@ AC_DEFUN([AM_PATH_PYTHON],
|
|||||||
[am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
|
[am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
|
||||||
AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_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:
|
dnl Set up 4 directories:
|
||||||
|
|
||||||
@@ -165,7 +183,14 @@ AC_DEFUN([AM_PATH_PYTHON],
|
|||||||
else
|
else
|
||||||
am_py_prefix=$prefix
|
am_py_prefix=$prefix
|
||||||
fi
|
fi
|
||||||
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`
|
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)"`
|
||||||
case $am_cv_python_pythondir in
|
case $am_cv_python_pythondir in
|
||||||
$am_py_prefix*)
|
$am_py_prefix*)
|
||||||
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
|
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
|
||||||
@@ -200,7 +225,14 @@ AC_DEFUN([AM_PATH_PYTHON],
|
|||||||
else
|
else
|
||||||
am_py_exec_prefix=$exec_prefix
|
am_py_exec_prefix=$exec_prefix
|
||||||
fi
|
fi
|
||||||
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`
|
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)"`
|
||||||
case $am_cv_python_pyexecdir in
|
case $am_cv_python_pyexecdir in
|
||||||
$am_py_exec_prefix*)
|
$am_py_exec_prefix*)
|
||||||
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
|
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
|
||||||
@@ -248,14 +280,12 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
|
|||||||
sys.exit(sys.hexversion < minverhex)"
|
sys.exit(sys.hexversion < minverhex)"
|
||||||
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
|
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
|
||||||
|
|
||||||
# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
|
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; the Free Software Foundation
|
# This file is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy and/or distribute it,
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
# with or without modifications, as long as this notice is preserved.
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
# serial 1
|
|
||||||
|
|
||||||
# AM_RUN_LOG(COMMAND)
|
# AM_RUN_LOG(COMMAND)
|
||||||
# -------------------
|
# -------------------
|
||||||
# Run COMMAND, save the exit status in ac_status, and log it.
|
# Run COMMAND, save the exit status in ac_status, and log it.
|
||||||
|
|||||||
183
configure
vendored
183
configure
vendored
@@ -661,6 +661,7 @@ DNET_BUILD
|
|||||||
DNET_DEPENDS
|
DNET_DEPENDS
|
||||||
LIBDNETDIR
|
LIBDNETDIR
|
||||||
LIBDNET_LIBS
|
LIBDNET_LIBS
|
||||||
|
LIBSSH2_LIBS
|
||||||
PCRE_DIST_CLEAN
|
PCRE_DIST_CLEAN
|
||||||
PCRE_CLEAN
|
PCRE_CLEAN
|
||||||
PCRE_BUILD
|
PCRE_BUILD
|
||||||
@@ -781,6 +782,7 @@ with_nping
|
|||||||
with_openssl
|
with_openssl
|
||||||
with_libpcap
|
with_libpcap
|
||||||
with_libpcre
|
with_libpcre
|
||||||
|
with_libssh2
|
||||||
with_libdnet
|
with_libdnet
|
||||||
with_liblua
|
with_liblua
|
||||||
with_liblinear
|
with_liblinear
|
||||||
@@ -1439,6 +1441,7 @@ Optional Packages:
|
|||||||
--with-libpcre=DIR Use an existing (compiled) pcre lib from DIR/include
|
--with-libpcre=DIR Use an existing (compiled) pcre lib from DIR/include
|
||||||
and DIR/lib.
|
and DIR/lib.
|
||||||
--with-libpcre=included Always use the version included with Nmap
|
--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
|
--with-libdnet=DIR Use an existing (compiled) dnet lib from DIR/include
|
||||||
and DIR/lib. This is NOT RECOMMENDED because we have
|
and DIR/lib. This is NOT RECOMMENDED because we have
|
||||||
made many important fixes to our included libdnet,
|
made many important fixes to our included libdnet,
|
||||||
@@ -5463,8 +5466,8 @@ if test "$with_ndiff" != "no"; then
|
|||||||
|
|
||||||
if test -n "$PYTHON"; then
|
if test -n "$PYTHON"; then
|
||||||
# If the user set $PYTHON, use it and don't search something else.
|
# If the user set $PYTHON, use it and don't search something else.
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 2.4" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 2.4" >&5
|
||||||
$as_echo_n "checking whether $PYTHON version >= 2.4... " >&6; }
|
$as_echo_n "checking whether $PYTHON version is >= 2.4... " >&6; }
|
||||||
prog="import sys
|
prog="import sys
|
||||||
# split strings by '.' and convert to numeric. Append some zeros
|
# split strings by '.' and convert to numeric. Append some zeros
|
||||||
# because we need at least 4 digits for the hex conversion.
|
# because we need at least 4 digits for the hex conversion.
|
||||||
@@ -5482,7 +5485,9 @@ sys.exit(sys.hexversion < minverhex)"
|
|||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
$as_echo "yes" >&6; }
|
$as_echo "yes" >&6; }
|
||||||
else
|
else
|
||||||
as_fn_error $? "too old" "$LINENO" 5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
as_fn_error $? "Python interpreter is too old" "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
am_display_PYTHON=$PYTHON
|
am_display_PYTHON=$PYTHON
|
||||||
else
|
else
|
||||||
@@ -5494,7 +5499,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
|
|||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
else
|
else
|
||||||
|
|
||||||
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
|
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
|
||||||
test "$am_cv_pathless_PYTHON" = none && break
|
test "$am_cv_pathless_PYTHON" = none && break
|
||||||
prog="import sys
|
prog="import sys
|
||||||
# split strings by '.' and convert to numeric. Append some zeros
|
# split strings by '.' and convert to numeric. Append some zeros
|
||||||
@@ -5610,6 +5615,25 @@ $as_echo "$am_cv_python_platform" >&6; }
|
|||||||
PYTHON_PLATFORM=$am_cv_python_platform
|
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
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5
|
||||||
@@ -5623,7 +5647,14 @@ else
|
|||||||
else
|
else
|
||||||
am_py_prefix=$prefix
|
am_py_prefix=$prefix
|
||||||
fi
|
fi
|
||||||
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`
|
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)"`
|
||||||
case $am_cv_python_pythondir in
|
case $am_cv_python_pythondir in
|
||||||
$am_py_prefix*)
|
$am_py_prefix*)
|
||||||
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
|
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
|
||||||
@@ -5660,7 +5691,14 @@ else
|
|||||||
else
|
else
|
||||||
am_py_exec_prefix=$exec_prefix
|
am_py_exec_prefix=$exec_prefix
|
||||||
fi
|
fi
|
||||||
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`
|
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)"`
|
||||||
case $am_cv_python_pyexecdir in
|
case $am_cv_python_pyexecdir in
|
||||||
$am_py_exec_prefix*)
|
$am_py_exec_prefix*)
|
||||||
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
|
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
|
||||||
@@ -5732,8 +5770,8 @@ if test "$with_zenmap" != "no"; then
|
|||||||
|
|
||||||
if test -n "$PYTHON"; then
|
if test -n "$PYTHON"; then
|
||||||
# If the user set $PYTHON, use it and don't search something else.
|
# If the user set $PYTHON, use it and don't search something else.
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 2.4" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 2.4" >&5
|
||||||
$as_echo_n "checking whether $PYTHON version >= 2.4... " >&6; }
|
$as_echo_n "checking whether $PYTHON version is >= 2.4... " >&6; }
|
||||||
prog="import sys
|
prog="import sys
|
||||||
# split strings by '.' and convert to numeric. Append some zeros
|
# split strings by '.' and convert to numeric. Append some zeros
|
||||||
# because we need at least 4 digits for the hex conversion.
|
# because we need at least 4 digits for the hex conversion.
|
||||||
@@ -5751,7 +5789,9 @@ sys.exit(sys.hexversion < minverhex)"
|
|||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
$as_echo "yes" >&6; }
|
$as_echo "yes" >&6; }
|
||||||
else
|
else
|
||||||
as_fn_error $? "too old" "$LINENO" 5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
as_fn_error $? "Python interpreter is too old" "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
am_display_PYTHON=$PYTHON
|
am_display_PYTHON=$PYTHON
|
||||||
else
|
else
|
||||||
@@ -5763,7 +5803,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
|
|||||||
$as_echo_n "(cached) " >&6
|
$as_echo_n "(cached) " >&6
|
||||||
else
|
else
|
||||||
|
|
||||||
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
|
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
|
||||||
test "$am_cv_pathless_PYTHON" = none && break
|
test "$am_cv_pathless_PYTHON" = none && break
|
||||||
prog="import sys
|
prog="import sys
|
||||||
# split strings by '.' and convert to numeric. Append some zeros
|
# split strings by '.' and convert to numeric. Append some zeros
|
||||||
@@ -5879,6 +5919,25 @@ $as_echo "$am_cv_python_platform" >&6; }
|
|||||||
PYTHON_PLATFORM=$am_cv_python_platform
|
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
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5
|
||||||
@@ -5892,7 +5951,14 @@ else
|
|||||||
else
|
else
|
||||||
am_py_prefix=$prefix
|
am_py_prefix=$prefix
|
||||||
fi
|
fi
|
||||||
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`
|
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)"`
|
||||||
case $am_cv_python_pythondir in
|
case $am_cv_python_pythondir in
|
||||||
$am_py_prefix*)
|
$am_py_prefix*)
|
||||||
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
|
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
|
||||||
@@ -5929,7 +5995,14 @@ else
|
|||||||
else
|
else
|
||||||
am_py_exec_prefix=$exec_prefix
|
am_py_exec_prefix=$exec_prefix
|
||||||
fi
|
fi
|
||||||
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`
|
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)"`
|
||||||
case $am_cv_python_pyexecdir in
|
case $am_cv_python_pyexecdir in
|
||||||
$am_py_exec_prefix*)
|
$am_py_exec_prefix*)
|
||||||
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
|
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
|
||||||
@@ -6667,6 +6740,92 @@ 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
|
have_dnet=no
|
||||||
requested_included_dnet=no
|
requested_included_dnet=no
|
||||||
LIBDNETDIR=libdnet-stripped
|
LIBDNETDIR=libdnet-stripped
|
||||||
|
|||||||
32
configure.ac
32
configure.ac
@@ -509,6 +509,38 @@ AC_SUBST(PCRE_BUILD)
|
|||||||
AC_SUBST(PCRE_CLEAN)
|
AC_SUBST(PCRE_CLEAN)
|
||||||
AC_SUBST(PCRE_DIST_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
|
have_dnet=no
|
||||||
requested_included_dnet=no
|
requested_included_dnet=no
|
||||||
LIBDNETDIR=libdnet-stripped
|
LIBDNETDIR=libdnet-stripped
|
||||||
|
|||||||
@@ -175,6 +175,8 @@
|
|||||||
|
|
||||||
#undef HAVE_PCRE_H
|
#undef HAVE_PCRE_H
|
||||||
|
|
||||||
|
#undef HAVE_LIBSSH2
|
||||||
|
|
||||||
#undef HAVE_PCRE_PCRE_H
|
#undef HAVE_PCRE_PCRE_H
|
||||||
|
|
||||||
#undef BSD_NETWORKING
|
#undef BSD_NETWORKING
|
||||||
|
|||||||
463
nse_libssh2.cc
Normal file
463
nse_libssh2.cc
Normal file
@@ -0,0 +1,463 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
||||||
8
nse_libssh2.h
Normal file
8
nse_libssh2.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef LIBSSH2
|
||||||
|
|
||||||
|
#define LIBSSH2
|
||||||
|
#define LIBSSH2LIBNAME "libssh2"
|
||||||
|
|
||||||
|
LUALIB_API int luaopen_libssh2 (lua_State *L);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "nse_openssl.h"
|
#include "nse_openssl.h"
|
||||||
#include "nse_debug.h"
|
#include "nse_debug.h"
|
||||||
#include "nse_lpeg.h"
|
#include "nse_lpeg.h"
|
||||||
|
#include "nse_libssh2.h"
|
||||||
|
|
||||||
#define NSE_MAIN "NSE_MAIN" /* the main function */
|
#define NSE_MAIN "NSE_MAIN" /* the main function */
|
||||||
|
|
||||||
@@ -545,6 +546,9 @@ static void set_nmap_libraries (lua_State *L)
|
|||||||
{BITLIBNAME, luaopen_bit},
|
{BITLIBNAME, luaopen_bit},
|
||||||
{LFSLIBNAME, luaopen_lfs},
|
{LFSLIBNAME, luaopen_lfs},
|
||||||
{LPEGLIBNAME, luaopen_lpeg},
|
{LPEGLIBNAME, luaopen_lpeg},
|
||||||
|
#ifdef HAVE_LIBSSH2
|
||||||
|
{LIBSSH2LIBNAME, luaopen_libssh2},
|
||||||
|
#endif
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
{OPENSSLLIBNAME, luaopen_openssl},
|
{OPENSSLLIBNAME, luaopen_openssl},
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
71
nselib/libssh2.luadoc
Normal file
71
nselib/libssh2.luadoc
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
--
|
||||||
|
-- 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)
|
||||||
@@ -112,6 +112,12 @@ fetch_host_key = function(host, port)
|
|||||||
end
|
end
|
||||||
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.
|
--- Format a key fingerprint in hexadecimal.
|
||||||
-- @param fingerprint Key fingerprint.
|
-- @param fingerprint Key fingerprint.
|
||||||
-- @param algorithm Key algorithm.
|
-- @param algorithm Key algorithm.
|
||||||
|
|||||||
35
scripts/ssh-auth-methods.nse
Normal file
35
scripts/ssh-auth-methods.nse
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
local shortport = require "shortport"
|
||||||
|
local stdnse = require "stdnse"
|
||||||
|
local libssh2 = 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')
|
||||||
|
|
||||||
|
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
|
||||||
118
scripts/ssh-brute.nse
Normal file
118
scripts/ssh-brute.nse
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
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
|
||||||
|
|
||||||
128
scripts/ssh-vuln-hostkey.nse
Normal file
128
scripts/ssh-vuln-hostkey.nse
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
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
|
||||||
Reference in New Issue
Block a user