summaryrefslogtreecommitdiff
path: root/other/guess-who/pubscan.cc
diff options
context:
space:
mode:
Diffstat (limited to 'other/guess-who/pubscan.cc')
-rw-r--r--other/guess-who/pubscan.cc193
1 files changed, 193 insertions, 0 deletions
diff --git a/other/guess-who/pubscan.cc b/other/guess-who/pubscan.cc
new file mode 100644
index 0000000..9a7cd29
--- /dev/null
+++ b/other/guess-who/pubscan.cc
@@ -0,0 +1,193 @@
1/*
2 * Copyright (C) 2003 Sebastian Krahmer.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Sebastian Krahmer.
16 * 4. The name Sebastian Krahmer may not be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32#include <stdio.h>
33#include <unistd.h>
34#include <pthread.h>
35#include <sys/types.h>
36#include <sys/socket.h>
37#include <arpa/inet.h>
38#include <vector>
39#include <errno.h>
40
41#include "ssh.h"
42#include "misc.h"
43#include "thread.h"
44
45using namespace std;
46
47void *try_pubkey(void *);
48static char range[128];
49
50void usage(const char *s)
51{
52 printf("Usage: %s <-n threads> <-l login> <-k pubkeyfile> "
53 "<-r ip-range> [-p port]\n\n", s);
54 exit(1);
55}
56
57
58int main(int argc, char **argv)
59{
60 int c, nthreads = 10, i = 0;
61 thread_data td;
62
63 td.port = 22;
64 td.passwd = false;
65
66 while ((c = getopt(argc, argv, "n:l:k:r:p:P")) != -1) {
67 switch (c) {
68 case 'P':
69 td.passwd = true;
70 break;
71 case 'r':
72 td.host = optarg;
73 snprintf(range, sizeof(range), "%s", optarg);
74 break;
75 case 'l':
76 td.login = optarg;
77 break;
78 case 'k':
79 td.keyfile = optarg;
80 break;
81 case 'p':
82 td.port = atoi(optarg);
83 break;
84 case 'n':
85 nthreads = atoi(optarg);
86 break;
87 default:
88 usage(*argv);
89 }
90 }
91
92 if (td.login.size() == 0 || td.keyfile.size() == 0 ||
93 td.host.size() == 0)
94 usage(*argv);
95
96 vector<pthread_t *> tids(nthreads);
97
98 for (i = 0; i < nthreads; ++i) {
99 pthread_t *tid = new pthread_t;
100 pthread_create(tid, NULL, try_pubkey, &td);
101 tids[i] = tid;
102 }
103 for (i = 0; i < nthreads; ++i) {
104 pthread_join(*tids[i], NULL);
105 delete tids[i];
106 }
107
108 return 0;
109}
110
111
112unsigned int last_ip = 0;
113pthread_mutex_t last_ip_lock = PTHREAD_MUTEX_INITIALIZER;
114pthread_mutex_t cout_lock = PTHREAD_MUTEX_INITIALIZER;
115
116
117void *try_pubkey(void *vp)
118{
119 thread_data *td = (thread_data*)vp;
120 char host[128];
121 struct in_addr in;
122 int fd = -1, r = 0;
123
124 while (1) {
125 SSH2 ssh; // need it here, so it is constructed
126 // in every loop cycle
127 pthread_mutex_lock(&last_ip_lock);
128 last_ip = next_ip(range, last_ip);
129 pthread_mutex_unlock(&last_ip_lock);
130
131 if (last_ip == -1)
132 break;
133 if ((last_ip & 0xff000000) == 0xff000000 ||
134 (last_ip & 0xff000000) == 0)
135 continue;
136
137 memcpy(&in.s_addr, &last_ip, 4);
138 if (inet_ntop(AF_INET, &in, host, sizeof(host)) < 0)
139 continue;
140
141 close(fd);
142 if ((fd = tcp_connect(host, td->port)) < 0) {
143 if (errno != ECONNREFUSED && errno != EINPROGRESS) {
144 cerr<<"Host "<<host<<" dead ("<<strerror(errno)<<")\n";
145 }
146 continue;
147 }
148
149 ssh.set_socket(fd);
150 if (ssh.banner_exchange() < 0) {
151 // cerr<<ssh.why()<<endl;
152 continue;
153 }
154
155 if (ssh.kex_init() < 0) {
156 cerr<<ssh.why()<<endl;
157 continue;
158 }
159 if (ssh.dh_exchange() < 0) {
160 cerr<<ssh.why()<<endl;
161 continue;
162 }
163 if (ssh.newkeys() < 0) {
164 cerr<<ssh.why()<<endl;
165 continue;
166 }
167
168 // Uha! An undocumented feature. Scanning for
169 // login/passwd ;-)
170 if (td->passwd)
171 r=ssh.userauth_passwd(td->login.c_str(),
172 td->keyfile.c_str());
173 else
174 r=ssh.userauth_pubkey(td->login.c_str(),
175 td->keyfile.c_str());
176 if (r < 0) {
177 cerr<<ssh.why()<<endl;
178 break;
179 }
180 pthread_mutex_lock(&cout_lock);
181 cout<<host<<": "<<ssh.banner()<<" ";
182 if (r == 0)
183 cout<<"Yes\n";
184 else
185 cout<<"No\n";
186 pthread_mutex_unlock(&cout_lock);
187
188 close(fd);
189 }
190
191 return NULL;
192}
193