~ubuntu-branches/ubuntu/trusty/xprobe/trusty

« back to all changes in this revision

Viewing changes to src/xpmodules/os_probe/tcp_rst/tcp_rst.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
/*
 
2
 * **
 
3
 * ** Copyright (C) 2001-2005  Fyodor Yarochkin <fygrave@tigerteam.net>,
 
4
 * **                                           Ofir Arkin       <ofir@sys-security.com>
 
5
 * **                                           Meder Kydyraliev <meder@o0o.nu>
 
6
 * **
 
7
 * ** This program is free software; you can redistribute it and/or modify
 
8
 * ** it under the terms of the GNU General Public License as published by
 
9
 * ** the Free Software Foundation; either version 2 of the License, or
 
10
 * ** (at your option) any later version.
 
11
 * **
 
12
 * **
 
13
 * ** This program is distributed in the hope that it will be useful,
 
14
 * ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * ** GNU General Public License for more details.
 
17
 * **
 
18
 * ** You should have received a copy of the GNU General Public License
 
19
 * ** along with this program; if not, write to the Free Software
 
20
 * ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
21
 * */
 
22
 
 
23
#include "xprobe.h"
 
24
#define _XPROBE_MODULE
 
25
#include "xplib.h"
 
26
#include "xprobe_module.h"
 
27
#include "xprobe_module_hdlr.h"
 
28
#include "target.h"
 
29
#include "interface.h"
 
30
#include "cmd_opts.h"
 
31
#include "tcp_rst.h"
 
32
 
 
33
extern Interface *ui;
 
34
extern Cmd_Opts *copts;
 
35
 
 
36
int tcp_rst_mod_init(Xprobe_Module_Hdlr *pt, char *nm) {
 
37
        TCP_Rst_Mod *rst = new TCP_Rst_Mod;
 
38
        rst->set_name(nm);
 
39
        xprobe_mdebug(XPROBE_DEBUG_MODULES, "Initializing the TCP RST module\n");
 
40
        pt->register_module(rst);
 
41
        pt->add_keyword(rst->get_id(), "tcp_rst_df");
 
42
        pt->add_keyword(rst->get_id(), "tcp_rst_ip_id_1");
 
43
        pt->add_keyword(rst->get_id(), "tcp_rst_ip_id_2");
 
44
        pt->add_keyword(rst->get_id(), "tcp_rst_ip_id_strategy");
 
45
        pt->add_keyword(rst->get_id(), "tcp_rst_ttl");
 
46
        pt->add_keyword(rst->get_id(), "tcp_rst_reply");
 
47
        return OK;
 
48
}
 
49
 
 
50
TCP_Rst_Mod::TCP_Rst_Mod(void): Xprobe_Module(XPROBE_MODULE_OSTEST, "fingerprint:tcp_rst", "TCP RST fingerprinting module") {
 
51
        TCP_Rst_Df_Bit_Check *df_check = new TCP_Rst_Df_Bit_Check;
 
52
        TCP_Rst_Ip_Id_Check *id_check_one = new TCP_Rst_Ip_Id_Check;
 
53
        TCP_Rst_Ip_Id_Check *id_check_two = new TCP_Rst_Ip_Id_Check;
 
54
        TCP_Rst_Ttl_Check       *ttl_check = new TCP_Rst_Ttl_Check;
 
55
        TCP_Rst_Ip_Id_Strategy *strat_check = new TCP_Rst_Ip_Id_Strategy;
 
56
        TCP_Rst_Reply_Check *reply_check = new TCP_Rst_Reply_Check;
 
57
 
 
58
        kwd_chk.insert(pair<string, Xprobe_Module_Param_TCP *>("tcp_rst_df", df_check));
 
59
        kwd_chk.insert(pair<string, Xprobe_Module_Param_TCP *>("tcp_rst_ip_id_1", id_check_one));
 
60
        kwd_chk.insert(pair<string, Xprobe_Module_Param_TCP *>("tcp_rst_ip_id_2", id_check_two));
 
61
        kwd_chk.insert(pair<string, Xprobe_Module_Param_TCP *>("tcp_rst_ip_id_strategy", strat_check));
 
62
        kwd_chk.insert(pair<string, Xprobe_Module_Param_TCP *>("tcp_rst_ttl", ttl_check));
 
63
        kwd_chk.insert(pair<string, Xprobe_Module_Param_TCP *>("tcp_rst_reply", reply_check));
 
64
}
 
65
 
 
66
TCP_Rst_Mod::~TCP_Rst_Mod(void) {
 
67
        map<string, Xprobe_Module_Param_TCP *>::iterator m_i;
 
68
 
 
69
        for (m_i = kwd_chk.begin(); m_i != kwd_chk.end(); m_i++) {
 
70
                delete m_i->second;
 
71
        }
 
72
}
 
73
 
 
74
 
 
75
int TCP_Rst_Mod::parse_keyword(int os_id, const char *kwd, const char *val) {
 
76
        map<string, Xprobe_Module_Param_TCP *>::iterator m_i;
 
77
        
 
78
        if ((m_i = kwd_chk.find(kwd)) == kwd_chk.end()) {
 
79
                ui->error("%s: unknown keyword %s", get_name(), kwd);
 
80
                return FAIL;
 
81
        }
 
82
        return m_i->second->parse_param(os_id, val);
 
83
}
 
84
 
 
85
int TCP_Rst_Mod::init(void) {
 
86
        xprobe_debug(XPROBE_DEBUG_MODULES, "%s module initialized\n", get_name());
 
87
        return OK;
 
88
}
 
89
 
 
90
int TCP_Rst_Mod::exec(Target *tg, OS_Matrix *os) {
 
91
        int done=0, ret;
 
92
        bool second_packet = false;
 
93
        char buf[1024];
 
94
        struct in_addr local = tg->get_interface_addr(), remote = tg->get_addr();
 
95
        struct timeval tv;
 
96
        map<string, Xprobe_Module_Param_TCP *>::iterator m_i;
 
97
        
 
98
        TCP request(inet_ntoa(remote));
 
99
        TCP sn(inet_ntoa(local)), sample1(inet_ntoa(local));
 
100
 
 
101
        if (tg->get_port(IPPROTO_TCP, XPROBE_TARGETP_CLOSED) == -1) {
 
102
                // ui->msg("[-] %s Module execution aborted (no closed TCP port known)\n", get_name());
 
103
                xprobe_debug(XPROBE_DEBUG_MODULES, "[%s] Sending probe to port 65535\n", get_name());
 
104
                //return FAIL;
 
105
        }
 
106
        srand(time(NULL));
 
107
        request.set_src(local.s_addr);
 
108
        request.set_dst(remote.s_addr);
 
109
        request.set_srcport(rand());
 
110
        request.set_dstport(tg->get_port(IPPROTO_TCP, XPROBE_TARGETP_CLOSED));
 
111
        request.set_ttl(64);
 
112
        request.set_win(6840);
 
113
        request.set_flags(TH_SYN);
 
114
        request.set_tos(0x10);
 
115
        request.set_fragoff(IP_DF);
 
116
        request.set_seq(rand());
 
117
        request.set_ack(0);
 
118
        request.set_id(rand());
 
119
 
 
120
        tv = tg->get_rtt();
 
121
        sn.init_device(tg->get_interface(), 0, 1500);
 
122
        sn.timeout(tv);
 
123
 
 
124
        request.sendpack("");
 
125
        while (!done) {
 
126
                ret = sn.sniffpack(buf, sizeof(buf));   
 
127
                if (!sn.timeout()) {
 
128
                        if (sn.get_src() == remote.s_addr && request.get_dstport() == sn.get_srcport() &&
 
129
                                        request.get_srcport() == sn.get_dstport()) {
 
130
                                                done = 1;
 
131
                        }
 
132
                } else {
 
133
                        done = 1; //timeout
 
134
                }
 
135
                if (done && !sn.timeout() && (sn.get_flags() & TH_RST) == TH_RST) {
 
136
                        if (!second_packet) {
 
137
                                xprobe_debug(XPROBE_DEBUG_MODULES, "[%s] Got first RST packet. Sending second\n", get_name());
 
138
                                sample1 = sn;
 
139
                                request.set_srcport(rand());
 
140
                                request.set_id(rand());
 
141
                                request.set_seq(rand());
 
142
                                request.set_tcpsum(0);
 
143
                                done = 0;       
 
144
                                sn.timeout(tv);
 
145
                                request.sendpack("");
 
146
                                second_packet=true;
 
147
                        } else {
 
148
                                xprobe_debug(XPROBE_DEBUG_MODULES, "[%s] Got second RST packet.\n", get_name());
 
149
                                done = 1;
 
150
                        }
 
151
                }
 
152
        } // while (!done)
 
153
        if (sn.timeout())
 
154
                return FAIL;
 
155
 
 
156
        // we got two packets
 
157
        for (m_i = kwd_chk.begin(); m_i != kwd_chk.end(); m_i++) {
 
158
                if (m_i->first == "tcp_rst_ip_id_strategy") {
 
159
                        m_i->second->check_param(&sn, &sample1, os);
 
160
                } else {
 
161
                        m_i->second->check_param(&sn, &request, os);
 
162
                }
 
163
        }
 
164
        if (tg->generate_sig())
 
165
                generate_signature(tg, &sample1, &request, &sn);
 
166
        return OK;
 
167
}
 
168
 
 
169
void TCP_Rst_Mod::generate_signature(Target *tg, TCP *pack, TCP *orig, TCP *second) {
 
170
        string keyword, value;
 
171
        unsigned int ttl;
 
172
        long id_diff;
 
173
        /*
 
174
         * tcp_rst_reply = [y,n]
 
175
         * tcp_rst_df=[0,1]
 
176
         * tcp_rst_ip_id_1=[0, !0, SENT]
 
177
         * tcp_rst_ip_id_2=[0, !0, SENT]
 
178
         * tcp_rst_ip_id_strategy=[R, I, 0]
 
179
         * tcp_rst_ttl = [<> decimal num]
 
180
        */
 
181
 
 
182
        if (pack->timeout() || second->timeout()) {
 
183
                tg->signature("tcp_rst_reply", "n");
 
184
                tg->signature("tcp_rst_df", "0");
 
185
                tg->signature("tcp_rst_ip_id_1", "!0");
 
186
                tg->signature("tcp_rst_ip_id_2", "!0");
 
187
                tg->signature("tcp_rst_ip_id_strategy", "I");
 
188
                tg->signature("tcp_rst_ttl", "<255");
 
189
                return;
 
190
        }
 
191
        tg->signature("tcp_rst_reply", "y");
 
192
        keyword = "tcp_rst_df";
 
193
        if (pack->get_fragoff() & IP_DF) {
 
194
                value="1";
 
195
        } else {
 
196
                value="0";
 
197
        }
 
198
        tg->signature(keyword.c_str(), value.c_str());
 
199
        keyword= "tcp_rst_ip_id_1";     
 
200
        if (pack->get_id() == 0) {
 
201
                value="0";
 
202
        } else if (pack->get_id() == orig->get_id()) {
 
203
                value = "SENT";
 
204
        } else {
 
205
                value = "!0";
 
206
        }
 
207
        tg->signature(keyword.c_str(), value.c_str());
 
208
        keyword= "tcp_rst_ip_id_2";     
 
209
        tg->signature(keyword.c_str(), value.c_str());
 
210
        keyword="tcp_rst_ttl";
 
211
        ttl = pack->get_ttl() + tg->get_distance();
 
212
        value = "<";
 
213
        if (ttl <= 32)
 
214
                value.append("32");
 
215
        else if (ttl <= 60)
 
216
                value.append("60");
 
217
        else if (ttl <= 64)
 
218
                value.append("64");
 
219
        else if (ttl <= 128)
 
220
                value.append("128");
 
221
        else if (ttl <= 255)
 
222
                value.append("255");
 
223
        tg->signature(keyword.c_str(), value.c_str());
 
224
        keyword="tcp_rst_ip_id_strategy";
 
225
        id_diff = second->get_id() - pack->get_id();
 
226
        if (id_diff > 256 || id_diff < 0) {
 
227
                value ="R";
 
228
        } else if (id_diff > 0 && id_diff <= 256) {
 
229
                value = "I";
 
230
        } else if (id_diff == 0) {
 
231
                value = "0";
 
232
        }
 
233
        tg->signature(keyword.c_str(), value.c_str());
 
234
        
 
235
}
 
236
 
 
237
int TCP_Rst_Mod::fini(void) {
 
238
        xprobe_debug(XPROBE_DEBUG_MODULES, "%s module has been deinitilized\n", get_name());
 
239
        return OK;
 
240
}
 
241
 
 
242
int TCP_Rst_Df_Bit_Check::check_param(TCP *p, TCP *o, OS_Matrix *os) {
 
243
        int retval = OK;
 
244
        o=o; //suspend compiler warning
 
245
        if (!p->timeout())
 
246
                retval = add_param(((p->get_fragoff() & IP_DF) != 0), 0,  os);
 
247
        return retval;
 
248
}
 
249
 
 
250
int TCP_Rst_Ip_Id_Check::check_param(TCP *p, TCP *o, OS_Matrix *os) {
 
251
        int retval = OK;
 
252
        if (!p->timeout())
 
253
                retval = add_param(p->get_id(), o->get_id(), os);
 
254
        return retval;
 
255
}
 
256
 
 
257
int TCP_Rst_Ttl_Check::check_param(TCP *p, TCP *o, OS_Matrix *os) {
 
258
        int retval=OK;
 
259
        if (!p->timeout())
 
260
                retval = add_param(p->get_ttl(), o->get_ttl(), os);
 
261
        return retval;
 
262
}
 
263
 
 
264
int TCP_Rst_Ip_Id_Strategy::check_param(TCP *p, TCP *o, OS_Matrix *os) {
 
265
        int retval = OK;
 
266
        if (!p->timeout())
 
267
                retval = add_param(p->get_id(), o->get_id(), os);
 
268
        return retval;
 
269
}
 
270
 
 
271
int TCP_Rst_Reply_Check::check_param(TCP *p, TCP *o, OS_Matrix *os) {
 
272
        int gotp=p->timeout() ? 0 : 1;
 
273
        // suspend warning
 
274
        o->timeout();
 
275
        add_param(gotp, 0, os);
 
276
        if (!gotp) {
 
277
                gen_match(5, os);
 
278
        }
 
279
return OK;
 
280
}