[gl-como] Net Sniff
Pietro Bertera
gl-como@lists.linux.it
Sat, 08 Mar 2003 16:07:42 +0100
This is a multi-part message in MIME format.
--------------030603020809010508000301
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
Pietro Bertera wrote:
Ups.. mi sono accorto che *dopo un po'* chrashava tutto (kernel panic).
dopo essere diventato scemo tutta la notte, tutta la mattina e parte del
pomeriggio mi sonoa ccorto che non sempre i pacchetti (in sk_buff) hanno
tutti i campi inizializzati e ad esempio paccehtti icmp non hanno il
numero di porta.
ho risolto il tutto con qualche if(pippo != NULL)
è interessante vedere come si degradano le prestazioni della cpu quando
ci sono scambi di dati tra kernel space e user space:
per ogni pacchetto, ogni volta che viene letto dal kernel, viene
stampato : source address, source port, destination address e
destination port.
Ogni pacchetto ricevuto viene letto 2 volte nei 2 hook facendo questo
percorso:
PREROUTING -> INPUT (se è per la macchina stessa)
PREROUTING -> FORWARD (se è per un altra macchina)
indem per i pacchetti inviati:
OUTPUT -> POSTROUTING (se parte dalla macchina stessa)
FORWARD -> POSTROUTING (se parte da un altra macchina)
quindi nel caso non ci siano regole di iptables per l'interfaccia lo
(127.0.0.1)
se si fa un nmap 127.0.0.1 ad ogni richiesta su ogni porta il kernel
risponde (con un pacchetto per dire se è aperta o chiusa)
In definitiva con in modulo installato quando si fa un nmap 127.0.0.1
vengono stampati 4 dati per ogni pacchetto generato da nmap e altri 4
per ogni pacchetto in risposta a quello di nmap, quindi in totale 8 dati
per ogni richiesta di nmap.
Un portscan in queste condizioni ci mette 2 minuti !!! (un nmap 127.0.0.1)
se dal sorgente eliminate le printk ci mette 2 secondi: come se non
fosse installato il modulo.
Questo fatto dovrebbe fare pensare sulla convenienza o meno di fare
logging massiccio.
allego ancora il codice corretto.
ciao
--------------030603020809010508000301
Content-Type: text/x-csrc;
name="NetSniff.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="NetSniff.c"
/* Sat Mar 8 00:05:40 2003
*
* Bertera Pietro
* e-mail: p.bertera@valtellinux.it dr.iggy@iol.it
*
* compile with:
* gcc -Wall -DMODULE -D__KERNEL__ -DDEBUG -c NetSniff.c -I/usr/src/linux/include
*
* run with:
* insmod NetSniff.o
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/config.h>
#include <linux/in.h>
#include <linux/socket.h>
MODULE_LICENSE("GPL");
unsigned int in_hook(unsigned int hooknum,
struct sk_buff **skb_p,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
int retval = NF_ACCEPT;
struct sk_buff *skb = (*skb_p);
struct iphdr *iph;
struct tcphdr *tcph = NULL;
struct udphdr *udph = NULL;
__u32 saddr;
__u32 daddr;
__u8 protocol_type;
__u16 dport = 0;
__u16 sport = 0;
if(&(skb->nh.iph) != NULL){
iph = skb->nh.iph;
}else{
return retval;
}
if(&(iph->saddr) != NULL){
saddr = iph->saddr;
}else{
return retval;
}
if(&(iph->daddr) != NULL){
daddr = iph->daddr;
}else{
return retval;
}
if(&(skb->h.th) != NULL){
tcph = skb->h.th;
}
if(&(skb->h.uh) != NULL){
udph = skb->h.uh;
}
if(iph->protocol){
protocol_type=iph->protocol;
}else{
return retval;
}
if((protocol_type == IPPROTO_TCP) && (&(tcph->dest) != NULL) && (&(tcph->source) != NULL)){
dport = tcph->dest;
sport = tcph->source;
}
if((protocol_type == IPPROTO_UDP) && (&(udph->dest) != NULL) && (&(udph->source) != NULL)){
dport = udph->dest;
sport = udph->source;
}
printk("INPUT --> S: %d.%d.%d.%d:%d D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
//printk("INPUT --> S: %d.%d.%d.%d D: %d.%d.%d.%d\n",NIPQUAD(saddr),NIPQUAD(daddr));
return retval;
}
unsigned int out_hook(unsigned int hooknum,
struct sk_buff **skb_p,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
int retval = NF_ACCEPT;
struct sk_buff *skb = (*skb_p);
struct iphdr *iph = NULL;
struct tcphdr *tcph = NULL;
struct udphdr *udph = NULL;
__u32 saddr;
__u32 daddr;
__u8 protocol_type;
__u16 dport = 0;
__u16 sport = 0;
if(&(skb->nh.iph) != NULL){
iph = skb->nh.iph;
}else{
return retval;
}
if(&(iph->saddr) != NULL){
saddr = iph->saddr;
}else{
return retval;
}
if(&(iph->daddr) != NULL){
daddr = iph->daddr;
}else{
return retval;
}
if(&(skb->h.th) != NULL){
tcph = skb->h.th;
}
if(&(skb->h.uh) != NULL){
udph = skb->h.uh;
}
if(iph->protocol){
protocol_type=iph->protocol;
}else{
return retval;
}
if((protocol_type == IPPROTO_TCP) && (&(tcph->dest) != NULL) && (&(tcph->source) != NULL)){
dport = tcph->dest;
sport = tcph->source;
}
if((protocol_type == IPPROTO_UDP) && (&(udph->dest) != NULL) && (&(udph->source) != NULL)){
dport = udph->dest;
sport = udph->source;
}
printk("OUT --> S: %d.%d.%d.%d:%d D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
//printk("OUT --> S: %d.%d.%d.%d D: %d.%d.%d.%d\n",NIPQUAD(saddr),NIPQUAD(daddr));
return retval;
}
unsigned int fw_hook(unsigned int hooknum,
struct sk_buff **skb_p,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
int retval = NF_ACCEPT;
struct sk_buff *skb = (*skb_p);
struct iphdr *iph;
struct tcphdr *tcph = NULL;
struct udphdr *udph = NULL;
__u32 saddr;
__u32 daddr;
__u8 protocol_type;
__u16 dport = 0;
__u16 sport = 0;
if(&(skb->nh.iph) != NULL){
iph = skb->nh.iph;
}else{
return retval;
}
if(&(iph->saddr) != NULL){
saddr = iph->saddr;
}else{
return retval;
}
if(&(iph->daddr) != NULL){
daddr = iph->daddr;
}else{
return retval;
}
if(&(skb->h.th) != NULL){
tcph = skb->h.th;
}
if(&(skb->h.uh) != NULL){
udph = skb->h.uh;
}
if(iph->protocol){
protocol_type=iph->protocol;
}else{
return retval;
}
if((protocol_type == IPPROTO_TCP) && (&(tcph->dest) != NULL) && (&(tcph->source) != NULL)){
dport = tcph->dest;
sport = tcph->source;
}
if((protocol_type == IPPROTO_UDP) && (&(udph->dest) != NULL) && (&(udph->source) != NULL)){
dport = udph->dest;
sport = udph->source;
}
printk("FW --> S: %d.%d.%d.%d:%d D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
//printk("FW --> S: %d.%d.%d.%d D: %d.%d.%d.%d\n",NIPQUAD(saddr),NIPQUAD(daddr));
return retval;
}
unsigned int pre_hook(unsigned int hooknum,
struct sk_buff **skb_p,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
int retval = NF_ACCEPT;
struct sk_buff *skb = (*skb_p);
struct iphdr *iph;
struct tcphdr *tcph = NULL;
struct udphdr *udph = NULL;
__u32 saddr;
__u32 daddr;
__u8 protocol_type;
__u16 dport = 0;
__u16 sport = 0;
if(skb->nh.iph){
iph = skb->nh.iph;
}else{
return retval;
}
if(&(skb->nh.iph) != NULL){
iph = skb->nh.iph;
}else{
return retval;
}
if(&(iph->saddr) != NULL){
saddr = iph->saddr;
}else{
return retval;
}
if(&(iph->daddr) != NULL){
daddr = iph->daddr;
}else{
return retval;
}
if(&(skb->h.th) != NULL){
tcph = skb->h.th;
}
if(&(skb->h.uh) != NULL){
udph = skb->h.uh;
}
if(iph->protocol){
protocol_type=iph->protocol;
}else{
return retval;
}
if((protocol_type == IPPROTO_TCP) && (&(tcph->dest) != NULL) && (&(tcph->source) != NULL)){
dport = tcph->dest;
sport = tcph->source;
}
if((protocol_type == IPPROTO_UDP) && (&(udph->dest) != NULL) && (&(udph->source) != NULL)){
dport = udph->dest;
sport = udph->source;
}
printk("PRE --> S: %d.%d.%d.%d:%d D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
//printk("PRE --> S: %d.%d.%d.%d D: %d.%d.%d.%d\n",NIPQUAD(saddr),NIPQUAD(daddr));
return retval;
}
unsigned int post_hook(unsigned int hooknum,
struct sk_buff **skb_p,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
int retval = NF_ACCEPT;
struct sk_buff *skb = (*skb_p);
struct iphdr *iph;
struct tcphdr *tcph = NULL;
struct udphdr *udph = NULL;
__u32 saddr;
__u32 daddr;
__u8 protocol_type;
__u16 dport = 0;
__u16 sport = 0;
if(&(skb->nh.iph) != NULL){
iph = skb->nh.iph;
}else{
return retval;
}
if(&(iph->saddr) != NULL){
saddr = iph->saddr;
}else{
return retval;
}
if(&(iph->daddr) != NULL){
daddr = iph->daddr;
}else{
return retval;
}
if(&(skb->h.th) != NULL){
tcph = skb->h.th;
}
if(&(skb->h.uh) != NULL){
udph = skb->h.uh;
}
if(iph->protocol){
protocol_type=iph->protocol;
}else{
return retval;
}
if((protocol_type == IPPROTO_TCP) && (&(tcph->dest) != NULL) && (&(tcph->source) != NULL)){
dport = tcph->dest;
sport = tcph->source;
}
if((protocol_type == IPPROTO_UDP) && (&(udph->dest) != NULL) && (&(udph->source) != NULL)){
dport = udph->dest;
sport = udph->source;
}
printk("POST --> S: %d.%d.%d.%d:%d D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
//printk("POST --> S: %d.%d.%d.%d D: %d.%d.%d.%d\n",NIPQUAD(saddr),NIPQUAD(daddr));
return retval;
}
struct nf_hook_ops in_hook_ops = {
hook : in_hook,
pf : PF_INET,
hooknum : NF_IP_LOCAL_IN,
};
struct nf_hook_ops out_hook_ops = {
hook : out_hook,
pf : PF_INET,
hooknum : NF_IP_LOCAL_OUT,
};
struct nf_hook_ops fw_hook_ops = {
hook : fw_hook,
pf : PF_INET,
hooknum : NF_IP_FORWARD,
};
struct nf_hook_ops pre_hook_ops = {
hook : pre_hook,
pf : PF_INET,
hooknum : NF_IP_PRE_ROUTING,
};
struct nf_hook_ops post_hook_ops = {
hook : post_hook,
pf : PF_INET,
hooknum : NF_IP_POST_ROUTING,
};
static int init_status_flag;
#define IN_HOOK_REGISTERED 0x02
#define OUT_HOOK_REGISTERED 0x04
#define FW_HOOK_REGISTERED 0x06
#define PRE_HOOK_REGISTERED 0x08
#define POST_HOOK_REGISTERED 0x20
void cleanup_module(void)
{
if (init_status_flag&IN_HOOK_REGISTERED)
nf_unregister_hook(&in_hook_ops);
if (init_status_flag&OUT_HOOK_REGISTERED)
nf_unregister_hook(&out_hook_ops);
if (init_status_flag&FW_HOOK_REGISTERED)
nf_unregister_hook(&fw_hook_ops);
if (init_status_flag&PRE_HOOK_REGISTERED)
nf_unregister_hook(&pre_hook_ops);
if (init_status_flag&POST_HOOK_REGISTERED)
nf_unregister_hook(&post_hook_ops);
}
int init_module(void)
{
int result;
result = nf_register_hook(&in_hook_ops);
if (result < 0) {
printk(KERN_ERR "can't register netfilter hook");
cleanup_module();
return result;
}
init_status_flag |= IN_HOOK_REGISTERED;
result = nf_register_hook(&out_hook_ops);
if (result < 0) {
printk(KERN_ERR "can't register netfilter hook");
cleanup_module();
return result;
}
init_status_flag |= OUT_HOOK_REGISTERED;
result = nf_register_hook(&fw_hook_ops);
if (result < 0) {
printk(KERN_ERR "can't register netfilter hook");
cleanup_module();
return result;
}
init_status_flag |= FW_HOOK_REGISTERED;
result = nf_register_hook(&pre_hook_ops);
if (result < 0) {
printk(KERN_ERR "can't register netfilter hook");
cleanup_module();
return result;
}
init_status_flag |= PRE_HOOK_REGISTERED;
result = nf_register_hook(&post_hook_ops);
if (result < 0) {
printk(KERN_ERR "can't register netfilter hook");
cleanup_module();
return result;
}
init_status_flag |= POST_HOOK_REGISTERED;
printk("Netfilter Sniff run! stop with: #rmmod NetSnif \n");
return 0;
}
--------------030603020809010508000301--