Advertisement
skygear

Fake - SSHD

Feb 14th, 2012
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.34 KB | None | 0 0
  1. /*
  2.  *  This program is free software; you can redistribute it and/or modify
  3.  *  it under the terms of the GNU General Public License as published by
  4.  *  the Free Software Foundation; either version 2 of the License, or
  5.  *  (at your option) any later version.
  6.  *
  7.  *  This program is distributed in the hope that it will be useful,
  8.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *  GNU Library General Public License for more details.
  11.  *
  12.  *
  13.  * Author:
  14.  *       NAME:   Arif S AKA Skygear
  15.  *       WWW:    http://seclist.wordpress.com/
  16.  *
  17.  */
  18.  
  19.  
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <errno.h>
  25. #include <signal.h>
  26. #include <syslog.h>
  27.  
  28. #include <arpa/inet.h>
  29. #include <netinet/in.h>
  30.  
  31. #include <sys/types.h>
  32. #include <sys/wait.h>
  33. #include <sys/socket.h>
  34.  
  35. #include <libssh/libssh.h>
  36. #include <libssh/server.h>
  37.  
  38.  
  39. int use_syslog = 0;
  40. int verbose = 0;
  41.  
  42. void logger(const char *fmt, ...) {
  43.     va_list ap;
  44.     va_start(ap, fmt);
  45.     vprintf(fmt, ap);
  46.     printf("\n");
  47.  
  48.     if (use_syslog)
  49.         vsyslog(LOG_NOTICE, fmt, ap);
  50.  
  51.     va_end(ap);
  52. }
  53.  
  54. void handle_sigchild(int signum) {
  55.     int status = -1;
  56.     int pid = 0;
  57.  
  58.     do {
  59.         int pid = waitpid(-1, &status, WNOHANG);
  60.         if (verbose > 0)
  61.             logger("Process %d Exited", pid);
  62.     } while(pid > 0);
  63. }
  64.  
  65. void print_help(FILE *fp, char *app) {
  66.  
  67.     fprintf(fp, "Usage: %s [<options>]\n", app);
  68.     fprintf(fp, "\n");
  69.     fprintf(fp, "\t-a   <secs>  Failed Auth delay\n");
  70.     fprintf(fp, "\t-b   <str>   Set the banner\n");
  71.     fprintf(fp, "\t-h       Print this help and exit\n");
  72.     fprintf(fp, "\t-m   <n>     Max attempts per connection\n");
  73.     fprintf(fp, "\t-p   <port>  Port to listen on\n");
  74.     fprintf(fp, "\t-r   <file>  Path to rsa key\n");
  75.     fprintf(fp, "\t-d   <file>  Path to dsa key\n");
  76.     fprintf(fp, "\t-s       Log to syslog\n");
  77.     fprintf(fp, "\t-t   <secs>  Timeout\n");
  78.     fprintf(fp, "\t-v       Verbose. Repeat for more info\n");
  79.     fprintf(fp, "\t-w   <secs>  Delay after connection\n");
  80.     fprintf(fp, "\t-z       Multiple Delay by 2 each failure\n");
  81.     fprintf(fp, "\n");
  82. }
  83.  
  84. int main(int argc, char **argv) {
  85.     ssh_bind sshbind;
  86.     ssh_session session;
  87.     int r = -1;
  88.     int auth = 0;
  89.     int c;
  90.     int delay = 0;
  91.     char *port = "22";
  92.     char *dsakey = "/home/james/etc/ssh/ssh_host_dsa_key";
  93.     char *rsakey = "/home/james/etc/ssh/ssh_host_rsa_key";
  94.     char *banner = 0;
  95.     int timeout = 0;
  96.     int authdelay = 0;
  97.     int doubledelay = 0;
  98.     int maxfail = 0;
  99.  
  100.     while( (c = getopt(argc, argv, "a:b:hm:p:r:d:st:vw:z")) != -1) {
  101.         switch(c) {
  102.             case 'a':
  103.                 authdelay = atoi(optarg);
  104.                 break;
  105.             case 'b':
  106.                 banner = optarg;
  107.                 break;
  108.             case 'p':
  109.                 port = optarg;
  110.                 break;
  111.             case 'h':
  112.                 print_help(stdout, argv[0]);
  113.                 exit(EXIT_SUCCESS);
  114.                 break;
  115.             case 'm':
  116.                 maxfail = atoi(optarg);
  117.                 break;
  118.             case 'r':
  119.                 rsakey = optarg;
  120.                 break;
  121.             case 'd':
  122.                 dsakey = optarg;
  123.                 break;
  124.             case 's':
  125.                 use_syslog = 1;
  126.                 break;
  127.             case 't':
  128.                 timeout = atoi(optarg);
  129.                 break;
  130.             case 'v':
  131.                 verbose++;
  132.                 break;
  133.             case 'w':
  134.                 delay = atoi(optarg);
  135.                 break;
  136.             case 'z':
  137.                 doubledelay = 1;
  138.                 break;
  139.             default:
  140.                 break;
  141.         }
  142.     }
  143.  
  144.     if (dsakey == NULL) {
  145.         if (access("/etc/ssh/ssh_host_rsa_key", R_OK) == 0)
  146.             rsakey = "/etc/ssh/ssh_host_rsa_key";
  147.     }
  148.  
  149.     if (rsakey == NULL) {
  150.         if (access("/etc/ssh/ssh_host_dsa_key", R_OK) == 0)
  151.             dsakey = "/etc/ssh/ssh_host_dsa_key";
  152.     }
  153.  
  154.     if (rsakey == NULL || dsakey == NULL) {
  155.         print_help(stderr, argv[0]);
  156.         exit(EXIT_FAILURE);
  157.     }
  158.  
  159.     sshbind = ssh_bind_new();
  160.  
  161.     ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, port);
  162.  
  163.     ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, dsakey);
  164.     ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, rsakey);
  165.  
  166.     if (banner != NULL)
  167.         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BANNER, banner);
  168.  
  169.     if (ssh_bind_listen(sshbind) < 0) {
  170.         logger("Error listening to socket: %s", ssh_get_error(sshbind));
  171.         exit(EXIT_FAILURE);
  172.     }
  173.  
  174.     signal(SIGCHLD, &handle_sigchild);
  175.  
  176. restart:
  177.     session = ssh_new();
  178.  
  179.     if (timeout > 0)
  180.         ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &timeout);
  181.  
  182.     r = ssh_bind_accept(sshbind, session);
  183.  
  184.     if (r == SSH_ERROR) {
  185.         logger("Error accepting connection: %s", ssh_get_error(sshbind));
  186.         goto restart;
  187.     }
  188.  
  189.     int ret = fork();
  190.  
  191.     if (fork < 0) {
  192.         logger("fork: %s", strerror(errno));
  193.         logger("exiting ...");
  194.         exit(EXIT_FAILURE);
  195.     }
  196.    
  197.     int sockfd = ssh_get_fd(session);
  198.     struct sockaddr_in peer;
  199.     socklen_t peer_len = sizeof(peer);
  200.     char *peername = 0;
  201.     int attempts = 0;
  202.  
  203.     if (ret > 0) {
  204.         if (verbose > 0)
  205.             logger("Started Process %d", ret);
  206.         ssh_free(session);
  207.         goto restart;
  208.     }
  209.  
  210.     ret = getpeername(sockfd, (struct sockaddr *) &peer, &peer_len);
  211.     peername = inet_ntoa(peer.sin_addr);
  212.     logger("Connection From %s:%d", peername, peer.sin_port);
  213.  
  214.     if (ssh_handle_key_exchange(session)) {
  215.         logger("ssh_handle_key_exchange: %s", ssh_get_error(session));
  216.         goto error;
  217.     }
  218.  
  219.     do {
  220.         ssh_message message = ssh_message_get(session);
  221.         if (message == NULL)
  222.             break;
  223.  
  224.         switch(ssh_message_type(message)) {
  225.             case SSH_REQUEST_AUTH:
  226.                 switch(ssh_message_subtype(message)) {
  227.                     case SSH_AUTH_METHOD_PASSWORD:
  228.                         attempts++;
  229.                         logger("IP: %s USER: %s PASS: %s", peername, ssh_message_auth_user(message), ssh_message_auth_password(message));
  230.                         if (authdelay > 0)
  231.                             sleep(authdelay);
  232.                         if (doubledelay)
  233.                             authdelay *= 2;
  234.                         if (attempts > maxfail) {
  235.                             if (verbose > 1)
  236.                                 logger("Max failures reached");
  237.                             ssh_message_free(message);
  238.                             goto error;
  239.                         }
  240.                     case SSH_AUTH_METHOD_NONE:
  241.                         if (verbose > 1)
  242.                             logger("AUTH_METHOD_NONE Requested");
  243.                         // break missing on purpose
  244.                     default:
  245.                         if (verbose > 1)
  246.                             logger("REQUEST_AUTH: %d", ssh_message_subtype(message));
  247.                         ssh_message_auth_set_methods(message, SSH_AUTH_METHOD_PASSWORD);
  248.                         ssh_message_reply_default(message);
  249.                         break;
  250.                 }
  251.                 break;
  252.             default:
  253.                 if (verbose > 0)
  254.                     logger("Message Type: %d", ssh_message_type(message));
  255.                 ssh_message_reply_default(message);
  256.                 break;
  257.         }
  258.         ssh_message_free(message);
  259.     } while(auth == 0);
  260.  
  261. error:
  262.     ssh_disconnect(session);
  263.     ssh_free(session);
  264.     ssh_bind_free(sshbind);
  265.     logger("Connection Closed From %s", peername);
  266.  
  267.     return 0;
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement