1
/* $Id: icmp_inforeq.cc,v 1.13 2005/02/09 18:36:46 mederchik Exp $ */
3
** Copyright (C) 2001 Fyodor Yarochkin <fygrave@tigerteam.net>,
4
** Ofir Arkin <ofir@sys-security.com>
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.
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.
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.
25
#include "usi++/usi++.h"
28
#define _XPROBE_MODULE
30
#include "xprobe_module.h"
31
#include "xprobe_module_hdlr.h"
32
#include "interface.h"
34
#include "icmp_inforeq.h"
38
/* initialization function */
40
int icmp_inforeq_mod_init(Xprobe_Module_Hdlr *pt, char *nm) {
42
ICMP_Inforeq_Mod *module = new ICMP_Inforeq_Mod;
45
xprobe_mdebug(XPROBE_DEBUG_MODULES, "Initializing the ICMP Inforeq module\n");
46
pt->register_module(module);
47
pt->add_keyword(module->get_id(),"icmp_info_reply");
48
pt->add_keyword(module->get_id(),"icmp_info_reply_ttl");
49
pt->add_keyword(module->get_id(), "icmp_info_reply_ip_id");
54
ICMP_Inforeq_Mod::ICMP_Inforeq_Mod(void):Xprobe_Module(XPROBE_MODULE_OSTEST, "fingerprint:icmp_info","ICMP Information request fingerprinting module") {
56
ICMP_Inforeq_Reply_Check *inforep = new ICMP_Inforeq_Reply_Check;
57
ICMP_Inforeq_Ip_Id_Check *infoid = new ICMP_Inforeq_Ip_Id_Check;
58
ICMP_Inforeq_Ttl_Check *infottl = new ICMP_Inforeq_Ttl_Check;
60
kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_info_reply",inforep));
61
kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_info_reply_ttl",infottl));
62
kwd_chk.insert(pair<string, Xprobe_Module_Param_ICMP *>("icmp_info_reply_ip_id",infoid));
65
ICMP_Inforeq_Mod::~ICMP_Inforeq_Mod(void) {
67
// free allocated classes
68
for (s_i=kwd_chk.begin(); s_i != kwd_chk.end(); s_i++)
73
int ICMP_Inforeq_Mod::init(void) {
75
xprobe_debug(XPROBE_DEBUG_MODULES, "%s module initialized\n", get_name());
80
int ICMP_Inforeq_Mod::exec(Target *tg, OS_Matrix *os) {
82
xprobe_debug(XPROBE_DEBUG_MODULES, "--%s module has been executed against: %s\n", get_name(),
83
inet_ntoa(tg->get_addr()));
91
int ICMP_Inforeq_Mod::fini(void) {
92
xprobe_debug(XPROBE_DEBUG_MODULES, "%s module has been deinitilized\n", get_name());
96
int ICMP_Inforeq_Mod::parse_keyword(int os_id, const char *kwd, const char *val) {
98
xprobe_debug(XPROBE_DEBUG_SIGNATURES, "Parsing for %i : %s = %s\n",
100
if ((s_i=kwd_chk.find(kwd)) != kwd_chk.end()) {
101
return s_i->second->parse_param(os_id, val);
106
int ICMP_Inforeq_Mod::do_icmp_query(Target *tg) {
112
unsigned short int icmpp_id;
113
struct in_addr local, remote;
115
/* our lamyer randomizer ;-p */
118
local = tg->get_interface_addr();
119
remote = tg->get_addr();
121
ICMP icmpp(inet_ntoa(remote));
122
ICMP sn(inet_ntoa(local));
123
sn.init_device(tg->get_interface(), 0, 1500);
127
icmpp.set_src(inet_ntoa(tg->get_interface_addr()));
128
icmpp.set_icmpId(icmpp_id);
129
icmpp.set_type(ICMP_INFO_REQUEST);
135
ret = icmpp.sendpack("");
138
ret = sn.sniffpack(buf, sizeof(buf));
139
/* packet response */
140
// if (ret > 0 && sn.get_src() != local.s_addr
141
if (!sn.timeout() && sn.get_src() == remote.s_addr
142
&& sn.get_type() == ICMP_INFO_REPLY && sn.get_icmpId() == icmpp_id) {
144
xprobe_debug(XPROBE_DEBUG_MODULES, "[%s] Received reply.\n", get_name());
146
// if (ret < 1) done = 1; /* timeout */
149
xprobe_debug(XPROBE_DEBUG_MODULES, "[%s] Timed out, no reply received.\n", get_name());
152
for (s_i = kwd_chk.begin(); s_i != kwd_chk.end(); s_i++)
153
s_i->second->check_param(&sn, &icmpp, current_os);
155
if (tg->generate_sig())
156
generate_signature(tg, &sn, &icmpp);
161
void ICMP_Inforeq_Mod::generate_signature(Target *tg, ICMP *pack, ICMP *orig) {
162
string keyword, value;
165
# icmp_info_reply = [ y, n]
166
# icmp_info_reply_ttl = [>< decimal num]
167
# icmp_info_reply_ip_id = [0, !0, SENT]
169
if (!pack->timeout()) {
170
tg->signature("icmp_info_reply", "y");
171
keyword = "icmp_info_reply_ttl";
172
ttl = pack->get_ttl() + tg->get_distance();
182
tg->signature(keyword, value);
183
keyword = "icmp_info_reply_ip_id";
184
if (pack->get_id() == 0)
186
else if (pack->get_id() == orig->get_id())
190
tg->signature(keyword, value);
192
tg->signature("icmp_info_reply", "n");
193
tg->signature("icmp_info_reply_ttl", "<255");
194
tg->signature("icmp_info_reply_ip_id", "!0");
199
int ICMP_Inforeq_Reply_Check::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
201
int gotp=ip_pkt->timeout() ? 0 : 1;
202
orig_pkt->timeout(); //suspend the warning
203
add_param(gotp, 0, os);
205
/* 2 keywords depend on this on
206
* so to be able to get 100% we
207
* generate 2 matches here if no
215
int ICMP_Inforeq_Ip_Id_Check::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
217
if (!ip_pkt->timeout())
218
return add_param(ip_pkt->get_id(), orig_pkt->get_id(), os);
222
int ICMP_Inforeq_Ttl_Check::check_param(ICMP *ip_pkt, ICMP *orig_pkt, OS_Matrix *os) {
224
if (!ip_pkt->timeout())
225
return add_param(ip_pkt->get_ttl(), orig_pkt->get_ttl(), os);