gaynoise/main.go

351 lines
7.1 KiB
Go

package main
import (
"bufio"
"encoding/binary"
"flag"
"fmt"
"math/rand"
"net"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
var (
// flags
cidr = flag.String("r", "", "")
targlist = flag.String("l", "", "")
duration = flag.Int("t", -1, "")
workers = flag.Int("c", 10, "")
delay = flag.Int("u", 0, "")
// colors
colorReset = "\033[0m"
colorRed = "\033[31m"
colorPurple = "\033[35m"
colorCyan = "\033[36m"
skull = "\u2620"
// target ports
ports = []int{21, 22, 23, 25, 53, 80, 81, 123, 389, 443, 445, 999, 1080, 1433, 2323, 5555, 5900, 7547, 8080, 8081, 8888}
)
func winsize(system int) uint16 {
switch system {
case 1:
return 29200 // Linux
case 2:
return 5840 // Linux
case 3:
return 5720 // Linux
case 4:
return 10220 // Linux
case 5:
return 14600 // Linux
case 6:
return 8192 // Windows
case 7:
return 65535 // Windows
case 8:
return 65535 // MacOS, FreeBSD
case 9:
return 16384 // OpenBSD
case 10:
return 4128 // Cisco IOS
case 11:
return 32850 // Solaris
case 12:
return 49640 // Solaris
default:
return 8192
}
}
func ittl(system int) uint8 {
switch system {
case 6:
return 128 // Windows
case 7:
return 128 // Windows
case 10:
return 255 // Cisco IOS
default:
return 64 // Linux, MacOS, FreeBSD, OpenBSD, Solaris
}
}
func assemble(daddr, saddr string, dport, sport, system int) ([]byte, error) {
ip := &layers.IPv4{
SrcIP: net.ParseIP(saddr).To4(),
DstIP: net.ParseIP(daddr).To4(),
Version: 4,
TTL: ittl(system),
Protocol: layers.IPProtocolTCP,
}
tcp := &layers.TCP{
SrcPort: layers.TCPPort(sport),
DstPort: layers.TCPPort(dport),
Window: winsize(system),
Seq: rand.Uint32(),
SYN: true,
}
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
payload := []byte{}
pl := gopacket.Payload(payload)
buf := gopacket.NewSerializeBuffer()
if err := tcp.SetNetworkLayerForChecksum(ip); err != nil {
return nil, err
}
if err := gopacket.SerializeLayers(buf, opts, ip, tcp, pl); err != nil {
return nil, err
}
packet := buf.Bytes()
return packet, nil
}
func rfc1918(ip net.IP) bool {
_, net0, _ := net.ParseCIDR("0.0.0.0/8")
_, net10, _ := net.ParseCIDR("10.0.0.0/8")
_, net192, _ := net.ParseCIDR("192.168.0.0/16")
_, net172, _ := net.ParseCIDR("172.16.0.0/12")
if net0.Contains(ip) || net10.Contains(ip) || net192.Contains(ip) || net172.Contains(ip) {
return true
}
return false
}
func sendpacket(fd int, packet []byte, addr string) error {
ip := net.ParseIP(addr)
dest := format4(ip)
if err := syscall.Sendto(fd, packet, 0, &dest); err != nil {
return err
}
return nil
}
func rawsocket() (int, error) {
handler, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
if err != nil {
return -1, err
}
return handler, nil
}
func format4(ip net.IP) (addr syscall.SockaddrInet4) {
addr = syscall.SockaddrInet4{Port: 0}
copy(addr.Addr[:], ip.To4()[0:4])
return addr
}
func runCIDR(cidr string, out chan string) error {
ip, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return err
}
for target := ip.Mask(ipnet.Mask); ipnet.Contains(target); inc(target) {
if rfc1918(target) {
continue
}
addr, _ := net.ResolveIPAddr("ip", target.String())
out <- addr.String()
}
return nil
}
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
func randIP() string {
for {
buf := make([]byte, 4)
ip := rand.Uint32()
binary.LittleEndian.PutUint32(buf, ip)
nip := net.IP(buf)
if !rfc1918(nip) {
return nip.String()
}
}
}
func thread(addrs chan string) {
sock, err := rawsocket()
if err != nil {
fatal(err.Error())
}
defer syscall.Close(sock)
for addr := range addrs {
rip := randIP()
dport := ports[rand.Intn(len(ports))]
sport := 1024 + rand.Intn(64511)
syst := 1 + rand.Intn(11)
pkt, _ := assemble(addr, rip, dport, sport, syst)
fmt.Printf("[%s%s%s] %s%s:%d%s -> %s%s%s:%s%d%s\n", colorRed, sysident(syst), colorReset, colorCyan, rip, sport, colorReset, colorPurple, addr, colorReset, colorCyan, dport, colorReset)
sendpacket(sock, pkt, addr)
time.Sleep(time.Microsecond * time.Duration(*delay))
}
}
func sysident(id int) string {
if id >= 1 && id <= 5 {
return "Linux"
} else if id >= 6 && id <= 7 {
return "Windows"
} else if id == 8 {
return "MacOS/FreeBSD"
} else if id == 9 {
return "OpenBSD"
} else if id == 10 {
return "Cisco IOS"
} else if id >= 11 && id <= 12 {
return "Solaris"
} else {
return "Windows"
}
}
func banner() {
fmt.Printf(`
%sgot some intelligence for u
right here%s%s
_ _
|_| |_|
| | /^^^\ | |
_| |_ (| "o" |) _| |_
_| | | | _ (_---_) _ | | | |_
| | | | |' | _| |_ | '| | | | |
| | / \ | |
\ / / /(. .)\ \ \ /
\ / / / | . | \ \ \ /
\ \/ / ||Y|| \ \/ /
\__/ || || \__/
() ()
|| ||
ooO Ooo
%s%sg a y n o i s e%s
sincerely,
~ delorean
`, colorRed, colorReset, colorCyan, colorReset, colorPurple, colorReset)
}
func usage() {
fmt.Fprintf(os.Stderr, `gaynoise:
(%s-r%s) - cidr range [%s0.0.0.0/0%s]
(%s-l%s) - target cidr list
(%s-c%s) - concurrent threads [%s100%s]
(%s-t%s) - duration [%s-1%s]
(%s-p%s) - usec delay between sends [%s0%s]
`, colorCyan, colorReset, colorPurple, colorReset, colorCyan, colorReset, colorCyan, colorReset, colorPurple, colorReset, colorCyan, colorReset, colorPurple, colorReset, colorCyan, colorReset, colorPurple, colorReset)
}
func fatal(e string) {
fmt.Printf("%s %s error:%s %s\n", colorRed, skull, colorReset, e)
os.Exit(-1)
}
func alarm(secs int) {
time.Sleep(time.Second * time.Duration(secs))
os.Exit(0)
}
func parsetargets(list string) []string {
fd, err := os.Open(list)
if err != nil {
fatal(err.Error())
}
defer fd.Close()
var targets []string
fs := bufio.NewScanner(fd)
for fs.Scan() {
line := strings.TrimSpace(fs.Text())
if len(line) > 0 {
if _, _, err := net.ParseCIDR(line); err == nil {
targets = append(targets, line)
}
}
}
if len(targets) == 0 {
fatal("no valid ranges parsed from file")
}
return targets
}
func main() {
flag.Usage = usage
flag.Parse()
var targets []string
if *targlist != "" {
targets = parsetargets(*targlist)
} else if *cidr == "" {
targets = []string{"0.0.0.0/0"}
} else {
targets = []string{*cidr}
}
// signals
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigs
fmt.Printf("\n%s%s Stopped%s\n", colorRed, skull, colorReset)
os.Exit(1)
}()
// threads
addrs := make(chan string)
go func() {
for x := 0; x < *workers; x++ {
thread(addrs)
}
}()
// start alarm
if *duration > 0 {
go alarm(*duration)
}
banner()
for {
for _, target := range targets {
if err := runCIDR(target, addrs); err != nil {
fatal(err.Error())
}
}
}
}