1
2 /*
3 libssh is available at http://www.libssh.org
4 current version is 0.4.8
5 If you want support for ssh v1 protocol, you
6 have to add option -DWITH_SSH1=On in the cmake
7 */
8
9 #include "hydra-mod.h"
10 #ifndef LIBSSH
dummy_sshkey()11 void dummy_sshkey() { printf("\n"); }
12 #else
13
14 #include <libssh/libssh.h>
15
16 #if LIBSSH_VERSION_MAJOR >= 0 && LIBSSH_VERSION_MINOR >= 4
17
18 extern ssh_session session;
19 extern char *HYDRA_EXIT;
20 extern int32_t new_session;
21
start_sshkey(int32_t s,char * ip,int32_t port,unsigned char options,char * miscptr,FILE * fp)22 int32_t start_sshkey(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
23 char *empty = "";
24 char *login, *key, keep_login[300];
25 int32_t auth_state = 0, rc = 0;
26 ssh_private_key privkey;
27
28 if (strlen(login = hydra_get_next_login()) == 0)
29 login = empty;
30 if (strlen(key = hydra_get_next_password()) == 0)
31 key = empty;
32
33 if (new_session) {
34 if (session) {
35 ssh_disconnect(session);
36 ssh_finalize();
37 ssh_free(session);
38 }
39
40 session = ssh_new();
41 ssh_options_set(session, SSH_OPTIONS_PORT, &port);
42 ssh_options_set(session, SSH_OPTIONS_HOST, hydra_address2string(ip));
43 ssh_options_set(session, SSH_OPTIONS_USER, login);
44 ssh_options_set(session, SSH_OPTIONS_COMPRESSION_C_S, "none");
45 ssh_options_set(session, SSH_OPTIONS_COMPRESSION_S_C, "none");
46 if (ssh_connect(session) != 0) {
47 // if the connection was drop, exit and let hydra main handle it
48 if (verbose)
49 hydra_report(stderr, "[ERROR] could not connect to target port %d\n", port);
50 return 3;
51 }
52
53 if ((rc = ssh_userauth_none(session, NULL)) == SSH_AUTH_ERROR) {
54 return 3;
55 } else if (rc == SSH_AUTH_SUCCESS) {
56 hydra_report_found_host(port, ip, "sshkey", fp);
57 hydra_completed_pair_found();
58 if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
59 return 2;
60 else
61 return 1;
62 }
63 } else
64 new_session = 1;
65
66 auth_state = ssh_auth_list(session);
67 if ((auth_state & SSH_AUTH_METHOD_PUBLICKEY) > 0) {
68 privkey = privatekey_from_file(session, key, 0, NULL);
69 if (!privkey) {
70 hydra_report(stderr, "[ERROR] skipping invalid private key: \"%s\"\n", key);
71 hydra_completed_pair();
72 if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
73 return 2;
74
75 return 1;
76 }
77 auth_state = ssh_userauth_pubkey(session, NULL, NULL, privkey);
78 } else {
79 return 4;
80 }
81
82 if (auth_state == SSH_AUTH_ERROR) {
83 new_session = 1;
84 return 1;
85 }
86
87 if (auth_state == SSH_AUTH_SUCCESS || auth_state == SSH_AUTH_PARTIAL) {
88 hydra_report_found_host(port, ip, "sshkey", fp);
89 hydra_completed_pair_found();
90 if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
91 return 2;
92 return 1;
93 } else {
94 strncpy(keep_login, login, sizeof(keep_login) - 1);
95 keep_login[sizeof(keep_login) - 1] = '\0';
96 hydra_completed_pair();
97 if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
98 return 2;
99 login = hydra_get_next_login();
100 if (strcmp(login, keep_login) == 0)
101 new_session = 0;
102 return 1;
103 }
104
105 /* not reached */
106 return 1;
107 }
108
service_sshkey(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname)109 void service_sshkey(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
110 int32_t run = 1, next_run = 1, sock = -1;
111
112 hydra_register_socket(sp);
113 if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
114 return;
115 while (1) {
116 switch (run) {
117 case 1: /* connect and service init function */
118 next_run = start_sshkey(sock, ip, port, options, miscptr, fp);
119 break;
120 case 2:
121 ssh_disconnect(session);
122 ssh_finalize();
123 ssh_free(session);
124 hydra_child_exit(0);
125 break;
126 case 3:
127 ssh_disconnect(session);
128 ssh_finalize();
129 ssh_free(session);
130 fprintf(stderr, "[ERROR] ssh protocol error\n");
131 hydra_child_exit(2);
132 break;
133 case 4:
134 ssh_disconnect(session);
135 ssh_finalize();
136 ssh_free(session);
137 fprintf(stderr, "[ERROR] ssh target does not support pubkey auth\n");
138 hydra_child_exit(2);
139 break;
140 default:
141 ssh_disconnect(session);
142 ssh_finalize();
143 ssh_free(session);
144 hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n");
145 hydra_child_exit(2);
146 }
147 run = next_run;
148 }
149 }
150 #else
151 #error "You are not using at least v0.4.x. Download from http://www.libssh.org and add -DWITH_SSH1=On in cmake to enable SSH v1 support"
152 #endif
153 #endif
154
service_sshkey_init(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname)155 int32_t service_sshkey_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
156 // called before the childrens are forked off, so this is the function
157 // which should be filled if initial connections and service setup has to be
158 // performed once only.
159 //
160 // fill if needed.
161 //
162 // return codes:
163 // 0 all OK
164 // -1 error, hydra will exit, so print a good error message here
165
166 return 0;
167 }
168
usage_sshkey(const char * service)169 void usage_sshkey(const char *service) {
170 printf("Module sshkey does not provide additional options, although the "
171 "semantic for\n"
172 "options -p and -P is changed:\n"
173 " -p expects a path to an unencrypted private key in PEM format.\n"
174 " -P expects a filename containing a list of path to some unencrypted\n"
175 " private keys in PEM format.\n\n");
176 }
177