view src/netcat.go @ 29:0f05c342fde1

gogemo v1.2 ( compress by bzip2 & English dictionary )
author pyon@macmini
date Sat, 23 Feb 2019 15:53:53 +0900
parents b0784443ed87
children
line wrap: on
line source

// OK : windows -> osx 
// Not OK : osx -> windows
// OK : osx, win <-> yahoo.com
/*
 Netcat

 -v  verbose
 -vv very verbose
 -w  timeout [ -w 2 2seconds ]
 -i  interval
 -s  local source address
 -z  zero-I/O mode ( for portscan )
 -u  with UDP ( default use TCP )
 -n  don't resolve name/address
 -d  stealth mode ( don't read from stdin )
 -l  listen mode ( once )
 -L  listen mode ( continuous )

 Portscan
 $ nc -v -z -w 1 192.168.1.1 1-140
 $ nc -u -v -z -w 1 192.168.1.1 1-140

 Web-client
 $ nc -v www.yahoo.com 80

 File transfer
 $ nc -l 1234 >  file
 % nc hoge.com 1234 < file

 Backdoor
 C:\> nc -L -d -e cmd.exe -p 8080

 */
package main

import (
    "flag"
    "fmt"
    "io"
    "log"
    "net"
    "os"
)

func main() {

    verbose  := flag.Bool( "v", false, "verbose" )
    vverbose := flag.Bool( "vv", false, "very verbose" )
    udp      := flag.Bool( "u", false, "with udp" )
//    interval := flag.Int( "i", 0, "interval for lines sent, port scanned" )
//    timeout := flag.Int( "w", 7, "timeout for connects and final net reads" )
    listen   := flag.Bool( "l", false, "listen mode" )
    zmode    := flag.Bool( "z", false, "zero-I/O mode" )
    laddr    := flag.String( "s", "", "local source address" )
    example  := flag.Bool( "e", false, "print examples" )

    flag.Parse()

    if *example {
        printExample()
        os.Exit( 0 )
    }

    if flag.NArg() == 0 {
        fmt.Fprintf( os.Stderr, "netcat v0.1 (20170604)\n" )
        fmt.Fprintf( os.Stderr, " -h or --help option\n" )
        os.Exit( 0 )
    }

    p := "tcp"
    if *udp {
        p = "udp"
    }

    if *listen {

        if flag.NArg() != 1 {
            flag.PrintDefaults()
            os.Exit( 1 )
        }

        port := flag.Arg( 0 )

        addr := getLocalIP()
        if *laddr == "" {
            addr = *laddr
        }

        if *verbose || *vverbose {
            msg := fmt.Sprintf( "listening... %s:%s[%s]", addr, port, p )
            printVerbose( msg, "" )
        }

        l, err := net.Listen( p, net.JoinHostPort( addr, port ) )
        if err != nil {
            log.Fatal( err )
        }
        defer l.Close()

        conn, err := l.Accept()
        if err != nil {
            log.Fatal( err )
        }
        io.Copy( os.Stdout, conn )
        conn.Close()

    } else {

        if flag.NArg() != 2 {
            flag.PrintDefaults()
            os.Exit( 1 )
        }

        addr := flag.Arg( 0 )
        port := flag.Arg( 1 )

        conn, err := net.Dial( p, net.JoinHostPort( addr, port ) )
        if err != nil {
            log.Fatal( err )
        }
        defer conn.Close()
        go mustCopy( os.Stdout, conn )
        mustCopy( conn, os.Stdin )
    }

    if *zmode {
        /*
        address := "" // for me.
        port := "1-1024"
        server := address + ":" + port
        */
    }
}

func mustCopy( dst io.Writer, src io.Reader ) {
    if _, err := io.Copy( dst, src ); err != nil {
        log.Fatal( err )
    }
}

func printVerbose( vmsg, vvmsg string ) {
    fmt.Fprintln( os.Stderr, vmsg, vvmsg )
}

func printExample() {
    fmt.Fprintln( os.Stderr, "\n[Exaples]" )
    fmt.Fprintln( os.Stderr, "  Portscan" )
    fmt.Fprintln( os.Stderr, "   $ nc -v -z -w 1 192.168.1.1 1-140" )
    fmt.Fprintln( os.Stderr, "   $ nc -u -v -z -w 1 192.168.1.1 1-140\n" )
    fmt.Fprintln( os.Stderr, "  Web-client" )
    fmt.Fprintln( os.Stderr, "   $ nc -v www.yahoo.com 80" )
    fmt.Fprintln( os.Stderr, "   GET / HTTP/1.0[Enter]" )
    fmt.Fprintln( os.Stderr, "   [ENTER]\n" )
    fmt.Fprintln( os.Stderr, "  File transfer" )
    fmt.Fprintln( os.Stderr, "   $ nc -l 1234 >  file" )
    fmt.Fprintln( os.Stderr, "   % nc hoge.com 1234 < file\n" )
    fmt.Fprintln( os.Stderr, "  Backdoor" )
    fmt.Fprintln( os.Stderr, "   C:\\> nc -L -d -e cmd.exe -p 8080" )
}

func getLocalIP() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        log.Fatal( err )
    }
    for _, addr := range addrs {
        if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                return ipnet.IP.String()
            }
        }
    }
    return "127.0.0.1"
}