pwntools icon indicating copy to clipboard operation
pwntools copied to clipboard

Make interactive() exit when recv side disconnects

Open gsingh93 opened this issue 2 years ago • 6 comments

This needs more testing and discussion, but I wanted to create a PR to at least see if this approach would work or whether this needs to be done in a completely different way.

This PR addresses https://github.com/Gallopsled/pwntools/issues/2106. I want tubes.interactive() to break out of its loop when it receives an EOF from the remote side. Currently if this happens, the send side will not break because it's blocked waiting for user input, and only after pressing enter does it try to send to the remote and see that it's disconnected.

My solution is to:

  1. Set go.set() in the receiving thread so the sending side knows that the receiving side disconnected.
  2. Instead of waiting indefinitely for a key press, wait for a timeout of 1 second, and then only report a sender EOF if the bytes read is 0 and not None (which would have meant a timeout occured). If there's no EOF, the loop continues to iterate and poll for input every second.

This works locally, and while it seems like there are some test cases I need to fix, I wanted to check if this general approach is OK before I put more time into it, or if there are any obvious problems with it that can't be easily fixed or if there's an overall better approach to this.

gsingh93 avatar Sep 13 '22 16:09 gsingh93

I haven't really looked at this problem at all, but can't we do something like select(...) on both network and stdin and either handle the network or stdin event?

You can definetely detect disconnects with select(), see https://stackoverflow.com/a/17818000/1508881

disconnect3d avatar Sep 22 '22 01:09 disconnect3d

Thanks! I originally didn't do that because it seemed complex, but I got something working. There's more code changes and it's a bit confusing, but it avoids modifying any of the internals of readline.

gsingh93 avatar Sep 22 '22 03:09 gsingh93

Although I will say, even though I'm catching the exception that's thrown when the process is stopped, this is still output from the logging:

[ERROR] A stopped process does not have a file number

gsingh93 avatar Sep 22 '22 03:09 gsingh93

select is a Linux syscall. I plan to remove it in a favor of a portable plan in a far future. At this momenbt I do not know what to advice...

gogo2464 avatar Dec 12 '22 22:12 gogo2464

One thing I believe should be considered is an option to keep current behaviour: now if the recv side disconnects, you can still send 'blind' TCP packets to it; I remember this was useful in a couple CTF challenges.

Arusekk avatar Jul 09 '23 13:07 Arusekk