Skip to content

Commit

Permalink
Merge branch 'master' into feature-smtp-auth
Browse files Browse the repository at this point in the history
  • Loading branch information
fvdveen committed Sep 11, 2018
2 parents 35aca31 + 32d1df9 commit 3345846
Show file tree
Hide file tree
Showing 139 changed files with 3,941 additions and 1,384 deletions.
216 changes: 205 additions & 11 deletions Gopkg.lock

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (

"github.com/BurntSushi/toml"
"github.com/op/go-logging"
"fmt"
)

var log = logging.MustGetLogger("honeytrap:config")
Expand Down Expand Up @@ -80,7 +81,10 @@ func (c *Config) Load(r io.Reader) error {
}
c.MetaData = md

logBackends := []logging.Backend{}
if len(c.Logging) == 0 {
fmt.Println("Warning: no logging backends configured. Add one to view log messages.")
}
var logBackends []logging.Backend
for _, log := range c.Logging {
var err error

Expand Down
287 changes: 284 additions & 3 deletions listener/netstack-experimental/netstack_linux.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// +build linux,!amd64

/*
* Honeytrap
* Copyright (C) 2016-2017 DutchSec (https://dutchsec.com/)
Expand Down Expand Up @@ -33,11 +31,294 @@
package netstack

import (
"context"
"fmt"
"net"
"strings"
"syscall"

"github.com/vishvananda/netlink"

"github.com/honeytrap/honeytrap/listener"
"github.com/honeytrap/honeytrap/pushers"

"github.com/google/netstack/tcpip"
"github.com/google/netstack/tcpip/adapters/gonet"
"github.com/google/netstack/tcpip/link/fdbased"
"github.com/google/netstack/tcpip/link/rawfile"
"github.com/google/netstack/tcpip/link/sniffer"
"github.com/google/netstack/tcpip/link/tun"
"github.com/google/netstack/tcpip/network/ipv4"
"github.com/google/netstack/tcpip/network/ipv6"
"github.com/google/netstack/tcpip/stack"
"github.com/google/netstack/tcpip/transport/tcp"
"github.com/google/netstack/tcpip/transport/udp"
"github.com/google/netstack/waiter"
)

// todo
// port /whitelist filtering (8022)
// custom (irs )

type netstackConfig struct {
Addresses []net.Addr

Addr string `toml:"addr"`
Interfaces []string `toml:"interfaces"`

Debug bool `toml:"debug"`
}

func (nc *netstackConfig) AddAddress(a net.Addr) {
nc.Addresses = append(nc.Addresses, a)
}

type netstackListener struct {
netstackConfig

s *stack.Stack

ch chan net.Conn

eb pushers.Channel
}

func (l *netstackListener) SetChannel(eb pushers.Channel) {
l.eb = eb
}

func New(options ...func(listener.Listener) error) (listener.Listener, error) {
return nil, fmt.Errorf("Netstack is not supported on ARM")
ch := make(chan net.Conn)

l := netstackListener{
netstackConfig: netstackConfig{},
eb: pushers.MustDummy(),
ch: ch,
}

for _, option := range options {
option(&l)
}

if len(l.Interfaces) == 0 {
return nil, fmt.Errorf("No interface defined")
} else if len(l.Interfaces) > 1 {
return nil, fmt.Errorf("Only one interface is supported currently")
}

return &l, nil
}

// ipToAddressAndProto converts IP to tcpip.Address and a protocol number.
//
// Note: don't use 'len(ip)' to determine IP version because length is always 16.
func ipToAddressAndProto(ip net.IP) (tcpip.NetworkProtocolNumber, tcpip.Address) {
if i4 := ip.To4(); i4 != nil {
return ipv4.ProtocolNumber, tcpip.Address(i4)
}
return ipv6.ProtocolNumber, tcpip.Address(ip)
}

// ipToAddress converts IP to tcpip.Address, ignoring the protocol.
func ipToAddress(ip net.IP) tcpip.Address {
_, addr := ipToAddressAndProto(ip)
return addr
}

func htons(n uint16) uint16 {
var (
high = n >> 8
ret = n<<8 + high
)

return ret
}

func (l *netstackListener) Start(ctx context.Context) error {
intfName := l.Interfaces[0]

mtu, err := rawfile.GetMTU(intfName)
if err != nil {
return err
}

ifaceLink, err := netlink.LinkByName(intfName)
if err != nil {
return fmt.Errorf("unable to bind to %q: %v", "1", err)
}

var fd int

if strings.HasPrefix(intfName, "tun") {
fd, err = tun.Open(intfName)
if err != nil {
return fmt.Errorf("Could not open tun interface: %s", err.Error())
}
} else if strings.HasPrefix(intfName, "tap") {
fd, err = tun.OpenTAP(intfName)
if err != nil {
return fmt.Errorf("Could not open tap interface: %s", err.Error())
}
} else {
fd, err = syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(htons(syscall.ETH_P_ALL)))
if err != nil {
return fmt.Errorf("Could not create socket: %s", err.Error())
}

if fd < 0 {
return fmt.Errorf("Socket error: return < 0")
}

if err = syscall.SetNonblock(fd, true); err != nil {
syscall.Close(fd)
return fmt.Errorf("Error setting fd to nonblock: %s", err)
}

ll := syscall.SockaddrLinklayer{
Protocol: htons(syscall.ETH_P_ALL),
Ifindex: ifaceLink.Attrs().Index,
Hatype: 0, // No ARP type.
Pkttype: syscall.PACKET_HOST,
}

if err := syscall.Bind(fd, &ll); err != nil {
return fmt.Errorf("unable to bind to %q: %v", "iface.Name", err)
}
}

la := tcpip.LinkAddress(ifaceLink.Attrs().HardwareAddr)

linkID := fdbased.New(&fdbased.Options{
FD: fd,
MTU: mtu,
EthernetHeader: true,
ChecksumOffload: false,
Address: la,
ClosedFunc: func(e *tcpip.Error) {
if e != nil {
log.Errorf("File descriptor closed: %v", e.String())
}
},
})

if l.Debug {
linkID = sniffer.New(linkID)
}

routes := []tcpip.Route{}

link := ifaceLink

rs, err := netlink.RouteList(link, netlink.FAMILY_ALL)
if err != nil {
return fmt.Errorf("error getting routes from %q: %v", link.Attrs().Name, err)
}

for _, r := range rs {
// Is it a default route?
if r.Dst == nil {
if r.Gw == nil {
return fmt.Errorf("default route with no gateway %q: %+v", link.Attrs().Name, r)
}
if r.Gw.To4() == nil {
log.Warningf("IPv6 is not supported, skipping default route: %v", r)
continue
}

routes = append(routes, tcpip.Route{
Destination: ipToAddress(net.IPv4zero),
Mask: ipToAddress(net.IP(net.IPMask(net.IPv4zero))),
Gateway: ipToAddress(r.Gw),
})
continue
}
if r.Dst.IP.To4() == nil {
log.Warningf("IPv6 is not supported, skipping route: %v", r)
continue
}
routes = append(routes, tcpip.Route{
Destination: ipToAddress(r.Dst.IP.Mask(r.Dst.Mask)),
Mask: ipToAddress(net.IP(net.IPMask(r.Dst.Mask))),
})
}

s := stack.New([]string{ipv4.ProtocolName, ipv6.ProtocolName}, []string{tcp.ProtocolName, udp.ProtocolName}, stack.Options{})

if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, tcp.RSTDisabled(true)); err != nil {
return fmt.Errorf("Could not set transport protocol option: %s", err.String())
}

s.AddTCPProbe(func(s stack.TCPEndpointState) {
})

s.SetRouteTable(routes)

fwd := tcp.NewForwarder(s, 30000, 10, func(r *tcp.ForwarderRequest) {
var wq waiter.Queue
ep, err := r.CreateEndpoint(&wq)
if err != nil {
// cleanup
r.Complete(false)

log.Errorf("Error creating endpoint: %s", err)
return
}

r.Complete(false)

c := gonet.NewConn(&wq, ep)
l.ch <- c
})

s.SetTransportProtocolHandler(tcp.ProtocolNumber, fwd.HandlePacket)

if err := s.CreateNIC(1, linkID); err != nil {
return fmt.Errorf(err.String())
}

addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
if err != nil {
return fmt.Errorf("Error retrieving interface ip addresses: %s", err.Error())
}

if l.Addr != "" {
if addr, err := netlink.ParseAddr(l.Addr); err == nil {
addrs = []netlink.Addr{*addr}
} else {
return fmt.Errorf("Bad IP address: %v: %s", l.Addr, err)
}
}

for _, parsedAddr := range addrs {
var addr tcpip.Address
var proto tcpip.NetworkProtocolNumber

if _, bits := parsedAddr.Mask.Size(); bits == 32 {
addr = tcpip.Address(parsedAddr.IP)
proto = ipv4.ProtocolNumber
} else if _, bits := parsedAddr.Mask.Size(); bits == 256 {
addr = tcpip.Address(parsedAddr.IP)
proto = ipv6.ProtocolNumber
} else {
return fmt.Errorf("Unknown IP type: %v, bits=%d", l.Addr, bits)
}

log.Debugf("Listening on: %s (%d)\n", parsedAddr.String(), proto)

// s.AddSubnet()
if err := s.AddAddress(1, proto, addr); err != nil {
return fmt.Errorf(err.String())
}
}

s.SetSpoofing(1, true)

l.s = s

return nil
}

func (l *netstackListener) Accept() (net.Conn, error) {
c := <-l.ch
return c, nil
}
Loading

0 comments on commit 3345846

Please sign in to comment.