5 17

「技术随笔」iptables报too many ports specified的解决

背景

笔者写的蜜罐的agent底层依赖iptables,在设置高交互蜜罐的端口转发规则时会用到iptables的multiport --dports指令,但是超过--dports超过15个的话,会报too many ports specified错误:

iptables -A INPUT -p tcp -m multiport --dports 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
iptables -A INPUT -p tcp -m multiport --dports 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
iptables v1.4.21: too many ports specified
Try `iptables -h' or 'iptables --help' for more information.

关于蜜罐与攻击欺骗防御系统的设计与实现,可以参考笔者之前写过的文章。

  1. 设计灵敏的蜜罐传感器
  2. 自制攻击欺骗防御系统
  3. 自制蜜罐之前端部分

解决方案

投石问路

蜜罐的规则在运营过程是肯定会超过15个,不可能为了规避iptables的这个特性就缩小规则列表。 IPTABLES报这个错误的根本原因是iptables的源码中include/linux/netfilter/xt_multiport.h的宏XT_MULTI_PORTS指定了参数个数为15个,如下所示:

#ifndef _XT_MULTIPORT_H
#define _XT_MULTIPORT_H

#include <linux/types.h>c

enum xt_multiport_flags {
    XT_MULTIPORT_SOURCE,
    XT_MULTIPORT_DESTINATION,
    XT_MULTIPORT_EITHER
};

#define XT_MULTI_PORTS    15

很傻很天真的我最初认为把这个将XT_MULTI_PORTS的值改大重新编译iptables就可以了,事实证明我还是太年青了。等编译完后一执行又报错了,提示让看dmesg,发现如下错误:

[ 1379.325905] x_tables: ip_tables: multiport.1 match: invalid size 48 (kernel) != (user) 456
[ 1650.126296] x_tables: ip_tables: multiport.1 match: invalid size 48 (kernel) != (user) 304

以上2条LOG分别是将XT_MULTI_PORTS改为150和100产生的。为什么捏?

通过观察include/linux/netfilter/xt_multiport.h的代码片断,确定为正好是以下struct中XT_MULTI_PORTS分别为150和100的size。

struct xt_multiport_v1 {
    __u8 flags;                /* Type of comparison */
    __u8 count;                /* Number of ports */
    __u16 ports[XT_MULTI_PORTS];    /* Ports */
    __u8 pflags[XT_MULTI_PORTS];    /* Port flags */
    __u8 invert;            /* Invert flag */
};

这个时候我才恍然大悟,本来iptables就是netfilter的用户接口,最终的操作结果是传到内核级模块netfilter中的,还需要修内核中netfilter模块相对应的代码部分,经确定在以下文件中include/uapi/linux/netfilter/xt_multiport.h,修改完还要重新编译内核。这个方案比较麻烦,先PASS了,还是在agent中实现吧。

柳暗花明

如果一条策略中的端口超过了15个,那我们将策略分成多条即可。先写一个端口数量分割的工具函数:

func SplitWhitePorts(ports []string) (map[int][]string) {
    result := make(map[int][]string)
    total := len(ports)
    batch := 0
    if total%15 == 0 {
        batch = total / 15
        for i := 0; i < batch; i++ {
            result[i] = ports[i*15 : (i+1)*15]
        }
    } else {
        batch = total / 15
        for i := 0; i < batch; i++ {
            result[i] = ports[i*15 : (i+1)*15]
        }
        result[batch] = ports[batch*15 : total]
    }

    return result
}

测试结果满足预期:

[ `go run csrf.go` | done: 561.973248ms ]
    map[0:[1 2 3 4 5 6]]
    map[0:[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]]
    map[0:[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15] 1:[16 17 18 19 20]]

然后在刷新策略部分应用之:

if strings.ToLower(mode) == "honeypot" {
        whiteIpPolicy := vars.HoneypotPolicy.WhiteIp
        // set white policy
        for _, whiteIp := range whiteIpPolicy {
            logger.Log.Println("/sbin/iptables", "-t", "filter", "-A", "WHITELIST", "-i", setting.Interface, "-s", whiteIp, "-j", "DROP")
            exec.Command("/sbin/iptables", "-t", "filter", "-A", "WHITELIST", "-i", setting.Interface, "-s",
                whiteIp, "-j", "DROP").Output()
        }

        for _, ports := range util.SplitWhitePorts(vars.HoneypotPolicy.WhitePort) {
            logger.Log.Println("/sbin/iptables", "-t", "nat", "-A", "HONEYPOT", "-i", setting.Interface,
                "-p", "tcp", "-m", "multiport", "!", "--dports", strings.Join(ports, ","),
                "-j", "DNAT", "--to-destination", vars.HoneypotPolicy.Backend)

            ret, err := exec.Command("/sbin/iptables", "-t", "nat", "-A", "HONEYPOT", "-i", setting.Interface,
                "-p", "tcp", "-m", "multiport", "!", "--dports", strings.Join(ports, ","), "-j",
                "DNAT", "--to-destination", vars.HoneypotPolicy.Backend).Output()
            logger.Log.Println(ret, err)
        }
    } 
1 31

github泄露巡航系统开发

概述

github敏感信息泄露一直是企业信息泄露和知识产权泄露的重灾区,安全意识薄弱的同事经常会将公司的代码、各种服务的账户等极度敏感的信息『开源』到github中,github也是黑、白帽子、安全工程师的必争之地,作为甲方的安全工程师,我们需要一套可以定期自动扫描特定的关键字系统,以期第一时间发现猪队友同事泄露出去的敏感信息。

积极响应开源号召的同学请开自己业余的项目,公司的产品代码、各系统账户属于公司的资产,擅自对外界公布属于侵犯公司的知识产权的行为,是违法的,造成后果严重者,不仅会被公司开除,还需承担相应的法律责任。

接下来我们一起来看看如何写一款github泄露扫描系统。

功能需求

虽然写代码可以一把梭,但一把梭之前需要先把要写的功能清单列一下,我们的github扫描系统会实现以下功能:

  1. 双引擎搜索,github code接口搜索全局github以及本地搜索例行监控的repos
  2. 支持对指定的用户、仓库、组织进行监控
  3. 提供WEB管理界面,支持规则管理(github搜索规则及本地repos搜索规则)
  4. 支持github token管理和用户管理
  5. 扫描结果审核

已经完成的项目的地址为:https://github.com/xiaomisec/x-patrol

1 4

设计灵敏的蜜罐传感器

设计灵敏的蜜罐传感器

以前我写过一篇蜜罐设计的文章自制蜜罐之前端部分,https://xsec.io/2016/7/8/how-to-develop-a-honeypot.html,这个蜜罐的传感器实现的原理是设置iptables的LOG指令,将NEW,ESTABLISHED,RELATED三种状态的连接信息记录到syslog中,然后再通过rsyslog的转发机制发送到蜜罐server中进行检测:

exec.Command("/sbin/iptables", "-t", "nat", "-A", "HONEYPOT", "-p", "tcp", "-m", "state",
        "--state", "NEW,ESTABLISHED,RELATED", "-j", "LOG", "--log-prefix", "iptables_honeypot").Run()

tips:iptables的几种状态

ESTABLISHED:表示包是完全有效的,而且属于一个已建立的连接,这个连接的两端都已经有数据发送。
NEW:表示包将要或已经开始建立一个新的连接,或者是这个包和一个还没有在两端都有数据发送的连接有关。
RELATED:表示包正在建立一个新的连接,这个连接是和一个已建立的连接相关的。比如,FTP data transfer,ICMP error 和一个TCP或UDP连接相关
INVALID:表示这个包没有已知的流或连接与之关联,也可能是它包含的数据或包头有问题

这个蜜罐的弊端是只能检测到有状态的扫描尝试,比如对Server端支持的服务的攻击尝试,对于server端没有监听的端口的扫描尝试,传感器是检测不到的。于是笔者打算把数据捕获模块更换一下,用sniff本地网卡的方式替换掉以前的iptables的LOG指令。

实现原理

利用libpcap库监听本地指定网卡的数据,先过一次白名单,将白名单中的数据忽略,将不在白名单中的的IP 五元组信息通过http的方式发到server端进行检测、报警。

使用libpcap抓包的前置条件是安装并设置数据转发

# centos
yum install -y libpcap-devel
# Debian/Ubuntu
sudo apt-get install -y libpcap-dev
# OSX
brew install libpcap

# OSX
sudo sysctl net.inet.ip.forwarding=1
# FreeBSD
sudo sysctl -w net.inet.ip.forwarding=1
# Linux
sudo sysctl -w net.ipv4.ip_forward=1
12 29

『安全开发教程』年轻人的第一款弱口令扫描器

概述

我们在做企业安全时,弱口令检测是系统/网络安全的最基础的部分之一,根据经验,经常会出现弱口令的服务如下:

  • FTP
  • SSH
  • SMB
  • MYSQL
  • MSSQL
  • POSTGRESQL
  • REDIS
  • MONGODB
  • ELASTICSEARCH

那咱们就一起用GO来写一款常见服务的弱口令扫描器,且支持以插件的形式增加新的服务扫描模块。我们的教程暂定为只扫以上服务。

给扫描器启一个屌炸天的名字x-crack,在$GOPATH/src/中建立一个x-crack项目后开始撸码,不要给我说什么底层原理、框架内核,老夫敲代码就是一把梭。

开发完毕的项目地址为:https://github.com/netxfly/x-crack

Next