masscan-mark-ii/src/proto-netbios.c

170 lines
5.1 KiB
C

#include "proto-netbios.h"
#include "proto-udp.h"
#include "proto-dns-parse.h"
#include "proto-preprocess.h"
#include "syn-cookie.h"
#include "util-logger.h"
#include "output.h"
#include "masscan-app.h"
#include "proto-banner1.h"
#include "massip-port.h"
#include "masscan.h"
#include "unusedparm.h"
#include <ctype.h>
/***************************************************************************
***************************************************************************/
static void
append_char(unsigned char *banner, size_t banner_max, unsigned *banner_length, char c)
{
if (*banner_length < banner_max)
banner[(*banner_length)++] = c;
}
/***************************************************************************
***************************************************************************/
static void
append_name(unsigned char *banner, size_t banner_max, unsigned *banner_length, const unsigned char *name)
{
unsigned i;
unsigned char c;
for (i=0; i<15; i++) {
c = name[i];
if (c == 0x20 || c == '\0')
append_char(banner, banner_max, banner_length, ' ');
else if (isalnum(c) || ispunct(c))
append_char(banner, banner_max, banner_length, c);
else {
append_char(banner, banner_max, banner_length, '<');
append_char(banner, banner_max, banner_length, "0123456789ABCDEF"[c>>4]);
append_char(banner, banner_max, banner_length, "0123456789ABCDEF"[c&0xF]);
append_char(banner, banner_max, banner_length, '>');
}
}
c = name[i];
append_char(banner, banner_max, banner_length, '<');
append_char(banner, banner_max, banner_length, "0123456789ABCDEF"[c>>4]);
append_char(banner, banner_max, banner_length, "0123456789ABCDEF"[c&0xF]);
append_char(banner, banner_max, banner_length, '>');
append_char(banner, banner_max, banner_length, '\n');
}
/*****************************************************************************
* Process one of them many "resource-records" within the NBTSTAT response
*****************************************************************************/
static unsigned
handle_nbtstat_rr(struct Output *out, time_t timestamp, unsigned ttl,
const unsigned char *px, unsigned length,
ipaddress ip_them, unsigned port_them)
{
unsigned char banner[65536];
unsigned banner_length = 0;
unsigned offset = 0;
unsigned name_count;
if (offset >= length)
return 0;
name_count = px[offset++];
/* Report all the names */
while (offset + 18 <= length && name_count) {
append_name(banner, sizeof(banner), &banner_length, &px[offset]);
offset += 18;
name_count--;
}
/* Report the MAC address at the end */
{
unsigned i;
for (i=0; i<6; i++) {
if (offset + i < length) {
unsigned char c = px[offset];
append_char(banner, sizeof(banner), &banner_length, "0123456789ABCDEF"[c>>4]);
append_char(banner, sizeof(banner), &banner_length, "0123456789ABCDEF"[c&0xF]);
if (i < 5)
append_char(banner, sizeof(banner), &banner_length, '-');
}
}
}
output_report_banner(
out, timestamp,
ip_them, 17, port_them,
PROTO_NBTSTAT,
ttl,
banner, banner_length);
return 0;
}
/***************************************************************************
***************************************************************************/
unsigned
handle_nbtstat(struct Output *out, time_t timestamp,
const unsigned char *px, unsigned length,
struct PreprocessedInfo *parsed,
uint64_t entropy)
{
ipaddress ip_them = parsed->src_ip;
ipaddress ip_me = parsed->dst_ip;
unsigned port_them = parsed->port_src;
unsigned port_me = parsed->port_dst;
struct DNS_Incoming dns[1];
unsigned offset;
uint64_t seqno;
seqno = (unsigned)syn_cookie(ip_them, port_them | Templ_UDP, ip_me, port_me, entropy);
proto_dns_parse(dns, px, parsed->app_offset, parsed->app_offset + parsed->app_length);
if ((seqno & 0xFFFF) != dns->id)
return 1;
if (dns->qr != 1)
return 0;
if (dns->rcode != 0)
return 0;
if (dns->qdcount > 1)
return 0;
if (dns->ancount < 1)
return 0;
if (dns->rr_count < 1)
return 0;
offset = dns->rr_offset[dns->qdcount];
offset = dns_name_skip(px, offset, length);
if (offset + 10 >= length)
return 0;
{
unsigned type = px[offset+0]<<8 | px[offset+1];
unsigned xclass = px[offset+2]<<8 | px[offset+3];
unsigned rrlen = px[offset+8]<<8 | px[offset+9];
unsigned txtlen = px[offset+10];
if (rrlen == 0 || txtlen > rrlen-1)
return 0;
if (type != 0x21 || xclass != 1)
return 0;
offset += 10;
return handle_nbtstat_rr(out, timestamp, parsed->ip_ttl,
px + offset,
length - offset,
ip_them,
port_them);
}
}