-
Notifications
You must be signed in to change notification settings - Fork 23
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
Fix metasploit-framework#15968 (Multiple Socket Abstraction Bugs) #20
Conversation
begin | ||
cli = accept | ||
unless cli | ||
elog('The accept() returned nil in stream server listener monitor') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dropped the fd.inspect
part because fd
isn't available in Meterpreter channels which caused an exception to be thrown.
|
||
module MonitoredRSock | ||
def close | ||
@close_requested = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only ever goes from true to false so I don't think there's a synchronization problem here but if another solution is preferred happy to go a different direction.
end | ||
break | ||
|
||
rsock.sysclose |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now the one and only location where a monitored rsock
will actually be closed. Other attempts to close it will result in the request being made and it's up to this loop to honor it and exit.
Thanks for looking into this! 🎉 Would you mind throwing up a separate PR for that first rubocop commit and I can ship that ASAP, it would just help make the git history a bit cleaner. Or I can cherry-pick your first commit and create a separate PR as well if that's easier - just let me know which you'd prefer 👍 |
Sure thing, see #21. I can rebase this one once that's landed. |
@zeroSteiner Merged, thanks! |
15eabe0
to
ecb278f
Compare
Thanks, this has been rebased now so it's a lot easier to review. |
Sorry, didn't realize there was a second commit related to running rubocop - grabbed that into master now too: #22 Also added Github actions to this repository to ensure that the test suite runs, although it looks like we don't have a lot of tests for this specific functionality that's being changed |
The monitor thread will notice that the lsock has been closed so wait for it to exit after processing all of the data that needed to be sent.
This means that if the rsock is closed from another thread like a DIO handler that the monitor thread can ensure that it has processed all data before closing it.
ecb278f
to
caa6027
Compare
@@ -182,14 +202,18 @@ def monitor_rsock(threadname = 'SocketMonitorRemote') | |||
|
|||
begin | |||
close_write if respond_to?('close_write') | |||
rescue IOError | |||
rescue StandardError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to mention, the Meterpreter error raised when calling close_write
on an invalid handle is not derived from IOError
so I changed this to StandardError
.
Pull in the changes from rapid7/rex-core#20
Pull in the changes from rapid7/rex-core#20
Pull in the changes from rapid7/rex-core#20
This fixes multiple issues I ran into while working on rapid7/metasploit-framework#15968. I also ran rubocop on the two files which accounts for quite a few of their changes. Each was done in a dedicated commit, so hopefully that will help isolate those changes from the actual fixes.
The core of the issues results in a users inability to open a reverse_http Meterpreter session over a pivot/port-forward. A user should be able to either start a local handler and portforward to it via Meterpreter or start a handler via a Meterpreter session directly (using the
ReverseListenerComm
datastore option). Without these changes, the Meterpreter session would consistently fail to be established. The user would see that the stage was being sent, but the session would never be fully opened and responsive. I tracked the issue down to the socket abstraction that would close the connection before the entire HTTP response had been sent due to a race condition.Testing
-1
shortcut does not work yet)The original issue mentioned using an explicit
portfwd
. While not strictly necessary to exercise the applicable code path, you can do so by modifying the steps to star the handler on the local Metasploit host and using a Meterpreter session opened in step 1 to start a reverse portforward. An SSH session won't work for this purpose because a single port can be forward since theportfwd
command is a Meterpreter-specific command.