首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试用C语言构建SSH蜜罐

尝试用C语言构建SSH蜜罐
EN

Stack Overflow用户
提问于 2013-10-16 22:34:59
回答 1查看 1.2K关注 0票数 0

我正在尝试用C语言编写一个复制SSH会话的蜜罐。我的目标是一个低交互的蜜罐(类似于Kippo)。

其思想是:客户端通过SSH连接到蜜罐,然后蜜罐理解并响应预定义的命令(例如wget、env等)。

我遇到的问题是创建初始SSH连接。我已经通读了SSH的RFC,以了解SSH会话是如何发起的。然后,我一直在研究OpenSSH、libssh和libssh2库--但是我不知道如何启动一个类似sshd的SSH会话。

不确定是否可以使用sshd服务创建SSH会话,然后从中运行蜜罐?

希望这是有意义的。在这方面的任何帮助都将非常感谢。

EN

回答 1

Stack Overflow用户

发布于 2013-10-18 16:50:29

我想我找到了我要找的东西: libssh。在他们的github页面上有一个很好的例子,展示了如何用C:https://github.com/substack/libssh/blob/master/examples/samplesshd.c实现ssh守护进程

对于C语言中基本的SSH蜜罐实现,在github上有一个由Pete Morris (https://github.com/PeteMo/sshpot)提供的名为sshpot的项目:

代码语言:javascript
复制
#include "config.h"
#include "auth.h"

#include <libssh/libssh.h>
#include <libssh/server.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <getopt.h>
#include <errno.h>
#include <sys/wait.h>

#define MINPORT 0
#define MAXPORT 65535

/* Global so they can be cleaned up at SIGINT. */
static ssh_session session;
static ssh_bind sshbind;


/* Print usage information to `stream', exit with `exit_code'. */
static void usage(FILE *stream, int exit_code) {
    fprintf(stream, "Usage: sshpot [-h] [-p <port>]\n");
    fprintf(stream,
            "   -h  --help          Display this usage information.\n"
            "   -p  --port <port>   Port to listen on; defaults to 22.\n");
    exit(exit_code);
}


/* Return the c-string `p' as an int if it is a valid port 
 * in the range of MINPORT - MAXPORT, or -1 if invalid. */
static int valid_port(char *p) {
    int port;
    char *endptr;

    port = strtol(p, &endptr, 10);
    if (port >= MINPORT && port <= MAXPORT && !*endptr && errno == 0) 
        return port;

    return -1;
}


/* Signal handler for cleaning up after children. We want to do cleanup
 * at SIGCHILD instead of waiting in main so we can accept multiple
 * simultaneous connections. */
static int cleanup(void) {
    int status;
    int pid;
    pid_t wait3(int *statusp, int options, struct rusage *rusage);

    while ((pid=wait3(&status, WNOHANG, NULL)) > 0) {
        if (DEBUG) { printf("process %d reaped\n", pid); }
    }

    /* Re-install myself for the next child. */
    signal(SIGCHLD, (void (*)())cleanup);

    return 0;
}


/* SIGINT handler. Cleanup the ssh* objects and exit. */
static void wrapup(void) {
    ssh_disconnect(session);
    ssh_bind_free(sshbind);
    ssh_finalize();
    exit(0);
}


int main(int argc, char *argv[]) {
    int port = DEFAULTPORT;

    /* Handle command line options. */
    int next_opt = 0;
    const char *short_opts = "hp:";
    const struct option long_opts[] = {
        { "help",   0, NULL, 'h' },
        { "port",   1, NULL, 'p' },
        { NULL,     0, NULL, 0   }
    };

    while (next_opt != -1) {
        next_opt = getopt_long(argc, argv, short_opts, long_opts, NULL);
        switch (next_opt) {
            case 'h':
                usage(stdout, 0);
                break;

            case 'p':
                if ((port = valid_port(optarg)) < 0) {
                    fprintf(stderr, "Port must range from %d - %d\n\n", MINPORT, MAXPORT);
                    usage(stderr, 1);
                }
                break;

            case '?':
                usage(stderr, 1);
                break;

            case -1:
                break;

            default:
                fprintf(stderr, "Fatal error, aborting...\n");
                exit(1);
        }
    }

    /* There shouldn't be any other parameters. */
    if (argv[optind]) {
        fprintf(stderr, "Invalid parameter `%s'\n\n", argv[optind]);
        usage(stderr, 1);
    }

    /* Install the signal handlers to cleanup after children and at exit. */
    signal(SIGCHLD, (void (*)())cleanup);
    signal(SIGINT, (void(*)())wrapup);

    /* Create and configure the ssh session. */
    session=ssh_new();
    sshbind=ssh_bind_new();
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, LISTENADDRESS);
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port);
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, "ssh-rsa");
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,RSA_KEYFILE);

    /* Listen on `port' for connections. */
    if (ssh_bind_listen(sshbind) < 0) {
        printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
        return -1;
    }
    if (DEBUG) { printf("Listening on port %d.\n", port); }

    /* Loop forever, waiting for and handling connection attempts. */
    while (1) {
        if (ssh_bind_accept(sshbind, session) == SSH_ERROR) {
            fprintf(stderr, "Error accepting a connection: `%s'.\n",ssh_get_error(sshbind));
            return -1;
        }
        if (DEBUG) { printf("Accepted a connection.\n"); }

        switch (fork())  {
            case -1:
                fprintf(stderr,"Fork returned error: `%d'.\n",-1);
                exit(-1);

            case 0:
                exit(handle_auth(session));

            default:
                break;
        }
    }

    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19406273

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档