Skip to content

Instantly share code, notes, and snippets.

@fortuna
Last active October 23, 2020 15:51
Show Gist options
  • Save fortuna/999a0a30626cb4997f517fa3b407a862 to your computer and use it in GitHub Desktop.
Save fortuna/999a0a30626cb4997f517fa3b407a862 to your computer and use it in GitHub Desktop.
Dial-back Echo Server
package main
import (
"io"
"log"
"net"
"os"
"sync"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/op/go-logging"
)
// Requires firewall rule to block incoming SYNs. Using PF:
// sudo pfctl -a com.apple/redial -f pf.conf
// block drop in proto tcp from any to port 8080 flags S/SA
var logger = logging.MustGetLogger("")
func main() {
var running sync.WaitGroup
// // Reference:
// // https://www.devdungeon.com/content/packet-capture-injection-and-analysis-gopacket
inactiveHandle, err := pcap.NewInactiveHandle("lo0")
if err != nil {
log.Fatal(err)
}
defer inactiveHandle.CleanUp()
inactiveHandle.SetImmediateMode(true)
inactiveHandle.SetPromisc(false)
inactiveHandle.SetSnapLen(1024)
handle, err := inactiveHandle.Activate()
if err != nil {
log.Fatal(err)
}
defer handle.Close()
// Capture SYNs
err = handle.SetBPFFilter("tcp[tcpflags] == tcp-syn and dst port 8080")
if err != nil {
log.Fatal(err)
}
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
packetChan := packetSource.Packets()
logger.Info("Waiting for SYN packets")
for packet := range packetChan {
running.Add(1)
go func() {
defer running.Done()
logger.Info("Got packet")
// Process packet here
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer == nil {
return
}
tcpInfo, _ := tcpLayer.(*layers.TCP)
ipLayer := packet.Layer(layers.LayerTypeIPv4)
ipInfo, _ := ipLayer.(*layers.IPv4)
logger.Infof("Got packet syn: %v\n src %v:%d, dst %v:%d",
tcpInfo.SYN, ipInfo.SrcIP, tcpInfo.SrcPort, ipInfo.DstIP, tcpInfo.DstPort)
tcpConn, err := net.DialTCP("tcp",
&net.TCPAddr{IP: ipInfo.DstIP, Port: int(tcpInfo.DstPort)},
&net.TCPAddr{IP: ipInfo.SrcIP, Port: int(tcpInfo.SrcPort)})
if err != nil {
logger.Fatal(err)
}
logger.Info("Server Dial done")
io.Copy(tcpConn, tcpConn)
tcpConn.Close()
logger.Info("Request processed")
}
logger.Info("No more packets")
}()
running.Wait()
}
# Useful:
# https://robert-chalmers.uk/2018/10/03/protect-your-mac-with-pf-the-all-powerful-firewall/
# https://www.openbsdhandbook.com/pf/filter/
block drop in proto tcp from any to port 8080 flags S/SA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment