Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make interactive() exit when recv side disconnects #2108

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions pwnlib/tubes/tube.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import abc
import logging
import re
import select
import six
import string
import subprocess
Expand All @@ -17,6 +18,7 @@
from pwnlib import atexit
from pwnlib import term
from pwnlib.context import context
from pwnlib.exception import PwnlibException
from pwnlib.log import Logger
from pwnlib.timeout import Timeout
from pwnlib.tubes.buffer import Buffer
Expand Down Expand Up @@ -862,21 +864,33 @@ def recv_thread():
t.start()

try:
while not go.isSet():
if term.term_mode:
data = term.readline.readline(prompt = prompt, float = True)
else:
stdin = getattr(sys.stdin, 'buffer', sys.stdin)
data = stdin.read(1)
while not go.isSet() and self.connected():
# Block until there is input on stdin or there's input on the receiving side
try:
rfds, _, _ = select.select([sys.stdin, self], [], [])
except PwnlibException:
# If the process stops while we're waiting for input, an
# exception will be thrown
go.set()
continue

if data:
try:
self.send(data)
except EOFError:
# If the there's input on stdin, handle it. Otherwise, on the
# next iteration of the loop we'll check if the receiving side disconnected
if sys.stdin in rfds:
if term.term_mode:
data = term.readline.readline(prompt = prompt, float = True)
else:
stdin = getattr(sys.stdin, 'buffer', sys.stdin)
data = stdin.read(1)

if data:
try:
self.send(data)
except EOFError:
go.set()
self.info('Got EOF while sending in interactive')
else:
go.set()
self.info('Got EOF while sending in interactive')
else:
go.set()
except KeyboardInterrupt:
self.info('Interrupted')
go.set()
Expand Down