what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

stealth.c

stealth.c
Posted Aug 27, 2002
Authored by Sean Trifero | Site innu.org

Stealth.c is a Linux 2.2.x kernel module which discards packets that many OS detection tools use to query the TCP/IP stack. Includes logging of the dropped query packets and packets with bogus flags.

tags | kernel, tcp
systems | linux
SHA-256 | 617372d951b886ece66db028d0d134637d1a62f13ff55eb4e94be19b042ea7a4

stealth.c

Change Mirror Download
/*  Stealth module by Derek Callaway <super@innu.org> -- S@IRC
* Original patch by Sean Trifero <sean@innu.org> -- solar@IRC
* $Id: stealth.c,v 1.3 2000/03/22 15:04:44 super Exp $
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/proc_fs.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/firewall.h>
#include <linux/ip_fw.h>
#include <asm/uaccess.h>
#ifdef __SMP__
#define SLOT_NUMBER() (cpu_number_map[smp_processor_id()]*2 + !in_interrupt())
#else
#define SLOT_NUMBER() (!in_interrupt())
#endif
#define STEALTH_INPUT_CHAIN stealth_chains
#define STEALTH_FORWARD_CHAIN (stealth_chains->next)
#define STEALTH_OUTPUT_CHAIN (stealth_chains->next->next)

/* kernel space variables */
static char kmsg[3][3] = { "1\n\0", "1\n\0", "1\n\0" };
static char *tcp_ignore_ack = kmsg[0];
static char *tcp_ignore_bogus = kmsg[1];
static char *tcp_ignore_synfin = kmsg[2];

/* structures from linux/net/ipv4/ip_fw.c */

/* Head of linked list of fw rules */
struct ip_counters
{
__u64 pcnt, bcnt; /* Packet and byte counters */
};

struct ip_reent
{
struct ip_chain *prevchain; /* Pointer to referencing chain */
struct ip_fwkernel *prevrule; /* Pointer to referencing rule */
struct ip_counters counters;
};

struct ip_chain
{
ip_chainlabel label; /* Defines the label for each block */
struct ip_chain *next; /* Pointer to next block */
struct ip_fwkernel *chain; /* Pointer to first rule in block */
__u32 refcount; /* Number of refernces to block */
int policy; /* Default rule for chain. Only *
* used in built in chains */
struct ip_reent reent[0]; /* Actually several of these */
};

static struct ip_chain *stealth_chains;

int stealth_check (struct iphdr *, const char *, __u16 *, struct ip_chain *,
struct sk_buff *, unsigned int, int);

int
stealth_input_check (struct firewall_ops *this, int pf, struct device *dev,
void *phdr, void *arg, struct sk_buff **pskb)
{
return (stealth_check (phdr, dev->name,
arg, STEALTH_INPUT_CHAIN, *pskb, SLOT_NUMBER (), 0));
}

int
stealth_output_check (struct firewall_ops *this, int pf, struct device *dev,
void *phdr, void *arg, struct sk_buff **pksb)
{
return (FW_SKIP);
}

int
stealth_forward_check (struct firewall_ops *this, int pf, struct device *dev,
void *phdr, void *arg, struct sk_buff **pksb)
{
return (FW_SKIP);
}

struct firewall_ops ipfw_ops = {
NULL,
stealth_output_check,
stealth_input_check,
stealth_forward_check,
PF_INET,
31337 /* This priority should be adequate. */
};

int
stealth_check (struct iphdr *ip,
const char *rif,
__u16 * redirport,
struct ip_chain *chain,
struct sk_buff *skb, unsigned int slot, int testing)
{
struct tcphdr *tcp;
if (ip->protocol != IPPROTO_TCP)
{
/* Not a TCP packet, don't worry about it. */
return (FW_SKIP);
}
tcp = (struct tcphdr *) ((__u32 *) ip + ip->ihl);
/* Check for those nasty unused bit fields. */
if ((*tcp_ignore_bogus != '0') && (tcp->res1))
{
/* I know goto statement should be avoided but I
* seriously doubt that this will evolve into
* spaghetti code. Furthermore, these jumps are
* extremely localized. */
goto tcp_bad_flags;
}
switch (tcp->fin)
{
case 0:
goto done;
default:
if (((*tcp_ignore_synfin != '0') && (tcp->syn))
|| ((*tcp_ignore_ack != '0') && (tcp->psh) && (tcp->urg)))
{
goto tcp_bad_flags;
}
}
if ((*tcp_ignore_bogus != '0') && (!(tcp->ack || tcp->syn || tcp->rst)))
{
goto tcp_bad_flags;
}
goto done;
tcp_bad_flags:
#ifdef CONFIG_TCPIP_STACK_LOG
printk (KERN_INFO
"Packet log: badflag DENY %s PROTO=TCP %d.%d.%d.%d:%d "
"%d.%d.%d.%d:%d L=%hu:%u:%u S=0x%2.2hX I=%hu:%u:%u "
"T=%hu %c%c%c%c%c%c%c%c\n",
skb->dev->name, NIPQUAD (skb->nh.iph->saddr),
ntohs (skb->h.th->source), NIPQUAD (skb->nh.iph->daddr),
ntohs (skb->h.th->dest), ntohs (skb->nh.iph->tot_len), skb->len,
skb->len - skb->h.th->doff * 4, skb->nh.iph->tos,
ntohs (skb->nh.iph->id), ntohl (skb->h.th->seq),
ntohl (skb->h.th->ack_seq), skb->nh.iph->ttl,
skb->h.th->res1 ? '1' : '.', skb->h.th->res2 ? '2' : '.',
skb->h.th->ack ? 'A' : '.', skb->h.th->syn ? 'S' : '.',
skb->h.th->fin ? 'F' : '.', skb->h.th->rst ? 'R' : '.',
skb->h.th->psh ? 'P' : '.', skb->h.th->urg ? 'U' : '.');
}
#endif
/* FW_BLOCK acts like ipchains -j DENY */
return (FW_BLOCK);
done:
/* FW_SKIP allows the next chain to evaluate the traffic. */
return (FW_SKIP);
}

static ssize_t
module_output (struct file *file, char *buf, size_t len, loff_t * offset)
{
static unsigned short done = 0;
unsigned short x = 0;
/* user land storage */
char umsg[2] = { 0 };
switch (file->f_dentry->d_name.name[11])
{
case 'a':
x = 0;
break;
case 'b':
x = 1;
break;
case 's':
x = 2;
}
if (done)
return (done = 0);
umsg[0] = kmsg[x][0], umsg[1] = '\n';
put_user (umsg[0], buf);
put_user (umsg[1], buf + 1);
put_user (umsg[2], buf + 2);
return (done = 2);
}

static ssize_t
module_input (struct file *file, const char *buf, size_t length,
loff_t * offset)
{
unsigned short x = 0;
switch (file->f_dentry->d_name.name[11])
{
case 'a':
x = 0;
break;
case 'b':
x = 1;
break;
case 's':
x = 2;
}
get_user (kmsg[x][0], buf);
kmsg[x][1] = 0;
return (2);
}

static int
module_permission (struct inode *inode, int op)
{
if (op == 4 || (op == 2 && current->euid == 0))
return (0);
return (-EACCES);
}

int
module_open (struct inode *inode, struct file *file)
{
MOD_INC_USE_COUNT;
return (0);
}

int
module_close (struct inode *inode, struct file *file)
{
MOD_DEC_USE_COUNT;
return (0);
}

/* <linux/fs.h> */

static struct file_operations fops =
{ NULL, module_output, module_input, NULL, NULL, NULL, NULL, module_open,
NULL, module_close };
static struct inode_operations iops =
{ &fops, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, module_permission };

/* <linux/proc_fs.h> */

static struct proc_dir_entry bogus =
{ 0, 16, "tcp_ignore_bogus", S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, 0, &iops,
NULL };
static struct proc_dir_entry synfin =
{ 0, 17, "tcp_ignore_synfin", S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, 0,
&iops, NULL };
static struct proc_dir_entry ack =
{ 0, 14, "tcp_ignore_ack", S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, 0, &iops,
NULL };

int
init_module (void)
{
proc_net_register (&bogus);
proc_net_register (&synfin);
proc_net_register (&ack);
register_firewall (PF_INET, &ipfw_ops);
return (0);
}

void
cleanup_module (void)
{
proc_net_unregister (bogus.low_ino);
proc_net_unregister (synfin.low_ino);
proc_net_unregister (ack.low_ino);
unregister_firewall (PF_INET, &ipfw_ops);
}
Login or Register to add favorites

File Archive:

May 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    44 Files
  • 2
    May 2nd
    5 Files
  • 3
    May 3rd
    11 Files
  • 4
    May 4th
    0 Files
  • 5
    May 5th
    0 Files
  • 6
    May 6th
    28 Files
  • 7
    May 7th
    0 Files
  • 8
    May 8th
    0 Files
  • 9
    May 9th
    0 Files
  • 10
    May 10th
    0 Files
  • 11
    May 11th
    0 Files
  • 12
    May 12th
    0 Files
  • 13
    May 13th
    0 Files
  • 14
    May 14th
    0 Files
  • 15
    May 15th
    0 Files
  • 16
    May 16th
    0 Files
  • 17
    May 17th
    0 Files
  • 18
    May 18th
    0 Files
  • 19
    May 19th
    0 Files
  • 20
    May 20th
    0 Files
  • 21
    May 21st
    0 Files
  • 22
    May 22nd
    0 Files
  • 23
    May 23rd
    0 Files
  • 24
    May 24th
    0 Files
  • 25
    May 25th
    0 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close