~ubuntu-branches/ubuntu/karmic/xprobe/karmic

« back to all changes in this revision

Viewing changes to src/xpmodules/os_probe/icmp_echo_id/icmp_echo_id.cc

  • Committer: Bazaar Package Importer
  • Author(s): Richard Atterer
  • Date: 2005-02-22 22:54:24 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050222225424-6cqy8rr45pkna819
Tags: 0.2.2-1
New upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: icmp_echo_id.cc,v 1.15 2005/02/08 20:00:51 mederchik Exp $ */
 
2
/*
 
3
** Copyright (C) 2001 Fyodor Yarochkin <fygrave@tigerteam.net>,
 
4
**                    Ofir Arkin       <ofir@sys-security.com>
 
5
**
 
6
** This program is free software; you can redistribute it and/or modify
 
7
** it under the terms of the GNU General Public License as published by
 
8
** the Free Software Foundation; either version 2 of the License, or
 
9
** (at your option) any later version.
 
10
**
 
11
**
 
12
** This program is distributed in the hope that it will be useful,
 
13
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
** GNU General Public License for more details.
 
16
**
 
17
** You should have received a copy of the GNU General Public License
 
18
** along with this program; if not, write to the Free Software
 
19
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
*/
 
21
 
 
22
 
 
23
 
 
24
#include "xprobe.h"
 
25
#include "usi++/usi++.h"
 
26
#include <signal.h>
 
27
#include <setjmp.h>
 
28
#define _XPROBE_MODULE
 
29
#include "xplib.h"
 
30
#include "xprobe_module.h"
 
31
#include "xprobe_module_param.h"
 
32
#include "xprobe_module_hdlr.h"
 
33
#include "interface.h"
 
34
#include "target.h"
 
35
#include "icmp_echo_id.h"
 
36
 
 
37
extern Interface *ui;
 
38
 
 
39
/* initialization function */
 
40
 
 
41
int icmp_echo_id_mod_init(Xprobe_Module_Hdlr *pt, char *nm) {
 
42
 
 
43
    ICMP_Echo_Id_Mod *module = new ICMP_Echo_Id_Mod;
 
44
 
 
45
    module->set_name(nm);
 
46
    xprobe_mdebug(XPROBE_DEBUG_MODULES, "Initializing the ICMP ECHO ID module\n");
 
47
    pt->register_module(module);
 
48
    pt->add_keyword(module->get_id(),"icmp_echo_reply");
 
49
    pt->add_keyword(module->get_id(),"icmp_echo_code");
 
50
    pt->add_keyword(module->get_id(),"icmp_echo_ip_id");
 
51
    pt->add_keyword(module->get_id(),"icmp_echo_tos_bits");
 
52
    pt->add_keyword(module->get_id(),"icmp_echo_df_bit");
 
53
    pt->add_keyword(module->get_id(),"icmp_echo_reply_ttl");
 
54
 
 
55
return OK;
 
56
}
 
57
 
 
58
ICMP_Echo_Id_Mod::ICMP_Echo_Id_Mod(void): Xprobe_Module(XPROBE_MODULE_OSTEST, "fingerprint:icmp_echo","ICMP Echo request fingerprinting module") { 
 
59
    
 
60
    ICMP_Echo_Code_Chk *iecc = new ICMP_Echo_Code_Chk;
 
61
    ICMP_Echo_Id_Chk   *ieic = new ICMP_Echo_Id_Chk;
 
62
    ICMP_Echo_Tos_Chk  *ietc = new ICMP_Echo_Tos_Chk;
 
63
    ICMP_Echo_Df_Bit_Chk *iedbc = new ICMP_Echo_Df_Bit_Chk;
 
64
    ICMP_Echo_Reply_Ttl_Chk *iertc = new ICMP_Echo_Reply_Ttl_Chk;
 
65
    ICMP_Echo_Reply_Check *ierc= new ICMP_Echo_Reply_Check;
 
66
 
 
67
    kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_echo_reply", ierc));
 
68
    kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_echo_code", iecc));
 
69
    kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_echo_ip_id", ieic));
 
70
    kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_echo_tos_bits", ietc));
 
71
    kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_echo_df_bit", iedbc));
 
72
    kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_echo_reply_ttl", iertc));
 
73
    
 
74
    return;
 
75
}
 
76
 
 
77
ICMP_Echo_Id_Mod::~ICMP_Echo_Id_Mod(void) {
 
78
    map <string, Xprobe_Module_Param_ICMP *>::iterator s_i;
 
79
 
 
80
/* free check objects */
 
81
    for (s_i = kwd_chk.begin(); s_i != kwd_chk.end(); s_i++) 
 
82
        delete (*s_i).second;
 
83
    
 
84
}
 
85
 
 
86
int ICMP_Echo_Id_Mod::init(void) {
 
87
 
 
88
    xprobe_debug(XPROBE_DEBUG_MODULES, "%s module initialized\n", get_name());
 
89
    return OK;
 
90
}
 
91
 
 
92
 
 
93
int ICMP_Echo_Id_Mod::exec(Target *tg, OS_Matrix *os) {
 
94
    int ret;
 
95
    
 
96
    xprobe_debug(XPROBE_DEBUG_MODULES, "--%s module has been executed against: %s\n", get_name(),
 
97
            inet_ntoa(tg->get_addr()));
 
98
 
 
99
    current_os = os;
 
100
    ret = do_icmp_ping(tg);
 
101
    
 
102
    if (!ret) return FAIL;
 
103
    return OK;
 
104
}
 
105
 
 
106
int ICMP_Echo_Id_Mod::fini(void) {
 
107
    xprobe_debug(XPROBE_DEBUG_MODULES, "%s module has been deinitilized\n", get_name());
 
108
    return OK;
 
109
}
 
110
 
 
111
void ICMP_Echo_Id_Mod::sig_insert(int os_id, int val) {
 
112
 
 
113
    if (sig.find(os_id) != sig.end()) {
 
114
        ui->msg("OS %i - duplicate signature\n", os_id);
 
115
        return;
 
116
    }
 
117
    sig.insert(pair <int, int>(os_id, val));
 
118
 
 
119
}
 
120
 
 
121
void ICMP_Echo_Id_Mod::sig_ttl_insert(int os_id, int val) {
 
122
 
 
123
    if (sig_ttl.find(os_id) != sig_ttl.end()) {
 
124
        ui->msg("OS %i - dublicate signature\n", os_id);
 
125
        return;
 
126
    }
 
127
 
 
128
    sig_ttl.insert(pair <int, int>(os_id, val));
 
129
 
 
130
}
 
131
 
 
132
 
 
133
 
 
134
 
 
135
int ICMP_Echo_Id_Mod::parse_keyword(int os_id, const char *kwd, const char *val)  {
 
136
        map <string, Xprobe_Module_Param_ICMP *>::iterator s_i;
 
137
 
 
138
    xprobe_debug(XPROBE_DEBUG_SIGNATURES, "Parsing for %i : %s  = %s\n",
 
139
                                                        os_id,  kwd, val);
 
140
        if ((s_i=kwd_chk.find(kwd)) != kwd_chk.end()) {
 
141
            return((*s_i).second->parse_param(os_id, val));
 
142
        }
 
143
    ui->msg("Ooops..none matched %s %s\n", kwd, val);   
 
144
    return FAIL;
 
145
 
 
146
};
 
147
 
 
148
int ICMP_Echo_Id_Mod::do_icmp_ping(Target *tg) {
 
149
 
 
150
    char buf[1024];
 
151
    struct timeval tv;
 
152
    int ret;
 
153
    int done;
 
154
    unsigned short int icmpp_id;
 
155
    struct in_addr local, remote;
 
156
    map <string, Xprobe_Module_Param_ICMP *>::iterator s_i;
 
157
 
 
158
/* our lamyer randomizer ;-p */
 
159
    srand(time(NULL));
 
160
    icmpp_id = rand();
 
161
    local = tg->get_interface_addr();
 
162
        remote = tg->get_addr();
 
163
 
 
164
    ICMP icmpp(inet_ntoa(remote));
 
165
    ICMP sn(inet_ntoa(local));
 
166
    sn.init_device(tg->get_interface(), 0, 1500);
 
167
 
 
168
    tv = tg->get_rtt();
 
169
 
 
170
    icmpp.set_src(inet_ntoa(tg->get_interface_addr()));
 
171
        // set ip id now, instead of letting os do that
 
172
        // since we need get_id() to return sent ip id
 
173
        icmpp.set_id(rand());
 
174
        icmpp.set_seq(256);
 
175
    icmpp.set_icmpId(icmpp_id);
 
176
    icmpp.set_type(ICMP_ECHO);
 
177
    icmpp.set_code(123); /* our test with non-0 icmp code */
 
178
    icmpp.set_tos(6);
 
179
    icmpp.set_fragoff(IP_DF);
 
180
    fflush(stderr);
 
181
    ret = -1;
 
182
    
 
183
    icmpp.timeout(tv);
 
184
    sn.timeout(tv);
 
185
        ret = icmpp.send_ping_payload();
 
186
    done = 0;
 
187
    while (!done) {
 
188
        ret = sn.sniffpack(buf, sizeof(buf));
 
189
        /* packet response */
 
190
//        if (ret > 0 && sn.get_src() != local.s_addr 
 
191
        if (!sn.timeout() && sn.get_src() == remote.s_addr && 
 
192
                        sn.get_type() == ICMP_ECHOREPLY && sn.get_icmpId() == icmpp_id) {
 
193
                        done = 1;
 
194
                        xprobe_debug(XPROBE_DEBUG_MODULES, "[%s] Received reply.\n", get_name());
 
195
                }
 
196
//        if (ret < 1) done = 1; /* timeout */    
 
197
        if (sn.timeout()) {
 
198
                        done = 1; /* timeout */    
 
199
                        xprobe_debug(XPROBE_DEBUG_MODULES, "[%s] Timed out, no reply received.\n", get_name());
 
200
                }
 
201
    }
 
202
    
 
203
    if (! sn.timeout()) {
 
204
        for (s_i = kwd_chk.begin(); s_i != kwd_chk.end(); s_i++) 
 
205
            ((*s_i).second->check_param(&sn, &icmpp, current_os));
 
206
        
 
207
                if (tg->generate_sig())
 
208
                        generate_signature(tg, &sn, &icmpp);
 
209
        return OK;
 
210
    }
 
211
    return FAIL;
 
212
 
 
213
}
 
214
 
 
215
void ICMP_Echo_Id_Mod::generate_signature(Target *tg, ICMP *pack, ICMP *orig) {
 
216
        string keyword, value;
 
217
        unsigned int ttl;
 
218
/*
 
219
#       icmp_echo_code = [0, !0]
 
220
#       icmp_echo_ip_id = [0, !0, SENT]
 
221
#       icmp_echo_tos_bits = [0, !0]
 
222
#       icmp_echo_df_bit = [0, 1]
 
223
#       icmp_echo_reply_ttl = [>< decimal num]
 
224
*/
 
225
        if (!pack->timeout()) {
 
226
                tg->signature("icmp_echo_reply", "y");
 
227
                keyword = "icmp_echo_code";
 
228
                if (pack->get_code() == 0)
 
229
                        value="0";
 
230
                else 
 
231
                        value="!0";
 
232
                tg->signature(keyword, value);
 
233
                keyword= "icmp_echo_ip_id";
 
234
                if (pack->get_id() == 0)
 
235
                        value = "0";
 
236
                else if (pack->get_id() == orig->get_id())
 
237
                        value = "SENT";
 
238
                else
 
239
                        value = "!0";
 
240
                tg->signature(keyword, value);
 
241
                keyword= "icmp_echo_tos_bits";
 
242
                if (pack->get_tos() == 0)
 
243
                        value="0";
 
244
                else 
 
245
                        value="!0";
 
246
                tg->signature(keyword, value);
 
247
                keyword = "icmp_echo_df_bit";
 
248
                if (pack->get_fragoff() & IP_DF)
 
249
                        value = "1";
 
250
                else 
 
251
                        value ="0";     
 
252
                tg->signature(keyword, value);
 
253
                keyword = "icmp_echo_reply_ttl";
 
254
                ttl = pack->get_ttl() + tg->get_distance();
 
255
                value = "<";
 
256
                if (ttl <= 32)
 
257
                        value.append("32");
 
258
                else if (ttl <= 64)
 
259
                        value.append("64");
 
260
                else if (ttl <= 128)
 
261
                        value.append("128");
 
262
                else if (ttl <= 255)
 
263
                        value.append("255");
 
264
                tg->signature(keyword, value);
 
265
        } else {
 
266
                tg->signature("# No ICMP Echo reply received", "");
 
267
                tg->signature("icmp_echo_reply", "n");
 
268
                tg->signature("icmp_echo_code", "");
 
269
                tg->signature("icmp_echo_ip_id", "");
 
270
                tg->signature("icmp_echo_tos_bits","");
 
271
                tg->signature("icmp_echo_df_bit", "");
 
272
                tg->signature("icmp_echo_reply_ttl", "");
 
273
        }
 
274
        
 
275
 
 
276
}
 
277
 
 
278
 
 
279
int ICMP_Echo_Code_Chk::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
 
280
 
 
281
   xprobe_debug(XPROBE_DEBUG_MODULES, "ICMP ECHO code %i\n", ip_pkt->get_code());
 
282
   return (add_param(ip_pkt->get_code(),orig_pkt->get_code(), os));
 
283
}
 
284
 
 
285
int ICMP_Echo_Id_Chk::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
 
286
 
 
287
   xprobe_debug(XPROBE_DEBUG_MODULES, "ICMP ip id %i\n", ip_pkt->get_id());
 
288
   return (add_param(ip_pkt->get_id(), orig_pkt->get_id(), os));
 
289
}
 
290
 
 
291
int ICMP_Echo_Tos_Chk::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
 
292
 
 
293
   xprobe_debug(XPROBE_DEBUG_MODULES, "ICMP ip tos 0x%x\n", ip_pkt->get_tos());
 
294
   return (add_param(ip_pkt->get_tos(), orig_pkt->get_tos(), os));
 
295
}
 
296
 
 
297
 
 
298
int ICMP_Echo_Df_Bit_Chk::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
 
299
 
 
300
   xprobe_debug(XPROBE_DEBUG_MODULES, "ICMP ip df %i\n",
 
301
                        (ip_pkt->get_fragoff() & IP_DF) !=0?1:0);
 
302
   return (add_param(((ip_pkt->get_fragoff() & IP_DF) != 0), ((orig_pkt->get_fragoff() & IP_DF) != 0), os));
 
303
}
 
304
 
 
305
int ICMP_Echo_Reply_Ttl_Chk::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
 
306
 
 
307
   xprobe_debug(XPROBE_DEBUG_MODULES, "ICMP ip ttl %i",  ip_pkt->get_ttl());
 
308
   return (add_param(ip_pkt->get_ttl(), orig_pkt->get_ttl(), os));
 
309
}
 
310
 
 
311
int ICMP_Echo_Reply_Check::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
 
312
        int gotp=ip_pkt->timeout() ? 0 : 1;
 
313
        // suspend warning
 
314
        orig_pkt->timeout();
 
315
        add_param(gotp, 0, os);
 
316
        if (!gotp) {
 
317
                gen_match(5, os);
 
318
        }
 
319
        return OK;
 
320
}