今天是光棍节。不知道我现在算不算光棍,呵呵。还是算吧,毕竟还是过着光棍的生活。典型地程序员的生活。

程序员不会觉得与电脑相处很无聊。如果无聊,也会做点rootkit来找找乐子。所以,鲁迅说过:世界上本是没有rootkit的,无聊的程序员多了,也就有了rootkit。

给个建议:调试还是用虚拟机吧,装个lfs。今天我的硬盘差点就坏了。所以换了个环境,改在win下了。现在的环境是LFS 6.3 linux 2.6.22.2。所以代码在 inline hook 那里有一点变。

玩过dota的都知道mkb是啥,但skb是个啥东西呢?

skb就是socket buffer。socket你总听过吧,就是网络编程要用到的那东西。skb在内核中就是代表一个数据包。简单地说法就是这样。它在linux 2.6.22.2的定义如下:

  1. struct sk_buff {
  2. /* These two members must be first. */
  3. struct sk_buff      *next;
  4. struct sk_buff      *prev;
  5. struct sock     *sk;
  6. ktime_t         tstamp;
  7. struct net_device   *dev;
  8. int         iif;
  9. /* 4 byte hole on 64 bit*/
  10. struct  dst_entry   *dst;
  11. struct  sec_path    *sp;
  12. /*
  13. * This is the control buffer. It is free to use for every
  14. * layer. Please put your private variables there. If you
  15. * want to keep them across layers you have to do a skb_clone()
  16. * first. This is owned by whoever has the skb queued ATM.
  17. */
  18. char            cb[48];
  19. unsigned int        len,
  20. data_len,
  21. mac_len;
  22. union {
  23. __wsum      csum;
  24. struct {
  25. __u16   csum_start;
  26. __u16   csum_offset;
  27. };
  28. };
  29. __u32           priority;
  30. __u8            local_df:1,
  31. cloned:1,
  32. ip_summed:2,
  33. nohdr:1,
  34. nfctinfo:3;
  35. __u8            pkt_type:3,
  36. fclone:2,
  37. ipvs_property:1;
  38. __be16          protocol;
  39. void            (*destructor)(struct sk_buff *skb);
  40. #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
  41. struct nf_conntrack *nfct;
  42. struct sk_buff      *nfct_reasm;
  43. #endif
  44. #ifdef CONFIG_BRIDGE_NETFILTER
  45. struct nf_bridge_info   *nf_bridge;
  46. #endif
  47. #ifdef CONFIG_NET_SCHED
  48. __u16           tc_index;   /* traffic control index */
  49. #ifdef CONFIG_NET_CLS_ACT
  50. __u16           tc_verd;    /* traffic control verdict */
  51. #endif
  52. #endif
  53. #ifdef CONFIG_NET_DMA
  54. dma_cookie_t        dma_cookie;
  55. #endif
  56. #ifdef CONFIG_NETWORK_SECMARK
  57. __u32           secmark;
  58. #endif
  59. __u32           mark;
  60. sk_buff_data_t      transport_header;
  61. sk_buff_data_t      network_header;
  62. sk_buff_data_t      mac_header;
  63. /* These elements must be at the end, see alloc_skb() for details.  */
  64. sk_buff_data_t      tail;
  65. sk_buff_data_t      end;
  66. unsigned char       *head,
  67. *data;
  68. unsigned int        truesize;
  69. atomic_t        users;
  70. };

这数据结构相对task_struct来说还是好接受一点。不过也不是个省油的灯。你看那么多个#ifdef就知道怎么回事了。没错,我们遇上了老问题----怎么确定指定字段的偏移?哪怕在同一个版本的内核上,不同的编译的选项都有可能造成不同的偏移,更何况版本不同。

先抛开这个问题不管,看下我们到底需要什么字段先。我们要用到的sk_buff里的字段有三个 protocol,data,len。

为啥呢?

1.protocol字段

我们先来看一下网卡驱动封装skb的代码,skb就是从这里诞生的。

sky2_status_intr()

  1. /* Process status response ring */
  2. static int sky2_status_intr(struct sky2_hw *hw, int to_do)
  3. {
  4. ....
  5. skb = sky2_receive(dev, length, status);
  6. if (unlikely(!skb)) {
  7. sky2->net_stats.rx_dropped++;
  8. goto force_update;
  9. }
  10. skb->protocol = eth_type_trans(skb, dev);
  11. sky2->net_stats.rx_packets++;
  12. sky2->net_stats.rx_bytes += skb->len;
  13. dev->last_rx = jiffies;
  14. #ifdef SKY2_VLAN_TAG_USED
  15. if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
  16. vlan_hwaccel_receive_skb(skb,
  17. sky2->vlgrp,
  18. be16_to_cpu(sky2->rx_tag));
  19. } else
  20. #endif
  21. netif_receive_skb(skb);

sky2_receive里的内容大概就是从io网卡读取数据包,新alloc一个skb,然后把数据放进去。

怎样判断包是不是发给我们的rootkit的呢?我们要做读最少的数据,然后作出判断。

因为我们的hook的地方可是战略要地啊,相当于巴拿马海峡。所有skb在这里经过。如果你有8个cpu,那8个cpu的skb全部都是从我们的hook里经过的,我们的hook要是有一点拖拉,那管理员下载a片的速度就会减个几十kb/s。

如果管理员发现a片下载的速度慢了,那就坏了,肯定抄个底朝天也要把我们的hook抄出来。

所以这里判断速度一定要快。

sky2_status_intr() -> eth_type_trans()

  1. /**
  2. * eth_type_trans - determine the packet's protocol ID.
  3. * @skb: received socket data
  4. * @dev: receiving network device
  5. *
  6. * The rule here is that we
  7. * assume 802.3 if the type field is short enough to be a length.
  8. * This is normal practice and works for any 'now in use' protocol.
  9. */
  10. __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
  11. {
  12. struct ethhdr *eth;
  13. unsigned char *rawp;
  14. skb->dev = dev;
  15. skb_reset_mac_header(skb);
  16. skb_pull(skb, ETH_HLEN);
  17. eth = eth_hdr(skb);
  18. if (is_multicast_ether_addr(eth->h_dest)) {
  19. if (!compare_ether_addr(eth->h_dest, dev->broadcast))
  20. skb->pkt_type = PACKET_BROADCAST;
  21. else
  22. skb->pkt_type = PACKET_MULTICAST;
  23. }
  24. /*
  25. *      This ALLMULTI check should be redundant by 1.4
  26. *      so don't forget to remove it.
  27. *
  28. *      Seems, you forgot to remove it. All silly devices
  29. *      seems to set IFF_PROMISC.
  30. */
  31. else if (1 /*dev->flags&IFF_PROMISC */ ) {
  32. if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr)))
  33. skb->pkt_type = PACKET_OTHERHOST;
  34. }
  35. if (ntohs(eth->h_proto) >= 1536)
  36. return eth->h_proto;
  37. rawp = skb->data;
  38. /*
  39. *      This is a magic hack to spot IPX packets. Older Novell breaks
  40. *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
  41. *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
  42. *      won't work for fault tolerant netware but does for the rest.
  43. */
  44. if (*(unsigned short *)rawp == 0xFFFF)
  45. return htons(ETH_P_802_3);
  46. /*
  47. *      Real 802.2 LLC
  48. */
  49. return htons(ETH_P_802_2);
  50. }
  51. EXPORT_SYMBOL(eth_type_trans);

这个eth_type_trans 是判断数据链路层协议的。函数首先处理多播和广播和混杂模式的情况,这些情况我们没必要了解。这是通过以太网头的两个mac地址来判断的。

以太网头就是这东西

  1. struct ethhdr {
  2. unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
  3. unsigned char h_source[ETH_ALEN]; /* source ether addr */
  4. __be16  h_proto;  /* packet type ID field */
  5. } __attribute__((packed));

你看,计算机网络的老师肯定讲过这东西吧,回忆起来没?

然后函数判断以太网头的协议字段是不是大于1536。我看了下,ETH_P_xxx有的是大于1536的,有的不是。如果是的话,就把skb->protocol设置为协议字段的内容。

然后函数判断是属于以太网的哪种类型。这也不用管。

我们要让内核在这里就把skb->protocol设为我们的协议号。这样,我们通过读skb->protocol就知道是不是我们的包了,就读16 bit而已。

2. len字段

这个字段没什么好说的了,首先要通过这个字段判断包的内容是否缺失。其次,我们处理完自己的包之后,要把它的len字段设置为0。这样,嗅探器就不会捡我们的垃圾了。

3. data字段

这个字段也没什么好说的了。指向数据的指针。

好了。知道了这些字段有什么用。我们咋得到它们的偏移呢?

有的人说“换成c语言就行了,直接取skb->protocol,多方便”

好,这idea真不错。。

下章讲解决这个问题

rootkit for linux 5.啥是skb相关推荐

  1. Rootkit原理——ROOTKIT ON LINUX X86 V2.6

    Linux2.6内核的LKM Rootkit原理 LKM Rootkit之HOOK系统调用表 一.修改系统调用表的地址 二.path系统调用过程的二进制代码 三.滥用DR寄存器 非LKM Rootki ...

  2. linux的rootkit工具包,Linux下rootkit后门检测工具chkrootkit

    一.安装编译工具包 yum install gcc gcc-c++ make yum install glibc-static 二.安装chkrootkit cd /usr/local/src/ wg ...

  3. linux下基于内存分析的rootkit检测方法

    0x00 引言 某Linux服务器发现异常现象如下图,确定被植入Rootkit,但运维人员使用常规Rootkit检测方法无效,对此情况我们还可以做什么? 图1 被植入Rootkit的Linux服务器 ...

  4. Linux Rootkit 系列三:实例详解 Rootkit 必备的基本功能

    本文所需的完整代码位于笔者的代码仓库:https://github.com/NoviceLive/research-rootkit. 测试建议: 不要在物理机测试!不要在物理机测试! 不要在物理机测试 ...

  5. linux内核根据skb获取目的mac地址

    linux内核根据skb获取目的mac地址 工作笔记 工作笔记 linux编程 直接通过skb里面的信息获取mac,如下 1.struct ethhdr *eth_hdr = (struct ethh ...

  6. 使用rkhunter检测Linux的rootkit

    转载来源 :使用rkhunter检测Linux的rootkit : https://www.jianshu.com/p/9a5fcd4b236b 介绍 rootkit是Linux平台下最常见的一种木马 ...

  7. 一个基于 LKM 的 Linux 内核级 rootkit 的实现

    博客已迁移至:https://gls.show/ GitHub链接 演示Slides overview rootkit是一种恶意软件,攻击者可以在获得 root 或管理员权限后安装它,从而隐藏入侵并保 ...

  8. 通过rootkit隐蔽行踪 Linux提权

    每天必问必答: ***1.每天在学什么? ***2.学了有什么用? ***3.工作中如何用? 心得:一定要把实验出错的地方.原因.解决方案都总结到笔记上.笔记一定要自己写的详细些! 服务端:xuego ...

  9. linux跟踪内存检测原理,wooyun/Linux下基于内存分析的Rootkit检测方法.html at master · exitmsconfig/wooyun · GitHub...

    Linux下基于内存分析的Rootkit检测方法 - 路人甲 原文地址:http://drops.wooyun.org/tips/4731 0x00 引言 某Linux服务器发现异常现象如下图,确定被 ...

最新文章

  1. LeetCode 1027. Longest Arithmetic Sequence--笔试题--C++解法
  2. Win2008 r2 iis7/iis7.5系统下HTTP重定向(301重定向)图文方法
  3. 找回Python IDLE Shell里的历史命令(用上下键翻历史命令怎么不好用了呢?)
  4. BBR及其在实时音视频领域的应用
  5. linux连接建立的时间,用timedatectl在Linux中检查当前时区及更改时区(创建符号链接来更改时区)...
  6. docker停止信号java_docker容器优雅停止
  7. 上周回顾:艾妮闹春 Sun/HP高层人士震荡
  8. HDU - 1054 Strategic Game (二分图匹配模板题)
  9. C/C++[codeup 1931]打印日期,一年的第n天是几月几号
  10. 本文介绍如何实现对应用加锁的功能,无须root权限
  11. 使用Jquery制作精美的图片展示效果
  12. android 半透明色值_Android设置十六进制颜色不同透明度对应的值
  13. Rust 官方入门程序(a Guessing Game)解读
  14. #一日一图#谁来暖床!
  15. js使用canvas画五角星以及渐变色,瞎画
  16. Windows CE 6.0完整版免费下载 下载地址
  17. 产品交互设计入门书籍推荐(亲自看过)
  18. 程序猿生存定律——选公司
  19. 住在储藏室的小夫妻【zt】
  20. 详解MySQL之事务

热门文章

  1. SV基础知识4---Class类和Package
  2. 【Linux】在Ubuntu中卸载、下载mysql以及如何检查mysql是否卸载成功
  3. linux-kernel-ecmp-ipv4
  4. golang go-sql-driver gorm 数据库报错 bad connection
  5. 数据压缩 Huffman编码
  6. 如何正确的自学Python?
  7. [最佳实践]从敏捷到精益:将看板应用于软件开发
  8. 刷题 保持城市天际线
  9. oracle 调优 资料
  10. 智慧客流统计AI视觉分析系统