Suggestion: SSHD pseudo/fake mode. Source available.
Daniel Kastenholz
daniel.kastenholz at in.tum.de
Sat Feb 26 04:50:22 EST 2005
Hi,
- context: yesterday I suggested a command line option for sshd that
turns the daemon into a fake (or pseudo) daemon to listen on port 22
while denying all logins even if the provided passwords are right. The
reason for this suggestion was the increasing number of brute force
attacks against SSH daemons and the wish to provide intruders a
playground where they can waste their time while being monitored and
without the chance to actually break anything.
I received a couple of replies and there seems to be interest in such an
option. As requested, I have now run a diff against the modified sources
(originally 3.9p1). The whole patch needs about 30 lines including
comments. It adds a command line option '-T' to sshd for enabling the
trap mode. The output of the diff follows at the end of this message.
Hope this helps.
If you have any further remarks, suggestions, questions ... just drop me
a line. I assume the patch could be modified to use even less lines, but
it works like this.
Do I have to file this diff anywhere else to make the patch request
official?
Regards,
Daniel
--------------------
diff --context=3 openssh-3.9p1/auth.h modified/auth.h
*** openssh-3.9p1/auth.h Mon May 24 02:36:23 2004
--- modified/auth.h Wed Feb 23 16:41:51 2005
***************
*** 50,55 ****
--- 50,56 ----
int success;
int postponed; /* authentication needs another step */
int valid; /* user exists and is allowed to login */
+ int trap; /* enforces login denial in trap mode */
int attempt;
int failures;
int force_pwchange;
diff --context=3 openssh-3.9p1/auth1.c modified/auth1.c
*** openssh-3.9p1/auth1.c Thu Aug 12 14:40:25 2004
--- modified/auth1.c Wed Feb 23 16:35:22 2005
***************
*** 74,80 ****
authctxt->valid ? "" : "invalid user ", authctxt->user);
/* If the user has no password, accept authentication immediately. */
! if (options.password_authentication &&
#ifdef KRB5
(!options.kerberos_authentication ||
options.kerberos_or_local_passwd) &&
#endif
--- 74,80 ----
authctxt->valid ? "" : "invalid user ", authctxt->user);
/* If the user has no password, accept authentication immediately. */
! if (authctxt->trap==0 && options.password_authentication &&
#ifdef KRB5
(!options.kerberos_authentication ||
options.kerberos_or_local_passwd) &&
#endif
***************
*** 142,148 ****
BN_num_bits(client_host_key->rsa->n), bits);
packet_check_eom();
! authenticated = auth_rhosts_rsa(authctxt, client_user,
client_host_key);
key_free(client_host_key);
--- 142,148 ----
BN_num_bits(client_host_key->rsa->n), bits);
packet_check_eom();
! authenticated = (authctxt->trap==0) &&
auth_rhosts_rsa(authctxt, client_user,
client_host_key);
key_free(client_host_key);
***************
*** 159,165 ****
fatal("do_authloop: BN_new failed");
packet_get_bignum(n);
packet_check_eom();
! authenticated = auth_rsa(authctxt, n);
BN_clear_free(n);
break;
--- 159,165 ----
fatal("do_authloop: BN_new failed");
packet_get_bignum(n);
packet_check_eom();
! authenticated = (authctxt->trap==0) && auth_rsa(authctxt, n);
BN_clear_free(n);
break;
***************
*** 177,183 ****
packet_check_eom();
/* Try authentication with the password. */
! authenticated = PRIVSEP(auth_password(authctxt, password));
memset(password, 0, strlen(password));
xfree(password);
--- 177,183 ----
packet_check_eom();
/* Try authentication with the password. */
! authenticated = (authctxt->trap==0) &&
PRIVSEP(auth_password(authctxt, password));
memset(password, 0, strlen(password));
xfree(password);
***************
*** 203,209 ****
if (options.challenge_response_authentication == 1) {
char *response = packet_get_string(&dlen);
packet_check_eom();
! authenticated = verify_response(authctxt, response);
memset(response, 'r', dlen);
xfree(response);
}
--- 203,209 ----
if (options.challenge_response_authentication == 1) {
char *response = packet_get_string(&dlen);
packet_check_eom();
! authenticated = (authctxt->trap==0) &&
verify_response(authctxt, response);
memset(response, 'r', dlen);
xfree(response);
}
diff --context=3 openssh-3.9p1/auth2.c modified/auth2.c
*** openssh-3.9p1/auth2.c Thu Aug 12 14:40:25 2004
--- modified/auth2.c Wed Feb 23 16:35:23 2005
***************
*** 210,215 ****
--- 210,218 ----
fatal("INTERNAL ERROR: authenticated invalid user %s",
authctxt->user);
+ /* Deny login if in trap mode */
+ if (authctxt->trap!=0) authenticated = 0;
+
/* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(method))
Common subdirectories: openssh-3.9p1/contrib and modified/contrib
Common subdirectories: openssh-3.9p1/openbsd-compat and
modified/openbsd-compat
Common subdirectories: openssh-3.9p1/regress and modified/regress
Common subdirectories: openssh-3.9p1/scard and modified/scard
diff --context=3 openssh-3.9p1/sshd.c modified/sshd.c
*** openssh-3.9p1/sshd.c Thu Aug 12 15:08:15 2004
--- modified/sshd.c Wed Feb 23 17:14:34 2005
***************
*** 125,130 ****
--- 125,137 ----
*/
int debug_flag = 0;
+ /*
+ * Trap mode flag. In this mode, the entire authentication procedure
+ * takes place, but the login always fails. The purpose of this flag
+ * is to enable the setup of fake servers for intrusion detection.
+ */
+ int trap_flag = 0;
+
/* Flag indicating that the daemon should only test the configuration
and keys. */
int test_flag = 0;
***************
*** 776,782 ****
fprintf(stderr, "%s, %s\n",
SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
fprintf(stderr,
! "usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g
login_grace_time]\n"
" [-h host_key_file] [-k key_gen_time] [-o option] [-p
port] [-u len]\n"
);
exit(1);
--- 783,789 ----
fprintf(stderr, "%s, %s\n",
SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
fprintf(stderr,
! "usage: sshd [-46DdeiqtT] [-b bits] [-f config_file] [-g
login_grace_time]\n"
" [-h host_key_file] [-k key_gen_time] [-o option] [-p
port] [-u len]\n"
);
exit(1);
***************
*** 918,924 ****
initialize_server_options(&options);
/* Parse command-line arguments. */
! while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) {
switch (opt) {
case '4':
IPv4or6 = AF_INET;
--- 925,931 ----
initialize_server_options(&options);
/* Parse command-line arguments. */
! while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46T")) != -1) {
switch (opt) {
case '4':
IPv4or6 = AF_INET;
***************
*** 929,934 ****
--- 936,944 ----
case 'f':
config_file_name = optarg;
break;
+ case 'T':
+ trap_flag = 1;
+ break;
case 'd':
if (debug_flag == 0) {
debug_flag = 1;
***************
*** 1675,1680 ****
--- 1685,1693 ----
authctxt = xmalloc(sizeof(*authctxt));
memset(authctxt, 0, sizeof(*authctxt));
+ /* set trap indicator if in trap mode */
+ if (trap_flag != 0) authctxt->trap = 1;
+
/* XXX global for cleanup, access from other modules */
the_authctxt = authctxt;
More information about the openssh-unix-dev
mailing list