1 |
// Copyright (C) 2003, 2004 Stephane Thiell |
2 |
// |
3 |
// This file is part of pxyscand (from pxys) |
4 |
// |
5 |
// This program is free software; you can redistribute it and/or |
6 |
// modify it under the terms of the GNU General Public License |
7 |
// as published by the Free Software Foundation; either version 2 |
8 |
// of the License, or (at your option) any later version. |
9 |
// |
10 |
// This program is distributed in the hope that it will be useful, |
11 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
// GNU General Public License for more details. |
14 |
// |
15 |
// You should have received a copy of the GNU General Public License |
16 |
// along with this program; if not, write to the Free Software |
17 |
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 |
// |
19 |
#define RCSID "$Id: PXMWingate.cc,v 1.4 2006/09/10 22:16:39 spale Exp $" |
20 |
|
21 |
// This class scans for Open Wingate or Cisco (with "cisco" password). |
22 |
|
23 |
#define WINGATE_SHORTNAME "WinGate" |
24 |
#define CISCO_SHORTNAME "Cisco" |
25 |
|
26 |
#define WINGATE_DESCR "Insecure WinGate server" |
27 |
#define CISCO_DESCR "Insecure Cisco router" |
28 |
|
29 |
#define WINGATE_PORT 23 |
30 |
#define CISCO_PORT WINGATE_PORT |
31 |
|
32 |
#define MAX_LINES_TRY 30 |
33 |
#define CRLF "\r\n" |
34 |
|
35 |
#include "PXMWingate.h" |
36 |
#include <iostream> |
37 |
#include <cassert> |
38 |
#include <cerrno> |
39 |
#include <cstring> |
40 |
#include <arpa/inet.h> |
41 |
#include <opas/opas.h> |
42 |
|
43 |
#include "PXSecret.h" |
44 |
|
45 |
using std::clog; |
46 |
using std::endl; |
47 |
|
48 |
uint32_t PXMWingate::sConnCount = 0; |
49 |
uint32_t PXMWingate::sProxyCount1 = 0; |
50 |
uint32_t PXMWingate::sProxyCount2 = 0; |
51 |
|
52 |
PXMWingate::PXMWingate(PXScan *inScan) |
53 |
: PXScanModule(inScan), mStream(NULL), mCiscoRequest(false), mLinesTry(0) |
54 |
{ |
55 |
} |
56 |
|
57 |
PXMWingate::~PXMWingate() |
58 |
{ |
59 |
} |
60 |
|
61 |
void |
62 |
PXMWingate::InitModule() |
63 |
{ |
64 |
RegisterPXM(WINGATE_SHORTNAME, WINGATE_PORT, &sConnCount, &sProxyCount1); |
65 |
RegisterPXM(CISCO_SHORTNAME, CISCO_PORT, &sConnCount, &sProxyCount2); |
66 |
} |
67 |
|
68 |
bool |
69 |
PXMWingate::StartScan() |
70 |
{ |
71 |
peak_task task = peak_task_self(); |
72 |
|
73 |
sockaddr_in sin; |
74 |
memset(&sin, 0, sizeof(sockaddr_in)); |
75 |
sin.sin_family = AF_INET; |
76 |
sin.sin_addr = this->GetAddress(); |
77 |
sin.sin_port = htons(WINGATE_PORT); |
78 |
|
79 |
mStream = peak_stream_socket_create((sockaddr *)&sin, sizeof(sin), |
80 |
PEAK_STREAM_OPT_DEFAULT, |
81 |
EventCallback, |
82 |
this); |
83 |
|
84 |
if (!mStream) |
85 |
return false; |
86 |
|
87 |
if (this->IsLocalAddressSet()) |
88 |
{ |
89 |
sockaddr_in local_sin; |
90 |
memset(&local_sin, 0, sizeof(local_sin)); |
91 |
local_sin.sin_family = AF_INET; |
92 |
local_sin.sin_addr = this->GetLocalAddress(); |
93 |
local_sin.sin_port = htons(0); |
94 |
|
95 |
peak_stream_set_address(mStream, (sockaddr*)&local_sin, sizeof(local_sin)); |
96 |
} |
97 |
|
98 |
/* Set write buffered mode. */ |
99 |
peak_stream_set_buffered(mStream, 1, 2, 512, NULL); |
100 |
|
101 |
/* Enable built-in timeout option, this is so useful here. */ |
102 |
peak_stream_set_timeout(mStream, GetTimeout() / 2 + 1); |
103 |
|
104 |
/* Connect (don't block) */ |
105 |
if (peak_stream_connect(mStream) == -1) |
106 |
{ |
107 |
peak_release(mStream); |
108 |
this->ProxyNotFound(); |
109 |
} |
110 |
else |
111 |
peak_stream_schedule(mStream, task); |
112 |
return true; |
113 |
} |
114 |
|
115 |
void |
116 |
PXMWingate::SendCiscoRequest(peak_stream s) |
117 |
{ |
118 |
in_addr targetAddr = GetTargetAddress(); |
119 |
char uriHostname[16]; |
120 |
int uriPort = GetTargetPort(); |
121 |
|
122 |
inet_ntop(AF_INET, &targetAddr, uriHostname, sizeof(uriHostname)); |
123 |
|
124 |
peak_stream_set_buffered(s, 1, 64, 64*2, NULL); |
125 |
peak_stream_msgbuf_make(s, "cisco" CRLF); |
126 |
peak_stream_msgbuf_make(s, "telnet %s %d" CRLF, uriHostname, uriPort); |
127 |
} |
128 |
|
129 |
void |
130 |
PXMWingate::ProcessEvent(peak_stream s, int type) |
131 |
{ |
132 |
char *line; |
133 |
char winReadBuf[64]; |
134 |
int err; |
135 |
|
136 |
switch (type) |
137 |
{ |
138 |
case PEAK_STREAM_EVT_OPEN: |
139 |
sConnCount++; |
140 |
break; |
141 |
case PEAK_STREAM_EVT_READ: |
142 |
if (!mCiscoRequest) |
143 |
{ |
144 |
memset(winReadBuf, 0, sizeof(winReadBuf)); |
145 |
if (peak_stream_read(s, winReadBuf, sizeof(winReadBuf)) > 0) |
146 |
{ |
147 |
if (!strncmp(winReadBuf, "WinGate>", 8) |
148 |
|| !strncmp(winReadBuf, "Too m", 5)) |
149 |
{ |
150 |
sProxyCount1++; |
151 |
#if 0 |
152 |
clog << "PXMWingate::ProcessEvent: proxy found: " |
153 |
<< winReadBuf << endl; |
154 |
#endif |
155 |
peak_release(s); |
156 |
this->ProxyFound(OPAS_PROXY_TYPE_WINGATE, WINGATE_PORT, |
157 |
WINGATE_DESCR); |
158 |
return; /* we are done */ |
159 |
} |
160 |
} |
161 |
if (mLinesTry++ < MAX_LINES_TRY) |
162 |
break; |
163 |
} |
164 |
else |
165 |
{ |
166 |
line = peak_stream_get_line(s); |
167 |
|
168 |
if (ScannerSha256StringCheck(line,strlen(line),GetTargetSecret())) |
169 |
{ |
170 |
sProxyCount2++; |
171 |
peak_release(s); |
172 |
this->ProxyFound(OPAS_PROXY_TYPE_CISCOROUTER, CISCO_PORT, |
173 |
CISCO_DESCR); |
174 |
return; /* done! */ |
175 |
} |
176 |
else if (mLinesTry++ < MAX_LINES_TRY) |
177 |
break; |
178 |
} |
179 |
/* fall through */ |
180 |
case PEAK_STREAM_EVT_END: |
181 |
this->ProxyNotFound(); |
182 |
peak_release(s); |
183 |
break; |
184 |
|
185 |
case PEAK_STREAM_EVT_ERROR: |
186 |
err = peak_stream_get_error(s); |
187 |
if (err == ENETUNREACH || err == EHOSTUNREACH) |
188 |
this->ScanError(OPAS_ERROR_NETUNREACH); // Can't scan ! |
189 |
else if (err == ENETDOWN || err == EHOSTDOWN) |
190 |
this->ScanError(OPAS_ERROR_NETDOWN); // Even worst ! |
191 |
else |
192 |
this->ProxyNotFound(); |
193 |
peak_release(s); |
194 |
break; |
195 |
|
196 |
case PEAK_STREAM_EVT_TIMEDOUT: |
197 |
if (!mCiscoRequest && peak_stream_is_open(s)) |
198 |
{ |
199 |
mCiscoRequest = true; |
200 |
peak_stream_set_linemode(s); |
201 |
peak_stream_set_timeout(s, GetTimeout()); |
202 |
this->SendCiscoRequest(s); |
203 |
} |
204 |
else |
205 |
{ |
206 |
this->ProxyNotFound(); |
207 |
peak_release(s); |
208 |
} |
209 |
break; |
210 |
default: |
211 |
break; |
212 |
} |
213 |
} |
214 |
|
215 |
void |
216 |
PXMWingate::EventCallback(peak_stream s, int type, void *context) |
217 |
{ |
218 |
PXMWingate *pxm = reinterpret_cast<PXMWingate*>(context); |
219 |
pxm->ProcessEvent(s, type); |
220 |
} |