Feature request: REST based fallback for older clients
Closed this issue · 7 comments
Would it be possible to create an option which simply starts an HTTP(S) REST server which a browser can continuously ping for updated commands.
Example
- Server starts with the
--rest
option - Server starts an HTTP(S) server on the configured ports
- Client executes code, but doesn't support websockets
- Client switches to REST and uses an HTTP GET call to get a buffer of code every x milliseconds
- Server sends response and clears the buffer for related session
- Client eval's the code passed to it, and POST's it back to the server as a response
- Server echoes the output to the user
That definitely seems possible. I've attempted this before using xmlhttprequests and a thin webserver.
I didn't get it fully functional so I scrapped the idea.
If you or anyone else wanted to work on this I'd merge it or help on it.
I'll be out for around a week but I'll research this and attempt to create it myself if no one else has when I get back.
@IMcPwn I just wrote a JavaScript class which uses the same naming convention of the WebSocket
class for module compatibility purposes, all you'd need to do is implement the Ruby code to make it work (as I don't have any experience writing Ruby, I'd most likely turn it into a giant mess)
I currently have the class set up to use the following logic:
- Server starts a WebSocket and HTTP server
- Client runs the payload, but is using an older browser (such as IE)
- Client creates a new instance of the
RestSocket
class - Client connects to the web server and sends an
HTTP GET
request to/session
- Server registers the client and assigns it a session ID which it sends back
- Client stores the session ID in an instance variable
- Client continuously makes
HTTP GET
requests to/buffer/<id>
- Server answers by returning the buffer of commands that the person running the server has sent
- Client
eval
s the code, and returns the response by making anHTTP POST
request to/buffer/<id>
- When the client calls
close()
, anHTTP DELETE
call is made to/session
instructing the server to empty the buffer and remove the client from the session list
I currently have the code for this on my gist. If you like the idea, I could make a PR to update the code.
Thanks a ton for your effort on this!
I think I'll need to implement a static way of setting session IDs first. Issue #31
I would like them to be unique and always increment starting at 1. I've had trouble adding this in the past so as of now session IDs are reused once the session closes which is bad.
This may be a more work than you thought, if you're still interested let me know.
Could you maybe point me in the right direction for this? I can't seem to find where the ID's are generated in the code
Currently IDs are not generated. They are added to an array: https://github.com/IMcPwn/browser-backdoor/blob/master/server/lib/bbs/websocket.rb
Then whenever you access a specific session the index of the array is used as the ID.
I think I'll need to store sessions in a hash instead of an array and have an "id" field which is used and generated at session creation time.
Once I'm home in a couple of days I'll try to set this up.
You could simply set the index to nil
instead of calling Array.delete
, that way you'll keep the index without it being re-used. As far as I can see you only do this on line 50
and 61
. If you use this snippet instead it might work:
@@wsList[ @@wsList.index(ws) ] = nil
There's going to be more to it than that. See: https://github.com/IMcPwn/browser-backdoor/blob/master/server/lib/bbs/commands.rb
I'll start attempting to update the backend tomorrow.